10 #include "../stdafx.h"
11 #include "../openttd.h"
12 #include "../driver.h"
14 #include "../core/alloc_func.hpp"
15 #include "../core/bitmath_func.hpp"
16 #include "../core/math_func.hpp"
20 #include <versionhelpers.h>
21 #include "../os/windows/win32.h"
22 #include "../thread.h"
24 #include "../safeguards.h"
28 static HWAVEOUT _waveout;
29 static WAVEHDR _wave_hdr[2];
31 static HANDLE _thread;
32 static DWORD _threadId;
35 static void PrepareHeader(WAVEHDR *hdr)
37 hdr->dwBufferLength = _bufsize * 4;
39 hdr->lpData = MallocT<char>(_bufsize * 4);
40 if (waveOutPrepareHeader(_waveout, hdr,
sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
throw "waveOutPrepareHeader failed";
43 static DWORD WINAPI SoundThread(LPVOID)
45 SetCurrentThreadName(
"ottd:win-sound");
48 for (
auto &hdr : _wave_hdr) {
49 if ((hdr.dwFlags & WHDR_INQUEUE) != 0)
continue;
50 MxMixSamples(hdr.lpData, hdr.dwBufferLength / 4);
51 if (waveOutWrite(_waveout, &hdr,
sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
52 MessageBox(
nullptr, L
"Sounds are disabled until restart.", L
"waveOutWrite failed", MB_ICONINFORMATION);
56 WaitForSingleObject(_event, INFINITE);
57 }
while (_waveout !=
nullptr);
65 wfex.wFormatTag = WAVE_FORMAT_PCM;
67 wfex.wBitsPerSample = 16;
69 wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8;
70 wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;
74 _bufsize = std::min<int>(_bufsize, UINT16_MAX);
77 if (
nullptr == (_event = CreateEvent(
nullptr, FALSE, FALSE,
nullptr)))
throw "Failed to create event";
79 if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)_event, 0, CALLBACK_EVENT) != MMSYSERR_NOERROR)
throw "waveOutOpen failed";
81 MxInitialize(wfex.nSamplesPerSec);
83 PrepareHeader(&_wave_hdr[0]);
84 PrepareHeader(&_wave_hdr[1]);
86 if (
nullptr == (_thread = CreateThread(
nullptr, 8192, SoundThread, 0, 0, &_threadId)))
throw "Failed to create thread";
87 }
catch (
const char *error) {
97 HWAVEOUT waveout = _waveout;
101 SignalObjectAndWait(_event, _thread, INFINITE, FALSE);
104 waveOutReset(waveout);
105 waveOutUnprepareHeader(waveout, &_wave_hdr[0],
sizeof(WAVEHDR));
106 waveOutUnprepareHeader(waveout, &_wave_hdr[1],
sizeof(WAVEHDR));
107 waveOutClose(waveout);
109 CloseHandle(_thread);
Factory for the sound driver for Windows.
void Stop() override
Stop this driver.
std::optional< std::string_view > Start(const StringList ¶m) override
Start this driver.
int GetDriverParamInt(const StringList &parm, const char *name, int def)
Get an integer parameter the list of parameters.
std::vector< std::string > StringList
Type for a list of strings.
Base for Windows sound handling.