diff options
author | Max Kellermann <max@musicpd.org> | 2016-11-07 07:42:18 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2016-11-07 07:42:18 +0100 |
commit | 30bb3f1fcb6c6e315d029022e43b97e15c163180 (patch) | |
tree | 4c64df6d01891974f139573f30ef6f3c5544cef8 | |
parent | b45ea66175d599b430c7bb501859e8efad31a21e (diff) |
output/winmm: migrate from class Error to C++ exceptions
-rw-r--r-- | src/output/plugins/WinmmOutputPlugin.cxx | 151 |
1 files changed, 57 insertions, 94 deletions
diff --git a/src/output/plugins/WinmmOutputPlugin.cxx b/src/output/plugins/WinmmOutputPlugin.cxx index 2405310ab..c520932ba 100644 --- a/src/output/plugins/WinmmOutputPlugin.cxx +++ b/src/output/plugins/WinmmOutputPlugin.cxx @@ -23,8 +23,7 @@ #include "pcm/PcmBuffer.hxx" #include "mixer/MixerList.hxx" #include "fs/AllocatedPath.hxx" -#include "util/Error.hxx" -#include "util/Domain.hxx" +#include "util/RuntimeError.hxx" #include "util/Macros.hxx" #include "util/StringCompare.hxx" @@ -40,7 +39,7 @@ struct WinmmBuffer { struct WinmmOutput { AudioOutput base; - UINT device_id; + const UINT device_id; HWAVEOUT handle; /** @@ -52,22 +51,18 @@ struct WinmmOutput { WinmmBuffer buffers[8]; unsigned next_buffer; - WinmmOutput() - :base(winmm_output_plugin) {} + WinmmOutput(const ConfigBlock &block); }; -static constexpr Domain winmm_output_domain("winmm_output"); - -static void -SetWaveOutError(Error &error, MMRESULT result, const char *prefix) +static std::runtime_error +MakeWaveOutError(MMRESULT result, const char *prefix) { char buffer[256]; if (waveOutGetErrorTextA(result, buffer, ARRAY_SIZE(buffer)) == MMSYSERR_NOERROR) - error.Format(winmm_output_domain, int(result), - "%s: %s", prefix, buffer); + return FormatRuntimeError("%s: %s", prefix, buffer); else - error.Set(winmm_output_domain, int(result), prefix); + return std::runtime_error(prefix); } HWAVEOUT @@ -82,14 +77,12 @@ winmm_output_test_default_device(void) return waveOutGetNumDevs() > 0; } -static bool -get_device_id(const char *device_name, UINT *device_id, Error &error) +static UINT +get_device_id(const char *device_name) { /* if device is not specified use wave mapper */ - if (device_name == nullptr) { - *device_id = WAVE_MAPPER; - return true; - } + if (device_name == nullptr) + return WAVE_MAPPER; UINT numdevs = waveOutGetNumDevs(); @@ -97,22 +90,16 @@ get_device_id(const char *device_name, UINT *device_id, Error &error) char *endptr; UINT id = strtoul(device_name, &endptr, 0); if (endptr > device_name && *endptr == 0) { - if (id >= numdevs) { - error.Format(winmm_output_domain, - "device \"%s\" is not found", - device_name); - return false; - } - - *device_id = id; - return true; + if (id >= numdevs) + throw FormatRuntimeError("device \"%s\" is not found", + device_name); + + return id; } /* check for device name */ const AllocatedPath device_name_fs = - AllocatedPath::FromUTF8(device_name, error); - if (device_name_fs.IsNull()) - return false; + AllocatedPath::FromUTF8Throw(device_name); for (UINT i = 0; i < numdevs; i++) { WAVEOUTCAPS caps; @@ -121,33 +108,23 @@ get_device_id(const char *device_name, UINT *device_id, Error &error) continue; /* szPname is only 32 chars long, so it is often truncated. Use partial match to work around this. */ - if (StringStartsWith(device_name_fs.c_str(), caps.szPname)) { - *device_id = i; - return true; - } + if (StringStartsWith(device_name_fs.c_str(), caps.szPname)) + return i; } - error.Format(winmm_output_domain, - "device \"%s\" is not found", device_name); - return false; + throw FormatRuntimeError("device \"%s\" is not found", device_name); } -static AudioOutput * -winmm_output_init(const ConfigBlock &block, Error &error) +WinmmOutput::WinmmOutput(const ConfigBlock &block) + :base(winmm_output_plugin, block), + device_id(get_device_id(block.GetBlockValue("device"))) { - WinmmOutput *wo = new WinmmOutput(); - if (!wo->base.Configure(block, error)) { - delete wo; - return nullptr; - } - - const char *device = block.GetBlockValue("device"); - if (!get_device_id(device, &wo->device_id, error)) { - delete wo; - return nullptr; - } +} - return &wo->base; +static AudioOutput * +winmm_output_init(const ConfigBlock &block, Error &) +{ + return &(new WinmmOutput(block))->base; } static void @@ -159,16 +136,13 @@ winmm_output_finish(AudioOutput *ao) } static bool -winmm_output_open(AudioOutput *ao, AudioFormat &audio_format, - Error &error) +winmm_output_open(AudioOutput *ao, AudioFormat &audio_format, Error &) { WinmmOutput *wo = (WinmmOutput *)ao; wo->event = CreateEvent(nullptr, false, false, nullptr); - if (wo->event == nullptr) { - error.Set(winmm_output_domain, "CreateEvent() failed"); - return false; - } + if (wo->event == nullptr) + throw std::runtime_error("CreateEvent() failed"); switch (audio_format.format) { case SampleFormat::S8: @@ -202,8 +176,7 @@ winmm_output_open(AudioOutput *ao, AudioFormat &audio_format, (DWORD_PTR)wo->event, 0, CALLBACK_EVENT); if (result != MMSYSERR_NOERROR) { CloseHandle(wo->event); - SetWaveOutError(error, result, "waveOutOpen() failed"); - return false; + throw MakeWaveOutError(result, "waveOutOpen() failed"); } for (unsigned i = 0; i < ARRAY_SIZE(wo->buffers); ++i) { @@ -231,10 +204,9 @@ winmm_output_close(AudioOutput *ao) /** * Copy data into a buffer, and prepare the wave header. */ -static bool +static void winmm_set_buffer(WinmmOutput *wo, WinmmBuffer *buffer, - const void *data, size_t size, - Error &error) + const void *data, size_t size) { void *dest = buffer->buffer.Get(size); assert(dest != nullptr); @@ -247,37 +219,30 @@ winmm_set_buffer(WinmmOutput *wo, WinmmBuffer *buffer, MMRESULT result = waveOutPrepareHeader(wo->handle, &buffer->hdr, sizeof(buffer->hdr)); - if (result != MMSYSERR_NOERROR) { - SetWaveOutError(error, result, - "waveOutPrepareHeader() failed"); - return false; - } - - return true; + if (result != MMSYSERR_NOERROR) + throw MakeWaveOutError(result, + "waveOutPrepareHeader() failed"); } /** * Wait until the buffer is finished. */ -static bool -winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer, - Error &error) +static void +winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer) { if ((buffer->hdr.dwFlags & WHDR_DONE) == WHDR_DONE) /* already finished */ - return true; + return; while (true) { MMRESULT result = waveOutUnprepareHeader(wo->handle, &buffer->hdr, sizeof(buffer->hdr)); if (result == MMSYSERR_NOERROR) - return true; - else if (result != WAVERR_STILLPLAYING) { - SetWaveOutError(error, result, - "waveOutUnprepareHeader() failed"); - return false; - } + return; + else if (result != WAVERR_STILLPLAYING) + throw MakeWaveOutError(result, + "waveOutUnprepareHeader() failed"); /* wait some more */ WaitForSingleObject(wo->event, INFINITE); @@ -285,15 +250,14 @@ winmm_drain_buffer(WinmmOutput *wo, WinmmBuffer *buffer, } static size_t -winmm_output_play(AudioOutput *ao, const void *chunk, size_t size, Error &error) +winmm_output_play(AudioOutput *ao, const void *chunk, size_t size, Error &) { WinmmOutput *wo = (WinmmOutput *)ao; /* get the next buffer from the ring and prepare it */ WinmmBuffer *buffer = &wo->buffers[wo->next_buffer]; - if (!winmm_drain_buffer(wo, buffer, error) || - !winmm_set_buffer(wo, buffer, chunk, size, error)) - return 0; + winmm_drain_buffer(wo, buffer); + winmm_set_buffer(wo, buffer, chunk, size); /* enqueue the buffer */ MMRESULT result = waveOutWrite(wo->handle, &buffer->hdr, @@ -301,8 +265,7 @@ winmm_output_play(AudioOutput *ao, const void *chunk, size_t size, Error &error) if (result != MMSYSERR_NOERROR) { waveOutUnprepareHeader(wo->handle, &buffer->hdr, sizeof(buffer->hdr)); - SetWaveOutError(error, result, "waveOutWrite() failed"); - return 0; + throw MakeWaveOutError(result, "waveOutWrite() failed"); } /* mark our buffer as "used" */ @@ -312,18 +275,14 @@ winmm_output_play(AudioOutput *ao, const void *chunk, size_t size, Error &error) return size; } -static bool -winmm_drain_all_buffers(WinmmOutput *wo, Error &error) +static void +winmm_drain_all_buffers(WinmmOutput *wo) { for (unsigned i = wo->next_buffer; i < ARRAY_SIZE(wo->buffers); ++i) - if (!winmm_drain_buffer(wo, &wo->buffers[i], error)) - return false; + winmm_drain_buffer(wo, &wo->buffers[i]); for (unsigned i = 0; i < wo->next_buffer; ++i) - if (!winmm_drain_buffer(wo, &wo->buffers[i], error)) - return false; - - return true; + winmm_drain_buffer(wo, &wo->buffers[i]); } static void @@ -343,8 +302,12 @@ winmm_output_drain(AudioOutput *ao) { WinmmOutput *wo = (WinmmOutput *)ao; - if (!winmm_drain_all_buffers(wo, IgnoreError())) + try { + winmm_drain_all_buffers(wo); + } catch (...) { winmm_stop(wo); + throw; + } } static void |