Главная » Программирование звука » Вызов подсистемы

0

B функции обратного вызова используется стандартный метод согласования характерного для языка C механизма обратных вызовов с классами C++. Как и большинство систем, разрешающих  использовать обратные  вызовы, Windows  позволяет применить  единственный  указатель,  который  будет  передаваться  этой  функции. (B Windows параметр dwInstance описывается как DWORD, однако он почти всегда используется для передачи указателя.) Я решил в этом указателе хранить значение this. Функция обратного вызова получает этот параметр и применяет его для передачи сообщения в объект. Вот таким образом функция WaveOutCallback преобразует вызов функции языка C в инициирование метода языка C++.

Листинг 6.3. Реализация класса WinPalyer (продолжение)

// Вызов   подсистемы.

void CALLBACK WaveOutCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParaml, DWORD dwParam2) { WinPlayer *me = reinterpret_cast<WinPlayer *>(dwInstance); switch(uMsg) {

case WOM_DONE:        // C этим  буфером закончено.

{

WAVEHDR *pWaveHdr = reinterpret_cast<WAVEHDR

*>(dwParam1);

me->NextBuff(pWaveHdr) ;

break;

} default: break;

}

}

Рассмотренная  функция  обратного  вызова  управляется  из  метода  NextBuff, который   заполняет   буфер   и   передает   его   управляющей   звуком   подпрограмме Windows.

Листинг 6.3. Реализация класса WinPlayer (продолжение)

void WinPlayer::NextBuff(WAVEHDR *pWaveHdr) {

long samplesRead = 0; switch(_sampleWidth) { case 16:

samplesRead = FromQueue(

reinterpret_cast<Sample16 *>(pWaveHdr->lpData), winBufferSize);

break;

case 8:

samplesRead = FromQueue(

reinterpret_cast<Sample8 *>(pWaveHdr->lpData), winBufferSize);

break;

}

if (samplesRead != 0) {        // Если   есть данные, то их   надо

// записать.

pWaveHdr->dwBufferLength = samplesRead * _sampleWidth / 8;

waveOutWrite(_device, pWaveHdr, sizeof(*pWaveHdr));

} else if (!_endOfQueue) {     // Ой! Пропал источник  сигнала.

waveOutPause(_device);     // Устройство  вывода переводим

// в состояние паузы.

_paused = true;

// Воспроизведение прервано  из-за

// перебоев с получением данных.

cerr << "Sound output paused due to lack of data.\n";

// Пишем несколько нулей, чтобы

// сохранить  блок в  очереди

// Windows. memset(pWaveHdr->lpData,0,winBufferSize); pWaveHdr->dwBufferLength = 256;

waveOutWrite(_device,pWaveHdr,sizeof(*pWaveHdr));

} else {                        // Данные   все, работа закончена.

pWaveHdr->dwFlags |= WHDR_DONE;  // Помечаем буфер  как

// прошедший   обработку.

}

}

Источник: Кинтцель Т.  Руководство программиста по работе со звуком = A Programmer’s Guide to Sound: Пер. с англ. М.: ДМК Пресс, 2000. 432 с, ил. (Серия «Для программистов»).

По теме:

  • Комментарии