Хорошая программа Spectroid! На её примере давайте выясним какие параметры быстрого преобразования Фурье следует использовать для достижения своих целей. У программы есть меню Settings/Audio. Давайте разберем подробнее что там можно выбирать. А именно:
какие параметры программы следует установить чтобы, к примеру, определять частоты с точностью до 0.5 цента по всему диапазону фортепиано - приблизительно с 35 до 3500гц?Я нарошно подобрал такие границы диапазона чтобы быстрее и нагляднее считать. Ведь с помощью
калькулятора перевода герц в центы мы можем определить что слева у нас 50 центов в герце а справа - 0.5 цента в герце.
Про середину диапазона сразу забудем. Если нам удастся подобрать удачные параметры для краев диапазона то они сойдут и для середины.
Начнем с верхов. По одной известной в узких кругах
теореме для того чтобы уверено распознавать диапазон частот вплоть до 3500гц нам необходимо нашинковать входящий сигнал по крайней мере вдвое чаще - на 3500*2=7000 кусочков в секунду. Этот параметр называется
частота дискретизации (sampling rate) и его значение по умолчанию позволяет распознавать частоты за 44100/2=22050гц и, следовательно, нас вполне устроит:
Мы могли бы даже выбрать sampling rate = 8000Hz. И такое значение нас также устроило бы в том смысле что распознать частоты фортепиано оно позволило бы (8000/2=4000>3500). Посмотрим теперь что насчет точности. Поскольку там где частоты 3500гц один герц это как раз 0.5 цента то определив частоту с точностью до 1 герца мы как раз определим ее с точностью до 0.5 цента. Это как раз то что нам нужно. Но, как мы уже
видели раньше, нам потребуется для этого собрать данные за 1 секунду. То есть, нам потребуются все 44100 значений из sample rate, переданных в программу за последнюю секунду. Но тут необходимо оказывается рассмотреть второй параметр программы который называется
FFT size и определяет сколько именно значений из 44100 будет передано в БПФ за раз для спектрального анализа:
Ну нельзя вот так взять и передать программе все 44100 значений. Можно меньше. Например, лишь 1024 из них. Зато это позволит нам показывать пользователю живое изменение частоты аж 44100/1024=43 раза в секунду или даже чаще если ухитриться "сдвигать" эти 1024 значения по всему диапазону в 44100 значений. Так программы обычно и поступают. Они не выбрасывают проанализированные 1024 значения входного сигнала а просто берут (от микрофона) еще несколько значений, пристраивают их в хвост этим 1024 и отрезают от начала такое же число входных значений сигнала. И снова можно производить анализ частоты.
Обратите внимание, однако, на то что
FFT size не может быть выбран слишком большим, таким как нам хотелось бы из соображений точности (44100). Предельно большое значение этого параметра соответствует 8192/44100=0.185 секунды. То есть, меньше секунды. Для нас это означает что замерить частоту 3500гц с желаемой точностью не удастся. Вместо 1 секунды анализатор спектра проанализирует в 5 раз меньший интервал времени и неизбежно даст ошибку больше чем 1 гц или больше чем 0.5цента. Если выбрать FFT size = 1024 то ошибка определения частоты в дискантах может составить (44100/1024)*0.5=21.5 цента.
Можно заметить что при выборе одних параметров программа услужливо пересчитывает другие. Мы видим что варианты выбора параметра
Decimations теперь выглядят следующим образом:
Одновременно мы переходим к рассмотрению басов. 43 Hz/bin - это как раз та точность которую мы получим в басах если будем использовать при анализе
FFT size = 1024. Это ужасно потому что нам для достижения точности в 0.5 цента необходима точность примерно в 100 раз лучше одного герца! Программа имеет выбор - 0.084 Hz/bin что примерно равно тому что мы хотим. Смысл этого параметра в том что в басах программа постарается использовать (1024*(2^9))=524288 входных значений сигнала вместо 1024 ради достижения требуемой точности.
Но! Для того чтобы увидеть частоту клавиши в басах вам придется подождать примерно 524288/44100=12 секунд прежде чем программа покажет ее всплески в левой стороне спектра. Это чудовищно но это справедливо. Попробуйте выбрать большое значение параметра
Decimations и вы увидите что правая часть спектра появляется практически сразу а вот появления левой приходится долго ждать.
Для сведения привожу описание параметра
Decimations взятое с сайта автора Carl Reinke: "
More decimations means greater frequency resolution at lower frequencies (but also slower impulse response). For example: With 0 decimations, all of the points on the plot are evenly spaced (in linear space). With 1 decimation (and a 48 kHz sample rate), the band from 6 kHz down to DC has points twice as dense. With 2 decimations, the band from 3 kHz to DC is twice as dense, yet again. And so on. The increasing density and log-space plotting sort of cancel out so that the result has more uniform density.
There is an option "decimations" that defines the number of downsampling stages, each stage having its own spectrum computed. When set to a high number you can see more detail at lower frequencies at the cost of greater lag.
Desired transform interval: This is the amount of time it waits from one FFT to the next. A shorter interval means the plot updates more often and that your battery gets eaten faster. (It also changes how quickly the waterfall scrolls, but that's more of a design flaw in the program.)"
В итоге компромиссный вариант набора основных параметров выглядит следующим образом:Sampling rate = 8000
FFT size = 8192
Decimations = 6 (0.015Hz/bin)
Прочие параметры:Window function = von Hann (говорят что выбор здесь окна Ханна позволяет наиболее точно определить именно частоту)
Desired transform interval = 100ms (как часто обновлять показания на дисплее)
Exponential smoothing factor = 0.5 (сглаживание)
В результате получим максимальную точность и в дискантах и в басах. Но для того чтобы увидеть показания частоты в басах, похоже, придется подождать примерно (8192*(2^6))/8000=65 секунд. В середине диапазона дела наверное обстоят лучше но практика показала что там тоже спектр показывается не мгновенно а требуется подождать несколько секунд.
Вот. Сам разобрался, надеюсь, и вам не наврал.