嗨,
我正在使用Arduino MKR1000和Adafruit SPH0645 I2S MEMS麦克风 突破以分析声音。
由于Arduino无法在特定条件下计算实时FFT 精度,我想为各种频率分配不同的FFT大小 间隔。有一个ArduinoSound库可以完成FFT 操作,但是当我选择12kHz(或更高)的采样率和128 FFTsize,Arduino停止计算。我不确定是否与 内存或处理器速度不足。
我必须分析直到15kHz(采样率为30kHz),但我不需要 只需要一个FFTsize。
直到1kHz,我要分析每100赫兹(或不同但接近 可能是120-240等)1kHz至10kHz之间,我想分析每500个 赫兹(或与600 Hz以上相同)等到15 Khz 每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
在0-1kHz FFTsize之间= 16
1-10kHz FFT大小之间= 32(或64)
在10-15kHz FFT大小之间= 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不会根据我的第一个忽略1000Hz 代码。
我还上传了修改后的代码,这是错误的,但解释了 机制。我需要将其分为多个部分。我知道我能做 它使用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
}
}
}