|
Определение периода сигнала, нужен простой алгоритм |
|
|
|
Aug 23 2010, 19:21
|

Профессионал
    
Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202

|
QUOTE (demiurg_spb @ Aug 23 2010, 23:14)  Я для настройки гитары пользуюсь вот этой софтинкой. Вполне сносно работает. Настройка не проблема, железный тюнер тоже нормально работатет. Просто интересная задача для разминки мозгов. Попробовал программу, тоже на этой струне показывет некоторое время 82 Гц, а потом перескакивает на 164 Гц. Настройке это не мешает, конечно. А вообще она показывает заниженные значения относительно аппаратного китайского тюнера. Кто-то врет  Нужно камертон купить. QUOTE (demiurg_spb @ Aug 23 2010, 23:14)  Я бы опыты на компе ставил, записал wav файлик и давай на нём реальные эксперименты с фильтрами ставить... Так я и сижу с матлабом.
Сообщение отредактировал Taradov Alexander - Aug 23 2010, 19:26
|
|
|
|
|
Aug 23 2010, 19:57
|
Местный
  
Группа: Участник
Сообщений: 468
Регистрация: 4-03-05
Пользователь №: 3 066

|
Alexander, попробуйте посмотреть в сторону алгоритмов обработки речи, точнее на методы измерения частоты основного тона ( Pitch detection algorithm). Кажется, Ваша задача именно из этого класса. Но не ждите готовых и простых решений  .
|
|
|
|
|
Aug 23 2010, 23:04
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Автокореляцию не пробовали? Вроде идеальная для этой задачи вещь. Легко ищет периоды сигналов со сложным спектром. Цитата(Taradov Alexander) Кроме применение мощного процессор противоречит самой идее простого гитарного тюнера. А применение 30 рублёвого проца ни чему не противоречит? Юзайте LPC111x для этой цели. На 32 битное ядро не смотрите, смотрите на цену  По поводу "ошибок" китайского тюнера. Он скорее всего не ошибается. Если в звуке струны пропадает "основной" тон, а остаются только гармоники, то китайский тюнер не врёт. Но в девайсе собственного изготовления можно сделать такой алгоритм, что если самая низкая гармоника будет относительно максимальной например не ниже -10 Дб (или 20, по вкусу), то она будет определяться основной. И опять же можно сделать чтобы такой алгоритм был завязан на частоту, например работал на басовых и не мешал на других (если вдруг он будет там давать ошибки).
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Aug 23 2010, 23:22
|

Пользователь забанен
    
Группа: Свой
Сообщений: 1 138
Регистрация: 9-08-05
Пользователь №: 7 492

|
Цитата В идеале нужен алгоритм, который найдет подобную зависимость и определит период. Так, какое определение периода для сложного сигнала? Может быть, от определения и надо плясать.. ..Для периодически повторяющегося сложного сигнала, наверное, это расстояние (во времени) между одинаковыми элементами в каждой "порции" сигнала..  В смысле, между одинаковыми элементами двух соседних "порций".. Наверное, стоит искать и анализировать экстремумы. Например, найти внутри периода уникальный экстремум. Тогда время между уникальными экстремумами будет периодом. А вот если от периода к периоду сигнал еще и масштабируется, то есть, изменяется по уровню, это сложней..
--------------------
It's me
|
|
|
|
|
Aug 24 2010, 18:39
|

Профессионал
    
Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202

|
И так, приемлемое решение нашлось. Алгоритм: 1. Входной сигнал разбиваем на блоки длинной в несколько раз большей чем длинна самого длинного периода (я взял 5). 2. Считается автокорреляция блока. 3. Ищется первый максимум (кроме центрального). Расстояние этого максимума от центрального - искомый период. 4. Можно еще дополнительные меры предпринять, напрмер иногда второй максимум получается немного больше первого, такие вещи можно отфильтровать пытась сначала искать максимум там, где он ожидается (ранее вычисленный период), а только потом глобально. Можно делать перекрывающиеся блоки, и т.д. Вот код на матлабе и результат его работы. CODE clear all
Fd = 44100;
data = wavread('~/guitar2.wav');
s = data'; l = 535 * 5; % Fd / 82 Hz = 535 (e string frequency). zz(length(s)) = 0; for i = 1:l:length(s)-l, tt = xcorr(s(i:i+l)); [~, i1] = max(tt); % always at l/2 for j = i1:length(tt), if tt(j+1) > tt(j), i2 = j; break; end; % Find first local minimum end [~, i3] = max(tt(i2:length(tt)));
zzv = (i2+i3)-i1; for j = i:i+l, zz(j) = zzv; end; end
figure; hold on; plot(s); plot(zz / 2000, 'r');
Сообщение отредактировал Taradov Alexander - Aug 24 2010, 18:42
Эскизы прикрепленных изображений
|
|
|
|
|
Mar 31 2011, 08:05
|
Группа: Новичок
Сообщений: 4
Регистрация: 15-09-07
Из: Беларусь, Пинск
Пользователь №: 30 560

|
Александр, но ведь ваш алгоритм не дает высокой точности - плюс-минус герц. А можно ли улучшить точность? И еще один вопрос: какая сложность вашего алгоритма? Т.е. если реализовывать его на С++, только функция xcorr потребует выполнения О(N*N) операций. Тот же БПФ гораздо быстрее.
|
|
|
|
|
Apr 2 2011, 19:10
|
Частый гость
 
Группа: Участник
Сообщений: 131
Регистрация: 30-11-10
Пользователь №: 61 268

|
Цитата(Taradov Alexander @ Aug 23 2010, 19:27)  FFT напрямую все-равно не подходит из-за недостаточного разрешения и неоднозначности результатов. Необходимо разрешение в единицы герц, желательно в десятые доли (это то, что заявляют китайцы в железках, но насколько им можно верить не мне судить). В спектре ложные составляющие иногда превышают по амплитуде правильные. Разумеется какое уж тут ФФТ если оси в попугаях прокалиброваны, а разрядность АЦП почему-то влияет на частоту дискретизации и размер временного блока Вообще-о лучше период считать через функцию неопределенности Гейзенберга, хотя это и противоречит второму постулату Гельсинора о дискретности времени
|
|
|
|
|
May 11 2011, 12:34
|
Группа: Новичок
Сообщений: 2
Регистрация: 23-05-09
Пользователь №: 49 456

|
Цитата(Taradov Alexander @ Aug 24 2010, 22:39)  И так, приемлемое решение нашлось. Алгоритм: 1. Входной сигнал разбиваем на блоки длинной в несколько раз большей чем длинна самого длинного периода (я взял 5). 2. Считается автокорреляция блока. 3. Ищется первый максимум (кроме центрального). Расстояние этого максимума от центрального - искомый период. 4. Можно еще дополнительные меры предпринять, напрмер иногда второй максимум получается немного больше первого, такие вещи можно отфильтровать пытась сначала искать максимум там, где он ожидается (ранее вычисленный период), а только потом глобально. Можно делать перекрывающиеся блоки, и т.д. Вот код на матлабе и результат его работы. Код clear all
Fd = 44100;
data = wavread('~/guitar2.wav');
s = data'; l = 535 * 5; % Fd / 82 Hz = 535 (e string frequency). zz(length(s)) = 0; for i = 1:l:length(s)-l, tt = xcorr(s(i:i+l)); [~, i1] = max(tt); % always at l/2 for j = i1:length(tt), if tt(j+1) > tt(j), i2 = j; break; end; % Find first local minimum end [~, i3] = max(tt(i2:length(tt)));
zzv = (i2+i3)-i1; for j = i:i+l, zz(j) = zzv; end; end
figure; hold on; plot(s); plot(zz / 2000, 'r'); Александр, у Вас получилось это в железе? Очень интересно, поскольку я сам делал то же самое в матлабе, еще года два назад промоделировал, в матлабе тогда результат меня устроил, период между максимумами функции автокорреляции тестового сигнала находил, усреднял еще, вычислялась частота с точностью чуть ли не десятки герца. А вот в атмеловском 8-ми разрядном контроллере промоделировать не получилось, в Протеусе я пытался. На компе в матлабе это удобнее, там и частоту любую задаешь и считает он с плавающей точкой. Вобщем интересно, что не я один догадался до такого способа )). Теперь бы результат в железе получить бы. Оставил эту затею в свое время, но мысль интересная, потому хотелось бы узнать как ее развивают другие.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|