Отображение бина Python scipy.fftpack.rfft

Я пытаюсь получить правильный индекс бита FFT на основе данной частоты. Звук отбирается с 44.1k Hz а размер БПФ – 1024 . Учитывая, что сигнал реальный (захват из PyAudio, декодированный через numpy.fromstring , оконный с помощью scipy.signal.hann ), я затем выполняю FFT через scipy.fftpack.rfft и вычисляю децибел результата в целом, magnitude = 20 * scipy.log10(abs(rfft(audio_sample)))

Исходя из этого , я первоначально имел свое отображение из индекса FFT bin, k , на любую частоту F , как:

F = k*Fs/N for k = 0 ... N/2-1 где Fs – частота дискретизации, а N – размер БПФ, в этом случае 1024 . И наоборот:

k = F*N/Fs for F = 0Hz ... Fs/2-Fs/N

Однако, понимая, что результат rfft не симметричен, как fft , и дает результат в массиве N размера. Теперь у меня есть некоторые вопросы относительно отображения и функции. К сожалению, документация не предоставила много информации, поскольку я новичок в этой области.

Мои вопросы:

  1. Для меня результат rfft на примере аудио может быть использован непосредственно из первого бина в последний бит, поскольку на выходе не возникает симметрии, верно ли это?

  2. Учитывая отсутствие симметрии из вышеизложенного, частотное разрешение, похоже, увеличилось, верно ли это толкование?

  3. Из-за использования rfft моя функция отображения из индекса bin k в частоту F теперь F = k*Fs/(2N) for k = 0 ... N-1 это правильно?

  4. Напротив, функция обратного отображения от частоты F к индексу k теперь становится k = 2*F*N/Fs for F = 0Hz ... Fs/2-(Fs/2/N) , что относительно правильности этого?

Моя общая путаница возникает из-за того, как rfft связано с fft , и как отображение может быть выполнено правильно при использовании rfft . Я считаю, что мое сопоставление компенсируется небольшой суммой, и это имеет решающее значение в моем приложении. Пожалуйста, укажите ошибку или посоветуйте по этому вопросу, если это возможно, большое спасибо.

Сначала проясните несколько вещей для вас:

Краткая ссылка на документацию fftpack показывает, что rfft дает только выходной вектор от 0..512 (в вашем случае). Причина этого заключается именно в том, что симметрия присутствует при вычислении дискретного преобразования Фурье вещественного входа: y [k] = y * [Nk] (см. Страницу Википедии о ДПФ ). Следовательно, функция rfft вычисляет и сохраняет значения N / 2 + 1, так как вы можете рассчитать другую половину, просто принимая сложные сопряжения (если вы действительно хотите ее для построения (скажем)). Функция fft не делает предположений о входных значениях (они могут иметь как действительную, так и мнимую часть), и поэтому на выходе не может быть принята симметрия, и она дает полный выходной вектор с N значениями. По общему признанию, большинство приложений используют реальный ввод, поэтому люди склонны считать, что симметрия всегда существует. Обратите внимание, что быстрое преобразование Фурье (FFT) является (эффективным) алгоритмом для вычисления Дискретного преобразования Фурье (DFT), а функция rfft также использует FFT для вычисления.

В свете вышесказанного, ваши индексы для доступа к выходному вектору выходят за рамки, т. Е.> 512. Причины, по которым / как вы можете это сделать, зависят от вашего кода. Вы должны четко различать «логический N» (который вы используете для сопоставления частот бункера, определения DFT и т. Д.) И «вычислительного N» (фактическое количество значений в вашем выходном векторе), тогда все ваши проблемы должны исчезнуть ,

Чтобы конкретно ответить на ваши вопросы:

  1. Нет. Существует симметрия, и вам нужно использовать ее для вычисления последних бункеров (но они не дают вам дополнительной информации).

  2. Нет. Единственный способ увеличить разрешение ДПФ – увеличить длину выборки.

  3. Нет, но почти. F = k * Fs / N для k = 0..N / 2

  4. Для выходного вектора с N бинами вы получаете частоты от 0 до (N-1) / N * Fs. Используя rfft, вы получите выходной вектор с N / 2 + 1 ячейками. Вы делаете математику, но я получаю 0..Fs / 2

Надеюсь, что теперь все ясно.