Воспроизведение WAV без SD\MMC-карты

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2168
Зарегистрирован: Ср май 01, 2013 13:53:56
Откуда: с пальмы в Рио-Инженейро

Сообщение fedyasolder »

В качестве подопытной крысы использован МК ATmega328P.
В нём коротит Avcc на землю (пережарил или пересолил...) и для применения в измерениях аналоговых величин он не пригоден.
Плюсом будет 32К памяти. В которой можно разместить короткие звуки. Для примера использован файл трям.wav размером ~38кб с сэмплированием 16кГц и разрядностью 16 бит. Для применения достаточно понизить битность до 8 (без ресемплирования на более низкую частоту). При этом размер файла уменьшится вдвое, такой размер (~20кБ) уже можно разместить во флеш МК. Использовать для подготовки файла будем бесплатную программу Audacity. Делается это через меню Файл -> экспорт аудио -> тип файла выбрать прочие несжатые файлы, в этом же окне нажать "параметры" и выбрать RAW (header-less) и unsigned 8bit PCM и сохраняем в файл sound.raw (так он прописан в тексте программы). В открывшемся окне я на всякий случай очистил поля метаданных. Нужны именно данные самого потока без посторонней информации. Получился файл в 19 500 байт. Это число выборок нужно указать в тексте программы:
в цикле по выборкам For I = 1 To 19500
и в описании прикрепляемого двоичного файла $inc Snd , 19500 , "sound.raw"
Компилируем, загружаем в МК и при подаче питания будет воспроизводиться звук однократно. Для минимума кода сделано именно так. Чтобы воспроизвести снова нужно передернуть питание. Звук конечно лучше вывести на простейший УНЧ, но для простоты этот вопрос не рассматриваю.

Фьюзы на внутренний генератор 8Мгц без деления частоты.

Изображение

Возможно применение внешней SPI-флеш для воспроизведения файлов большей длины если разберусь с этим вопросом.
Вложения
трям.wav.rar
(30.82 КБ) 247 скачиваний
sound.raw.rar
(11.49 КБ) 248 скачиваний
bas + bin + hex.rar
(35.57 КБ) 271 скачивание
схема.GIF
(6.43 КБ) 1892 скачивания
Последний раз редактировалось fedyasolder Пт окт 14, 2016 17:05:37, всего редактировалось 3 раза.
электропримат паяю даже лёжа...
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Ценой некоторого ухудшения звука можно применить кодер ADPCM. Пожмёт звуки ещё в 2 раза. Для распаковки не требует высокой производительности.
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ценой ухудшения звука можно и частоту дискретизации снизить, и никаких кодеров не нужно :)
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2168
Зарегистрирован: Ср май 01, 2013 13:53:56
Откуда: с пальмы в Рио-Инженейро

Сообщение fedyasolder »

Оба правы. Возможен случай когда декодер будет занимать больше самих данных. Поскольку нет исходника декодера на васике, то продолжу крутить WAVки.
электропримат паяю даже лёжа...
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

fedyasolder писал(а):разрядностью 16 бит. Для применения достаточно понизить битность до 8
Если понижать битность при помощи G.711, то можно будет это сделать без существенного ухудшения качества. А алгоритм начала 70-х прошлого века, я думаю, на МК реализовать не сложно.
Если уж залазить в компрессию, то и использовать надо тоже телефонные кодеки. Например, G.729 Annex A. Хоть и качество низкое, зато 8 килобит/сек. То есть на секунду - килобайт. Исходников в сети полно.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

ptr128 писал(а):Если понижать битность при помощи G.711, то можно будет это сделать без существенного ухудшения качества.
Это без сомнения хороший способ, но вот сомневаюсь, что разница в качестве между 8-ю и 16-ю битами будет сильно заметна при воспроизведении через ШИМ. Разве только для звуков ну с очень большим динамическим диапазоном.

А вот какой-нибудь простой алгоритм сжатия данных (можно даже с потерями) для 8-битного звука было бы действительно интересно узнать. Звук отличается сильной коррелированностью между соседними отсчётами. Можно пытаться сжимать храня не последовательность кодов, а разность между соседними отсчётами. Гиблое дело: такое прокатит, если сигнал является низкочастотным с высокой частотой дискретизации. Звуковые сигналы отличаются периодичностью, которую так легко с помощью разностей не закодировать. Здесь надо пытаться выделять периодические повторяющиеся части, сохраняя что-то усреднённое и отличия между сохранённым куском и воспроизводимыми периодами.

Хотя, в большинстве случаев сжатие с потерями подразумевает анализ психоакустических эффектов, так что вряд ли такой алгоритм будет простым.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

B@R5uk писал(а):Гиблое дело:
Музыкальный фрагмент, закодированный 4-разрядной дельтой(снизу, adpcm A-law) и оригинальный сигнал(сверху):
Изображение
11025Гц
Процедура целочисленного декодера для МК в 15 строчек + маленькая табличка.
B@R5uk писал(а):Здесь надо пытаться выделять периодические повторяющиеся части
Технология вокодеров уже не для атмег, поскольку требует быстрые манипуляции с многоразрядными числами. Тут крайне желательно хотя бы 16-разрядное ядро с поддержкой операций 32x32.
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

uk8amk писал(а):Технология вокодеров уже не для атмег
G.729 Annex A специально адаптирован к МК из базового G.729 для использования только целочисленной арифметики. Смотрим алгоритм и видим, что переменные длиней 16-ти бит ему не требуются. В чем проблемы то?
А вместо 64 килобит получить 8, я думаю, вполне оправдывает затраты на декодер. Енкодер в МК при данном применении не нужен. Только на ПК.

Добавлено after 5 minutes 7 seconds:
B@R5uk писал(а):А вот какой-нибудь простой алгоритм сжатия данных
Я же писал выше: G.729 Annex A, 8 килобит, 1 килобайт на секунду. Обеспечивает частотный диапазон 300 - 3400 Гц
Если брать Annex D - он хуже качеством, но требует всего 6.4 килобита. То есть на секунду 800 байт.
Эталонные исходники и описания есть на www.itu.int, так как это стандартный вокодер для телефонии.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2168
Зарегистрирован: Ср май 01, 2013 13:53:56
Откуда: с пальмы в Рио-Инженейро

Сообщение fedyasolder »

uk8amk писал(а):Процедура целочисленного декодера для МК в 15 строчек + маленькая табличка.
Дык переведите кто умеет на васик. Я клинопись не осилю.
===
Или сделайте комментарий на каждый оператор.
электропримат паяю даже лёжа...
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

ptr128 писал(а):Я же писал выше: G.729 Annex A, 8 килобит, 1 килобайт на секунду.
Так свой велосипед изобретать гораздо веселее, чем кататься на готовом.
uk8amk писал(а):Музыкальный фрагмент, закодированный 4-разрядной дельтой(снизу, adpcm A-law) и оригинальный сигнал(сверху)
Чрезвычайно паршивый для сжатия сигнал. Голос, который использует топикстартер будет жаться куда лучше. Вот, посмотрите какие замечательные периодичности:
СпойлерИзображение
СпойлерИзображение
СпойлерИзображение
Сдаётся мне алгоритм декомпрессии должен быть таким.
1) На каждом шаге алгоритм восстанавливает пакет семплов, количество которых является периодом сигнала (штук 20-60).
2) Для восстановления текущего пакета семплов алгоритм может:
2а) прочитать пакет как есть из начала фрейма, либо
2б) умножить предыдущий пакет на величину близкую к 1 и добавить к результату пакет небольших дельта (вот она сила приращений в купе с силой периодичности!!!)
3) Все величины хранятся в виде аналогичном кодированию G.711, но
4) Экспонента для всего пакета приращений и для инициализирующего пакета в начале фрейма одна!!! (опять же, сила периодичности)

Как-то так. :tea: Алгоритм кодирования только писать сложно будет.
Вложения
Signal_3.gif
(9.93 КБ) 837 скачиваний
Signal_2.gif
(9.17 КБ) 1096 скачиваний
Signal_1.gif
(11.55 КБ) 1125 скачиваний
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

ptr128 писал(а): В чем проблемы то?
В том варианте что представлен в стандарте атмеги скорее не хватит даже на декодер версии А.
Аргументы действительно много где 16-разрядные. Но вычисления в циклах имеют поболее разрядов. Там MUL32, MAC32 и т.д.
Например кусочек BASIC_OP.c
L_produit = (Word32)var1 * (Word32)var2;
L_produit = (L_produit & (Word32) 0xffff8000L) >> 15;

Быть может получится если ооочень сильно оптимизировать такие операции под конкретное ядро avr.

Вот попался футпринт кодека под TMS320С64:
http://www.dspwizard.com/g729aC64p.htm
Декодер съедает около мегагерца производительности. С атмегой эту числомолотилку сравнивать даже нет смысла.

Но в любом случае кодек хорош и если будет время надо попробовать на ARM
fedyasolder писал(а):Или сделайте комментарий на каждый оператор.
Есть очень детальное описание в
Microsoft Multimedia Standarts Update
April 15, 1994
Revision: 3.0

Также стоит посмотреть
AN643
Adaptive Differential Pulse Code Modulation using PICmicro™ Microcontrollers
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

В общем, я тут подумал, поднапрягся и вот что придумал и сделал.

Поскольку анализ периодичности сигнала — штука довольно нетривиальная, то я подумал, "а как бы попроще?" И решил сосредоточится на пункте 4) алгоритма выше. Идея проста: сохранять экспоненту из алгоритма G.711 не для каждого семпла в отдельности, а одну для целой пачки семплов. Алгоритм G.711 фактически заменяет 16-битное число с фиксированной точкой на число с плавающей точкой и меньшим числом бит в мантиссе. За счёт этого достигается заметное сжатие (в два раза), причём как громкие, так и тихие сигналы кодируются одинаково хорошо. Почему бы не пойти дальше?

И ведь логично: какой смысл хранить значения близкие к нулю с повышенной точностью (как это делает представление с плавающей запятой), когда совсем рядом, на расстоянии 2-3 семплов, находится весьма большое значение, которое имеет, соответственно большую погрешность. Поэтому моё решение было такое: порезать весь звуковой файл на кусочки не шибко большие и не шибко маленькие, для каждой получившейся пачки семплов подобрать свою экспоненту, вернее уже не экспоненту, а полноценный множитель — число с плавающей точкой, поделить соответственно пачку на это число и закодировать то что получилось малым количеством бит, чтобы получить сжатие. Подбор множителя — задача оптимизации суммы квадратов разностей между кодируемыми данными и декодированным сигналом. Фактически минимизация суммарного шума (баланс между шумом клиппирования и шумом квантования).

Сказано — сделано. Поэкспериментировав, я обнаружил, что даже 3 (трёх!!!) бит на семпл включая знак достаточно чтобы вполне сносно кодировать голос. Шум квантования слышен, но не режет ухо. Если использовать все шесть бит на семпл, то качество звука вполне приемлемое.

В архиве результаты эксперимента. Цифры 19, 7, 3 означают 19 семплов на фрейм 7 бит на множитель фрейма 3 бита (включая знак) на семпл во фрейме. Получается 19*3+7=64 бита на фрейм или 64/19=3,37 бита на семпл всего. Аналогично цифры 18, 6, 5 — 18 семплов на фрейм, 5 бит на множитель и 6 бит на семпл. 18*5+6=96 бит на фрейм и 96/18=5,33 бита на семпл всего. Файл, оканчивающийся на "_decoded", содержит результат декодирования сжатых данных, а на "_qunoise" — разность между исходным и декодированным звуком, то есть шум квантования. Музыка в отличие от голоса звучит гораздо хуже и весит больше, её лучше через что-нибудь более прогрессивное сжимать.

Осталось декодер для МК написать. Жаль в восьмую мегу не лезет никак. Только если 2 бита на семпл поставить (1 бит — знак и 1 бит — данные). :facepalm:
Вложения
Bach_Fuga_qunoise.rar
(667.04 КБ) 198 скачиваний
Bach_Fuga_decoded.rar
(517.47 КБ) 192 скачивания
Trjam.rar
(96.24 КБ) 176 скачиваний
abc
Друг Кота
Аватара пользователя
Сообщения: 3687
Зарегистрирован: Чт мар 20, 2008 01:06:40
Откуда: Севастополь

Сообщение abc »

Осталось декодер для МК написать. Жаль в восьмую мегу не лезет никак
А если все-таки не тратить время на упихивание невпихуемого и для хранения звука использовать внешнюю память, то чип SPI-FLASH объемом 8 МБайт стоит 30 рублей.
>(*.*)<
Котище огромно, ушасто, пушисто, глазасто, зубасто, колючелапо и мявай. (c)
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

uk8amk писал(а):Но в любом случае кодек хорош и если будет время надо попробовать на ARM
если уж арм, то STM32F103 может программно декодировать MP3 и выводить звук на внутренний ЦАП.
Исходный файл 16 000 Гц 16 бит трям.wav размером 39192 байт после сжатия в 16 000 Гц 16 бит MP3 стал размером 3816 байт, т.е. сжатие в 10 раз, потери качества нет. На STM32F407 с 1Мб внутреннего флэша страшно подумать сколько таких трямов можно разместить :o .
з.ы. делал проектик на STM32F051 с флэш 32кб, там применил ADPCM для записи звука (голосовое сообщение) с микрофона->усилитель->ацп во внутреннюю флэш микроконтроллера и последующего воспроизведения через цап. 16-ти битные значения АЦП (точнее 12 бит) упаковывались в 4 бита ADPCM, при воспроизведении 4 бит распаковывались в 12 бит. Заказчик качеством остался весьма доволен. Перед этим пробовал кодировать/декодировать 16 битную музычку этим же исходником на ПК - после декодирования на слух разницы не услышал. ADPCM потянет даже старичок PIC16, у Микрочипа аппнота по ADPCM была и у Атмела тоже.
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

abc писал(а):чип SPI-FLASH объемом 8 МБайт стоит 30 рублей.
А можно пару примеров моделей таких чипов?
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

ptr128, спасибо, возьму на заметку. Хотя те же SD-карты на мой взгляд куда более универсальнее.

Между тем решил вспомнить как да чё у ATmega8, понял что даже 10-битный ШИМ на ней крайне уныл, про 16-битный вообще молчу (240 Гц). :facepalm: Помнится я как-то удачно городил сигма-дельта ЦАП на модуле USART, он у меня чуть ли не 11 бит был. Но для звука всё равно маловато, медленновато. Плюс ресурсы жрёт огого. Грустно это всё.
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

B@R5uk писал(а):ptr128, спасибо, возьму на заметку. Хотя те же SD-карты на мой взгляд куда более универсальнее.
Пожалуйста )
Кесарю кесарево. SPI-Flash IC можно поставить на плату в любое место и шить ее прямо там, по мере надобности. А SD будет в разы дороже, занимать намного больше места и потребует предусмотренной в корпусе возможности ее вынимания.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

B@R5uk писал(а):у ATmega8, понял что даже 10-битный ШИМ на ней крайне уныл, про 16-битный вообще молчу (240 Гц)
Чен из двух выходов 8 бит шима сделал 16-битный шим:
Изображение
http://elm-chan.org/works/sd8p/report.html
для получения частоты шима повыше лучше взять тини с PLL
з.ы. W25Q80: 8 Мбит/1 Мбайт
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

B@R5uk писал(а):ATmega8, понял что даже 10-битный ШИМ на ней крайне уныл, про 16-битный вообще молчу (240 Гц).
"Вы просто не умеете их готовить" (с)
Используейте Fast PWM и сможете до 4МГц получить.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Ответить

Вернуться в «AVR»