tron@2186: /* $Id$ */ tron@2186: tron@2189: #include "../stdafx.h" tron@2189: #include "../openttd.h" tron@2189: #include "../driver.h" tron@2189: #include "../mixer.h" rubidium@8626: #include "../core/alloc_func.hpp" tron@2189: #include "win32_s.h" truelight@0: #include tron@2189: #include truelight@0: peter1138@7666: static FSoundDriver_Win32 iFSoundDriver_Win32; peter1138@7666: truelight@0: static HWAVEOUT _waveout; truelight@0: static WAVEHDR _wave_hdr[2]; truelight@0: static int _bufsize; tron@2171: truelight@0: static void PrepareHeader(WAVEHDR *hdr) truelight@0: { tron@1468: hdr->dwBufferLength = _bufsize * 4; truelight@0: hdr->dwFlags = 0; KUDr@5860: hdr->lpData = MallocT(_bufsize * 4); tron@1468: if (hdr->lpData == NULL || tron@1468: waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) truelight@0: error("waveOutPrepareHeader failed"); truelight@0: } truelight@0: rubidium@6573: static void FillHeaders() truelight@0: { truelight@0: WAVEHDR *hdr; tron@1468: tron@1468: for (hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) { truelight@0: if (!(hdr->dwFlags & WHDR_INQUEUE)) { tron@2977: MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4); truelight@0: if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) truelight@0: error("waveOutWrite failed"); truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@2449: static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, tron@1468: DWORD dwParam1, DWORD dwParam2) truelight@0: { tron@1468: switch (uMsg) { tron@1468: case WOM_DONE: Darkvater@6314: if (_waveout != NULL) FillHeaders(); tron@1468: break; Darkvater@6314: default: break; truelight@0: } truelight@0: } truelight@0: peter1138@7666: const char *SoundDriver_Win32::Start(const char* const* parm) truelight@0: { truelight@0: WAVEFORMATEX wfex; truelight@0: wfex.wFormatTag = WAVE_FORMAT_PCM; truelight@0: wfex.nChannels = 2; truelight@0: wfex.wBitsPerSample = 16; Darkvater@6314: wfex.nSamplesPerSec = GetDriverParamInt(parm, "hz", 11025); Darkvater@6314: wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8; Darkvater@6314: wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; Darkvater@6314: rubidium@9280: _bufsize = GetDriverParamInt(parm, "bufsize", 2048); Darkvater@6314: tron@2449: if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)&waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) truelight@0: return "waveOutOpen failed"; Darkvater@6314: truelight@0: PrepareHeader(&_wave_hdr[0]); truelight@0: PrepareHeader(&_wave_hdr[1]); truelight@0: FillHeaders(); truelight@0: return NULL; truelight@0: } truelight@0: peter1138@7666: void SoundDriver_Win32::Stop() truelight@0: { truelight@0: HWAVEOUT waveout = _waveout; tron@1468: truelight@0: _waveout = NULL; truelight@0: waveOutReset(waveout); truelight@0: waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR)); truelight@0: waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR)); truelight@0: waveOutClose(waveout); truelight@0: }