Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Спектральный анализ 44kHz stereo на STM32Fxxx...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
KnightIgor
Привет всем.

Первичный поиск по форуму дал мне не много результатов. Тема немного затрагивалась в 2013.

Вопросы:
- делал ли кто сабж,
- какой минимально возможный STM32F мог бы потянуть задачу спектрального анализа музыки 44kHz 16 бит стерео на предмет определения гармонии (скорее - доминирующего тона в каждый момент времени в медленных композициях); данные идут по I2S.

Спасибо за внимание.
_pv
fft у кортексов очень грубо говоря - 100 тактов на отсчёт у M4, раза в два больше у М3.
отдельные ноты неплохо бы различать, то есть корень 12й степени из 2 = 5%, от, пусть будет 200Гц. то есть 10 Гц разрешения по частоте хотя бы иметь надо, то есть ~100мс и соответственно FFT на 4k точек, даёт 4e3 * 100 / 0.1 = аж 4МГц тактовой частоты. => STM32 абсолютно любой, даже M0, у которого на FFT десять раз больше времени уйдёт, если ему данные малость проредить (зачем ему 44кГц для определения частоты в районе 1кГц) то и F0 вполне справится.

ну и если надо просто некую "среднюю" частоту сигнала найти, то отношение среднеквадратичного значения производной к среднеквадратичному значению сигнала можно хоть на калькуляторе руками успеть посчитать sm.gif
Obam
На we.easyelectronics.ru года 3 назад делали цветомузыку спектроанализом на каком-то слабеньком кортексе.
khach
Берите семерки STM32F746 или STM32F769 - там и с аудиоинтерфейсом все наконец в порядке, и памяти много ( внешняя) и FPU на борту. Впихнуть то можно и более слабые камни, но это будет именно впихивание. Фурье то работать будет, но или с памятью начнуться проблемы или небудем успевать всякий сервис крутить. С тактированием I2S тоже у младших STM32 были неудобные проблемы.
KnightIgor
Цитата(_pv @ Feb 22 2017, 19:09) *
STM32 абсолютно любой, даже M0, у которого на FFT десять раз больше времени уйдёт, если ему данные малость проредить (зачем ему 44кГц для определения частоты в районе 1кГц) то и F0 вполне справится.

Спасибо за расчеты. На плате имеется F103, но сделана так, что можно поставить до F4xx. Попробую сначала на F103.
Genadi Zawidowski
Тогда точно придется утаптывать в целочисленку... На DSP операциях 746 от 429 примерно в полтора-два раза шустрее. 429 с его 168 МГц просто быстрее чем 103 с 72... Зачем себя загонять? Отладитесь, потом впихивать-утаптывать будете...
Allregia
Цитата(khach @ Feb 22 2017, 20:05) *
Берите семерки STM32F746 или STM32F769 - там и с аудиоинтерфейсом все наконец в порядке, и памяти много ( внешняя)


А что было не в порядке у F4?

Цитата
и FPU на борту.


Причем с double precision, в отличие от F4!


Цитата
Впихнуть то можно и более слабые камни, но это будет именно впихивание.



Смотря какая задача стоит, а так вообще - спектроанализатор был 30 лет назад даже на Спектруме, а там Z80 с тактовой 3.5МГц.

Цитата
Фурье то работать будет, но или с памятью начнуться проблемы или небудем успевать всякий сервис крутить. С тактированием I2S тоже у младших STM32 были неудобные проблемы.


Какие? Я видел только одну, если нужно еще и SDIO - вход внешнего клока сидит на том-же пине, что и одна из линий данных. К счасть., не Д0, поэтому хотя бы в 1-битном режиме SDIO использовать можно.
KnightIgor
Цитата(Allregia @ Feb 23 2017, 07:10) *
Смотря какая задача стоит, а так вообще - спектроанализатор был 30 лет назад даже на Спектруме, а там Z80 с тактовой 3.5МГц.
Какие? Я видел только одну, если нужно еще и SDIO - вход внешнего клока сидит на том-же пине, что и одна из линий данных. К счасть., не Д0, поэтому хотя бы в 1-битном режиме SDIO использовать можно.

Я тоже всегда вспоминаю мой первый собственный ПК на урезаном 486 с 25MHz. Была машина-зверь после Синклера или PDP-11 на кафедре. Нынешние Cortex-Mx зачастую имеют внутренней памяти больше, чем тогда в ПК. Так что надежда осилить задачу есть. M7 лежит на полке, но он - явно пушка по воробьям.

Плата уже давно готова. Все требуемые интерфейсы разведены. С этой стороны проблем нет. Задачи у процессора скорее административного плана: управление BT модулем по UART и усилителем класса D по I2C, поэтому загрузка небольшая. Есть еще режим USB громкоговорителя, I2S на выход работает по DMA. Теперь стоит задача >альтернативно< использовать I2S как вход и анализировать поток от BT модуля на лету и управлять LED в зависимости от доминирующего тона. Почти светомузыка, но гораздо спокойнее и с другой целью, чем затуманивать девушкам мозги.

Я нашел проект на easyelectronics.ru. Спасибо Obam за подсказку.
khach
Спектроанализатор, блютус, USB, I2S на одном камне в риалтайме? Не верю (с). Как пример - SDR радио на кортексах (любительское). Конечно без особой оптимализации, но в эпоху STM32F4 пришлось использовать два процессора с межпроцессорным взаимодействием. И только с появлением STM32F7 все "утопталось" в один камень.

KnightIgor
Цитата(_pv @ Feb 22 2017, 19:09) *
Отдельные ноты неплохо бы различать, то есть корень 12й степени из 2 = 5%, от, пусть будет 200Гц. то есть 10 Гц разрешения по частоте хотя бы иметь надо

Тут я задумался и засомневался, подходит ли FFT для анализа именно гармонии по той самой причине, что музыкальный тональный ряд нелинеен и есть степенная функция, то есть тот самый корень 12-й степени из 2 на полутон, спасибо Баху за темперирование. Может замутить, скажем, 12*N отдельных цифровых фильтра, где N - количество перекрываемых октав? Думаю, трех - малой, первой и второй, - будет достаточно. Это получается от 131Hz "до" малой до 1047Hz "си" второй. Какова оценка необходимой производительности будет?

Спасибо заранее.

Цитата(khach @ Feb 23 2017, 12:04) *
Спектроанализатор, блютус, USB, I2S на одном камне в риалтайме? Не верю (с). Как пример - SDR радио на кортексах (любительское). Конечно без особой оптимализации, но в эпоху STM32F4 пришлось использовать два процессора с межпроцессорным взаимодействием. И только с появлением STM32F7 все "утопталось" в один камень.

Не все так страшно. Во-первых, BT - отдельный модуль с I2S выходом. CPU лишь настраивает его по UART. Во-вторых, спектроанализатор с I2S как вход CPU и USB с I2S как выходом - альтернативно-работающие объекты.
_pv
Цитата(KnightIgor @ Feb 23 2017, 16:21) *
Может замутить, скажем, 12*N отдельных цифровых фильтра, где N - количество перекрываемых октав? Думаю, трех - малой, первой и второй, - будет достаточно. Это получается от 131Hz "до" малой до 1047Hz "си" второй. Какова оценка необходимой производительности будет?

Герцелю надо лишь умножение и сложение на отсчёт, но в результате 5-10 тактов на отсчёт набежит, соответственно если надо посчитать спектр на отдельных 10-20 частотах, то Герцель будет быстрее, плюс сетка частот произвольная, но если больше 20, то ФФТ хоть и для всего спектра будет быстрее.
KnightIgor
Цитата(_pv @ Feb 23 2017, 13:13) *
Герцелю надо лишь умножение и сложение на отсчёт, но в результате 5-10 тактов на отсчёт набежит, соответственно если надо посчитать спектр на отдельных 10-20 частотах, то Герцель будет быстрее, плюс сетка частот произвольная, но если больше 20, то ФФТ хоть и для всего спектра будет быстрее.

Я так понимаю, что для случая 36 частот FFT будет быстрее, но вопрос остается, как "попасть" на нотный стан отсчетами FFT: шаг между частотами растет от 8Hz внизу малой октавы быстро до 55Hz в конце второй. Если взять шаг те же 8Hz, то получим (1047-131)/8=115 бинов частот, или 230 FFT точек. Так? Для анализа наличия нот надо будет просто выбрать подходящие близкие бины из результата?
_pv
Цитата(KnightIgor @ Feb 23 2017, 17:33) *
Я так понимаю, что для случая 36 частот FFT будет быстрее, но вопрос остается, как "попасть" на нотный стан отсчетами FFT: шаг между частотами растет от 8Hz внизу малой октавы быстро до 55Hz в конце второй.

ну будет немного быстрее, но там по быстродействию всё равно запас вроде есть.
я бы попробовал Гёрцеля для начала, если не хватит скорости, тогда уже можно будет думать как ускорить.

Цитата(KnightIgor @ Feb 23 2017, 17:33) *
Если взять шаг те же 8Hz, то получим (1047-131)/8=115 бинов частот, или 230 FFT точек. Так?

Нет, 230 точек на 44кГц дадут разрешение по частоте 190Гц.

Цитата(KnightIgor @ Feb 23 2017, 17:33) *
Для анализа наличия нот надо будет просто выбрать подходящие близкие бины из результата?

полученный спектр можно тоже интерполировать и брать значение на нужной частоте. хотя и интерполяция "ближайшим соседом" возможно тоже подойдёт.
khach
Цитата(KnightIgor @ Feb 23 2017, 14:33) *
но вопрос остается, как "попасть" на нотный стан отсчетами FFT

Ненадо попадать- интерполяция по нескольким соседним отсчетам около максимума даст и точную частоту, и точную амплитуду. http://dspguru.com/dsp/howtos/how-to-interpolate-fft-peak
KnightIgor
Цитата(_pv @ Feb 23 2017, 14:21) *
Нет, 230 точек на 44кГц дадут разрешение по частоте 190Гц.

Хочу поток 44kHz проредить в 10 раз, до 4410Hz, и уже это все проанализировать. Пока ковыряю Görzel.
jcxz
Цитата(khach @ Feb 23 2017, 12:04) *
Как пример - SDR радио на кортексах (любительское). Конечно без особой оптимализации, но в эпоху STM32F4 пришлось использовать два процессора с межпроцессорным взаимодействием. И только с появлением STM32F7 все "утопталось" в один камень.

Странно... А у меня оно на M3 (одном!) на 78МГц вполне себе нормально работает. На LPC1788. И загрузка CPU всего 60-70%...
При этом и WiFi успевает обслуживать и на LCD рисовать и много чего другого.
ЧЯДНТ? rolleyes.gif
KnightIgor
Цитата(jcxz @ Feb 23 2017, 19:43) *
Странно... А у меня оно на M3 (одном!) на 78МГц...

Заинтриговало, почему "кривая" частота 78MHz?
Allregia
Цитата(khach @ Feb 23 2017, 11:04) *
Спектроанализатор, блютус, USB, I2S на одном камне в риалтайме? Не верю (с). Как пример - SDR радио на кортексах (любительское). Конечно без особой оптимализации, но в эпоху STM32F4 пришлось использовать два процессора с межпроцессорным взаимодействием.


Ну может, только из-за спектроанализатора, потому что все остальное прекрасно работало на 100MHz LPC1768, который М3, причем на 96/24.

А на М4, с FPU/DSP, на 200Мгц F4, да на 44/16 - вполне и простенький спектроанализатор должен влезьть.
Во всяком случае, DDS генератор, где синус считается в риалтайме, работает на 168МГу F407 даже на 384/32.
khach
Проблемы были не со скоростью а с памятью- буфера под ФФТ, буфера под USB, буфера под аудиопоток, копия экрана для быстрой перерисовки. И если в F407 это уже можно было как то запихать, то в F103 не лезло. Тут еще вопрос- по задаче требуется полный риалтайм или нет, потому что полный риалтайм- это двойное буферирование аудиопотока. Хотя выше по теме я немного недопонял что I2S и БТ это то же самое в данном приложении, думал что это два разных потока, например вход и выход аудио.
С экраном тоже все сильно зависило от подключения- через SPI перерисовать графику сложновато было в риалтайме, только появление FSMC решило проблему. Вот только контроллер LCD на FSMC часто дрался с внешней статической памятью, которую можно было бы использовать под буфера, но не получалось. Только появление DRAM у F7 решило эту проблему, хотя обновление экрана из этой же памяти бывает вызывает странные глюки при работе периферии с DMA в буфера во внешней памяти. Тут еще болезнь развития накладывается- ту задачу, которую можно запихать сейчас в камень, зная его все особенности и глюки, не получалось запихать когда процессор только появился на рынке и его только осваивали.
Allregia
Выводить спектроанализатор - не кино смотреть (и не в игры играть), 10фпс более чем достаточно, и буфер экрана не обязательно в памяти держать.

Буфера USB и аудиопотока, как я гооворил, прекрасно вмещались в LPC1768, у которого памяти куда меньше чем у F4, внешняя память не использовалась.
Спектроанализатор тут-же не измерительный, а больше индикаторный, ФФТ на 8К точек дает около 5гц разщрешения по частоте на 44.1, а это в F4 тоже без внешней памяти влезет.
jcxz
Цитата(KnightIgor @ Feb 24 2017, 11:04) *
Заинтриговало, почему "кривая" частота 78MHz?

У меня там была SDRAM, а у этого МК максимальная частота работы внешней шины SDRAM ==80МГц. И эта частота получается из частоты ядра делённой на 1 или 2.
Так что если частота ядра >80МГц, то делитель получался ==2 и общая скорость работы резко падала (SDRAM интенсивно использовалась, а при отладке и код из неё выполнялся).
Конечно при дальнейшем увеличении частоты ядра до 120МГц, низкая скорость шины (до 60МГц) компенсировалась частотой ядра, но такая частота ядра уже была излишняя, так как и на 78 всё работает с большим запасом (до 30%).
А почему не 80, а 78 - уже точно не помню, по быстродействию это примерно то же самое.
Скорей всего хотел чтобы частоты периферии некратные получались (для удобства отладки), а периферии там много использовалось разной.
Или по скорости UART ошибка меньше получалась (там среди прочих использовались большие baudrate на UART-ах).
Точно уже не помню, да и без разницы - по быстродействию обработки это примерно то же самое.

Цитата(khach @ Feb 24 2017, 12:40) *
С экраном тоже все сильно зависило от подключения- через SPI перерисовать графику сложновато было в риалтайме, только появление FSMC решило проблему.

И LCD у меня в том проекте был подключен как раз по SPI.
А какая разница? Естественно не нужно рисовать напрямую в видеопамяти LCD (если таковая есть). Я рисовал в памяти МК, а готовую картинку - по SPI+DMA -> LCD.
KnightIgor
Цитата(KnightIgor @ Feb 22 2017, 18:49) *

Привет всем, again.

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

1. Пока остановился на "белых" клавишах малой, первой и второй октав. Всего 21 нота/частота. Частоты получаются:
131,147,165,175,196,220,247,262,294,330,349,392,440,494,523,587,659,698,784,880,
988

2. Применяю Гёрцеля. Описано, например, здесь, с кусками кода. Коэффициенты для каждой частоты посчитаны в Excel и занесены константами в код. Таким образом, синусы и косинусы не вызываются.

3. Предварительно исходный поток стерео с 44.1kHz 16-ти битных выборок я прореживаю до 2205Hz частоты стерео выборок. Для этого DMA просто складывает поток из I2S по кольцу в двойной буфер размером на 20 стереовыборок на каждый буфер, в результате прерывания от DMA (HT/TC) идут c требуемой частотой в 2205Hz. По этим прерываниям происходит усреднение всех 20-ти стереовыборок соответствующего буфера и запись результата в накопительный двойной буфер для Гёрцеля размером 222 выборки каждый. На такую операцию (прерывание) уходит про всё 10мкс. Перед записью идет масштабирование из 16-бит в диапазон [0..100]. Почему? Изначально я сделал так исходя из кода примера (там генегируются тестовые последовательности в диапазоне амплитуд [0..100]). Когда же вернулся к полному диапазону, "узнаваемость" нот ухудшилась.

4. Эти 222 выборки произошли от желания получить разрешение в 10Hz (2205/10=221) с округлением вверх до четного числа (с нечетным 221 получались странные результаты, не стал углубляться).

5. После примерно 100мс один из буферов Гёрцеля заполняется, и происходит запуск поиска указаных частот по этому буферу. Поиск ведется из синхронного цикла (система типа round robin условно многозадачная, кооперативная и синхронная, похожа на protothreads) и разделен на этапы с поиском одной частоты из 21 за этап. Общее время обработки буфера - примерно 35мс, то есть треть от времени заполнения буфера. Результат - массив значений амплитуд для всех 21 нот. Это на STM32F103 на 72MHz, загрузка побочная небольшая.

6. Для выделения доминирующего тона происходит усреднение амплитуд для каждой ноты из трех октав (мне нужно знать имя ноты, а не точно, какой октаве она принадлежит), то есть, усреднение трех гармоник каждой ноты, после чего находится максимум из 7-ми значений.

Чистые ноты (эмуляция пианино на смартфоне) распознаются достаточно хорошо.

Пока так. Займусь FFT для сравнения.

P.S. Нашел ошибочку, после чего масштабирование в [0..100] убрал, все распознается хорошо. Время поиска сократилось с 35мс до 20мс. Не любит процессор байтные диапазоны и операции.

P.P.S. Заметочка на полях: если I2S запрограммирован на вход (приём) как ведомый (slave), а I2S сигналы на входе CPU уже активны (внешний источник рубает вовсю), то разрешение I2S интерфейса следует засинхронизировать к сигналу LRCK (WS в терминах документации на STM32F), а именно разрешать I2S, пока LRCK = 1, то есть - ДО ниспадающего фронта на нем. Иначе происходит нарушение битовой синхронизации, и прием данных идет со сдвигом. Самый тупой метод синхронизации перед установкой бита I2SE - синхронное ожидание перепада LRCK с 0 в 1.
romas2010
Цитата(KnightIgor @ Feb 27 2017, 16:25) *
Привет всем, again.

1. Пока остановился на "белых" клавишах малой, первой и второй октав. Всего 21 нота/частота. Частоты получаются:
131,147,165,175,196,220,247,262,294,330,349,392,440,494,523,587,659,698,784,880,
988

..........
Пока так. Займусь FFT для сравнения.



Я бы рискнул все-таки через БПФ, но при этом
1) 4096 выборок, соответственно дискрета по частоте 44100/4096 ~=11 Гц ОЗУ надо 32к (4096*(float Re+float Im))
2) Табличный синус, а косинус-это синус,сдвинутый на pi/2, то есть на cos[x]=sin[x+1024]
3) бабочки БПФ написать на ассемблере с командами сопроцессора
4) DMA I2S не использовать,а вычитывать в каждом прерывании I2S выборку и сразу же кинуть в буфер отсчётов БПФ с бит-реверсией адреса(есть у М4 __rbit() intrinsic)+ экономия ОЗУ

Хотя возникает вопрос- а какже на контроктаве и субконтроктаве, там дельта частот очень маленькая?




Obam
Нету у ТС пока "сопра"...
KnightIgor
Цитата(romas2010 @ Feb 28 2017, 19:43) *
Я бы рискнул все-таки через БПФ, но при этом
1) 4096 выборок, соответственно дискрета по частоте 44100/4096 ~=11 Гц ОЗУ надо 32к (4096*(float Re+float Im))
2) Табличный синус, а косинус-это синус,сдвинутый на pi/2, то есть на cos[x]=sin[x+1024]
3) бабочки БПФ написать на ассемблере с командами сопроцессора
4) DMA I2S не использовать,а вычитывать в каждом прерывании I2S выборку и сразу же кинуть в буфер отсчётов БПФ с бит-реверсией адреса(есть у М4 __rbit() intrinsic)+ экономия ОЗУ

Хотя возникает вопрос- а какже на контроктаве и субконтроктаве, там дельта частот очень маленькая?

1). Не слабо так, 32К. На моем F103 - всего 48K. Ну, должно хватить, т.к. другие задачи не прожорливые.
2). Это реально.
3). Нету сопроцессора. Разбаловались тут все на F4xx....
4). I2S прерывания идут в 2*44.1K, т.к. сигнал - стерео. Это каждые 12мкс. Проц зашьется. Говорить об экономии ОЗУ здесь, выделив сразу 32К в пункте 1)., есть несколько непоследовательно wink.gif .
5). Да, уже в малой октаве между ми и фа - 9.8Hz, а глубже - меньше.

Что имеется ввиду под бит-реверсией адреса?
Aleksandr Baranov
Цитата(KnightIgor @ Feb 28 2017, 14:50) *
Что имеется ввиду под бит-реверсией адреса?

Это для FFT:

http://www.dspguide.com/ch12/2.htm
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.