XMP goes full circle: earlier this week I merged a patch from Lorence Lombardo that allows the player to work in AHI-compatible Amiga systems. Of course it’s not the most efficient way to play Amiga formats on an Amiga, but a curious development nonetheless. I was surprised to see how easy it is to configure the audio output in this port, even compared to the simple descriptor/ioctl approach used in most Unixes:
int fd;
if ((fd = open("AUDIO:B/16/F44100/C/2/BUFFER/358000, O_WRONLY)) < 0)
return -1;
write(fd, data, len);
close(fd);
I also spent some time preparing a Windows port built with MinGW. If the Amiga API above was the simplest to implement, the WinMM API is in the opposite extreme (words like “clumsy” and “design disaster” come quickly to mind). The following code does the exacly same thing using the WinMM API. Don’t read if you have a weak stomach.
MMRESULT res;
WAVEFORMATEX wfe;
HWAVEOUT hwaveout;
WAVEHDR header
wfe.wFormatTag = WAVE_FORMAT_PCM;
wfe.wBitsPerSample = 16;
wfe.nChannels = 2;
wfe.nSamplesPerSec = 44100;
wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nChannels * wfe.wBitsPerSample / 8;
wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
res = waveOutOpen(&hwaveout, WAVE_MAPPER, &wfe, (DWORD)wave_callback, 0, CALLBACK_FUNCTION);
if (res != MMSYSERR_NOERROR)
return -1
waveOutReset(hwaveout);
header.dwBufferLength = len;
header.lpData = data;
waveOutPrepareHeader(hwaveout, &header, sizeof(WAVEHDR));
waveOutWrite(hwaveout, &header, sizeof(WAVEHDR));
waveOutUnprepareHeader(hwaveout, &header, sizeof(WAVEHDR));
while (waveOutClose(hwaveout) == WAVERR_STILLPLAYING)
Sleep(10);
Ouch. And you’ll also need a callback function that’s not displayed. Further comments are left as an exercise to the reader.

Entries (RSS)
November 14th, 2007 at 8:18 am
Just wait until you see how it is done on DirectX :P
Anyway, I would use SDL for this kind of things.
And yes, Win32 API sucks for the most part.