#c #embedded #signal-processing #fft #pitch-tracking
Вопрос:
Я пытаюсь распознать последовательность аудиокадров во встроенной системе — аудиокадр представляет собой частоту или интерполяцию двух частот в течение переменного промежутка времени. Я знаю звуки, которые пытаюсь распознать (т. Е. начальную и конечную частоты, которые линейно интерполируются, и продолжительность каждого аудиокадра), но они производятся другой встроенной системой, поэтому микрофон и динамик дешевы и несколько неточны. На выходе получается прямоугольная волна. Есть какие-нибудь предложения, как это сделать?
То, что я пытаюсь сделать сейчас, — это использовать FFT, чтобы получить величину всех частот, обнаружить пики, посмотреть на длительность обнаружения/2 мс назад и проверить, соответствует ли это звуковому кадру, и, наконец, просто проверить, соответствует ли какой-либо звук, который я ищу, последовательности.
До сих пор я использовал БПФ для обработки микрофонного входа — после применения окна Ханна — а затем присваивал каждой ячейке частоты коэффициент, который является пиком, основанный на том, сколько стандартных отклонений от среднего. Это не очень хорошо сработало, так как он думал, что есть пики, когда в комнате царила тишина. Есть какие-нибудь идеи о том, как более точно обнаружить пики? Также я думаю, что есть много гармоник из-за прямоугольной волны / интерполяции? Могу ли я получить спектр гармонического произведения, если пики на самом деле не совпадают с удвоенной частотой?
Здесь я изобразил шум (почти тихая комната) где-то с интерполяцией 2226 и 1624 Гц. https://i.stack.imgur.com/R5Gs2.png
Я выполняю выборку с частотой 91 микросекунда -> 10989 Гц. Следует ли мне чаще пробовать?
Я добавил сюда примеры того, как звучит интерполяция при записи на моем ноутбуке и во встроенной системе. https://easyupload.io/m/5l72b0
#define MIC_SAMPLE_RATE 10989 // Hz
#define AUDIO_SAMPLES_NUMBER 1024
MicroBitAudioProcessor::MicroBitAudioProcessor(DataSourceamp; source) : audiostream(source)
{
arm_rfft_fast_init_f32(amp;fft_instance, AUDIO_SAMPLES_NUMBER);
buf = (float *)malloc(sizeof(float) * (AUDIO_SAMPLES_NUMBER * 2));
output = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER);
mag = (float *)malloc(sizeof(float) * AUDIO_SAMPLES_NUMBER / 2);
}
float henn(int i){
return 0.5 * (1 - arm_cos_f32(2 * 3.14159265 * i / AUDIO_SAMPLES_NUMBER));
}
int MicroBitAudioProcessor::pullRequest()
{
int s;
int resu<
auto mic_samples = audiostream.pull();
if (!recording)
return DEVICE_OK;
int8_t *data = (int8_t *) amp;mic_samples[0];
int samples = mic_samples.length() / 2;
for (int i=0; i < samples; i )
{
s = (int) *data;
result = s;
data ;
buf[(position )] = (float)resu<
if (position % AUDIO_SAMPLES_NUMBER == 0)
{
position = 0;
float maxValue = 0;
uint32_t index = 0;
// Apply a Henn window
for(int i=0; i< AUDIO_SAMPLES_NUMBER; i )
buf[i] *= henn(i);
arm_rfft_fast_f32(amp;fft_instance, buf, output, 0);
arm_cmplx_mag_f32(output, mag, AUDIO_SAMPLES_NUMBER / 2);
}
}
return DEVICE_OK;
}
uint32_t frequencyToIndex(int freq) {
return (freq / ((uint32_t)MIC_SAMPLE_RATE / AUDIO_SAMPLES_NUMBER));
}
float MicroBitAudioProcessor::getFrequencyIntensity(int freq){
uint32_t index = frequencyToIndex(freq);
if (index <= 0 || index >= (AUDIO_SAMPLES_NUMBER / 2) - 1) return 0;
return mag[index];
}
Комментарии:
1. C ,
malloc
, ой2. Позвольте мне посмотреть, правильно ли я понимаю, что у вас есть треугольная волна с переменным периодом? в этом случае БПФ не будет лучшим подходом, лучше использовать обнаружение пика в отфильтрованном сигнале высоких частот 😉
3. Это должна быть квадратная волна — я не уверен, что именно получилось, так как из-за микрофона много шума. Вы знаете, где я мог бы найти хорошие ресурсы по обнаружению пиков и фильтрации высоких частот?