Помогите пожалуйста разобраться, инет пестрит огромным количеством схем WAV плееров. Но там выложены либо только hex-файлы, либо код написан так, что черт ногу сломит.
Ни у кого нет случайно доступного описания wav формата, и описания его открытия avr. Может есть библиотечка? Был бы признателен.
Я уже второй день читаю http://microsin.ru/content/view/1197/44/, но яснее чего-то не становится
На самом деле по ссылке все достаточно просто описано, но чтобы лучше понять нужно открыть wav-файл hex-редактором и сравнить то, что описано в статье с содержимым файла.
Если формат файла заведомо известен, то тупо ищем последовательность "data", читаем 4 байта после нее (это размер), а дальше тупо читаем семпл и отправляем его в ЦАП с частотой квантования (или в OCR, если использовать ШИМ, но тут не всякая частота квантования прокатит!).
Если формат не известен, то тут придется разбирать данные из раздела "fmt" (количество каналов, частоту квантования, разрядность) и на их основе настраивать таймер для считывания и вывода семплов в ЦАП. Для воспроизведения 99% wav-файлов этого достаточно, все остальные параметры внимания не стоят.
ИМХО сложнее разобраться с чтением данных с SD-карты, чем с их разбором в wav-плеере...
Ну там достаточно информации для начала разбора. Загрузите любой wav файл, откройте хексом и смотрите. Понятно, что музыку вручную дешифровать не надо, но хотя бы посмотрите секции. Будет понятнее.
В конце концов можно записать что-либо голосом на микрофон и сохранить в разных форматах - сжатым и не сжатым, будут видны отличия, это поможет разобраться с форматом.
Есть кристаллы, специально предназначенные для реализации плееров, с аппаратной поддержкой. Чтобы не лезть в дебри, нужно просто по прерыванию загружать данные в буфер. И всё.
Пока плату сделал, пока остальную периферию сделал... Вообщем, все затянулось. Вопрос в догонку: данные 2-х байтные точно со знаком? Если да, то надо его еще переводить соответственно в без знаковый чтобы отправить в таймер? И если сигнал моно, то читаем все подряд, нет пропусков? У нас просто получается один канал?
eess9 писал(а):...данные 2-х байтные точно со знаком?..
со знаком, надо добавить 0x7FFF,
в моно данные для 1 канала, в стерео для 2х (левый канал, правый, левый канал, правый и т.д.)
и скачайте файлик, кот. вам предлагали - там есть и разбор заголовка и преобразование
PS сделал себе WAV плеер на XMega (таймер -> event system -> ЦАП, ПДП + двойная буферизация + FatFs + SD)
послушал некоторое время, счас внешний ЦАП паяю
16 бит таймер шим даже если тактировать PLL 200МГц, считаем:
200000000/65535 = 3051.80437933928
3 кГц частота сэмплирования маловато будет
а к чему 0x7FFF добавлять?
Согласен с oleg110592. Но загрубить 2-х байтное число к 1-му байту не бог весть какая штука - семь раз сдвинуть вправо.
Только не хочется делать эту операцию над отрицательными числами, да они мне и не нужны.
Вот здесь http://microsin.ru/content/view/1197/44/ все отлично и понятно написано для меня, кроме одного места в секции data:
Один момент, касающийся данных выборок, который может вызвать некоторое замешательство - когда выборки представлены 8 битами, они определены как значения без знака (unsigned). Все другие битовые размеры указываются как величины со знаком (signed). Например, выборка 16 бит может иметь значение в диапазоне от -32768 до +32767, где средняя точка (напряжение сигнала равно 0) соответствует значению 0.
То есть, выгрибать будем по 2 байта, но со знаком. Правильно я понимаю? Дальше надо ли приводить выборку к без знаковому виду или так отправлять в таймер?
Зачем вот это
а к чему 0x7FFF добавлять?
я тоже не понял? А если число будет 0xFFFF и добавим 0x7FFF, то получим 0x7FFE, что не верно.
"загрубить" можно, сразу сделав 8-ми битный wav файл, но можно проиграть и полный 16-ти битный и используя два 8-ми разрядных шим, реализацию можно (и нужно) посмотреть у первооткрывателя велосипеда - проигрывателя wav файлов господина Чена (там заодно и видно в исходниках, что не надо приводить ни к без знаковому виду, ни добавлять магические числа 0x7FFF): http://elm-chan.org/works/sd8p/report.html
з.ы. После такой разработки не вижу смысла заново изобретать велосипед.
ld r24, Z+ ;Get R-ch/LSB data and send it to PWM
out _SFR_IO_ADDR(OCR1A), r24 ;/
ld r24, Z+ ;Get L-ch/MSB data and send it to PWM
out _SFR_IO_ADDR(OCR1B), r24 ;/
8-битный звук хранится в беззнаковых целых, поэтому его необходимо нормализовать, отняв от каждого сэмпла половину амплитуды.
subi r24, 0x80 != чан вычитает 0x8000
Диапазон изменения значений выборок определяется дискретизацией. Для 8-битовых данных диапазон составляет от 0 до 255 (0xff), причем отсутствию сигнала (полная тишина) соответствует значение 128 (0x80); для 16-битовых значений диапазон изменения составляет от –32768 (-0x8000) до 32767 (0x7fff), отсутствию сигнала соответствует значение 0.
sbic _FLAGS, 4 - проверка 8/16 бит при 8 битах пропуск 1 чтения и вычитания 0x80
и что в ШИМ, что в ЦАП надо отправлять безнаковое с нулем посередине
8бит не трогаем а 16 бит приводим к беззнаковому (+0x7fff или -0x8000)
если используем только 8 бит, то к старшему байту +0x7f или -0x80 (без разницы)
спутал все свой древний исходник на меге48 - смешивал резисторами два 8-ми битных шима для получения 16 битного звука (типа как Чен), данные с карты отправлял напрямую регистры шим без всяких буферов и нормализаций - звучало вполне хорошо, заказчик был доволен. Будет время - надо с дискавери будет поэкспериментировать.