Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Аудио-плеер. PWM-DAC + DMA

Вт окт 02, 2018 00:44:18

Здравствуйте, уважаемые радиокоты.
Осваиваю тут потихоньку МК stm32. Вот сейчас делаю wav-плеер (в целях изучения МК от ST) на stm32f103c8.
Плеер работает! Читает в буфер с SD-карты через SPI, используя либу FatFs. Таймер4 работает в качестве ЦАПа. Прерывания 3-го таймера срабатывают с частотой дискретизации wav-файла. В обработчике запихиваю байт в регистр сравнения таймера4.
DMA не используется.
В каких-то проектах этого было бы достаточно, но ведь было бы красивее сделать чтоб DMA запихивал порцию байт аудио-файла из буфера в регистр сравнения. Тем самым ещё больше уменьшить нагрузку на ЦПУ!
Ну вот и вопрос: как же сделать так, чтоб буфер с аудио-данными, длиною, например 512 байт, был передан таймеру4 с заданной частотой (частотой дискретизации аудио) и на протяжении всей передачи этого буфера 512 байт, на это не отвлекалось ЦПУ?

Надеюсь вопрос и задумка ясна.

UPD:
Всё-же дополнительно объясню, чего хочу добиться.
В текущей реализации проекта, каждый байт аудио-файла пихаю в "ЦАП" (точнее регистр сравнения таймера4) силами ЦПУ, в прерывании.
Идея, дать команду DMA переслать 512 байт (или больше) в "ЦАП" и занять ЦПУ чем-то другим, выглядит заманчиво!
Но вот тут-то и появляется проблема: как заставить DMA слать байты по заданной частоте?

В случае связки DMA с каким-нибудь периферийным модулем, например USART, всё понятно: по окончанию передачи очередного байта DMA получает об этом уведомление и если ещё есть данные для передачи "кидает" в USART следующий байт.
А как быть с регистром сравнения какого-нибудь таймера или с аппаратным ЦАП-ом какого-нибудь другого МК данной конторы.

Re: Аудио-плеер. PWM-DAC + DMA

Вт окт 02, 2018 06:58:03

Сперва для 8бит моно.Таймер конфигурируем как PWM.
Частота PWM -частота дискретизации звука, лежит в заголовке wav.
Реквесты канала DMA по TIMx_UP. Источник буфер звука, приемник CCP таймера, счетчик - размер буфера. Режим не циклический.
CCP тамера буферизированный

8бит стерео, здесь придется задействовать DMA burst.

В любом случае отслеживаем половину буфера и завершение транзакции ,или поллингом флагов DMA либо в прерывании.
Так называемый пинг-понг - пока воспроизводится одна половина буфера - заполняем другую...

Re: Аудио-плеер. PWM-DAC + DMA

Вт окт 02, 2018 14:40:24

То-есть используется только один таймер: и для вывода во внешний мир ШИМ-сигнала, и для "пинания" DMA?
Тогда получается частота несущей == частоте модуляции (дискретизации звука). Так?
Вроде как, чем больше частота ШИМ-сигнала тем проще его преобразовать (сгладить) в аналоговый.
Поэтому я и хотел сделать частоту несущей выше частоты дискретизации звука.

По Вашему способу решения вопроса:
Предполагаю что, аудио-файлы с частотой дискретизации звука более 20kHz будут воспроизводиться нормально, возможно даже без фильтров!
А как быть с частотами дискретизации в диапазоне 20 - 20 000 Hz? Например, частота дискретизации 8kHz считается достаточной для передачи голоса.
Не будут ли слышны изъяны в таком случае, когда частота несущей == частоте модуляции?

Re: Аудио-плеер. PWM-DAC + DMA

Вт окт 02, 2018 17:31:47

Делал плеер на 22КГц все звучало достойно.
Завтра посмотрю, вроде и до 44 поднимал...

Re: Аудио-плеер. PWM-DAC + DMA

Ср окт 03, 2018 15:27:35

В общем всё получилось! Воспроизведение звука сделал с использованием одного таймера, который работает в режиме ШИМ и "пинает" DMA на частоте дискретизации звука.
Аудио-файлы с частотой дискретизации 22050Hz и 44100Hz воспроизводятся нормально — звучание достойное! Пробовал файлы 8000Hz, слышно несущую 8 килоГерц (свист). Надо ставить фильтр — это минус такой реализации, так сказать дань за использование только одного таймера.
При любой частоте дискретизации проскакивают сильные помехи, которые возникают при чтении с SD-карты! Но это к программированию уже не относится! Как именно это решить я пока не знаю.
Позже смогу выложить исходники, тем более если это будет интересно читателям.
Реквесты канала DMA по TIMx_UP

dosikus, спасибо за эту фразу и за идею использовать только один таймер! Пытался тебя плюсануть, ничего не получается, flash зависает, может с другого браузера получится.

Re: Аудио-плеер. PWM-DAC + DMA

Ср окт 03, 2018 18:40:41

На счет помех -у меня их нет. Карточка подключена через отдельный стаб , подтяжки везде кроме CLK.
Время выкрою попробую на 8КГц, но помнится свиста не было.
Да у меня F0,a так же делал вариант на F1.
Завтра не забуду скину.
И о дма_бурст http://mcu.goodboard.ru/viewtopic.php?id=31

Re: Аудио-плеер. PWM-DAC + DMA

Ср окт 03, 2018 22:45:11

Аудио-файлы с частотой дискретизации 22050Hz и 44100Hz воспроизводятся нормально — звучание достойное! Пробовал файлы 8000Hz, слышно несущую 8 килоГерц (свист).

Какой смысл привязываться к частоте дискретизации источника? И ещё и перестраивать частоту под каждый источник.
Делайте вывод на любой частоте какая нравится. А входной сигнал нетрудно передискретизировать на нужную частоту.
Мой проект (интернет-радио) воспроизводит с любых источников (MP3- или AAC-) независимо от их частоты. Частота ЦАП стоит 98кГц - никаких свистов не слышно. Использую встроенный ЦАП, а не ШИМ. Фильтров никаких нет (правда они есть в самих декодерах).

Re: Аудио-плеер. PWM-DAC + DMA

Чт окт 04, 2018 06:49:30

имхо, DMA надо пинать с частотой дискретизации файла/потока, а таймер ШИМом должен молотить на фиксированной частоте, как можно более высокой. и свиста не будет, и качество будет предельно достижимое технически

Re: Аудио-плеер. PWM-DAC + DMA

Чт окт 04, 2018 09:47:33

имхо, DMA надо пинать с частотой дискретизации файла/потока, а таймер ШИМом должен молотить на фиксированной частоте, как можно более высокой. и свиста не будет, и качество будет предельно достижимое технически

Бред. Частота изменения выходного сигнала останется прежней. Как было 8 кГц, так и останется. Куда тогда денется свист?
DMA должна "пинать" периферия, которую он обслуживает. В данном случае - таймер. С частотой работы этой самой периферии. И соответственно сэмплы в буфере отправляемом DMA, должны идти с той же частотой. Ресэмплинг этого буфера на данную частоту делается CPU (предварительно). Можно простой кусочно-линейной интерполяцией (как у меня), можно другим методом (более качественно). Таймер должен работать в shadow-режиме.
Вот тогда всё будет ок.

Re: Аудио-плеер. PWM-DAC + DMA

Сб окт 06, 2018 03:32:57

marengo писал(а):При любой частоте дискретизации проскакивают сильные помехи, которые возникают при чтении с SD-карты!
Подозреваю, что "помехи" проистекают от задержки на чтение очередной порции данных с SD-шки. В таких случаях помогает двойная буферизация.

Re: Аудио-плеер. PWM-DAC + DMA

Сб окт 06, 2018 23:22:24

DMA надо пинать с частотой дискретизации файла/потока, а таймер ШИМом должен молотить на фиксированной частоте, как можно более высокой

Вот именно так я и хотел сделать, используя general purpose timer! Но покопавшись в reference manual, посмотрев регистры этих таймеров, я как-то не нашел ничего, с помощью чего можно было бы выполнить условие "Частота несущей выше частоты модуляции звуком этой несущей". Вот и решил спросить у знающих. И как оказалось не зря! dosikus указал мне на регистр "RCR" — Reload Counter Register, за что ему отдельное спасибо! Данный регистр позволяет "пинать" DMA (или выдавать запрос на прерывание) не при каждом переполнении счётного регистра таймера, а при каждом N переполнений! Таким образом частоту ШИМ можно сделать выше частоты дискретизации аудио.
Правда есть и один минус: регистра RCR нет в general purpose timers, он есть только в advanced таймерах (TIM1, TIM8), коих в МК значительно меньше чем general purpose таймеров (1-2 шт.). Прошу учесть что я читал reference manual и прочие материалы только те, которые относятся к stm32f103c8.

В результате вот что пишу в регистры предделителя (PSC), автоматической перезагрузки (ARR) и счётчика повторений (RCR):

Есть, правда, и один минус (как же без него). Частота воспроизведения (чит. запросы DMA) могут не соответствовать частоте дискретизации источника. Следствие: замедленное или ускоренное воспроизведение аудио-потока! Как с этим бороться, кроме как применять предварительный ресемплинг буфера (как писал jcxz), я не знаю! Нет, конечно можно завести рядом с МК какой-нибудь внешний генератор с требуемой частотой, но опять же минус — ещё один компонент на плате.
Но меня такой результат пока что устраивает!

Обращение к jcxz:


Обращение к afz:


Фух

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 03:06:26

marengo писал(а):вообще ничего не понял.
Я имел в виду вот это:
dosikus писал(а):В любом случае отслеживаем половину буфера и завершение транзакции ,или поллингом флагов DMA либо в прерывании.
Так называемый пинг-понг - пока воспроизводится одна половина буфера - заполняем другую...
Две половины одного буфера, или два отдельных буфера - не суть важно, по-любому, это двойная буферизация.

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 07:33:15

afz
Проблем с логикой работы программы у меня не было! Были вопросы по настройке работы периферии (и не надо тыкать меня носом в "CubeMX").
Но всё равно спасибо!

Короче, выкладываю исходники.
Сначала тот вариант, который был до того как я создал эту тему. Шпора "PWM_wav0.3"


И вариант на текущий момент (PWM_wav0.5)

Код написан в CoIDE. И не забываем что это только "шпоры"! Но исходники рабочие, поставленную задачу выполняют!

P.S. Так, если кто копирует исходники, те ставят мне "плюс"! 8) dosikus-а тоже можно плюсовать, без него я ещё долго не мог бы прикрутить DMA к своему проекту!

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 07:53:21

Две половины одного буфера, или два отдельных буфера - не суть важно, по-любому, это двойная буферизация.


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

Добавлено after 4 minutes 45 seconds:
marengo,
Код:
DMA1->IFCR |= DMA_ISR_TCIF5;        //очистить флаг окончания обмена
   DMA1->IFCR |= DMA_ISR_HTIF5;        //очистить флаг передачи половины буфера


DMA1->IFCR = DMA_ISR_TCIF5;
DMA1->IFCR = DMA_ISR_HTIF5;

IFCR write only

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 09:37:25

IFCR write only
Можно даже не побояться и
Код:
DMA1->IFCR = DMA_IFCR_TCIF5 | DMA_IFCR_HTIF5;

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 09:50:06

Ну это и ежу понятно, но вот на смарте на этом движке форума редактировать -каторга. :)))

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 15:38:46

Таким образом частоту ШИМ можно сделать выше частоты дискретизации аудио.

А смысл? Зачем?? :dont_know:

Добавлено after 3 minutes 20 seconds:
"Передискретизировать на нужную частоту" — означает выполнять дополнительную работу, то-есть использовать ресурсы ЦПУ!

А без этого не избавитесь от свиста на 8 кГц на который сами жалуетесь.
Ресурсы они на то и есть чтобы их использовать. А зачем они ещё? солить впрок? :)))

Добавлено after 12 minutes 44 seconds:
Две половины одного буфера, или два отдельных буфера - не суть важно, по-любому, это двойная буферизация.

Совершенно неверно!
"Два буфера" - это фактически даже хуже чем вообще без DMA, по прерываниям. Так как требует времени реакции от ISR не превышающего 1/Ts (где Ts - период сэмплирования). Такое же требование и для работы без DMA, по прерываниям. Но в случае с "двумя буферами" всё гораздо хуже, так как операций внутри ISR придётся сделать гораздо больше (перепрограммирование DMA). И в этом случае теряются почти все плюсы DMA.
А вот "две половинки одного буфера" - совсем другое дело, так как в этом случае от ISR требуется время реакции <= размер_половины_буфера/Ts.

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 15:58:39

А смысл? Зачем?? :dont_know:


Что, действительно не въезжаешь? :)))

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 16:01:07

Что, действительно не въезжаешь? :)))

Не въезжаю.
Видимо - чтобы посильнее загрузить шины МК? :?

Re: Аудио-плеер. PWM-DAC + DMA

Вс окт 07, 2018 16:03:52

"Нагрузка на шины" точно такая же что и в варианте с двумя таймерами. Здесь же один.
Причем можно еще прикрутить DMA burst -получится стерео и дополнить каждый канал инверсным -повысим громкость .
Ты не смотри со своей колокольни, здесь же простой плеер вавок.
Последний раз редактировалось dosikus Вс окт 07, 2018 16:29:15, всего редактировалось 1 раз.
Ответить