Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Определение периода сигнала
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Математика и Физика
ataradov
На картинке приведено несколько периодов колебания басовой струны гитары. Красным отмечен ожидаемый период. Необходимо определить частоту колебаний, но прямой подсчет дает в 2 раза завышенный результат, так как там полно гармоник, но на глаз период хоршо заметен. При этом амплитуда "внутреннего" колебания изменяется от полного пропадания, до равной и даже большей, чем "основного" колебания.

Нужен способ определить период, при этом сложные вычисления (типа FFT) не желательны, так как должно работать все на 8-бит микроконтроллере.
scifi
Что-то мне подсказывает, что здесь без "сложных" вычислений не обойтись. И ещё для обсуждения полезно будет указать, в каком диапазоне может меняться период.
ataradov
QUOTE (scifi @ Aug 23 2010, 18:00) *
И ещё для обсуждения полезно будет указать, в каком диапазоне может меняться период.

Для гитары частоты от 80 до 330 Гц. Желательно, чтобы получилось для полного диапазона фортепиано -- 27 - 4200 Гц.

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

Китайский аппаратный тюнер работает значительно лучше, но все-равно на басовых струнах подглючивает.

Интерес чисто академический, особой практической цели не преследует. Ну если получится удобоваримый алгоритм можно и железку сделать.
Microwatt
Цитата(Taradov Alexander @ Aug 23 2010, 16:01) *
На картинке приведено несколько периодов колебания басовой струны гитары. Красным отмечен ожидаемый период. Необходимо определить частоту колебаний, но прямой подсчет дает в 2 раза завышенный результат, так как там полно гармоник, но на глаз период хоршо заметен. При этом амплитуда "внутреннего" колебания изменяется от полного пропадания, до равной и даже большей, чем "основного" колебания.

Нужен способ определить период,

Странная проблема.... "Ожидаемый период"- скорее всего, "неожиданный", это попытка измерить вторую субгармонику.
Из теории колебаний период однозначно связан с основонй частотой колебаний. Никакие гармоники не могут изменить его, могут изменить только форму колебаний, но не период. Т.е тембр струны может быть разным, но не основонй тон, частота.
Посему, нужно считать время меж пересечениями сигналом нуля, это даст полупериод. Время между фронтами или спадами даст период. Сигнал перед оцифровкой нужно пропустить через нуль-компаратор (усилитель с большим коэффициентом усиления).
"Ля" первой октавы должно давать 440гц.
Oldring
Цитата(Taradov Alexander @ Aug 23 2010, 17:01) *
так как должно работать все на 8-бит микроконтроллере.



В настоящее время уже очень странное требование.
ataradov
QUOTE (Microwatt @ Aug 23 2010, 18:16) *
Странная проблема.... "Ожидаемый период"- скорее всего, "неожиданный", это попытка измерить вторую субгармонику.

Красным изображен период соответствующей частоте 82 Гц, 6 струна гитары. Синим - реальное колебание этой струны. Есть моменты, когда реальное колебание почти синус, но большую часть времени по нему бегут такие "волны". Програмные тюнеры схватываются за моменты чистой синусоиды, но они длятся долю секунды.

QUOTE (Microwatt @ Aug 23 2010, 18:16) *
Из теории колебаний период однозначно связан с основонй частотой колебаний. Никакие гармоники не могут изменить его, могут изменить только форму колебаний, но не период. Т.е тембр струны может быть разным, но не основонй тон, частота.

Именно так. Форма колебаний изменяется настолько, что в определенные моменты времени пересечений сигнала с 0 становится больше, но период сигнала не изменился и это видно из картинки. Такого искажения формы достаточно, чтобы простой метод подсчета длительности сигнала между пересечениями нуля давал сбои.

QUOTE (Microwatt @ Aug 23 2010, 18:16) *
Посему, нужно считать время меж пересечениями сигналом нуля, это даст полупериод. Время между фронтами или спадами даст период. Сигнал перед оцифровкой нужно пропустить через нуль-компаратор (усилитель с большим коэффициентом усиления).
"Ля" первой октавы должно давать 440гц.

Это все в теории (ну и на практике для более высокочастотных струн), но не работает для басовых струн, у них очень богатый спектр.

QUOTE (Oldring @ Aug 23 2010, 18:31) *
В настоящее время уже очень странное требование.

В конечном итоге важны цена и потребление. Если по цене действительно можно найти альтернативы, то по потреблению уже сложнее (ну если не пускать АРМ на 16 МГц, конечно).

Кроме применение мощного процессор противоречит самой идее простого гитарного тюнера.
Oldring
Цитата(Taradov Alexander @ Aug 23 2010, 18:47) *
В конечном итоге важны цена и потребление. Если по цене действительно можно найти альтернативы, то по потреблению уже сложнее (ну если не пускать АРМ на 16 МГц, конечно).

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


У вас действительно миллионные тиражи, чтобы бороться за плюс-минус доллар цены?
Задача явно для 16-битного DSP. По потреблению скорее всего DSP окажется эффективнее 8-битника - потребуется меньше команд для реализации одинакового алгоритма. Тем более, если он будет спать, когда не нужен.
ataradov
QUOTE (Oldring @ Aug 23 2010, 19:17) *
У вас действительно миллионные тиражи, чтобы бороться за плюс-минус доллар цены?

Нет, у меня вообще нет планов по выпуску его. Возможно DSP будет и лучше. Можно убрать из вопроса требование к ресурсам.

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

-----------
Прицепил wav-файл с записью звука всех струн, если кому интересно поэкспериментировать.
В матлабе можно сделать data = wavread('guitar2.wav'); и он весь ваш smile.gif
Alex11
Вы бы поиграли с модельками, тем более, что у Вас есть разные варианты записанного сигнала. Возможно, что Вам будет достаточно очень небольшого по буферу Фурье, чтобы определить основную частоту. Нужно только разойтись с гармониками, а дальше уточнить частоту по огибающей.
ataradov
QUOTE (Alex11 @ Aug 23 2010, 19:28) *
Вы бы поиграли с модельками, тем более, что у Вас есть разные варианты записанного сигнала. Возможно, что Вам будет достаточно очень небольшого по буферу Фурье, чтобы определить основную частоту. Нужно только разойтись с гармониками, а дальше уточнить частоту по огибающей.
Я и играюсь тут, просто коллективный разум хотел еще привлечь, иожет велосипед изобретаю.

Так же попробовал метод описанный в одном из блогов:
QUOTE
The solution I used is a pretty simple one. We set two thresholds (a positive and a negative one), and start counting when the signal value becomes higher than the positive threshold. We keep counting and wait for the signal to go below the negative threshold, then wait for it to go above the positive one again. This sometimes helps us count only the transitions we’re interested in.

Он дает правильное определение чаще чем обычный подсчет переходов через ноль, но все-равно ошибается, когда амплитуда "помехи" достаточно велика.

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

В идеале нужен алгоритм, который найдет подобную зависимость и определит период.
Microwatt
Цитата(Taradov Alexander @ Aug 23 2010, 18:51) *
Он дает правильное определение чаще чем обычный подсчет переходов через ноль, но все-равно ошибается, когда амплитуда "помехи" достаточно велика.

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

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

Вы привели картинки неполностью, неаккуратно наложенных колебаний. Форма их может несколько отличаться, но частота (период) одинаковы.
Возможно, я чего-то в Вашей формулировке не понимаю, но ни о каких "помехах" речь идти не должна. Период легко должен определяться через подсчет времени переходов через нуль. Вы как и чем пытаетесь измерять? Неужели по-эмбеддерски, с помощью АЦП?
ataradov
QUOTE (Microwatt @ Aug 23 2010, 20:06) *
Возможно, я чего-то в Вашей формулировке не понимаю, но ни о каких "помехах" речь идти не должна.

На первой картинке я черным изобразил период синуса (как смог, извините) 82 Герц. Я вполне уверен, что струна колеблется именно с этой частотой. Искажение ("провал") по центру - это особенность огибающей этой струны, простое определение по пересечениям даст удвоенную частоту.

Вторая картинка - то-же эффект, но не так сильно выраженный. Период сигнала заключен между двумя большими "горбами".

Так что просто посчетом переходов через ноль нельзя отделаться.

--------------------
И еще один рисунок где проблема видна очень хорошо. Период OK по переходам через 0 определится правильно, период BAD - нет.

@Ark
Судя по Вашему описанию и картинкам, главное отличие основной частоты от остальных в том, что ее амплитуда
меняется гораздо медленнее - практически постоянна на их фоне. Если это предположение верно, то попробуйте
за него как-то "зацепиться" при выработке алгоритма.
rezident
Может я чего-то не понял, но почему из всего спектра нельзя выбрать наименьшую частоту? К тому же, если диапазон изменения основной частоты при разном натяжении для каждой струны примерно известен, то можно корреляцию с требуемой частотой посчитать.
ataradov
QUOTE (rezident @ Aug 23 2010, 21:51) *
Может я чего-то не понял, но почему из всего спектра нельзя выбрать наименьшую частоту? К тому же, если диапазон изменения основной частоты при разном натяжении для каждой струны примерно известен, то можно корреляцию с требуемой частотой посчитать.
Вот спектр той-же 6-ой струны. Нужен какой-то хороший критерий поиска. Курсором помечена нужная частота. Слева от нее сравнимого уровня "палка" 50 Гц - это похоже сеть, не ожидал ее тут увидеть, попробую отфильтровать. Максимум - это 160 Гц, та самая "помеха".

Кроме того приведеный FFT сделан по 83000 точек (вся выборка), если делать окнами реального размера, то получется каша и недостаточное разрешение (хотя для первого приближения может и подойдет).

Делать фильтры на частоты конкретных струн нельзя, так как они могу быть значительно рассторены (иногда специально), нужно именно определить частоту и сказать к какой ноте она ближе всего и на сколко процентов не совпадает с ней.
Microwatt
Ага, теперь из картинки "ОК" и "Плохо" стало понятно..... Понятна проблема, но не видны простейшие пути решения.sad.gif
demiurg_spb
Я для настройки гитары пользуюсь вот этой софтинкой.
Вполне сносно работает.

Я бы опыты на компе ставил, записал wav файлик и давай на нём реальные эксперименты с фильтрами ставить...
ataradov
QUOTE (demiurg_spb @ Aug 23 2010, 23:14) *
Я для настройки гитары пользуюсь вот этой софтинкой.
Вполне сносно работает.
Настройка не проблема, железный тюнер тоже нормально работатет. Просто интересная задача для разминки мозгов.

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

QUOTE (demiurg_spb @ Aug 23 2010, 23:14) *
Я бы опыты на компе ставил, записал wav файлик и давай на нём реальные эксперименты с фильтрами ставить...
Так я и сижу с матлабом.
demiurg_spb
Цитата(Taradov Alexander @ Aug 23 2010, 23:21) *
Так я и сижу с матлабом.
Отлично! Тогда успех неизбеженsmile.gif
Самурай
Alexander, попробуйте посмотреть в сторону алгоритмов обработки речи, точнее на методы измерения частоты основного тона (Pitch detection algorithm). Кажется, Ваша задача именно из этого класса. Но не ждите готовых и простых решенийsmile.gif.
GetSmart
Автокореляцию не пробовали? Вроде идеальная для этой задачи вещь. Легко ищет периоды сигналов со сложным спектром.

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

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

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

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

..Для периодически повторяющегося сложного сигнала, наверное, это расстояние (во времени) между одинаковыми элементами в каждой "порции" сигнала.. rolleyes.gif
В смысле, между одинаковыми элементами двух соседних "порций"..
Наверное, стоит искать и анализировать экстремумы.
Например, найти внутри периода уникальный экстремум. Тогда время между уникальными экстремумами будет периодом.
А вот если от периода к периоду сигнал еще и масштабируется, то есть, изменяется по уровню, это сложней..
fontp
Здесь много всего муыкального, в том числе и определение частоты основного тона. Но с FFT
https://ccrma.stanford.edu/STANM/stanm/node3.html
ataradov
И так, приемлемое решение нашлось.
Алгоритм:
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');
Dmitry Valento
Александр, но ведь ваш алгоритм не дает высокой точности - плюс-минус герц.
А можно ли улучшить точность?
И еще один вопрос: какая сложность вашего алгоритма? Т.е. если реализовывать его на С++, только функция xcorr потребует выполнения О(N*N) операций. Тот же БПФ гораздо быстрее.
Andrey_1
Цитата(Taradov Alexander @ Aug 23 2010, 19:27) *
FFT напрямую все-равно не подходит из-за недостаточного разрешения и неоднозначности результатов. Необходимо разрешение в единицы герц, желательно в десятые доли (это то, что заявляют китайцы в железках, но насколько им можно верить не мне судить). В спектре ложные составляющие иногда превышают по амплитуде правильные.


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


Вообще-о лучше период считать через функцию неопределенности Гейзенберга, хотя это и противоречит второму постулату Гельсинора о дискретности времени
Alexey Lukin
Улучшить точность можно с помощью параболической интерполяции пика автокорреляционной функции.
Make_Pic
Цитата(Alexey Lukin @ Apr 7 2011, 12:15) *
Улучшить точность можно с помощью параболической интерполяции пика автокорреляционной функции.


А можно "на пальцах" показать как это практически сделать?
jer
Цитата(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-ми разрядном контроллере промоделировать не получилось, в Протеусе я пытался. На компе в матлабе это удобнее, там и частоту любую задаешь и считает он с плавающей точкой.
Вобщем интересно, что не я один догадался до такого способа )). Теперь бы результат в железе получить бы. Оставил эту затею в свое время, но мысль интересная, потому хотелось бы узнать как ее развивают другие.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.