Страница 1 из 1
воспроизведение файла формата WAV
Добавлено: Вт ноя 12, 2013 12:58:55
eess9
Привет всем котам!
Помогите пожалуйста разобраться, инет пестрит огромным количеством схем WAV плееров. Но там выложены либо только hex-файлы, либо код написан так, что черт ногу сломит.
Ни у кого нет случайно доступного описания wav формата, и описания его открытия avr. Может есть библиотечка? Был бы признателен.
Я уже второй день читаю
http://microsin.ru/content/view/1197/44/, но яснее чего-то не становится

Re: воспроизведение файла формата WAV
Добавлено: Вт ноя 12, 2013 13:33:29
Engineer_Keen
На самом деле по ссылке все достаточно просто описано, но чтобы лучше понять нужно открыть wav-файл hex-редактором и сравнить то, что описано в статье с содержимым файла.
Если формат файла заведомо известен, то тупо ищем последовательность "data", читаем 4 байта после нее (это размер), а дальше тупо читаем семпл и отправляем его в ЦАП с частотой квантования (или в OCR, если использовать ШИМ, но тут не всякая частота квантования прокатит!).
Если формат не известен, то тут придется разбирать данные из раздела "fmt" (количество каналов, частоту квантования, разрядность) и на их основе настраивать таймер для считывания и вывода семплов в ЦАП. Для воспроизведения 99% wav-файлов этого достаточно, все остальные параметры внимания не стоят.
ИМХО сложнее разобраться с чтением данных с SD-карты, чем с их разбором в wav-плеере...
Re: воспроизведение файла формата WAV
Добавлено: Вт ноя 12, 2013 15:12:08
Шурики
Ну там достаточно информации для начала разбора. Загрузите любой wav файл, откройте хексом и смотрите. Понятно, что музыку вручную дешифровать не надо, но хотя бы посмотрите секции. Будет понятнее.
В конце концов можно записать что-либо голосом на микрофон и сохранить в разных форматах - сжатым и не сжатым, будут видны отличия, это поможет разобраться с форматом.
Есть кристаллы, специально предназначенные для реализации плееров, с аппаратной поддержкой. Чтобы не лезть в дебри, нужно просто по прерыванию загружать данные в буфер. И всё.
Немного опоздал, но смысл совпадает
Re: воспроизведение файла формата WAV
Добавлено: Вт ноя 12, 2013 15:34:26
eess9
Спасибо парни, буду разбираться.
Сделаю платку и начну...
Re: воспроизведение файла формата WAV
Добавлено: Вт ноя 12, 2013 22:41:07
uk8amk
В свое время тоже игрался с WAV.
Вот мой кусок кода, там есть разбор основных секций/чанков.
Возможно будет полезным.
Re: воспроизведение файла формата WAV
Добавлено: Ср ноя 13, 2013 12:32:04
eess9
За код спасибо!
Но я буду делать под xmega. Но DMA и ЦАП - это идея. А то я думал ШИМ использовать, у меня же аппаратный ЦАП есть!
Re: воспроизведение файла формата WAV
Добавлено: Вт дек 17, 2013 19:28:36
eess9
Пока плату сделал, пока остальную периферию сделал... Вообщем, все затянулось. Вопрос в догонку: данные 2-х байтные точно со знаком? Если да, то надо его еще переводить соответственно в без знаковый чтобы отправить в таймер? И если сигнал моно, то читаем все подряд, нет пропусков? У нас просто получается один канал?
Re: воспроизведение файла формата WAV
Добавлено: Вт дек 17, 2013 20:11:46
oleg110592
а как вы "2-х байтные" будете отправлять в 1-байтный шим?
Re: воспроизведение файла формата WAV
Добавлено: Вт дек 17, 2013 20:47:07
mrFox
oleg110592 писал(а):...в 1-байтный шим?
у XMega таймеры 16 бит
eess9 писал(а):...данные 2-х байтные точно со знаком?..
со знаком, надо добавить 0x7FFF,
в моно данные для 1 канала, в стерео для 2х (левый канал, правый, левый канал, правый и т.д.)
и скачайте файлик, кот. вам предлагали - там есть и разбор заголовка и преобразование
PS сделал себе WAV плеер на XMega (таймер -> event system -> ЦАП, ПДП + двойная буферизация + FatFs + SD)
послушал некоторое время, счас внешний ЦАП паяю

Re: воспроизведение файла формата WAV
Добавлено: Вт дек 17, 2013 21:17:16
oleg110592
mrFox писал(а):у XMega таймеры 16 бит
16 бит таймер шим даже если тактировать PLL 200МГц, считаем:
200000000/65535 = 3051.80437933928
3 кГц частота сэмплирования маловато будет
а к чему 0x7FFF добавлять?
Re: воспроизведение файла формата WAV
Добавлено: Ср дек 18, 2013 13:54:23
eess9
Согласен с
oleg110592. Но загрубить 2-х байтное число к 1-му байту не бог весть какая штука - семь раз сдвинуть вправо.
Только не хочется делать эту операцию над отрицательными числами, да они мне и не нужны.
Вот здесь
http://microsin.ru/content/view/1197/44/ все отлично и понятно написано для меня, кроме одного места в секции data:
Один момент, касающийся данных выборок, который может вызвать некоторое замешательство - когда выборки представлены 8 битами, они определены как значения без знака (unsigned). Все другие битовые размеры указываются как величины со знаком (signed). Например, выборка 16 бит может иметь значение в диапазоне от -32768 до +32767, где средняя точка (напряжение сигнала равно 0) соответствует значению 0.
То есть, выгрибать будем по 2 байта, но со знаком. Правильно я понимаю? Дальше надо ли приводить выборку к без знаковому виду или так отправлять в таймер?
Зачем вот это
а к чему 0x7FFF добавлять?
я тоже не понял? А если число будет 0xFFFF и добавим 0x7FFF, то получим 0x7FFE, что не верно.
Re: воспроизведение файла формата WAV
Добавлено: Ср дек 18, 2013 15:20:32
oleg110592
"загрубить" можно, сразу сделав 8-ми битный wav файл, но можно проиграть и полный 16-ти битный и используя два 8-ми разрядных шим, реализацию можно (и нужно) посмотреть у первооткрывателя велосипеда - проигрывателя wav файлов господина Чена (там заодно и видно в исходниках, что не надо приводить ни к без знаковому виду, ни добавлять магические числа 0x7FFF):
http://elm-chan.org/works/sd8p/report.html
з.ы. После такой разработки не вижу смысла заново изобретать велосипед.
Re: воспроизведение файла формата WAV
Добавлено: Ср дек 18, 2013 21:26:28
mrFox
eess9 писал(а):... А если число будет 0xFFFF и добавим 0x7FFF, то получим 0x7FFE, что не верно.
путаете - 0xFFFF это -1 и 0x7FFF - 1 = 0x7FFE так что все правильно
чан вычитает 0x8000 - что абсолютно тоже самое
я так сделал
Код: Выделить всё
uint8_t wave_buff[512];
void wp_convert16(uint16_t *buff, uint16_t len)
{
for( ; len; --len, ++buff ) *buff += 0x7fff;
}
вызов:
wp_convert16( (uint16_t *)wave_buff, ARRAY_LENGTH(wave_buff)/sizeof(uint16_t) );
Re: воспроизведение файла формата WAV
Добавлено: Ср дек 18, 2013 22:25:54
oleg110592
0xFFFF это -1 и 0x7FFF - 1 = 0x7FFE
лихо к тракторам лошадей прибавлять 0x7FFF - шестнадцатеричное, 1 десятичное
на калькуляторе: 0x7FFF-0xFFFF=0x8000
чан вычитает 0x8000 - что абсолютно тоже самое
где? покажите в коде, пока вижу это:
Код: Выделить всё
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 ;/
из буфера берем и прямехонько в шим заносим
Re: воспроизведение файла формата WAV
Добавлено: Чт дек 19, 2013 22:07:39
mrFox
oleg110592 писал(а):0x7FFF - шестнадцатеричное, 1 десятичное
ну я там раскрыл выражение должно быть (-1) + 0x7FFF, смотрим представление -1, получаем 0xFFFF + 0x7FFF
oleg110592 писал(а):где? покажите в коде,
Код: Выделить всё
fb_wave: ; Store the data bytes to the audio FIFO
...
rcall rcv_spi
subi r24, 0x80
...
Re: воспроизведение файла формата WAV
Добавлено: Пт дек 20, 2013 00:01:05
oleg110592
мы же вроде о 16-битном звуке
Код: Выделить всё
sbic _FLAGS, 4 ;if (16bit data)
subi r24, 0x80 ;
8-битный звук хранится в беззнаковых целых, поэтому его необходимо нормализовать, отняв от каждого сэмпла половину амплитуды.
subi r24, 0x80 !=
чан вычитает 0x8000
Диапазон изменения значений выборок определяется дискретизацией. Для 8-битовых данных диапазон составляет от 0 до 255 (0xff), причем отсутствию сигнала (полная тишина) соответствует значение 128 (0x80); для 16-битовых значений диапазон изменения составляет от –32768 (-0x8000) до 32767 (0x7fff), отсутствию сигнала соответствует значение 0.
Re: воспроизведение файла формата WAV
Добавлено: Пт дек 20, 2013 13:13:32
mrFox
oleg110592 писал(а):
8-битный звук хранится в беззнаковых целых, поэтому его необходимо нормализовать, отняв от каждого сэмпла половину амплитуды.
наиболее простой кусок для понимания у Чана:
Код: Выделить всё
sbic _FLAGS, 4 ;Get R-ch data into ZL
rcall rcv_spi ;
rcall rcv_spi ;
sbic _FLAGS, 4 ;
subi r24, 0x80
sbic _FLAGS, 4 - проверка 8/16 бит при 8 битах пропуск 1 чтения и вычитания 0x80
и что в ШИМ, что в ЦАП надо отправлять безнаковое с нулем посередине
8бит не трогаем а 16 бит приводим к беззнаковому (+0x7fff или -0x8000)
если используем только 8 бит, то к старшему байту +0x7f или -0x80 (без разницы)

Re: воспроизведение файла формата WAV
Добавлено: Пт дек 20, 2013 15:06:33
oleg110592
да был неправ - глянул тут исходники
http://radiokot.ru/forum/viewtopic.php? ... 8&start=40
Код: Выделить всё
case 17://16 бит моно
fread_status = file_read(&Mp3File,(Mp3Buffer_size),Buf);
while(Temp<(Mp3Buffer_size))
{
DAC_TEMP =(uint16_t) (Buf[Temp] << 0);
Temp++;
DAC_TEMP |=(uint16_t) (Buf[Temp] << 8);
Temp++;
DAC_TEMP = (0x8000 - DAC_TEMP);
DAC_DVALUE =(uint32_t)((DAC_TEMP) << 16)|(DAC_TEMP);
*wav_buff++ = DAC_DVALUE;
}
спутал все свой древний исходник на меге48 - смешивал резисторами два 8-ми битных шима для получения 16 битного звука (типа как Чен), данные с карты отправлял напрямую регистры шим без всяких буферов и нормализаций - звучало вполне хорошо, заказчик был доволен. Будет время - надо с дискавери будет поэкспериментировать.