C/C++/Obj-C Алгоритм реального времени для определения ноты (не высоты звука) из вокального ввода
Я хочу определить не высоту тона, а класс тона спетой ноты.
Таким образом, не важно, является ли это C4 или C5: они оба должны быть определены как C.
Представьте себе 12 полутонов, расположенных на циферблате, где стрелка указывает на класс высоты тона. Это то, что я после! в идеале я хотел бы иметь возможность определить, является ли спетая нота точечной или слегка неактивной.
Это не дубликат ранее заданных вопросов, поскольку он вводит ограничения, которые:
источник звука - единственный человеческий голос, надеюсь, с незначительным фоновым вмешательством (хотя мне, возможно, придется иметь дело с этим)
октава не важна, только класс высоты тона
РЕДАКТИРОВАТЬ - Ссылки:
Обнаружение основного тона
Использование Apple FFT и Accelerate Framework
9 ответов
Большинство алгоритмов определения частоты, приведенных в других ответах, плохо работают для голоса. Чтобы понять, почему это так интуитивно понятно, подумайте, что все гласные на языке можно петь в одной конкретной ноте. Даже если все эти гласные имеют очень разное частотное содержание, все они должны быть обнаружены как одна и та же нота. Любой алгоритм обнаружения нот для голосов должен как-то это учитывать. Кроме того, человеческая речь и песня содержат много фрикативных выражений, многие из которых не имеют скрытой высоты тона.
В общей (не голосовой) функции, которую вы ищете, она называется функцией цветности, и по этому вопросу довольно много работы. Он также известен как профиль класса гармонического тона. Оригинальный справочный документ по этой концепции - " Распознавание музыкального звука в реальном времени аккордом Таюки Фудзисимы : система, использующая общую музыку на Лиспе ". Запись в Википедии содержит обзор более современного варианта алгоритма. Существует множество бесплатных статей и реализаций MATLAB для определения характеристик цветности.
Однако, поскольку вы сосредотачиваетесь только на человеческом голосе, и поскольку человеческий голос, естественно, содержит тонны обертонов, то, что вы практически ищете в этом конкретном сценарии, - это алгоритм обнаружения основной частоты или алгоритм обнаружения f0. Есть несколько таких алгоритмов, явно настроенных для голоса. Кроме того, вот широко цитируемый алгоритм, который работает с несколькими голосами одновременно. Затем вы проверяете обнаруженную частоту по равной шкале и затем находите наиболее близкое соответствие.
Так как я подозреваю, что вы пытаетесь создать детектор и / или корректор высоты тона а-ля автонастройки, вы можете использовать превосходную реализацию WORLD от M. Morise, которая позволяет быстро и качественно обнаруживать и модифицировать f0 в голосовых потоках.
Наконец, имейте в виду, что есть только несколько детекторов основного тона, которые хорошо работают в регистре вокала. Почти все из них, в том числе WORLD, терпят неудачу на вокале, а также очень низкие голоса. В ряде статей голосовые фраи называются "скрипучим голосом", и в них разработаны специальные алгоритмы, специально предназначенные для этого типа голосового ввода.
Смотрите мой ответ здесь для получения плавного обнаружения ЧАСТОТЫ: /questions/33207532/ispolzovanie-apple-fft-i-accelerate-framework/33207542#33207542
Что касается привязки этой частоты к ближайшей ноте - вот метод, который я создал для своего приложения тюнера:
- (int) snapFreqToMIDI: (float) frequencyy {
int midiNote = (12*(log10(frequencyy/referenceA)/log10(2)) + 57) + 0.5;
return midiNote;
}
Это вернет значение ноты MIDI ( http://www.phys.unsw.edu.au/jw/notes.html).
Чтобы получить строку из этого значения ноты MIDI:
- (NSString*) midiToString: (int) midiNote {
NSArray *noteStrings = [[NSArray alloc] initWithObjects:@"C", @"C#", @"D", @"D#", @"E", @"F", @"F#", @"G", @"G#", @"A", @"A#", @"B", nil];
return [noteStrings objectAtIndex:midiNote%12];
}
Для примера реализации определения высоты тона с сглаживанием выходных данных, смотрите musicianskit.com/developer.php
Пек это человеческое психо-перцептивное явление. Содержание пиковой частоты не совпадает ни с шагом, ни с классом высоты тона. Методы БПФ и ДПФ напрямую не обеспечивают высоту тона, а только частоту. Измерения пересечения нуля также не будут хорошо работать для источников человеческого голоса. Попробуйте AMDF, ASDF, автокорреляционные или кепстральные методы. Есть также много научных работ на тему оценки высоты тона.
Здесь есть еще один длинный список алгоритмов оценки высоты тона.
Отредактированное дополнение: примеры приложений Apple SpeakHere и aurioTouch (доступны в их центре разработки iOS) содержат пример исходного кода для получения образцов блоков PCM с микрофона iPhone.
Если вы ищете класс основного тона, вы должны взглянуть на хроматограмму ( http://labrosa.ee.columbia.edu/matlab/chroma-ansyn/)
Вы также можете просто дешифровать f0 (используя что-то вроде алгоритма YIN) и вернуть соответствующий полутон, большинство основных алгоритмов оценки частоты страдают от ошибки октавы
Размещать информацию так, как я ее нахожу...
Алгоритм определения высоты тона в Википедии - хорошее место для начала. В нем перечислены несколько методов, которые не в состоянии определить октаву, что хорошо для моей цели.
Хорошее объяснение автокорреляции можно найти здесь (почему Википедия не может просто так называть??).
Выполните дискретное преобразование Фурье на выборках из вашего входного сигнала, затем сложите значения, которые соответствуют эквивалентным нотам в разных октавах. Возьмите наибольшее значение в качестве доминирующей частоты.
Скорее всего, вы можете найти существующий код DFT в Objective C, который соответствует вашим потребностям.
Наконец-то у меня есть завершение, благодаря этой статье из DSP Dimension
Статья содержит исходный код.
В основном он выполняет БПФ. затем он объясняет, что частоты, которые не совпадают точно с центром корзины, в которую они попадают, будут размазываться по соседним корзинам в виде колоколообразной кривой. и он объясняет, как извлечь точную частоту из этих данных во втором проходе (FFT - первый проход).
статья затем идет дальше к смещению тона; Я могу просто удалить код.
обратите внимание, что они поставляют коммерческую библиотеку, которая делает то же самое (и намного больше) только супер оптимизированными. есть бесплатная версия библиотеки, которая, вероятно, будет делать все, что мне нужно, хотя, поскольку я работал через аудиоподсистему iOS, я мог бы просто реализовать ее самостоятельно.
для записи, я нашел альтернативный способ извлечения точной частоты путем аппроксимации квадратичной кривой над корзиной и двумя ее соседями. Я понятия не имею, какова относительная точность между этими двумя подходами.
Как уже упоминали другие, вы должны использовать алгоритм обнаружения высоты тона. Поскольку это основание хорошо освещено, я рассмотрю несколько деталей вашего вопроса. Вы сказали, что вы ищете класс ноты. Однако способ найти это состоит в том, чтобы вычислить частоту ноты, а затем использовать таблицу для преобразования ее в класс высоты тона, октаву и центы. Я не знаю ни одного способа получить класс высоты тона, не найдя основную частоту.
Вам понадобится алгоритм обнаружения основного тона в реальном времени. При оценке алгоритмов обращайте внимание на задержку каждого алгоритма по сравнению с желаемой точностью. Хотя некоторые алгоритмы лучше других, принципиально вы должны поменять один на другой и не можете знать оба с уверенностью - что-то вроде принципа неопределенности Гейзенберга. (Как вы можете знать, что нота - это C4, когда слышна только часть цикла?)
Ваш подход "сглаживания" эквивалентен цифровому фильтру, который изменит частотные характеристики голоса. Короче говоря, это может помешать вашим попыткам оценить высоту тона. Если вас интересует цифровое аудио, цифровые фильтры являются фундаментальными и полезными инструментами в этой области, а также увлекательной темой. Это помогает иметь хороший математический фон для их понимания, но вам не обязательно это нужно, чтобы понять основную идею.
Кроме того, ваш метод пересечения нуля является основной техникой для оценки периода сигнала и, следовательно, высоты тона. Это можно сделать таким образом, но только с большим количеством эвристик и тонкой настройки. (По сути, разработайте ряд "кандидатских" шагов и постарайтесь сделать вывод о доминирующем. Появится множество особых случаев, которые запутают это. Чем быстрее, тем меньше.) Вам будет гораздо проще начать с алгоритма обнаружения основного тона в частотной области.
Если вы новичок, это может быть очень полезно. Он доступен как на Java, так и на IOS.