Как насчет:
this.ClearValue(TextBox.TextProperty);
Это намного более чисто, я думаю;)
Если вам не нужна такая высокая точность, может быть достаточно БПФ. Сначала откройте фрагмент звука, чтобы получить четко определенные пики, а затем найдите первый значимый пик.
Ширина бина = частота дискретизации / размер БПФ:
Основные параметры варьируются от от 20 Гц до 7 кГц, поэтому будет достаточно частоты дискретизации 14 кГц. Следующая «стандартная» частота дискретизации - 22050 Гц.
Затем размер БПФ определяется желаемой точностью. Выходной сигнал БПФ является линейным по частоте, в то время как музыкальные тоны имеют логарифмическую частоту, поэтому в худшем случае точность будет на низких частотах. Для 20% полутона при 20 Гц вам потребуется ширина 1,2 Гц , что означает длину БПФ 18545 . Следующая степень двойки равна 2 15 = 32768. Это 1,5 секунды данных, и процессору моего ноутбука требуется 3 мс для расчета.
Это не будет работать с сигналами, которые имеют « пропущенный основной сигнал », и найти «первый значимый» пик довольно сложно (поскольку гармоники часто выше, чем основная ), но вы можете найти способ, который подходит для вашей ситуации.
Автокорреляция и спектр гармонического произведения лучше подходят для нахождения истинной основной гармоники для волны, а не для одной из гармоник, но я не думаю, что они так же хорошо справляются с негармоничностью и большинством инструментов как пианино или гитара негармоничны (гармоники немного резкие по сравнению с тем, какими они должны быть). Однако это действительно зависит от ваших обстоятельств.
Кроме того,
Если вы хотите распознавать высоту звука в реальном времени (и с точностью до 1/100 полутона), ваша единственная реальная надежда - это подход с переходом через ноль. И это, к сожалению, слабая надежда. Переход через ноль позволяет оценить высоту тона только на основе пары длин волн данных, и это можно сделать с помощью вычислительной мощности смартфона, но это не особенно точно, так как крошечные ошибки в измерении длин волн приводят к большим ошибкам в расчетной частоте. Такие устройства, как гитарные синтезаторы (которые определяют высоту звука из гитарной струны с помощью всего лишь пары длин волн) работают, преобразуя измерения в ноты гаммы. Это может сработать для ваших целей, но имейте в виду, что переход через ноль отлично работает с простыми формами волны, но имеет тенденцию работать все меньше и меньше с более сложными звуками инструментов.
В моем приложении (программный синтезатор, работающий на смартфонах) я использую записи отдельных нот инструментов в качестве исходного материала для синтеза волновой таблицы, и для создания нот с определенной высотой тона мне нужно знать основную высоту тона запись с точностью до 1/1000 полутона (мне действительно нужна только 1/100 точность, но я ОКР по этому поводу). Подход с пересечением нуля слишком слишком неточен для этого, а подходы на основе БПФ либо слишком неточны, либо слишком медленны (иногда и то, и другое).
Лучший подход, который я нашел в в этом случае следует использовать автокорреляцию. С помощью автокорреляции вы в основном угадываете высоту звука, а затем измеряете автокорреляцию вашего образца на соответствующей длине волны.
Я не знаком со всеми упомянутыми вами методами, но то, что вы выбираете, должно зависеть в первую очередь от характера ваших входных данных. Вы анализируете чистые тона или ваш источник ввода имеет несколько нот? Речь - это особенность вашего ввода? Существуют ли какие-либо ограничения на продолжительность выборки входных данных? Можете ли вы найти компромисс между точностью и скоростью?
В какой-то степени то, что вы выберете, также зависит от того, хотите ли вы выполнять свои вычисления в времени или в частотном пространстве . Преобразование временного ряда в частотное представление требует времени, но, по моему опыту, дает лучшие результаты
Автокорреляция сравнивает два сигнала во временной области. Наивная реализация проста, но относительно дорога в вычислении, поскольку для этого требуется попарное различие между всеми точками в исходном и сдвинутом во времени сигналах, с последующим дифференцированием для определения поворотных точек в автокорреляционной функции, а затем выбором минимума, соответствующего основной частоте. Есть альтернативные методы. Например, Средняя величина разности - очень дешевая форма автокорреляции, но страдает точность. Все методы автокорреляции сопряжены с риском октавных ошибок, поскольку в функции присутствуют пики, отличные от основной гармоники.
Измерение точек пересечения нуля является простым и понятным процессом, но при наличии нескольких сигналов возникнут проблемы. присутствует в сигнале.
В частотном пространстве методы, основанные на БПФ , могут быть достаточно эффективными для ваших целей. Одним из примеров является метод гармонического произведения спектра, который сравнивает спектр мощности сигнала с субдискретизированными версиями на каждой гармонике и определяет высоту звука путем умножения спектров вместе для получения четкого пика.
Как всегда, нет замены для тестирование и профилирование нескольких методов, чтобы эмпирически определить, что лучше всего подойдет для вашей проблемы и ограничений.
Такой ответ может лишь поверхностно затронуть эту тему. Наряду с предыдущими ссылками, вот некоторые соответствующие ссылки для дальнейшего чтения.
В моем проекте данстунер я взял код из Audacity . По сути, потребовалось БПФ, а затем была найдена пиковая мощность, построив кубическую кривую на БПФ и найдя пик этой кривой. Работает довольно хорошо, хотя мне пришлось остерегаться скачков на октаву.
См. Spectrum.cpp .
Переход через ноль не будет работать, потому что типичный звук имеет гармоники и переходы через ноль намного больше, чем базовая частота.
Я экспериментировал (в качестве домашнего проекта) вот с чем:
Однако я обнаружил, что при вводе с моей электронной клавиатуры для звуков некоторых инструментов удавалось увеличить базовую частоту в 2 раза (на следующую октаву). Это был побочный проект, и я так и не успел реализовать решение, прежде чем перейти к другим вещам. Но я думал, что это обещает гораздо меньшую загрузку процессора, чем FFT.