Перейти к содержанию
    

Определение периода сигнала

Ага, теперь из картинки "ОК" и "Плохо" стало понятно..... Понятна проблема, но не видны простейшие пути решения.:(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я для настройки гитары пользуюсь вот этой софтинкой.

Вполне сносно работает.

 

Я бы опыты на компе ставил, записал wav файлик и давай на нём реальные эксперименты с фильтрами ставить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я для настройки гитары пользуюсь вот этой софтинкой.

Вполне сносно работает.

Настройка не проблема, железный тюнер тоже нормально работатет. Просто интересная задача для разминки мозгов.

 

Попробовал программу, тоже на этой струне показывет некоторое время 82 Гц, а потом перескакивает на 164 Гц. Настройке это не мешает, конечно. А вообще она показывает заниженные значения относительно аппаратного китайского тюнера. Кто-то врет :) Нужно камертон купить.

 

Я бы опыты на компе ставил, записал wav файлик и давай на нём реальные эксперименты с фильтрами ставить...
Так я и сижу с матлабом.
Изменено пользователем Taradov Alexander

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так я и сижу с матлабом.
Отлично! Тогда успех неизбежен:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Alexander, попробуйте посмотреть в сторону алгоритмов обработки речи, точнее на методы измерения частоты основного тона (Pitch detection algorithm). Кажется, Ваша задача именно из этого класса. Но не ждите готовых и простых решений:).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Автокореляцию не пробовали? Вроде идеальная для этой задачи вещь. Легко ищет периоды сигналов со сложным спектром.

 

Кроме применение мощного процессор противоречит самой идее простого гитарного тюнера.

А применение 30 рублёвого проца ни чему не противоречит? Юзайте LPC111x для этой цели. На 32 битное ядро не смотрите, смотрите на цену :)

 

По поводу "ошибок" китайского тюнера. Он скорее всего не ошибается. Если в звуке струны пропадает "основной" тон, а остаются только гармоники, то китайский тюнер не врёт. Но в девайсе собственного изготовления можно сделать такой алгоритм, что если самая низкая гармоника будет относительно максимальной например не ниже -10 Дб (или 20, по вкусу), то она будет определяться основной. И опять же можно сделать чтобы такой алгоритм был завязан на частоту, например работал на басовых и не мешал на других (если вдруг он будет там давать ошибки).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В идеале нужен алгоритм, который найдет подобную зависимость и определит период.

Так, какое определение периода для сложного сигнала?

Может быть, от определения и надо плясать..

 

..Для периодически повторяющегося сложного сигнала, наверное, это расстояние (во времени) между одинаковыми элементами в каждой "порции" сигнала.. :rolleyes:

В смысле, между одинаковыми элементами двух соседних "порций"..

Наверное, стоит искать и анализировать экстремумы.

Например, найти внутри периода уникальный экстремум. Тогда время между уникальными экстремумами будет периодом.

А вот если от периода к периоду сигнал еще и масштабируется, то есть, изменяется по уровню, это сложней..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь много всего муыкального, в том числе и определение частоты основного тона. Но с FFT

https://ccrma.stanford.edu/STANM/stanm/node3.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И так, приемлемое решение нашлось.

Алгоритм:

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');

post-24202-1282674775_thumb.png

Изменено пользователем Taradov Alexander

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Александр, но ведь ваш алгоритм не дает высокой точности - плюс-минус герц.

А можно ли улучшить точность?

И еще один вопрос: какая сложность вашего алгоритма? Т.е. если реализовывать его на С++, только функция xcorr потребует выполнения О(N*N) операций. Тот же БПФ гораздо быстрее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

FFT напрямую все-равно не подходит из-за недостаточного разрешения и неоднозначности результатов. Необходимо разрешение в единицы герц, желательно в десятые доли (это то, что заявляют китайцы в железках, но насколько им можно верить не мне судить). В спектре ложные составляющие иногда превышают по амплитуде правильные.

 

Разумеется какое уж тут ФФТ если оси в попугаях прокалиброваны, а разрядность АЦП почему-то влияет на частоту дискретизации и размер временного блока

 

 

Вообще-о лучше период считать через функцию неопределенности Гейзенберга, хотя это и противоречит второму постулату Гельсинора о дискретности времени

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Улучшить точность можно с помощью параболической интерполяции пика автокорреляционной функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Улучшить точность можно с помощью параболической интерполяции пика автокорреляционной функции.

 

А можно "на пальцах" показать как это практически сделать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И так, приемлемое решение нашлось.

Алгоритм:

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-ми разрядном контроллере промоделировать не получилось, в Протеусе я пытался. На компе в матлабе это удобнее, там и частоту любую задаешь и считает он с плавающей точкой.

Вобщем интересно, что не я один догадался до такого способа )). Теперь бы результат в железе получить бы. Оставил эту затею в свое время, но мысль интересная, потому хотелось бы узнать как ее развивают другие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...