Аудио-модуль для мультирума на SAM4S-EK

Добрый день!

Хочу предоставить вашему вниманию небольшое устройство, предназначенное для воспроизведения аудио-записей для «Умного дома».
Сразу хочу внести некую ясность, чтобы у читателей не возникало вопросов типа «А почему для такого простого устройства использовалось такое мощное железо?» и «В интернете уже описано очень много устройств воспроизведения музыкальных файлов, зачем изобретать свой велосипед?»:

У нас уже реализован мультирум для «Умного дома», который имеет 4 стерео входа, 1 моно вход (как раз для аудио-модуля) и 20 выходов на колонки (количество выходов можно наращивать до 32).
После установки у друзей в коттедже, мультирум был успешно протестирован на потолочных колонках и его работа понравилась хозяевам дома.
Было решено продолжить его усовершенствование, и очередным этапом мы запланировали как раз реализовать выдачу голосовых реакций со стороны «Умного дома» на полученные команды, включать проигрывание мелодии в качестве будильника, оповещать о срабатывании датчиков и т.п.

Мы хотели сделать аудио-модуль как можно быстрее, без проектирования плат и пайки, а тут нам очень вовремя подвалило счастье в виде подаренной отладочной платы SAM4S-EK. Поэтому прототип аудио-модуля мы решили сделать на данной отладке, заодно и изучить новый процессор.




Сначала мы выработали требования к устройству:
1. Управление аудио-модулем посредством USART (в мультируме есть специальный разъем для подключения аудио-модуля).
2. Вывод звука в моно-режиме (в мультируме для «голоса» Умного дома присутствует моно-вход).
3. Хранение аудио-файлов на SD-карте.

Для разработки использовалась Atmel Studio 7.0.
За основу был взять проект из примеров от Atmel, содержащий модуль FatFS, который мы используем для чтения WAV-файла с SD-карты:



Затем в ASF Wizard «набрасываем» используемую периферию:



Исходники находятся в Github

Принцип работы:
Есть 2 буфера: в момент старта воспроизведения оба буфера заполняются данными из музыкального файла.
Затем из одного буфера процессор по прерываниям по таймеру начинает «гнать» данные в ЦАП, по мере «опустошения» буфера переключается на второй, а первый в main'е опять заполняется данными.
Примерно, когда проиграно 10% второго буфера, первый уже снова полон новыми данными, и когда второй буфер «опустошился», они вновь меняются местами.
Здесь под фразой «буфер опустошился» имеется в виду, что данные из него считаны. Физически они перетираются только в момент наполнения буфера.

Получившийся девайс умеет читать музыкальные файлы только формата WAV, моно, 44100 Гц, 16 бит.
Но в процессоре ЦАП 12 битный, поэтому в коде сдвигаем на 4 бита:
dac_val = dac_val>>4;

Музыкальные файлы должны находиться в корне флеш-карты.

Для начала воспроизведения необходимо послать по UART команду play=имя_файла.
В конце данной команды должен быть символ 0x0D.
Обратно в UART выведется отладочная информация.
Чтобы остановить воспроизведение, надо отправить команду stop.

В процессе тестирования мы слышали щелчки в наушниках.
Долго искали ошибку в коде, но спустя несколько часов безуспешных поисков была заменена строчка
dacc_write_conversion_data(DACC_BASE, dac_val);

на
dacc_write_conversion_data(DACC_BASE, 0);

и вот тогда поняли, что в данной отладочной плате безобразно разведена аналоговая часть.
При чтении данных с карточки можно услышать этот процесс из динамиков :)
Щелчки совсем незначительные, но если знать, как они звучат, то услышать их не составляет труда.
При проектировании платы под своё устройство (если планируете реализовать подобное не на макетке) необходимо учитывать этот момент.

Комментарии (5)

RSS свернуть / развернуть
«А почему для такого простого устройства использовалось такое мощное железо?»
Этот вопрос так и остается не до конца ясен. Судя по «У нас уже реализован мультирум для «Умного дома», это не одноразовая разработка, а с прицелом на сколько-то серийное прозводство, серийная сборка аудио-модулей из отладочных плат выглядит сомнительтно и все приведенные в пользу мощного железа аргументы становятся неактуальны.

И если уж взяли оверкильный МК, почему бы не реализовать дополнительные плюшки? Скажем, поддержку сжатых файлов, например mp3.
0
  • avatar
  • Vga
  • 11 мая 2016, 02:54
Атмеловские фреймворки производят тяжелое впечатление. Вроде бы написано все нормально, а не покидает ощущение что через жопу сделано.
0
Есть 2 буфера: в момент старта воспроизведения оба буфера заполняются данными из музыкального файла.
Затем из одного буфера процессор по прерываниям по таймеру начинает «гнать» данные в ЦАП, по мере «опустошения» буфера переключается на второй, а первый в main'е опять заполняется данными.
Примерно, когда проиграно 10% второго буфера, первый уже снова полон новыми данными, и когда второй буфер «опустошился», они вновь меняются местами.
А зачем 2 буфера, если тоже самое можно делать с одним буфером? Процессор начинает гнать данные в ЦАП, и одновременно заполняет буфер новыми значениями. Я вижу это так: Взяли число из buf[0] и передали его в ЦАП, потом взяли число из buf[1] и передали его в ЦАП, потом записали в buf[1] новое значение, потом взяли число из buf[2] и передали его в ЦАП, потом записали в buf[2] новое значение и т.д.
0
Схема с двумя буферами может работать практически полностью аппаратно через DMA и минимально грузить сам проц.
0
Можно, в принципе, по half transfer (если у атмела такой есть) перезаполнять. Хотя это по сути та же двойная буферизация.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.