Проблема БПФ (возвращает случайные результаты) - PullRequest
1 голос
/ 29 августа 2009

У меня есть этот код, но он продолжает возвращать случайные частоты от 0 до примерно 1050. Пожалуйста, вы можете помочь мне понять, почему это происходит.

Длина моих данных - 1024, частота дискретизации - 8192, а данные - это короткий массив, заполненный входными данными с микрофона.


float *iSignal = new float[2048];
float *oSignal = new float[2048];
int pitch = 0;

for(x=0;x&#60=1024;x++) {
    iSignal[x] = data[x];
}

fft(iSignal,oSignal,1024); //Input data, output data, length of input and output data

for(int y=0;y&#60 2048;y+=2) {
if((pow(oSignal[y],2)+pow(oSignal[y+1],2))>(pow(oSignal[pitch],2)+pow(oSignal[(pitch)+1],2))) {
        pitch = y;
    }
}

double pitchF = pitch / (8192.0/1024);
printf("Pitch: %f\n",pitchF);

Спасибо

Найл.

Редактировать: Код изменен, но он все еще возвращает случайные частоты.

Ответы [ 4 ]

7 голосов
/ 29 августа 2009

Если предположить, что oSignal заполнено комплексными числами таким образом, что чередуются действительная и мнимая части, это может помочь изменить

for(int y=0;y< 8191;y++)

до

for(int y=0;y< 8191;y+=2)

Редактировать: я даже не заметил, что вы передаете только 1024 сэмпла. Вы должны передать столько выборок во временной области, сколько будет выборок в частотной области, в вашем случае 4096.

Редактировать: Еще одна вещь: вы явно пытаетесь найти базовую частоту чего-то. Если что-то не является сгенерированным компьютером тоном или человеческим свистом (оба из которых очень чистые тона), вы можете быть разочарованы результатом. Простой метод, который вы опубликовали, едва работает на флейте.

Редактировать: Для голоса и гитары вам не повезло. Я написал программу некоторое время назад, которая отображает частотную область, попробуйте, вы увидите проблему. Есть также источники , если вам интересно.

Окончательное редактирование : Возможно, вы захотите прочитать статью Википедии об определении высоты звука . Сконцентрируйтесь на подходах во временной области.

1 голос
/ 29 августа 2009

Кажется, iSignal [1025] .. iSignal [8191] содержит случайные данные. Вы можете попробовать установить его на 0. Но почему вы передаете 8192 в fft (), если длина ваших данных равна 1024 (или 1025)?

Кроме того, вы теряете некоторую точность в целочисленном делении. Измените это на двойной шаг F = шаг / (8192,0 / 1024);

Ваша функция fft ожидает реальных или сложных входных данных? В случае, если он ожидает сложных данных, вы должны установить для каждой другой записи iSignal значение 0.

0 голосов
/ 30 августа 2009

Две вещи:

  • Вы уверены, что правильно используете функцию fft? Вы обрабатываете вывод, как если бы он был сложным массивом, организованным [R_1 I_1 R_2 I_2 ...], но вы обрабатываете входной массив, как будто он организован [R_1 R_2 R_3 ... R_1024 I_1 I_2 ...] и , как Хенрик говорит , тогда оставляя сложные части неинициализированными.
  • Ваше обнаружение пиков чрезвычайно примитивно, хотя оно должно быть сделано для простого ввода (как один гитарный укус). Для использования с человеческим голосом вам почти наверняка понадобится более сложный подход.

Вы пытались поместить в качестве входного сигнала известный простой (т.е. чистый синусоидальный) сигнал?

0 голосов
/ 29 августа 2009

"случайные частоты от 0 до примерно 1050" - разве типичный аудиосигнал не состоит из комбинации частот? Поскольку частота дискретизации составляет 8192 Гц, ваше БПФ может обнаруживать до 8192/2 = 4096 Гц. Я ожидаю, что вы увидите комбинацию множества частот, но я бы не назвал их «случайными».

Почему ты удивлен? Что я пропустил?

...