Direct Sound в объятиях программиста Фленов Михаил Спецвыпуск Xakep, номер #044, стр. 044-014-5 Песни и пляски Если при кодинге звука через MMSystem для обеспечения нормальной параллельной работы проги и звука приходилось создавать отдельный поток и в нем запускать цикл работы с буфером, то здесь это происходит автоматом. Заметь, что никаких потоков нет, а все работает, не загружая систему. Конечно, мы рассмотрели самый сложный способ, при котором данные загружаются в буфер ручками, и потом запускается воспроизведение. Если таким образом грузить MP3, то придется самостоятельно, на лету преобразовывать данные. А зачем это делать, если в системе точно установлен фильтр, который сможет сделать это за нас? Пара телодвижений функциями DirectSound - и никаких проблем. Листинг 1 function InitDirectSound(hDlg: hWnd): boolean; var hr : hResult; dsbd : TDSBufferDesc; DSBPrimary : IDirectSoundBuffer; wfx : TWaveFormatEx; begin Result := false; // Инициализация Direct Sound hr := DirectSoundCreate(NIL, DS, NIL); if failed(hr) then exit; // Устанавливаем уровень приоритета hr := DS.SetCooperativeLevel(hDlg, DSSCL_PRIORITY); if failed(hr) then exit; FillChar(dsbd, SizeOf(dsbd), 0); dsbd.dwSize := SizeOf(dsbd); dsbd.dwFlags := DSBCAPS_PRIMARYBUFFER; hr := DS.CreateSoundBuffer(dsbd, DSBPrimary, NIL); if failed(hr) then exit; FillChar(wfx, SizeOf(wfx), 0); with wfx do begin wFormatTag := WAVE_FORMAT_PCM; nChannels := 1; nSamplesPerSec := 22050; wBitsPerSample := 16; nBlockAlign := (wBitsPerSample shr 3) * nChannels; nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; end; hr := DSBPrimary.SetFormat(@wfx); if failed(hr) then exit; if Assigned(DSBPrimary) then DSBPrimary := NIL; Result := true; end; Листинг 2 function PlayBuffer(looped: boolean): boolean; var hr : hResult; dwLooped : dWord; begin Result := false; if not Assigned(DSBuffer) then exit; if not RestoreBuffers then exit; if looped then dwLooped := DSBPLAY_LOOPING else dwLooped := 0; hr := DSBuffer.Play(0, 0, dwLooped); if failed(hr) then exit; Result := true; end; Чтобы не заморачиваться с кодингом Direct Sound, для простых программ можно поступить умнее – использовать через COM компоненту Media Player. Асинхронная работа Direct Sound достигается автоматически. В других технологиях приходится создавать отдельные потоки и мучиться с ними. Для воспроизведения простого потока данных можно использовать только первичный буфер, а если нужны серьезные манипуляции, то лучше создать и использовать вторичные буферы. В Direct Sound можно изменять громкость звучания каждого буфера в отдельности. |