winapi audio output
-
12-06-2021 - |
Question
I am searching some alternative of pulseaudio for windows. Under linux there is very simple way to output raw sound (with pulseaudio):
pa_simple_write(pulse, data, bufferSize, &error);
It's work perfect with small buffers, that i send to function in the loop.
Under windows i use something like this:
void writeAudioBlock(HWAVEOUT hWaveOut, LPSTR block, DWORD size)
{
WAVEHDR header;
ZeroMemory(&header, sizeof(WAVEHDR));
header.dwBufferLength = size;
header.lpData = block;
waveOutPrepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
ResetEvent(waveDone);
waveOutWrite(hWaveOut, &header, sizeof(WAVEHDR));
WaitForSingleObject(waveDone, INFINITE);
waveOutUnprepareHeader(
hWaveOut,
&header,
sizeof(WAVEHDR)
);
}
It's working, but when i send another piece of data i hear small delay between pieces. Any other way to output small chunks of data buffer to sound device?
La solution
If you want to play some audio file, you can use the PlaySound function in windows API.
For chunks of data stored in memory you have to use the Waveform API - waveOutXXX functions.
For the problems with the delay between chunks of audio you have to use some double buffering mechanism.
You can find an example here: double buffering
Autres conseils
I created this function in assembly some months ago, maybe it can be useful for you:
PlayMultimediaProc Proc hWin : DWORD, szFileName : DWORD
.data
lpDll db "msvfw32.dll", 0
lpFunc db "MCIWndCreate", 0
.code
invoke GetModuleHandle, addr lpDll
invoke GetProcAddress, eax, addr lpFunc
mov esi, eax
push szFileName
push MCIWNDF_NOTIFYPOS or MCIWNDF_NOMENU or MCIWNDF_SHOWALL or MCIWNDF_SHOWNAME
invoke GetModuleHandle, NULL
push eax
push hWin
call esi
Ret
PlayMultimediaProc endp
XAudio2 is best audio API on windows. It's wrapper under WinMM, DirectSound and other windows audio frameworks. It's easy to use as pulseaudio, it has no problems with latency.