воспроизведение файла формата WAV

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

Привет всем котам!

Помогите пожалуйста разобраться, инет пестрит огромным количеством схем WAV плееров. Но там выложены либо только hex-файлы, либо код написан так, что черт ногу сломит.
Ни у кого нет случайно доступного описания wav формата, и описания его открытия avr. Может есть библиотечка? Был бы признателен.
Я уже второй день читаю http://microsin.ru/content/view/1197/44/, но яснее чего-то не становится :cry:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

На самом деле по ссылке все достаточно просто описано, но чтобы лучше понять нужно открыть wav-файл hex-редактором и сравнить то, что описано в статье с содержимым файла.
Если формат файла заведомо известен, то тупо ищем последовательность "data", читаем 4 байта после нее (это размер), а дальше тупо читаем семпл и отправляем его в ЦАП с частотой квантования (или в OCR, если использовать ШИМ, но тут не всякая частота квантования прокатит!).
Если формат не известен, то тут придется разбирать данные из раздела "fmt" (количество каналов, частоту квантования, разрядность) и на их основе настраивать таймер для считывания и вывода семплов в ЦАП. Для воспроизведения 99% wav-файлов этого достаточно, все остальные параметры внимания не стоят.
ИМХО сложнее разобраться с чтением данных с SD-карты, чем с их разбором в wav-плеере...
Реклама
Вымогатель припоя
Сообщения: 506
Зарегистрирован: Пн авг 31, 2009 22:10:50
Откуда: СК

Сообщение Шурики »

Ну там достаточно информации для начала разбора. Загрузите любой wav файл, откройте хексом и смотрите. Понятно, что музыку вручную дешифровать не надо, но хотя бы посмотрите секции. Будет понятнее.
В конце концов можно записать что-либо голосом на микрофон и сохранить в разных форматах - сжатым и не сжатым, будут видны отличия, это поможет разобраться с форматом.

Есть кристаллы, специально предназначенные для реализации плееров, с аппаратной поддержкой. Чтобы не лезть в дебри, нужно просто по прерыванию загружать данные в буфер. И всё.

Немного опоздал, но смысл совпадает
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

Спасибо парни, буду разбираться.

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

Сообщение uk8amk »

В свое время тоже игрался с WAV.
Вот мой кусок кода, там есть разбор основных секций/чанков.
Возможно будет полезным.
Вложения
WAV.zip
(6.25 КБ) 283 скачивания
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

За код спасибо!

Но я буду делать под xmega. Но DMA и ЦАП - это идея. А то я думал ШИМ использовать, у меня же аппаратный ЦАП есть!
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

Пока плату сделал, пока остальную периферию сделал... Вообщем, все затянулось. Вопрос в догонку: данные 2-х байтные точно со знаком? Если да, то надо его еще переводить соответственно в без знаковый чтобы отправить в таймер? И если сигнал моно, то читаем все подряд, нет пропусков? У нас просто получается один канал?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

а как вы "2-х байтные" будете отправлять в 1-байтный шим?
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение mrFox »

oleg110592 писал(а):...в 1-байтный шим?
у XMega таймеры 16 бит
eess9 писал(а):...данные 2-х байтные точно со знаком?..
со знаком, надо добавить 0x7FFF,
в моно данные для 1 канала, в стерео для 2х (левый канал, правый, левый канал, правый и т.д.)
и скачайте файлик, кот. вам предлагали - там есть и разбор заголовка и преобразование
PS сделал себе WAV плеер на XMega (таймер -> event system -> ЦАП, ПДП + двойная буферизация + FatFs + SD)
послушал некоторое время, счас внешний ЦАП паяю :solder:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

mrFox писал(а):у XMega таймеры 16 бит
16 бит таймер шим даже если тактировать PLL 200МГц, считаем:
200000000/65535 = 3051.80437933928
3 кГц частота сэмплирования маловато будет
а к чему 0x7FFF добавлять?
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение 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, что не верно.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

"загрубить" можно, сразу сделав 8-ми битный wav файл, но можно проиграть и полный 16-ти битный и используя два 8-ми разрядных шим, реализацию можно (и нужно) посмотреть у первооткрывателя велосипеда - проигрывателя wav файлов господина Чена (там заодно и видно в исходниках, что не надо приводить ни к без знаковому виду, ни добавлять магические числа 0x7FFF): http://elm-chan.org/works/sd8p/report.html
з.ы. После такой разработки не вижу смысла заново изобретать велосипед.
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение 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) );
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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	;/
из буфера берем и прямехонько в шим заносим
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение 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
...
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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.
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение 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)
и что в ШИМ, что в ЦАП надо отправлять безнаковое с нулем посередине
8бит не трогаем а 16 бит приводим к беззнаковому (+0x7fff или -0x8000)
если используем только 8 бит, то к старшему байту +0x7f или -0x80 (без разницы) :tea:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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 битного звука (типа как Чен), данные с карты отправлял напрямую регистры шим без всяких буферов и нормализаций - звучало вполне хорошо, заказчик был доволен. Будет время - надо с дискавери будет поэкспериментировать.
Ответить

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