![]() |
|
![]() ![]() ![]() |
|
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
В общем задача следующая - необходимо реализовать гитарный тюнер - мы играем ноту и нам с определённой точностью выводится её частота , мы крутим колки гитары в нужную сторону и таким образом настраиваем .
Итак , изначально я решил что лучше всего для этого подойдет алгоритм FFT (быстрое преобразование Фурье - перевод из временной в частотную область ). У микрофона (АЦП) можно было выбрать несколько частот дискретизации - 44100 , 8000 , вроде ещё 11К . Соответственно на выходе преобразования мы можем получить макс допустимую частоту в 44100/2 , 8000/2 Гц и т.д Для настройки гитары в принципе было бы достаточно предела в 2000Гц , так что была выбрана част дискр в 8000 . Но возникает проблема - для того чтобы получить более- менее точную частоту - нам надо взять как можно больше значений . - если мы берём например 8000 то за 1 гц отвечает одно значение , если 16К - то по 0.5 Гц , если 4 - то по 2Гц . Но с частотой по 8000 значений в секунду нам понадобится 0.5- 2 секунды чтобы только считать значения + ещё FFT рассчитать ! Я видел тюнеры которые за доли секунды настраивали с точностью в 0.1 Гц !! Начал копать в сторону выделения одной основной частоты - нашел АКФ . Умножает значения друг на друга с увеличивающимся смещением , и выходит что макс знач дают нам макс амплитуду. Сказано - сделано . Результат меня просто поразил - работает в реальном времени .периоды нот стали видны очень отчетливо . Здесь получается что наша частота- это ЧД/ на наш период . - след-но чем больше ЧД тем более точным оказывается результат , но на высоких нотах его все ещё не достаточно - с макс ЧД в 44100 получается что шаг на 85-75 Гц составляет 0.1- 0.2 Гц , но на 300-400 он уже в 2-4 Гц . Скачал пару оупен соурсов , покапался , ничего не понял кроме того , что они все таки используют FFT !! Может быть я его неправильно понял ? Но вопрос все таки в следующем - каким образом можно получить частоту играемой ноты максимально точно ? Буду очень благодарен ![]() |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Есть высокие частоты, есть низкие. Вот низкие частоты 20Гц и ниже ухо не воспринимает ввиду того есть определённые сложности с его определением и восприятием. А да не только ухо но и нелюбой микрофон способен воспринимать низкие частоты. Что касается точности то она зависит от метода определения для FFT можете использовать следующую формулу 1/(N/(fd/f))=fd/(f*N)
N- число принятых байт fd- частота дискретизации f - нужная частота. Да для 1Гц точность не велика, но уже для f=20Гц она уже 1/20=0.05 А так еще совет применять оконные функции они помогут решить проблемы. Для низких частот точность можно повысить если искать отфильтровать высокии частоты и искать переходы через 0. И уже оттуда отсчитывать корреляцию. |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, Но разве точность частоты не одинаковая на протяжении всего ЧР ?- currFreq= sampleFreq * i / N
где sampleFreq- ЧД i - номер в массиве , нужный нам N- размер окна . Получается что чем больше окно и меньше ЧД- тем больше точность Например для точности в 1Гц на значение нам получается нужно брать окно в 8к значений (для чд в 8кГц) . Что займет целую секунду . Ведь золотое правило преобр фурье звучит так - проигрывая по времени мы выигрываем по частоте , и наоборот . Я же не понимаю - как можно за 100-150 мс быстро считать и рассчитать фурье и вывести это с точностью в 0.1 Гц ! Недавно даже на ютюбе видел мужикак который сделал политюнер - и показывал спектр который почти мгновенно реагировал на любой звук. Да , низкие частоты фурье давит , АКФ же наоборот расчитывает очень точно . Наверно в фурье придется умножать на какой нибудь угосающий коэффициент чтобы их выровнять . Оконные функции я использовал - выбрал блэкмена за самую яркую амплитуду. Также пробовал HPS - но работает очень медленно и результаты не из лучших .
Да я думаю для НЧ поможет . Но проблема в АКФ была в высоких частотах - они очень неточные . Нужна большая ЧД . |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Видимо под точностью мы разные термины понимаем. Вот это посмотрите то или не то? http://www.numerix-dsp.com/zoomfft.html Во вот тут лучше описано. На русском еще не видел, не искал. http://arc.id.au/ZoomFFT.html |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Ну скорее всего подойдет, если оно работает ). Можно взять спектр 40- 1000Гц и расширить его , либо находить частоту , а потом расширять .
Ещё где то нашёл , что можно записать только часть сигнала а все остальное заполнить нулями . Но даже не знаю , будет ли необходимая точность если я например запишу 1024 значения с чд 8к , а фурье возьму по 64К значений. Zoom FFT в принципе будет побыстрее и поточнее , но и в понимании сложнее ) |
|||
|
||||
vedun |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
||||
|
|||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, спасибо за книжки , но мне бы примеры реализации . Неохота в этой математике копаться .
Кстати разобрал один тюнер - использует фурье но только для определения автокореляции . Мне это в принципе не подходит , так как хочется сделать поли тюнер - сразу для всех струн . |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
А не подскажите как вы с помощю автокорреляции определяли частоту? Вы считали автокореляцию записного сигнала гитары? Эх, мне уже самому интересно стало, надо будет попробовать написать фурье "считтатель частоты". Жалко со временем напряжёнка. Я правильно понял что вам надо мерять частоту в диапазоне 20..2000 Гц ? Да и гитара ведь не даёт читстый тон, там в спектре наверно есть высшие гармоники, или их влиянием можно пренебречь ? |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, сама по себе формула очень простая . Вот тут она есть . Мы умножаем друг на друга 2 числа с изменяемым смещением и их суммируем . И выходит что если смещение соотв периоду и в этой точке мы имеем макс значение , то значит это он и есть .Вообще на выходе получается очень резкий график и различить визуально нужный период не составляет труда . Потом ЧД делим на индекс с макс значением (смещение, период) и получаем частоту .
Это кстати довольно тяжелый алгоритм - х^2 , против х*logx у фурье , поэтому и используют фурье как ф-ю автокорреляции -не знаю точно как - вроде берут прямое и инверсное преобразование и нормализуют между ними. Работает так : считывается звук с микрофона , преобразуется с акв, ищется период и переводится в частоту . Из недостатков этого метода то что даже при макс чд в 44100 шаг частоты на 300 -400 гц составляет 8 гц , на 86 Гц (нижняя струна ) 0.2 Гц . Касательно гармоник - как таковые в графике акв отсутствуют .Есть только пики с удвоенным , утроенным , н-ым периодом . Ноту это определить никак не помешает , частоту в редких случаях . Да , и как говорит википедия полифонические звуки он не поддерживает , поэтому мне остается только фурье, если конечно нету других способов . |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
Kpeved напишите чётко требования по точночти и диапазону, я может на выходных или раньше когда будет время попробую сделать. Мне надо:
|
|||
|
||||
ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 2 Всего: 17 |
Если нужно проверить наличие одной конкретной частоты, то ДПФ - да, не очень подходит. Я слышал, что для этого подходит алгоритм Гёрцеля (Goertzel).
-------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
Алгоритм Герцеля - это расчёт одного спектрального отсчёта ДПФ. Фактически это полосовой фильтр на конкретную частоту. Его можно использовать как индикатор наличия/отсутствия сигнала на заданой частоте. Но автору как я понял надо именно измерить эту частоту в довольно широком диапазоне. |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, 1. Диапазон 70 - 400 Гц - для стандартного строя - это минимум . Но если вдруг например я захочу проверить мензуру (буду играть на 12м или на 24м ладу) или решу на тон - 2 выше перестроить , то этого мало . В идеале - до 1700 -2000 Гц
2. Понятия не имею как это можно сделать . Да и зачем . Разве только для увеличения точности - тогда буду рад услышать какой нибудь интересный алгоритм ). 3. Точность в идеале +-0.1 Гц . Ну ещё можно допустить в среднем +-0.3 . На высоких частотах +-1Гц , ткак и расстояние между нотами там больше . 4. Спектрограмма исходного сигнала ниже . Микрофон - дешёвый Genius - прищепка .Инструмент - дешёвая китайская электро гитара - НЕ подключенная (вообще - худший случай для настройки . если тюнер может её в таком состоянии настроить , то значит настроит все что угодно )) ЧД - 44100 , PCM 16bit . Позже выложу файлы с самой записью . Играю по очереди с самой нижней по верхнюю струны + в конце на самой высокой струне 24й лад (х4 самой высокой струны ) ![]() п.с . Пайнт немного подпортил спектрограмму , но все равно видно .) |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
Попробовал поиграться в матлабе с квадратичной интерполяцией ДПФ, предварительно результат такой:
Для диапазона 50 Гц ... 2750 Гц и точности +- 0.1 Гц достаточно 4096 точек + дециматор понижающий тактовую частоту в 8 раз. Либо, если это возможно захватывать данные с тактовой частотой около 5...6 кГц (не знаю возможно ли это сделать). Если делать дециматор, на точность это не повлияет а только увеличит вычислительную нагрузку. Завтра распишу подробнее как получить этот результат, а то уже позно, и пора спать ![]() |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
vedun,
Берем записанные данные, массив А кратные 2^n. Создаешь массив новой длины B A[0],0, 0, 0, 0,0....,0,A[1],0,0,0,0,..,0,A[2],.... Для ваших требований подойдет по 15 нулей. Точность повыситься в 16 раз, если надо больше бери больше нулей. После делаешь БПФ. Дальше в виду того что это инструмен ишешь самую большую гармонику. Только не на всем диапазоне частот вч частоты Обычная передескритезация. Только фильтровать не нужно так как это лишняя операция. А.Б.Сергиенко_Цифровая обработка сигналов |
|||
|
||||
vedun |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
![]()
|
||||||||
|
|||||||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, можете объяснить каким образом это может нам помочь ? Мы ведь просто увеличиваем ЧД , и взяв дпф мы просто получаем тот же сигнал только растянутый на большую частоту .
Этот способ сможет помочь при использовании АКФ , но при определении частоты с помощью дпф - только увеличит вычислительную нагрузку. |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
vedun,
Kpeved, С утра времени подумать не хватило. Малость ошибся. Интерполировать надо в частотной области. Во временной выражается добавлением нулей к хвосту. Хотя я предпочту вместо нулей сделать так. БПФ как есть, а потом уже поиск максимума и после уже его уточнение через интерполяцию (кубическую). Это сообщение отредактировал(а) Pavia - 1.3.2012, 15:18 |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, не знаю , подойдет ли тебе вот в таком вот формате - PCM 16 бит ,по 2 байта на значение .Чд 44100 и 8000. Каждую струну я записывал отдельно по 10с по 2 удара (имеется ввиду извлекал звук из струны )). Они подписаны с 6(самая толстая ) по 1 (самая тонкая) , и ещё все вместе .Просто скинул считанные массивы в .txt файлы , так что никакой кодировки .
Инструмент- дешёвая электруха , микрофон в 15ти см от струн . http://dl.dropbox.com/u/29529555/44k-1.rar |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Да, и совсем забыл сказать . Всего 6 струн , настроены по тюнеру кроме двух , кот-е я немного расстроил ) Если определишь какие - думаю задача решена ) . Строй стандартный , в инете все частоты есть .
|
|||
|
||||
vedun |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
![]()
![]() |
||||
|
|||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
А wav не судьба было выложить? |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, я думал напрямую с массивом проще работать . Ок , позже wav выложу .
vedun, числа обычные signed short . Да , со знаком - амплитуда ведь и вверх и вниз идет ) Порядок такой - младший , потом старший . |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
Померял на файлах с ЧД = 8000 Гц, везде второй импульс.
Там на спектрах стоит лес гармоник, мерял частоту 1-й (она везде почти самого низкого уровня, возможно это завал АЧХ микрофона на низких частотах её давит):
В данныхрасчётах я брал длину ДПФ 8192. Каков результат судить вам. Это сообщение отредактировал(а) vedun - 2.3.2012, 21:14 |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
vedun,
Пока грубо посчитал с точностью до 0.5Гц через БПФ N=16*1024 отсчёта fd=8000 1 - 328.6 Гц 2 - 251 Гц 3 - 194.8 Гц 4 - 146 Гц 5 - 109.4 Гц 6 - 80 Гц Что то у нас результаты разнятся на 1 Гц. Пересчитал более точно через ПФ с шагом 0.1 Гц N=4*16*1024 fd=44100 1 - 328.5 2 - 251.2 3 - 196.1 4 - 146.5 5 - 109.5 6 - 80.8 Пересчитал более точно через ПФ тс шагом 0.01 Гц N=4*16*1024 fd=44100 1 - 328.53 2 - 251.24 3 - 196.09 4 - 146.55 5 - 109.53 6 - 80.81 Видимо над точностью надо поработать. Это сообщение отредактировал(а) Pavia - 3.3.2012, 12:11 |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
А какой вы фильтр использовали? |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
vedun,
Прямоугольный, по пробовал Ланцоша и Хэмминга разница 0.02 Гц от прямоугольного. Но видимо из-за упругости струны часта плавает в пределах 1 Гц. Постепенно уменьшаясь. Но у вас всё равно на 1-2 ГЦ больше. Само ПФ. И детектирование частоты
Это сообщение отредактировал(а) Pavia - 3.3.2012, 12:37 |
|||
|
||||
vedun |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
||||
|
|||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
vedun,
Я под ПФ- имел ввиду Преобразование Фурье, те расчёт коэффициента Фурье для заданной частоты. По сути это корреляция сигнала с sin и cos заданной частоты. С полосой не скажу, толи 1 Гц толи стремится к нулю. Это сообщение отредактировал(а) Pavia - 3.3.2012, 13:25 |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Вот такие ноты должны получится при идеальной настройке .
1) ми - 329,6 Гц 2) си - 246,9 Гц 3) соль - 196 Гц 4) ре - 146,8 Гц 5) ля - 110 Гц 6) ми - 82,4 Гц У меня же не строили - 6ая вниз , 2ая вверх . У вас получается что расхождение стабильно около 1 гц . Если на высоких это ещё приемлемо , то на низких не очень . Частоты vedun мне больше нравятся . Но 8192 - это очень много Это только целая секунда чтобы снять значения . Не пострадает ли точность если мы снимем 2048 и забьём все до 8к нулями ? Вы кстати использовали оконные ф-ии хэмминга , блекмэна ? |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Частота в вашей гитаре не равномерная. Уменьшаешь размер буфера частота меняется, растёт. Или сдвигаешь буфер тоже меняется. Это сообщение отредактировал(а) Pavia - 3.3.2012, 22:14 |
|||
|
||||
vedun |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
![]() Вообще трудно сказать как померять частоту такого импульсного сигнала, возможно на переходных процессах происходят смещения частоты, а так как там установившегося режима нет, то и меряем мы не понятно что.
|
||||
|
|||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, а можешь поподробнее сказать про интерполяцию эту ? Может быть пример кода на каком нибудь с-образном языке )
Я сейчас пишу чтобы это все в нормальной граффической форме выводилось, поэксперементирую нормально и скажу результаты . Pavia, я сдесь раньше картинку из аудишна выкладывал . Впринципе хоршо видно что частота колебается +- , только она равномерная . Даже супер крутые педальки грешат тем сыграв 2 раза одну и ту же струну результаты будут немного отличаться . Я думаю надо брать что то среднее после нескольких замеров - тесть точность будет постепенно расти . Можно кстати узнать как вы выделяли основную гармонику ? Когда я замерял гармоники скакали как бешеные и частота всегда получалась в 2 - в 3 потом снова в 2 - раза больше . Или вы опирались на возможный диапазон настройки? |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Где-то у меня был код, но что-то он не попался поэтому делал на глазок, указывая диапазон где искать максимум. А вообще раньше пользовался таким кодом. В частотной области после БПФ. По памяти так отступаем 5 Гц (в вашем случае я бы пропустил 20Гц), так как там обычно большая горка. Далее берём производную и ищем перепад знака с - на +. Первый перепад это и будет первая гармоника. А да для надежности ещё перед производной применяю простое сглаживание фильтром [1 2 1]. и использую порог чтобы отсечь лишний шум. Ещё можно через адаптивный порог делать, но его я не пробовал. Вернее для этих целей не пробовал пробовал для других. У адаптивного порога настройка хуже в виду нелинейности порога. А да перед БПФ надо удалять постоянную составляющую. У вас видимо галочка стоит и горки нет. Набрал код по новый.
Это сообщение отредактировал(а) Pavia - 4.3.2012, 22:25 |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Большое спасибо за ответы
![]() Pavia, а что ещё за постоянная составляющая ? И каким образом можно фильтр реализовать ? Вообще не шарю в VB но предположу что на 21 вы проверяете значение на пик ,а потом передаете в DetectF временной массив и частоту +- 5 знач от пика ? Пока ещё не совсем понимаю что эта ф-я делает .. точнее совсем не понимаю .. vedun, Да , вроде понял ). находим а, б , а потом по формуле . Ну а как найти этот пик ? как делал Pavia? я ещё поэксперементировал с граффиками - вобщем если забить часть нулями то уменьшается амплитуда сигналов , но пики все ещё очень хорошо видны . Вот только мне кажется возникнут погрешности при интерполяции Как кстати оконные ф-ии блэкмена , хемминга могут влиять на интерполяцию ? |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Убираем постоянную составляющую так. r:=Mean(aa); // вычисляю среднее sub(aa,r); // вычитаю по поэлементно. Теорию особо не встречал это чисто из практики. Это Delphi.
Да всё верно, пик проверяю через нахождение второй производной. Интерполяция это попытка отгадать, что там между двумя отсчётами. Наиболее правдивое это, то что я делаю через корреляцию с заданной частотой(Преобразование Фурье). Добавление нулей делает определённые предположения о том что между отсчётами, но это далеко от правды. |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Вот какие у меня результаты получились . Выделял первый пик , а потом находил вершину параболы .
Всего отсчетов -4096, ЧД 8000. Ни окна ни порги не использовал 1. 329.1 2. 251 3. 196.3 4. 147.47 5. 110.37 6. 81.1 для 8192 ЧД 8000 1. 328.6 2. 251.46 3. 194.83 4. 146 5. 109.87 6. 80.57 для 16384 ЧД 8000 1. 328.37 2. 251.7 3. 194.56 4. 146.2 5. 109.6 6. 80.32 да , скорее всего частота скачет туда сюда .Думаю эта точность до десятых - сотых нам ничего не скажет Ещё потом попробую через ещё одно преобразование фурье , если его пойму .. Может быть кстати правильней на нормальном генераторе попробывать .. |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Протестил с простеньким генератором .
Вот сдесь вот записал как раньше с микрофона http://dl.dropbox.com/u/29529555/8k%20gen.rar Чд 8000 частоты были такие : 90, 135, 200, 300, 400, и телефонный гудок , частота которого должна была быть 440гц , но мне кажется меньше) результаты : 2048 отсчетов: 91.88 134.82 201.2 302.76 400.4 427.75 4096: 90.84 135.76 200.2 299.8 399.4 426.76 8192: 90.34 135.26 200.69 300.3 398.9 426.27 16384: 90.04 135.01 199.95 300.05 399.17 426.5 Было бы интересно посмотреть на результаты со вторым преобразованием с различным кол-вом отсчетов .) |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Использую Хэмминга. 2048
1) 90.08 2) 134.99 3) 200.01 4) 300.01 5) 399.01 6) 426.37 Использую Хэмминга. 4096 1) 90.00 2) 134.99 3) 200.15 4) 300.00 5) 399.01 6) 426.33 Использую Хэмминга. 8192 1) 89.93 2) 135.01 3) 200.01 4) 300.00 5) 399.00 6) 426.34 Без окна 2048 1) 90.12 2) 135.00 3) 200.01 4) 300.01 (вначале по пал на пик 175.5 увеличел порог) 5) 399.02 6) 426.35 Без окна 4096 1) 89.99 2) 134.99 3) 200.11 4) 300.00 5) 399.01 6) 426.34 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, Спасибо большое .
Очень интересные результаты ) Ваш алгоритм поточнее получается .С хеммингом так вообще лучше не придумаешь . |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, а что у вас делает функция Amp(x)? вычисляет корень из суммы квадратов реальной и мнимой части?
|
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Да.
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Ффу , наконецто в С переписал ... Результаты просто поражают . показатели расходятся +- 0.1 Гц при учёте того что я беру 2000 значений из нужных 4х )) . И при увеличении массива точность не меняется !
![]() Ещё раз всем спасибо за помощь . ) ![]() |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
Раскажите на каком алгоритме вы остановились ?
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
vedun, на подборе частоты с помощью синуса и косинуса . Другими словами алгоритм
Pavia ) . Впринципе судить только по синусоидальному сигналу (которые я выложил выше ) нельзя , т как у гитары там набор синусоид , косинусоид и непонятно чего , но если выбирать между этим алгоритмом и параболой то он намного точнее . Самой по себе параболы быть не может - фронт и спад у неё разные + погрешности самого преобразования |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Блин , ещё одна небольшая проблема возникла . Взял акустику , и решил так же сделать пару записей разных нот . Делаю преобразование от этого массива по 2000 знач с ЧД 8000, и пока амплитуда максимальная ( первые пол секунды - секунда) граффик фурье просто обрезается где то на 100- 500 Гц . Пики до этого момента сохраняются , а потом просто идёт сплошной ноль (на самом деле что то в районе 0 +-5 )
вот , на скрине все видно . ![]() сам фурье брал вот отсюда http://psi-logic.narod.ru/fft/fft6.htm П.с На самом деле акустика намного громче электрики ). Микрофон был в 20см . Может он просто не воспринимает такую амплитуду и что то обрезает , искажает сигнал? или может слишком большие числа для фурье и дело в нем? Это сообщение отредактировал(а) Kpeved - 8.3.2012, 17:57 |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Сигнал после Фурье принято выводить в дБ в виду того что амплитуда может быть очень большой или очень маленькой (0.000001). Во вторых тот листинг что вы взяли для 2 в степени N, а у вас массив в 2000. |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Да ,были небольшие ошибки в коде из -за особенностей с++. Все переделал и сделал по дБ с логарифмической шкалой - да , намного удобнее . Сам по себе звуковой сигнал затухает логарифмом , поэтому на граффике все плавно и хорошо видно )
С массивом в 2000 вполне хорошо справляется - точность от этого не страдает , ведь мы только выделяем нужную частоту , а потом уже её уточняем .Разницы большой нет если бы мы сразу взяли от 2К фурье - просто так на граффике разброс побольше .) |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
А если взять экспоненциально затухающий синус с генератора? Мне кажется этот эффект останется! (Или эмулировать) Это сообщение отредактировал(а) Santik - 13.3.2012, 12:58 |
|||
|
||||
Santik |
|
||||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Я тоже думаю, что упругость струны тут не при чём. Такой же эффект наблюдается и в протонных магнитометрах. Но там частоту считают с точностью 0.001 Гц Это сообщение отредактировал(а) Santik - 13.3.2012, 21:42 Присоединённый файл ( Кол-во скачиваний: 8 ) ![]() |
||||
|
|||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Проверил чисто математически без преобразователей динамик-микрофон
Эффекта уплывания частоты нет. Более того я данные с гитары пробовал выравнивать по амплитуде эффект отсройки частоты сохранялся. То есть мой алгоритм детектирования частоты не зависит от амплитуды. Это сообщение отредактировал(а) Pavia - 13.3.2012, 21:46 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Надо подумать. Может вид огибающей неправильно выбран. Я то всегда думал, что это из-за амплитудной модуляции эффект. В магнитометрах сдвиг около 0.002 Гц приблизительно.
|
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
![]() |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Santik,
По мерил один вслеск с некоторым шагом. 484.1473 484.1523 484.1524 484.1526 484.1527 484.1528 484.1528 484.1495 Ошибка измерения +-0.0020 Тут частота стабильная в приделах метода. То что тут плавает это из за того что у нас частота дискретизации не кратна измеряемой. В моем методе это не учитывается. А ещё это я без оконной функции сделал, так что эффект Гиббса присутствует(скорее всего это он и есть). Если попадает два импульса в один буфер, то тут из за разной частоты или разных начальных фаз будет нестабильность. 484.1084 484.0920 484.0878 С дискретизацией напутал. Это сообщение отредактировал(а) Pavia - 14.3.2012, 07:19 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Что- то совсем не те частоты получились!
Магнитное поле около 62000Нт и частота должна быть 62000/23.8=2605 Гц Да и на мой "немузыкальный" слух это на телефонный гудок непохоже (440 Гц) ![]() Да и данные - это измерения в движении по конкретному профилю, а не в точке, так что ошибку не корректно так считать. Даже если в точке - всё равно надо вычитать естественные вариации магнитного поля. Это сообщение отредактировал(а) Santik - 14.3.2012, 00:02 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Да, действительно - и переходной процесс и фильтр в магитометре присутствуют. Причём фильтр настраивается по максимуму сигнала... Я в своё время перестраивал фильтр и вверх и вниз от целевой частоты - всё равно затяжка вниз была! Основной алгоритм был как у Pavia , но процедура нахождения максимума по частоте - итерационная (кстати, с помощью параболы ![]() Это сообщение отредактировал(а) Santik - 14.3.2012, 00:15 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Kpeved,
А если вернуться к основной задаче... Если я, зажав на 3 ладу, 5 струну ударю, что я должен получить с учётом всех гармоник? Аккорд До- мажор! То есть До будет само собой , какая то из гармоник - Ми и Соль А уж если взять аккорд До-мажор - мне даже трудно представить. Хотя надо посчитать - может всё не так страшно... Для полифонии всё-таки надо взаимную корреляцию. Через FFT это просто. Делаешь FFT своих данных, FFT эталона (хотя эталоны уже могут храниться в виде FFT ) - умножаешь и делаешь обратное FFT (получишь функцию взаимной корреляции). Может какую-то итерационную процедуру можно придумать для более быстрого выбора эталона. Эталоны можно эмулировать. Я бы на твоём месте просто вычислил sin( До )+sin( Ми )+sin( Соль ) и нашел ФВК с записанными аккордами. На записи с До- мажор должен быть максимум ФВК. Это сообщение отредактировал(а) Santik - 14.3.2012, 08:42 |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Santik,
Да напутал с частотой дескритизации. Вот правильные. 2606,337; 2606,338; 2606,338; 2606,338; 2606,338; 2606,338; 2606,339; 2606,339; 2606,339; 2606,339; 2606,339; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,340; 2606,341; 2606,341; 2606,347; 2606,322; |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Pavia ,Ну вот это уже другое дело! Хотел свою программу восстановить для сравнения, но наверное не получится. 10 лет прошло. Она ещё на Паскале писана. Паскаля у меня нет давно, я только текст с трудом в Блокноте смог прочитать. Да и смысла теперь особого не вижу.
Единственное могу сказать, что выигрышь по сравнению с другими методами получился только при большых шумах. Мой магнитометр заработал в помещении!!! И чувствовал проезжающие по трассе "Жигули" (расстояние около 100 метров)! А так тяжелый алгоритм. У меня тогда только Р-133 был. ![]() |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
||||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Конечно грубее при такой частоте дискретизации
![]() В реальном магнитометре - 1 бит , но время очень точно считают. |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Посмотрел спектр сигнала (1-ая стуна 44кГц). В некотором шоке. Вообще-то надо струну "дёргать" надо было автору на 12 ладу... Но от этого пока интерес к задаче не потерялся.
Смысл: "Кто нам мешает - тот нам поможет!" (С) Кто мешает для расчёта использовать гармоники? Это сообщение отредактировал(а) Santik - 14.3.2012, 22:25 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, если мы зажмем на 3м ладу 5ую струну то мы получим .. мм.. С - то есть До . Ноту До - не До мажор. Если ударить 5 струн и зажать С -аккорд то тогда мы его получим . Разобрать такой аккорд не зная что за он - нереально (мозг то умеет , а вот с фурье врятли ))- ноты имеют свойство иметь двойную или тройную частоту какой нибудь совершенно другой ноты - эта же совершенно другая имеет свойство н-ых гармоник и т.д , поэтому и возникает путанница .
Не думаю что взаимная корелляция подойдет . Даже если мы и будем брать взаимную корреляцию с какой то забитой частотой , то определить частоту мы никак не сможем в силу того что частота у гитары не постоянная , к тому же минимальное отклонение и все идет на смарку - а нам ведь как раз нужно определить отклонение частоты , чего мы не сможем сделать. Да билн .. Вы тут точности считаете до тысячных . Достаточно 10х ). Частота струн гитары плавает - думаю обычное явление - дерево вибрирует + другие струны + ещё хз что .Это ведь не генератор сигналов . Начет алгоритма Pavia - очень медленный . На слабенькой машинке считает 2000 знач с частотой +-2 Гц (первый проход по 0.5 гц , второй +-0.5 по 0.1 Гц ) пол секунды . Тут и речи не может быть о мульти где 6 раз нужно пики считать .. |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Kpeved,
Ускорить в 100 раз это не проблема. |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Вот возьми и сам посчитай штук 11 гармоник от ноты С !!! Увидишь там и Е и G !!! А это уже - аккорд ![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, интересная особенность ). 5ую я нашёл точно (G ) , а вот 3ая немного не строит на 5Гц .
Получается в мажоре выходит немного больше этой частоты , а в миноре немного меньше ) Pavia, и как это можно сделать не потеряв точность ? |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
"Кто нам мешает - тот нам поможет!" (С)
Сделал взаимную корреляцию сигнала не с чистым синусом, а со смесью гармоник. Результаты положительные! Это сообщение отредактировал(а) Santik - 15.3.2012, 17:05 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Вот ещё добавление.
Интересно, что при изменении начала записи существенного изменения частоты не обнаружил! Скачком изменилась частота на 0.2 Гц . Как будто 2 конкурирующих процесса существуют.... Амплитудная модуляция??? Но тогда 3 частоты должно быть... Не понятно... ![]() Подробности в файле (лист "Задержка") Это сообщение отредактировал(а) Santik - 15.3.2012, 22:38 Присоединённый файл ( Кол-во скачиваний: 6 ) ![]() |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Проблема быстродействия существует. Кто-то обещал в 100 раз увеличить?
Я пока двигаюсь в сторону FFT:
Проблема в том, что каждый раз приходится FFT считать для суммы синусов и косинусов. Как это сделать без FFT??? В файле - результаты расчёта интегралом и FFT. Это сообщение отредактировал(а) Santik - 17.3.2012, 08:48 Присоединённый файл ( Кол-во скачиваний: 6 ) ![]() |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Santik,
Построить можно, но много не выиграешь N*ng против N*log(N) А вот если ng=1. То там FFT можно вынести из цикла. Правда потребует переделки FFT. |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Мне кажется FFT можно для синусов и косинусов можно по простой формуле посчитать.
Вот я для 7 гармоник прикинул (в файле). Я не понял, причем сдесь Ng=1??? FFT вне этого цикла ! Если FFT не делать - в цикле останется умножение 2-х векторов и реверсное FFT . Добавлено @ 10:48 Файл Это сообщение отредактировал(а) Santik - 17.3.2012, 10:52 Присоединённый файл ( Кол-во скачиваний: 2 ) ![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Дыра в быстродействии не в ФФТ а в синусах и косинусах . При нахождении 1го пика мы мы M-раз , в зависимости от точности , проходим по всему массиву длинной N и каждый раз считаем син и кос . Потом ещё берём корень...
По быстродействию должен получится как ФФТ , но получается намного медленнее . Может можно применить формулу эйлера или ещё что то ? |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Неее... Ты не прав! Просто каждый раз приходится вычислять "длинный" интеграл внутри которого умножения на син/кос.
А то что М-проходов - сделай итерационную процедуру поиска экстремума. У меня до 0.001 за 5-6 итераций сходилось... А так "тупо" никто не делает. Pavia это же для примера написал... Добавлено через 13 минут и 24 секунды И мне кажется надо попробывать как vedun предлагал, но только использовать все гармоники. Только полученные не забывай поделить на номер. И среднюю взять. Наверное точности хватит. |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Ну первую мы вычислили... А дальше "тупо" умножаем на 2 , 3, .... 11 . И методом параболы уточняем.
Чем выше гармоника, тем точнее расчёт... Это сообщение отредактировал(а) Santik - 17.3.2012, 12:02 |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Pavia |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Santik,
Вы считаете через FFT свёртку. Для sin и cos свёртку линейная.
Не кажется так и есть. Вот корреляцию для вашего случая можно считать со сложностью N*Ng. Но это не даёт преимуществ. Надо выносить FFT из цикла по k. Santik, Я интерационно не считал, так как с полосой был не уверен. Сейчас уверен, да можно интерационо. Только вот полоса пропускания 1 Гц поэтому интонационно можно только когда у нас такая точность 1 Гц. В виду того что у нас массив менее секунды точность не дотягивает до 1 Гц. Так что тут прирост будет в 2 раза. А вот свёртку можно ускорить в виду того что у меня используется FT где sin и cos вычисляется на каждом шагу. Есть алгоритм Герцеля. В виду того что он плохо описан в литературе, дальнейшее что я опишу может отличаться или не соответствовать. Так вот для быстрого расчёта можно использовать свойство косинус суммы и синус суммы.
Здесь Cos(-2*Pi*i*w*N1); можно представить в виде cos(-2*Pi*(i-1)*N1+-2*Pi*1*N1)=переобозначим=cos(a_I_1+b)=cos(a_I_1)*cos(b)-sin(a_I_1)*sin(b) sin(a_I_1+b)=sin(a_I_1)*cos(b)+cos(a_I_1)*sin(b) 1)sin(b) cos(b) Вычисляются вне цикла. 2) sin(a_I_1) cos(a_I_1) Известно с предыдущей итерации цикла. Раз в 10 должно ускориться. Добавлено через 12 минут и 34 секунды А вообще всё это ерунда, берём FFT и немного переделываем поделив начальную частоту в N раз. Тем самым мы повысим точность и скорость. |
||||
|
|||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
А почему не кратны? Это же колебания струны. Обязаны быть кратными! Я проверял. Правда если вы не на 44100 Гц смотрели , то возможно, что пролезают гармоники с частотами больше Найквиста, которые благополучно в низкочастотную отражаются... Это сообщение отредактировал(а) Santik - 17.3.2012, 15:55 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Так вот я и хочу одно FFT из цикла убрать. Останется в цикле перемножение векторов и обратное FFT. Тоже конечно не очень... Так где мне посмотреть это "так и есть"??? У меня вылезает что-то типа SIN(X)/X. Велосипед изобретать не хочется. |
|||
|
||||
vedun |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 23.12.2010 Репутация: 2 Всего: 2 |
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Исходя из задачи
![]() vedun, докладываю: Дисперсии не обнаружено!
А если и есть, то совсем маленькая и почти совсем незаметная... ![]() Это сообщение отредактировал(а) Santik - 17.3.2012, 17:53 |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Я что-то пропустил, наверное! Новые методы появились??? ![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Pavia, а можно поподробнее как именно нужно переделать ? И зачем нам частоту делить ?
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Pavia похоже погорячился... Я вот испытал модифицированный метод Vedunа. Через 3 точки Х(f0),Х(f1),Х(f2) (из FFT, при f1- макс. значение) проводим параболу. Находим f3. Далее модификация - считаем наш интеграл и находим Х(f3) Ещё раз считаем интеграл Х(f3 +- h) (+ или минус в зависимости от значений Х(f1) и Х(f3). Через 3 точки снова проводим параболу. Находим искомую частоту. Ошибка менене 0.1 Гц на частоте 380 Гц. (Fd=44100) Таким образом "длинный" интеграл считаем всего 2 раза! Можно, конечно, еще раз эту процедуру повторить, чтобы получить ещё меньшую погрешность. Это сообщение отредактировал(а) Santik - 19.3.2012, 21:56 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, а на чем проверяли ? На генераторе или реальном звуке ? Мне кажется что там вообще не парабола - фронт и спады разные и она там никак не получится .
И у вас как я понял 3 раза интеграл считается - для X(f3) , X(f3-h) , X(f3+h) - потом находится методом параболы ? Т.есть мы просто считаем значения амплитуды в этих точках и строим параболу ? Не совсем точный метод . Тем более если учесть искажённые сигналы с перегрузом или дисторшном или с чем нибудь ещё то там будет точно не парабола . Я все ещё надеюсь что Pavia что нибудь напишет по поводу переделки алгоритма ) ![]() |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Работаем с модулем FFT !!! Можно 2 раза - т.к. одну точку ты уже нашёл через FFT. Если алгоритм расчёта параболы рассчитан на равномерную сетку, тогда три раза интеграл считать. Но это лучше перебора с шагом 0.5. И лучше с 44100 работать. На увеличение быстродействия особо не надейся ![]() Прикинь сколько вообще ты можешь итераций себе позволить. Учти, что на коротком сигнале ты не получишь хорошую точность! И ничего не поможет! Я думаю точность 0.1 Гц для 6 струны получишь при длительности сигнала 1 секунда. |
|||
|
||||
Pavia |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 6.12.2008 Репутация: 11 Всего: 12 |
Самый простой способ увеличить в 10-20 раз это взять библиотеку FFTW, она быстрее обычной самописной реализации.
Берем 2 буфера 1) N=2048 отсчётов 2) NewN=64*1024 отсчётов В первый пишем сигнал пишем сигнал потом умножаем на оконную функцию лучше Ланцоша (sinc) Копируем результат во второй остававшийся часть заполняем нулями. После FFT и ищем максимум. i*Fd/(NewN); частоту определяем как. Точность будет 0.1 Гц. Больше ничего не требуется. Без FFTW по скорости не отличается от предыдущего алгоритма.
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Сейчас проверил ещё один интересный способ уточнения частоты.
Алгоритм такой: 1. FFT и находим основную частоту 2. Определяем сигнал с линейно меняющейся частотой Fmax +- 0.5 Гц (44100) 3. FFT этого сигнала 4. Перемножаем вектора 5. Реверсное FFT--> X(i) 5. Отношение Х(N/2)/X(1) даст поправку к определённой в п.1 частоте Проверил на тестовом сигнале. Точность 0.001 Гц !!! (Fd=44100) |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, а как по производительности? Сколько итераций это все приблизительно займет ? И что значит "Сигнал с линейно меняющейся частотой"?
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
А итераций нет совсем. Грубо говоря - всё забито в прямое и обратное преобразование Фурье.
Алгоритм я уже приводил на Фортране. Там нужно только ввести сигнал с переменной частотой: f=f0+(0.5)/T*t Все примеры для 44100, Т=1сек. Пусть мы из FFT определили fmax= 328 Гц . Если значение при 329 больше чем в 327 то нам надо двигаться в +. f(t)=328+(0.5)/T*t , т.е. частота меняется линейно во времени от 328 до 328.5 Гц Интеграл от 2*Pi*f(t) даст фазу сигнала Ф(t). cos(Ф(t)) +i sin(Ф(t)) - это и будет наш сигнал с линейно меняющейся частотой. Далее делаем свёртку этого сигнала с исходным сигналом (см. программу) (умножаем вектора результатов FFT и делаем обратное FFT Максимум модуля свёртки (или точная частота) гарантированно будет в этом диапазоне. Завтра приведу данные по производительности. Программу полноценную мне конечно лень писать. Но для примера текст отладочной программы приведу, чтобы можно разобраться было. Ну а дальше - сам. ![]() |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Данные по быстродействию:
Fd=44100 N=44100 (1 сек) Тестовый сигнал 329.123456 Гц с шумом. 600 значений частот рассчитаны за 53 секунды. (P-4 3ГГц) Погрешность 0.001 Гц. |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
||||
|
||||
Kpeved |
|
||||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Наконецто набрася храбрости прочитать код на ещё одном неизвестном мне языке .) По коду мне все ещё непонятно следующее :
Ещё не знаю - есть ли в фортране перегрузка операторов - но как именно он умножает операнды ? Да, и что делает DCONJG тоже не ясно )
Вроде бы по коду все . Ещё по быстродействию - Если мы будем использовать ЧД 8К при 1024 значениях - будет ли у нас нужная точность ? Получается что на 1 отсчет придется по 8Гц и +- надо брать намного больше . |
||||
|
|||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Даже это уже положительный момент!!! Да и что может быть проще Фортрана? Приивлекает богатейшая библиотека IMSL. БПФ, к примеру, - с любым количеством точек и очень быстро! DCONJG -функция комплексного сопряжения (комплексного вектора FX - в данном случае в FX - БПФ исходного сигнала ) CDABS - -функция возвращае модуль комплексного числа (D- двойная точность) По быстродействию сказать ничего не могу. При изменении N "магические числа" могут быть другими! По точности см. http://dsplib.ru/forum/viewtopic.php?f=7&a...42&start=10 Выбираешь нужную погрешность и находишь М и потом N - число точек (для 6 струны - обязательно, т.к. НЧ хуже по точности) Я пока этот алгоритм не "обкатыва". Надеюсь совместными усилиями .... Это сообщение отредактировал(а) Santik - 26.3.2012, 07:39 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, ну а что вообще за числа в 73 ? Как их рассчитывать ?
Как я понял М и N рассчитываются по последней формуле ? Тогда если Т=0.128 ,f= 70Гц, то M =8.96. Погрешность около 0.1 Гц . И ??) |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Определение коэффициентов: Снимаем характеристику er=CDABS(X1(N/2))/CDABS(X1(1)) при расстройке частоты от 0 до 0.5 с шагом 0.01 Гц. Находим ошибку. Находим тренд функции Ошибка(er). (я для начала в Excel делал) Получаем df=-0.861*er+0.85504 По полученному значению er находим ошибку df. У меня сейчас: df=0.11356244E+01*er**7-0.56608063E+01*er**6+0.11240384E+02*er**5-0.11300708E+02*er**4+ 0.64610102E+01*er**3-0.25383018E+01*er**2 -0.60435858E-01*er+ 0.72327669E+00 ![]() ... И ??) Это говорит о том, что при данной частоте и времени сигнала ты определишь частоту с погрешностью не менее 0.1 Гц . Если тебе нужна меньшая погрешность - придется увеличивать Т и другого выхода нет! |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Для Fd=8000 Гц и N=1024
df=-0.69019186E+01*er+ 0.68520498E+01 При частоте 78 Гц метод даёт погрешность 0.2 Гц |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
В файле некоторые результаты вычисления при Fd=8000 Гц.
Присоединённый файл ( Кол-во скачиваний: 10 ) ![]() |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Исследуем полифонический сигнал (файл 44k-all.txt)!
Это сообщение отредактировал(а) Santik - 29.3.2012, 19:09 Присоединённый файл ( Кол-во скачиваний: 10 ) ![]() |
|||
|
||||
Kpeved |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Так . Ещё раз прочитал код и опять не понял - что значит вот эта строчка :
X2 и X1 у нас структуры , содержащие реальную и мнимую части , а не фазу и модули . Так ? Комплексное сопряжение DCONJG всего лишь меняет знак на противоположный .Верно? Что тогда делает оператор * ? Это какое то умножение , или свертка , или ещё что то ? Можно про это поподробнее . И как то все просто в этом случае
Т.есть мы берём прямое , обратное фурье только для того чтобы взять и разделить модули от N/2 -го и 1го элементов массива X1 ? Или я тут тоже что то не понимаю ? И вот по этому ещё :
Как эти цифры в нормальном виде записать ? Там , с кучей нулей впереди , или наоборот . |
||||||
|
|||||||
ramateur |
|
||||
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 12.4.2012 Репутация: нет Всего: нет |
Доброго времени суток!
Занимаюсь обработкой речи, недавно тоже была проблема определения частоты основного тона. По ходу ковыряний в этой теме выяснил, что принципы для голоса и монофонических музыкальных звуков (звук одной струны в случае гитары) по сути одни и те же. В связи с этим предлагаю метод YIN для задачи Kpeved'а. Описание его тут: Статья про метод YIN. У мну получился такой код для Matlab:
Функция принимает в качестве параметров frame – короткий фрагмент сигнала (30...80 мс), частоту дискретизации Fs и пределы полосы, где ищем частоту основного тона (открытых струн гитары с запасом сгодится flow=60, fhigh=400). Даже при частоте дискретизации 48 кГц ошибка дискретизации для первой струны может составить около 330—1/(1/330+1/48000)=2,25 Гц, поэтому для повышения точности поиска минимума функции D2 прикручена параболическая интерполяция:
Возможно пригодится... |
||||
|
|||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
ramateur, да , для одной струны этот метод прокатит . я думаю что все тюнеры которые за долю секунды определяют частоту работают с автокорелляцией . Но для множества струн он не подходит .
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
67: Да, это умножение двух векторов, один из которых комплекно сопряженный. Если сделать потом обратное Фурье - получим взаимную корреляцию .
72: Да, мы делаем прямое и обратное преобразование для того чтобы взять потом 2 элемента массива. Зато потом формула простая... Это чтобы с кардинальным синусом не возится. А последнего вопроса я как-то не понял... Это сообщение отредактировал(а) Santik - 13.4.2012, 15:59 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, т.есть в 67 формула будет такой : (a+bi)·(a′+b′i)= (a·a′−b·b′)+(a·b′+b·a′)i . Верно?
Хм . нормальном значит в .. обычном , поянтным для компилятора, и для человека ) . Ну тоесть -0.69019186E+01 - это число умноженное на Е + 01 , или + 0.1 , или это Е в степени 01 ... Вобщем , как записать это число , не используя буквы Е . |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Да, верно. В 67 все числа комплексные. Только надо все-таки сделать для второго операнда комплекное сопряжение - т.е. изменить знак мнимой части. E - это 10. E+01 - это 10 в степени 1. -0.69019186E+01 =-6.9019186 Это сообщение отредактировал(а) Santik - 13.4.2012, 18:56 |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Наконец то проверил . Деля модуль N/2 числа из конченого массива на модуль 1го числа мы всегда получаем Er = 1 . Потому что их значения одинаковые . Поэтому результаты неправильные . Разве только .. неправильная трактовка элементов массива . В фортране эл-ты массива начинаются с 1го или с 0го элемента ?
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
В Фортране с первого. |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Все , решил . проблемма как всегда была в приведении типов в С . Проверял на сигнале генератора в 300 Гц - значения скачут с 302 до 288 Гц , причем последовательно то уменшается , то увеличивается . Вобщем
![]() |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
A частоту в ЛЧМ- сигнале в каких пределах менял? При fd=44100 и N= 44100 надо 0.5 Гц
При fd=8000 и N= 1024 надо 0.5*8000/1024 Сигнал 300 гц вышли, посмотрим ![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
ЛЧМ имеется ввиду df ? Поменял , все равно ничего не изменилось .
Вот мои сигналы в txt . Кодировка вроде младший , потом старший . http://dl.dropbox.com/u/29529555/8k%20gen.rar |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Что то меня вообще частотные методы смущают . Медленные и недостаточная точность , и разброс значений больтшой . За секунду меняет значения на +- 100 Гц (очень сильно плавает по гармоникам ). Думаю надо попробовать с корреляцией . И вот самый главный вопрос - можно ли выловить 6 частот из сигнала , если их приблизительно знать (забитый строй +- )
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Так в принципе всё, что до этого делалось - это корреляционные методы. Частотный метод (с уточнением) предлагал только Vedun. В остальных FFT используется для быстрого вычисления функции взаимной корреляции... И полифонический сигнал я смотрел (см. выше) |
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Открыл файл 8000gen300.txt Что- то не похоже на запись синуса!!!
|
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, не знаю , сигнал сгенерирован генератором и записан . Генератор генерировал синус )
|
|||
|
||||
Santik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 13.3.2012 Где: Мирный (Якутия) Репутация: нет Всего: нет |
Kpeved , посмотри сам файл 300 Гц. Что- то у меня не получилось его нормально прочитать. Такое ощущение, что я между байтами попадаю....
![]() |
|||
|
||||
Kpeved |
|
|||
Новичок Профиль Группа: Участник Сообщений: 42 Регистрация: 26.2.2012 Репутация: нет Всего: нет |
Santik, может быть неправильно дешифрируешь их ? надо старший байт умножить 65К - чето там и сложить с младшим, либо сдвинуть на 8 бит влево и тоже сложить .Да , и проблемма ещё может быть в unsigned- signed
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |