Войти
ПрограммированиеФорумЗвук

DirectSound потоковый звук.

#0
22:11, 2 окт. 2018

Делаю потоковый звук. Проблема в том, что при заполнении следующего фрагмента в буфере звук на долю секунды заедает.
Варианты с сторонними библиотеками не предлагайте. Если кому интересно предоставлю код.


#1
(Правка: 22:35) 22:32, 2 окт. 2018

Из файла читаешь? Чтение то не быстрое, надо его заранее осуществлять, не когда уже воспроизводить пора. Преобразовывать из частотной формы в амплитудную тоже неплохо бы заранее, параллельно с воспроизведением предыдущего фрагмента.

Могут быть еще щелчки на стыке кадров, если бпф на них натравливать автономно на каждый, при формировании трека. Чтобы щелчков избежать, чаще всего приглушают громкость на стыках, что тоже дает эффект пауз. Надеюсь, у тебя не этот случай.

#2
(Правка: 23:24) 23:22, 2 окт. 2018

zeleniy5
Я делал как-то так - https://github.com/mrDIMAS/SoundWorks/blob/master/src/device.c

В общем ключевое здесь - создание маркеров на позиции в буфере

dev->points[0] = CreateEvent(0, 0, 0, 0);
dev->points[1] = CreateEvent(0, 0, 0, 0);

pPosNotify[0].dwOffset = 0;
pPosNotify[0].hEventNotify = dev->points[0];

pPosNotify[1].dwOffset = bufferHalfSize;
pPosNotify[1].hEventNotify = dev->points[1];

IDirectSoundNotify_SetNotificationPositions(dev->notify, 2, pPosNotify);

И отправка данных на устройство с ожиданием событий

void * outputData;
int size;
int result = WaitForMultipleObjects(2, dev->points, 0, INFINITE);
if(result == WAIT_OBJECT_0) {
  IDirectSoundBuffer8_Lock(dev->buffer, dev->bufferHalfSize, dev->bufferHalfSize, &outputData, (LPDWORD)&size, 0, 0, 0);
  memcpy(outputData, inputData, size);
  IDirectSoundBuffer8_Unlock(dev->buffer, outputData, size, 0, 0);
}
if(result == (WAIT_OBJECT_0 + 1)) {
  IDirectSoundBuffer8_Lock(dev->buffer, 0, dev->bufferHalfSize, &outputData, (LPDWORD)&size, 0, 0, 0);
  memcpy(outputData, inputData, size);
  IDirectSoundBuffer8_Unlock(dev->buffer, outputData, size, 0, 0);
}

Только таким способом получилось избежать разрывов и щелчков. Естественно к моменту отправки новый кусок должен уже быть загружен в оперативку.

ЗЫ. У буфера должен быть выставлен флаг

bufferDesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY;

#3
13:55, 3 окт. 2018

zeleniy5
Проще говоря, дели буфер пополам, как только начала воспроизводиться первая половина - уже заливай данные во вторую. И наоборот.

#4
19:07, 3 окт. 2018
Непойму зачем брать дысаунд, когда хаудио в разы проще, разве что поддерживать икспи, которое уже давно отжило свое.
#5
19:25, 3 окт. 2018

nes
> хаудио в разы проще
Неужели есть что-то проще, чем DirectSound?
nes
> Непойму зачем брать дысаунд
Ну, если работает, возможностей хватает, зачем терять совместимость, пусть даже только с XP? Хотя не только, как там под Вайном, заработает без танцев с бубном?

#6
19:35, 3 окт. 2018

Mikle так и делал но без POSITIONNOTIFY с эвентами, переписал код работает теперь нормально.

ПрограммированиеФорумЗвук