Несколько настроек и петли для настройки I2S для различных спектров - PullRequest
0 голосов
/ 28 октября 2018

Привет,

Я использую прорыв микрофона I2S MEMS Arduino MKR1000 и Adafruit SPH0645 для анализа звука.

Поскольку Arduino не способен рассчитывать БПФ в реальном времени с определеннымТочность, я хочу назначить разные размеры FFT для разных частотных интервалов.Существует библиотека ArduinoSound, которая выполняет операции FFT, но когда я выбираю частоту дискретизации 12 кГц (или более) и размер 128 FFT, Arduino прекращает вычисление.Я не уверен, что это связано с нехваткой памяти или скоростью процессора.

Я должен анализировать до 15 кГц (то есть с частотой дискретизации 30 кГц), но мне не нужен только один размер FFT.

До 1 кГц я хочу анализировать каждые 100 герц (или разные, но близкие могут быть 120-240 и т. Д.). Между 1 кГц и 10 кГц я хочу анализировать каждые 500 герц (или то же самое с частотой выше 600 Гц и т. Д.) И, наконец, до 15 кГц, яхочу анализировать каждые 800 герц (или 1200 Гц и т. д.)

Поэтому я хочу получить приблизительно эти частоты (не зацикливаясь на числах):

120-240-360-480-600-720-840-960-1400-1900-2300-2700-3100-3500-3900-4300-4700-5100-5500-5900-6300-6700-7100-7500-7900-8300-8700-9100-9500-9900-10800-11800-12800-13800-14800

Размер FFT от 0 до 1 кГц = 16

Размер FFT от 1 до 10 кГц = 32 (или 64)

Между 10-15 кГцFFTsize = 8 (или 16)

Мой начальный код:

#include <ArduinoSound.h>

// sample rate for the input
const int sampleRate = 8000;

// size of the FFT to compute
const int fftSize = 128;

// size of the spectrum output, half of FFT size
const int spectrumSize = fftSize / 2;

// array to store spectrum output
int spectrum[spectrumSize];

// create an FFT analyzer to be used with the I2S input
FFTAnalyzer fftAnalyzer(fftSize);

void setup() {
// Open serial communications and wait for port to open:
  // A baud rate of 115200 is used instead of 9600 for a faster data rate
  // on non-native USB ports
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // setup the I2S audio input for the sample rate with 32-bits per sample
  if (!AudioInI2S.begin(sampleRate, 32)) {
    Serial.println("Failed to initialize I2S input!");
    while (1); // do nothing
  }

  // configure the I2S input as the input for the FFT analyzer
  if (!fftAnalyzer.input(AudioInI2S)) {
    Serial.println("Failed to set FFT analyzer input!");
    while (1); // do nothing
  }
}

void loop() {
  // check if a new analysis is available
  if (fftAnalyzer.available()) {
    // read the new spectrum
    fftAnalyzer.read(spectrum, spectrumSize);

    // print out the spectrum
    for (int i = 0; i < spectrumSize; i++) {
      Serial.print((i * sampleRate) / fftSize); // the starting frequency
      Serial.print("\t"); // 
      Serial.println(spectrum[i]); // the spectrum value
    }
  }
}

Как вы видите в части void setup (), код конфигурирует образец I2Sоценить позначение в строке 4. Но я хочу использовать 3 различных sampleRate и fftSize.Если вам нужно больше разъяснений, пожалуйста, спросите.Я думал, что смогу решить эту проблему с 3 различными настройками и циклом, но я не знаю, как настроить мой код для достижения этой цели.Если вы также покажете, как каждый sampleRate может быть действительным только для определенного интервала (например, 1000-10000), я также уменьшу вычисления.Потому что sampleRate 2000 не будет игнорировать первые 1000 Гц в соответствии с моим кодом.

Я также загрузил свой модифицированный код, что неверно, но объясняет механизм.Мне нужно разделить его на несколько разделов.Я знаю, что могу сделать это с 3 различными кодами и Arduino, так как я могу сделать это только с одним.

#include <ArduinoSound.h>

// sample rate for the input
const int sampleRate1 = 2000;
const int sampleRate2 = 20000;
const int sampleRate3 = 30000;

// size of the FFT to compute
const int fftSize1 = 32;
const int fftSize2 = 64;
const int fftSize3 = 16;

// size of the spectrum output, half of FFT size
const int spectrumSize1 = fftSize1 / 2;
const int spectrumSize2 = fftSize2 / 2;
const int spectrumSize3 = fftSize3 / 2;

// array to store spectrum output
int spectrum1[spectrumSize1];
int spectrum2[spectrumSize2];
int spectrum3[spectrumSize3];

// create an FFT analyzer to be used with the I2S input
FFTAnalyzer fftAnalyzer1(fftSize1);
FFTAnalyzer fftAnalyzer2(fftSize2);
FFTAnalyzer fftAnalyzer3(fftSize3);

void setup() {
// Open serial communications and wait for port to open:
  // A baud rate of 115200 is used instead of 9600 for a faster data rate
  // on non-native USB ports
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // setup the I2S audio input for the sample rate with 32-bits per sample
  if (!AudioInI2S.begin(sampleRate1, 32)) {
    Serial.println("Failed to initialize I2S input!");
    while (1); // do nothing
  }
    if (!AudioInI2S.begin(sampleRate2, 32)) {
    Serial.println("Failed to initialize I2S input!");
    while (1); // do nothing
  }
    if (!AudioInI2S.begin(sampleRate3, 32)) {
    Serial.println("Failed to initialize I2S input!");
    while (1); // do nothing
  }

  // configure the I2S input as the input for the FFT analyzer
  if (!fftAnalyzer1.input(AudioInI2S)) {
    Serial.println("Failed to set FFT analyzer input!");
    while (1); // do nothing
  }
    if (!fftAnalyzer2.input(AudioInI2S)) {
    Serial.println("Failed to set FFT analyzer input!");
    while (1); // do nothing
  }
    if (!fftAnalyzer3.input(AudioInI2S)) {
    Serial.println("Failed to set FFT analyzer input!");
    while (1); // do nothing
  }
}

void loop() {
  {
  // check if a new analysis is available 
  if (fftAnalyzer1.available()) {
    // read the new spectrum
    fftAnalyzer1.read(spectrum1, spectrumSize1); }
      // check if a new analysis is available
  if (fftAnalyzer2.available()) {
    // read the new spectrum
    fftAnalyzer2.read(spectrum2, spectrumSize2); }
      // check if a new analysis is available
  if (fftAnalyzer3.available()) {
    // read the new spectrum
    fftAnalyzer3.read(spectrum3, spectrumSize3); }

    // print out the spectrum
    for (int i = 0; i < spectrumSize1; i++) {
      Serial.print((i * sampleRate1) / fftSize1); // the starting frequency
      Serial.print("\t"); // 
      Serial.println(spectrum1[i]); // the spectrum value
    }
        for (int i = 0; i < spectrumSize2; i++) {
      Serial.print((i * sampleRate2) / fftSize2); // the starting frequency
      Serial.print("\t"); // 
      Serial.println(spectrum2[i]); // the spectrum value
    }
        for (int i = 0; i < spectrumSize3; i++) {
      Serial.print((i * sampleRate3) / fftSize3); // the starting frequency
      Serial.print("\t"); // 
      Serial.println(spectrum3[i]); // the spectrum value
    }
  }
}
...