lib/alsa/Error: a std::system_error category for libasound errors
This commit is contained in:
44
src/lib/alsa/Error.cxx
Normal file
44
src/lib/alsa/Error.cxx
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2021 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Error.hxx"
|
||||
|
||||
#include <alsa/error.h>
|
||||
|
||||
namespace Alsa {
|
||||
|
||||
ErrorCategory error_category;
|
||||
|
||||
std::string
|
||||
ErrorCategory::message(int condition) const
|
||||
{
|
||||
return snd_strerror(condition);
|
||||
}
|
||||
|
||||
} // namespace Avahi
|
53
src/lib/alsa/Error.hxx
Normal file
53
src/lib/alsa/Error.hxx
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2021 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace Alsa {
|
||||
|
||||
class ErrorCategory final : public std::error_category {
|
||||
public:
|
||||
const char *name() const noexcept override {
|
||||
return "libasound";
|
||||
}
|
||||
|
||||
std::string message(int condition) const override;
|
||||
};
|
||||
|
||||
extern ErrorCategory error_category;
|
||||
|
||||
inline std::system_error
|
||||
MakeError(int error, const char *msg) noexcept
|
||||
{
|
||||
return std::system_error(error, error_category, msg);
|
||||
}
|
||||
|
||||
} // namespace Avahi
|
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "HwSetup.hxx"
|
||||
#include "Error.hxx"
|
||||
#include "Format.hxx"
|
||||
#include "util/ByteOrder.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
@@ -185,29 +186,27 @@ SetupHw(snd_pcm_t *pcm,
|
||||
/* configure HW params */
|
||||
err = snd_pcm_hw_params_any(pcm, hwparams);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_any() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_any() failed");
|
||||
|
||||
err = snd_pcm_hw_params_set_access(pcm, hwparams,
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_set_access() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_set_access() failed");
|
||||
|
||||
err = SetupSampleFormat(pcm, hwparams,
|
||||
audio_format.format, params);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("Failed to configure format %s: %s",
|
||||
sample_format_to_string(audio_format.format),
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err,
|
||||
fmt::format("Failed to configure format {}",
|
||||
audio_format.format).c_str());
|
||||
|
||||
unsigned int channels = audio_format.channels;
|
||||
err = snd_pcm_hw_params_set_channels_near(pcm, hwparams,
|
||||
&channels);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("Failed to configure %i channels: %s",
|
||||
(int)audio_format.channels,
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err,
|
||||
fmt::format("Failed to configure {} channels",
|
||||
audio_format.channels).c_str());
|
||||
|
||||
audio_format.channels = (int8_t)channels;
|
||||
|
||||
@@ -218,9 +217,9 @@ SetupHw(snd_pcm_t *pcm,
|
||||
err = snd_pcm_hw_params_set_rate_near(pcm, hwparams,
|
||||
&output_sample_rate, nullptr);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("Failed to configure sample rate %u Hz: %s",
|
||||
requested_sample_rate,
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err,
|
||||
fmt::format("Failed to configure sample rate {} Hz",
|
||||
requested_sample_rate).c_str());
|
||||
|
||||
if (output_sample_rate == 0)
|
||||
throw FormatRuntimeError("Failed to configure sample rate %u Hz",
|
||||
@@ -253,8 +252,7 @@ SetupHw(snd_pcm_t *pcm,
|
||||
err = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams,
|
||||
&buffer_time, nullptr);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_set_buffer_time_near() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_set_buffer_time_near() failed");
|
||||
} else {
|
||||
err = snd_pcm_hw_params_get_buffer_time(hwparams, &buffer_time,
|
||||
nullptr);
|
||||
@@ -275,32 +273,27 @@ SetupHw(snd_pcm_t *pcm,
|
||||
err = snd_pcm_hw_params_set_period_time_near(pcm, hwparams,
|
||||
&period_time, nullptr);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_set_period_time_near() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_set_period_time_near() failed");
|
||||
}
|
||||
|
||||
err = snd_pcm_hw_params(pcm, hwparams);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params() failed");
|
||||
|
||||
HwResult result;
|
||||
|
||||
err = snd_pcm_hw_params_get_format(hwparams, &result.format);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_get_format() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_get_format() failed");
|
||||
|
||||
err = snd_pcm_hw_params_get_buffer_size(hwparams, &result.buffer_size);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_get_buffer_size() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_get_buffer_size() failed");
|
||||
|
||||
err = snd_pcm_hw_params_get_period_size(hwparams, &result.period_size,
|
||||
nullptr);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_hw_params_get_period_size() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_hw_params_get_period_size() failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "NonBlock.hxx"
|
||||
#include "Error.hxx"
|
||||
#include "event/MultiSocketMonitor.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
|
||||
@@ -29,8 +30,7 @@ AlsaNonBlockPcm::PrepareSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
||||
if (count == 0)
|
||||
throw std::runtime_error("snd_pcm_poll_descriptors_count() failed");
|
||||
else
|
||||
throw FormatRuntimeError("snd_pcm_poll_descriptors_count() failed: %s",
|
||||
snd_strerror(-count));
|
||||
throw Alsa::MakeError(count, "snd_pcm_poll_descriptors_count() failed");
|
||||
}
|
||||
|
||||
struct pollfd *pfds = pfd_buffer.Get(count);
|
||||
@@ -40,8 +40,7 @@ AlsaNonBlockPcm::PrepareSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
||||
if (count == 0)
|
||||
throw std::runtime_error("snd_pcm_poll_descriptors() failed");
|
||||
else
|
||||
throw FormatRuntimeError("snd_pcm_poll_descriptors() failed: %s",
|
||||
snd_strerror(-count));
|
||||
throw Alsa::MakeError(count, "snd_pcm_poll_descriptors() failed");
|
||||
}
|
||||
|
||||
m.ReplaceSocketList(pfds, count);
|
||||
@@ -71,8 +70,7 @@ AlsaNonBlockPcm::DispatchSockets(MultiSocketMonitor &m,
|
||||
unsigned short dummy;
|
||||
int err = snd_pcm_poll_descriptors_revents(pcm, pfds, i - pfds, &dummy);
|
||||
if (err < 0)
|
||||
throw FormatRuntimeError("snd_pcm_poll_descriptors_revents() failed: %s",
|
||||
snd_strerror(-err));
|
||||
throw Alsa::MakeError(err, "snd_pcm_poll_descriptors_revents() failed");
|
||||
}
|
||||
|
||||
Event::Duration
|
||||
|
@@ -14,6 +14,7 @@ conf.set('ENABLE_ALSA', true)
|
||||
alsa = static_library(
|
||||
'alsa',
|
||||
'Version.cxx',
|
||||
'Error.cxx',
|
||||
'AllowedFormat.cxx',
|
||||
'HwSetup.cxx',
|
||||
'NonBlock.cxx',
|
||||
|
Reference in New Issue
Block a user