tron@2186: /* $Id$ */ tron@2186: tron@2189: #include "../stdafx.h" tron@2189: #include "../openttd.h" tron@2189: #include "../driver.h" tron@2189: #include "../functions.h" tron@2189: #include "../mixer.h" tron@2189: #include "win32_s.h" tron@2174: #include tron@2189: #include tron@2174: tron@2174: static HWAVEOUT _waveout; tron@2174: static WAVEHDR _wave_hdr[2]; tron@2174: static int _bufsize; tron@2174: tron@2174: static void PrepareHeader(WAVEHDR *hdr) tron@2174: { tron@2174: hdr->dwBufferLength = _bufsize * 4; tron@2174: hdr->dwFlags = 0; tron@2174: hdr->lpData = malloc(_bufsize * 4); tron@2174: if (hdr->lpData == NULL || tron@2174: waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) tron@2174: error("waveOutPrepareHeader failed"); tron@2174: } tron@2174: tron@2174: static void FillHeaders(void) tron@2174: { tron@2174: WAVEHDR *hdr; tron@2174: tron@2174: for (hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) { tron@2174: if (!(hdr->dwFlags & WHDR_INQUEUE)) { tron@2977: MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4); tron@2174: if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) tron@2174: error("waveOutWrite failed"); tron@2174: } tron@2174: } tron@2174: } tron@2174: tron@2449: static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, tron@2174: DWORD dwParam1, DWORD dwParam2) tron@2174: { tron@2174: switch (uMsg) { tron@2174: case WOM_DONE: tron@2174: if (_waveout) FillHeaders(); tron@2174: break; tron@2174: tron@2174: default: tron@2174: break; tron@2174: } tron@2174: } tron@2174: tron@2174: static const char *Win32SoundStart(const char* const* parm) tron@2174: { tron@2174: WAVEFORMATEX wfex; tron@2174: int hz; tron@2174: tron@2174: _bufsize = GetDriverParamInt(parm, "bufsize", 1024); tron@2174: hz = GetDriverParamInt(parm, "hz", 11025); tron@2174: wfex.wFormatTag = WAVE_FORMAT_PCM; tron@2174: wfex.nChannels = 2; tron@2174: wfex.nSamplesPerSec = hz; tron@2174: wfex.nAvgBytesPerSec = hz * 2 * 2; tron@2174: wfex.nBlockAlign = 4; tron@2174: wfex.wBitsPerSample = 16; tron@2449: if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)&waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) tron@2174: return "waveOutOpen failed"; tron@2174: PrepareHeader(&_wave_hdr[0]); tron@2174: PrepareHeader(&_wave_hdr[1]); tron@2174: FillHeaders(); tron@2174: return NULL; tron@2174: } tron@2174: tron@2174: static void Win32SoundStop(void) tron@2174: { tron@2174: HWAVEOUT waveout = _waveout; tron@2174: tron@2174: _waveout = NULL; tron@2174: waveOutReset(waveout); tron@2174: waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR)); tron@2174: waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR)); tron@2174: waveOutClose(waveout); tron@2174: } tron@2174: tron@2174: const HalSoundDriver _win32_sound_driver = { tron@2174: Win32SoundStart, tron@2174: Win32SoundStop, tron@2174: };