summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2016-11-07 07:42:18 +0100
committerMax Kellermann <max@musicpd.org>2016-11-07 07:42:18 +0100
commit30bb3f1fcb6c6e315d029022e43b97e15c163180 (patch)
tree4c64df6d01891974f139573f30ef6f3c5544cef8
parentb45ea66175d599b430c7bb501859e8efad31a21e (diff)
output/winmm: migrate from class Error to C++ exceptions
-rw-r--r--src/output/plugins/WinmmOutputPlugin.cxx151
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