Здравствуйте, товарищи.
Мне нужно улучшить алгоритм поиска основной частоты по методу максимального правдоподобия. Был пример у меня, как делать, я его модифицировал в нескольких местах (добавил настраиваемость оконной функции и фильтра). Возможно, некоторые места вам покажутся совершенно абсурдными - но я пока новичок в DSP, некоторые места в старом алгоритме вызывают у меня сильное удивление, но пока не хватает опыта для однозначного решения: или я не понимаю момент, или предыдущий программист допустил косяк.
- Вход: массив байтов byteData длиной sampleLength, количество разбиений sampleRate.
- Выход: фундаментальная частота fundamentalFrequency и громкость fundamentalVolume.
Алгоритм:
1. Массив байтов преобразуется в вешественный массив амплитуд.
2. Проверяется максимальная амплитуда - если она ниже определённого значения, то это квалифицируется как почти полная тишина (выход из алгоритма)
3. Получение спектра из массива амплитуд:
3.1. Умножение массива амплитуд на оконную функцию;
3.2. Преобразование Фурье.
4. Фильтрация массива спектральных значений.
5. Расчёт массива громкости (модуль от спектральных значений).
6. Нормализация громкости:
6.1. Поиск максимальной громкости (maxVolume).
6.2. Нормализация (volume[i] = volume[i]/maxVolume);
7. Квалификация спектра как информативного или зашумлённого.
8. Инициализация 3 пиков громкости и соответствующих им частот.
9. Поиск фундаментальной частоты.
9.1. Если один из 2 главных пиков громкости ниже некоторого порога громкости, то выбрать частоту другого главного пика, выход из алгоритма.
9.2. Поиск фундаментальной частоты по 2 главным пикам согласно известным пропорциям 1/2, 1/3, 2/3, 2/5, 3/4, 3/5.
9.3. Коррекция фундаментальной частоты по 3-му пику.
Мне нужно пробежаться по некоторым пунктам, чтобы удостовериться в валидности алгоритма.
Пункты 1, 2, 6, 8 и 9 вопросов не вызывают.
Самые горячие вопросы сейчас такие:
1. Правильно ли считается громкость? Массив спектральных значений имеет следующую структуру: в ячейках spectre[2*i] лежат коэффициэнты при косинусах, в spectre[2*i+1] лежат коэффициэнты при синусах. Соответственно, громкость считаю так: volume[i] = sqrt(sqr(spectre[2*i])+sqr(spectre[2*i+1])); Может, таким методом не громкость считается, а что-то другое?
2. Как рассчитать шум? И как рассчитать порог шума (если его превысить, то выход из алгоритма)? Сейчас шум рассчитывается как среднее арифметическое по массиву громкости.