Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Побайтное воспроизвидение wav


Автор: mishapk 26.1.2012, 18:40
Добрый день.
Имеется устройство при подачи на которое через порт RS232 поблочно wav файл, на устройстве происходит его воспроизведение.
Проблема в том, что с какой скоростью мы этот файл зальем с такой скоростью он и воспроизведется.

1. Подскажите как вычислить задержку что бы она соответствовала реальности. На мой слух задержка равна 20мл.сек.

Код

while(!feof(fin))
{
 Sleep(20);
fread(&a,sizeof(a),1,fin);
WriteFile(hComm,&a,320,&dwBytesWrite,NULL);
}



2. Сопутствующий вопрос. Как из фала wav извлечь data раздел - пропустить заголовок и если есть что то в конце пропустить его тоже.

Автор: tzirechnoy 26.1.2012, 22:12
1) Очевидно, что разница между записью в миллисекундах должна быть равна 1000*samplecount/samplerate, где samplecount -- сколько звуковых значений пишэтся в порт за один раз, в Вашэм примере 320 / 1, 2 или 4 в зависимости от количества бит в аудиопотоке .wav-файла (/1 или /2 для 8-бит и /2 или /4 для 16-бит) и количества каналов (/1 или /2 в моно- и /2 или /4 в стереофайле), а samplerate -- частота дискретизацыи, в Вашэм примере -- из метаинформацыи .wav-файла.
Замечу, что простые устройства воспроизведения (а у Вас, кажэтся, именно простое) требуют одного конретного формата, и если данные в .wav-файле им не соответствуют, то требуется их перекодировать. Для количества каналов (ну, в пределах 2-х) это просто, для разрешэния -- тожэ. Смена частоты дискретизацыи требует некоторых мыслительных затрат.
2) Возьмите какую-нибудь библиотеку для чтения .wav, например, http://www.mega-nerd.com/libsndfile/.

Добавлено через 1 минуту и 3 секунды
1) Очевидно, что разница между записью в миллисекундах должна быть равна 1000*samplecount/samplerate, где samplecount -- сколько звуковых значений пишэтся в порт за один раз, в Вашэм примере 320 / 1, 2 или 4 в зависимости от количества бит в аудиопотоке .wav-файла (/1 или /2 для 8-бит и /2 или /4 для 16-бит) и количества каналов (/1 или /2 в моно- и /2 или /4 в стереофайле), а samplerate -- частота дискретизацыи, в Вашэм примере -- из метаинформацыи .wav-файла.
Замечу, что простые устройства воспроизведения (а у Вас, кажэтся, именно простое) требуют одного конретного формата, и если данные в .wav-файле им не соответствуют, то требуется их перекодировать. Для количества каналов (ну, в пределах 2-х) это просто, для разрешэния -- тожэ. Смена частоты дискретизацыи требует некоторых мыслительных затрат.
2) Возьмите какую-нибудь библиотеку для чтения .wav, например, http://www.mega-nerd.com/libsndfile/.

Добавлено через 3 минуты и 5 секунд
1) Очевидно, что разница между записью в миллисекундах должна быть равна 1000*samplecount/samplerate, где samplecount -- сколько звуковых значений пишэтся в порт за один раз, в Вашэм примере 320 / 1, 2 или 4 в зависимости от количества бит в аудиопотоке .wav-файла (/1 или /2 для 8-бит и /2 или /4 для 16-бит) и количества каналов (/1 или /2 в моно- и /2 или /4 в стереофайле), а samplerate -- частота дискретизацыи, в Вашэм примере -- из метаинформацыи .wav-файла.
Замечу, что простые устройства воспроизведения (а у Вас, кажэтся, именно простое) требуют одного конретного формата, и если данные в .wav-файле им не соответствуют, то требуется их перекодировать. Для количества каналов (ну, в пределах 2-х) это просто, для разрешэния -- тожэ. Смена частоты дискретизацыи требует некоторых мыслительных затрат.
2) Возьмите какую-нибудь библиотеку для чтения .wav, например, http://www.mega-nerd.com/libsndfile/.

Автор: borisbn 27.1.2012, 09:30
Модератор: Сообщение скрыто.

Автор: mishapk 27.1.2012, 10:24
Не совсем понял. В общем формат файла 16 бит 8 кгц моно, 128 кбит/ сек. Как теперь подсчитать?

Автор: borisbn 27.1.2012, 10:28
Цитата(mishapk @  27.1.2012,  10:24 Найти цитируемый пост)
формат файла 16 бит 8 кгц моно

вроде ж несложно:
за 1/8000 секунды должно уйти 2 байта.
такую задержку Sleep'ом не сделаешь.
вот, лови
Код

#define Sleep_mks(mks) { \
            LARGE_INTEGER F,P1,P2; QueryPerformanceFrequency(&F); QueryPerformanceCounter(&P2); \
            P2.QuadPart+=(__int64)mks*(__int64)((double)F.QuadPart/1e6); \
            do { QueryPerformanceCounter(&P1); } while (P1.QuadPart < P2.QuadPart); }

Автор: mishapk 27.1.2012, 10:30
Наверное 320/16=20

Добавлено через 4 минуты и 3 секунды
Именно Sleep(20) на слух в самый раз при 320 байт в сек на порт 

Автор: tzirechnoy 27.1.2012, 10:34
1000*(320/2)/8000. Но учтите, это -- разница между записью (в миллисекундах). Поскольку на read/write уходит некоторое время, лучшэ воспользоваться функцыями времени для определени задержки или спецыальными таймерами.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)