Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Англоязычный видеоролик на эту тему, возможно, будет интересен:
The more general uncertainty principle, regarding Fourier transforms

Если вдуматься, то этот момент хорошо иллюстрирует теорему Котельникова-Найквиста-Шеннона, о том, что частота дискретизации должна быть не меньше максимальной удвоенной частоты сигнала…
Дискретное преобразование Фурье даёт нам дискретный спектр, где каждое значение амплитуды отстоит от соседних на равные промежутки по частоте. И если частота в сигнале кратна шагу равному (частота дискретизации)/(количество отсчётов), то мы получим выраженный остроконечный пик, но если частота сигнала лежит где-то между границами шага ближе к середине у нас выйдет пик со «срезанной» вершиной и нам будет затруднительно сказать, что же там за частота
…
Чтобы как-то обойти это ограничение иногда применяют аппроксимирующие функции, например, параболические.
Существует ли более естественный путь для точного определения частоты?
Да, и скрыт он как раз-таки в использовании фазового спектра сигнала, которым часто пренебрегают.
Данный метод уточнения частоты сигнала, основан на вычислении задержки фаз у спектров двух кадров, наложенных друг на друга, но немного сдвинутых во времени.
То есть, использовать информацию из нескольких окон подряд? Практически то же самое, что и использовать окно большего размера.
Нотный анализ музыкальных произведений открывает ряд интересных возможностей. Ведь имея в наличии готовый нотный рисунок, можно осуществлять поиск других музыкальных композиций со схожим рисунком.


Поскольку человек с помощью своего слухового аппарата может выполнить эту задачу, то, теоретически, это доступно и компьютеру… Но для этого нужна, как минимум, специально обученная нейронная сеть. Обучением этой сети, как раз-таки и занимаются люди слушая звуки мира, различную музыку, музицируя…
m_timer = new DispatcherTimer();
m_timer.Interval = TimeSpan.FromMilliseconds(m_timeInterval);
m_timer.Tick += OnTimerTick;
m_timer.Start();
var timer = new DispatcherTimer();
timer.Tick += (sender, args) => FrameworkDispatcher.Update();
timer.Start();
var device = Microphone.Default;
device.BufferDuration = TimeSpan.FromMilliseconds(100);
var bufferSize = device.GetSampleSizeInBytes(device.BufferDuration) / 2;
var sampleBytes = new byte[2 * bufferSize];
device.BufferReady += (sender, args) =>
{
var sampleSizeInBytes = device.GetData(sampleBytes);
var sampleSize = sampleSizeInBytes / 2;
var sample = new double[sampleSize];
for (var i = 0; i < sampleSize; i++)
{
sample[i] = Convert.ToDouble(BitConverter.ToInt16(sampleBytes, 2 * i));
}
m_pitchTracker.ProcessBuffer(sample.Select(t=>(float)t).ToArray());
UpdateDisplay();
};
FrameworkDispatcher.Update();
device.Start();
Преобразование Фурье в действии: точное определение частоты сигнала и выделение нот