aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends/alsa.cpp
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-05 13:52:12 +0100
committerSven Göthel <[email protected]>2024-01-05 13:52:12 +0100
commitec98cdacc85ff0202852472c7756586437912f22 (patch)
tree42414746a27ab35cb8cdbc95af521d74821e57f4 /alc/backends/alsa.cpp
parentfd5269bec9a5fe4815974b1786a037e6a247bfd2 (diff)
parentb82cd2e60edb8fbe5fdd3567105ae76a016a554c (diff)
Merge remote-tracking branch 'upstream/master'HEADmaster
Diffstat (limited to 'alc/backends/alsa.cpp')
-rw-r--r--alc/backends/alsa.cpp121
1 files changed, 61 insertions, 60 deletions
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index 0d9ff30d..4bda5b02 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -53,6 +53,7 @@
namespace {
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char alsaDevice[] = "ALSA Default";
@@ -252,10 +253,11 @@ std::vector<DevMap> PlaybackDevices;
std::vector<DevMap> CaptureDevices;
-const char *prefix_name(snd_pcm_stream_t stream)
+const std::string_view prefix_name(snd_pcm_stream_t stream)
{
- assert(stream == SND_PCM_STREAM_PLAYBACK || stream == SND_PCM_STREAM_CAPTURE);
- return (stream==SND_PCM_STREAM_PLAYBACK) ? "device-prefix" : "capture-prefix";
+ if(stream == SND_PCM_STREAM_PLAYBACK)
+ return "device-prefix";
+ return "capture-prefix";
}
std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
@@ -267,11 +269,11 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
snd_pcm_info_t *pcminfo;
snd_pcm_info_malloc(&pcminfo);
- auto defname = ConfigValueStr(nullptr, "alsa",
+ auto defname = ConfigValueStr({}, "alsa",
(stream == SND_PCM_STREAM_PLAYBACK) ? "device" : "capture");
devlist.emplace_back(alsaDevice, defname ? defname->c_str() : "default");
- if(auto customdevs = ConfigValueStr(nullptr, "alsa",
+ if(auto customdevs = ConfigValueStr({}, "alsa",
(stream == SND_PCM_STREAM_PLAYBACK) ? "custom-devices" : "custom-captures"))
{
size_t nextpos{customdevs->find_first_not_of(';')};
@@ -299,8 +301,8 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
}
}
- const std::string main_prefix{
- ConfigValueStr(nullptr, "alsa", prefix_name(stream)).value_or("plughw:")};
+ const std::string main_prefix{ConfigValueStr({}, "alsa", prefix_name(stream))
+ .value_or("plughw:")};
int card{-1};
int err{snd_card_next(&card)};
@@ -309,12 +311,14 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
std::string name{"hw:" + std::to_string(card)};
snd_ctl_t *handle;
- if((err=snd_ctl_open(&handle, name.c_str(), 0)) < 0)
+ err = snd_ctl_open(&handle, name.c_str(), 0);
+ if(err < 0)
{
ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
continue;
}
- if((err=snd_ctl_card_info(handle, info)) < 0)
+ err = snd_ctl_card_info(handle, info);
+ if(err < 0)
{
ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
snd_ctl_close(handle);
@@ -326,8 +330,7 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
name = prefix_name(stream);
name += '-';
name += cardid;
- const std::string card_prefix{
- ConfigValueStr(nullptr, "alsa", name.c_str()).value_or(main_prefix)};
+ const std::string card_prefix{ConfigValueStr({}, "alsa", name).value_or(main_prefix)};
int dev{-1};
while(true)
@@ -339,7 +342,8 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
snd_pcm_info_set_device(pcminfo, static_cast<uint>(dev));
snd_pcm_info_set_subdevice(pcminfo, 0);
snd_pcm_info_set_stream(pcminfo, stream);
- if((err=snd_ctl_pcm_info(handle, pcminfo)) < 0)
+ err = snd_ctl_pcm_info(handle, pcminfo);
+ if(err < 0)
{
if(err != -ENOENT)
ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
@@ -352,8 +356,7 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
name += cardid;
name += '-';
name += std::to_string(dev);
- const std::string device_prefix{
- ConfigValueStr(nullptr, "alsa", name.c_str()).value_or(card_prefix)};
+ const std::string device_prefix{ConfigValueStr({},"alsa", name).value_or(card_prefix)};
/* "CardName, PcmName (CARD=cardid,DEV=dev)" */
name = cardname;
@@ -405,13 +408,14 @@ int verify_state(snd_pcm_t *handle)
break;
case SND_PCM_STATE_XRUN:
- if((err=snd_pcm_recover(handle, -EPIPE, 1)) < 0)
- return err;
+ err=snd_pcm_recover(handle, -EPIPE, 1);
+ if(err < 0) return err;
break;
case SND_PCM_STATE_SUSPENDED:
- if((err=snd_pcm_recover(handle, -ESTRPIPE, 1)) < 0)
- return err;
+ err = snd_pcm_recover(handle, -ESTRPIPE, 1);
+ if(err < 0) return err;
break;
+
case SND_PCM_STATE_DISCONNECTED:
return -ENODEV;
}
@@ -443,8 +447,6 @@ struct AlsaPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(AlsaPlayback)
};
AlsaPlayback::~AlsaPlayback()
@@ -644,7 +646,7 @@ void AlsaPlayback::open(std::string_view name)
else
{
name = alsaDevice;
- if(auto driveropt = ConfigValueStr(nullptr, "alsa", "device"))
+ if(auto driveropt = ConfigValueStr({}, "alsa", "device"))
driver = std::move(driveropt).value();
}
TRACE("Opening device \"%s\"\n", driver.c_str());
@@ -692,7 +694,7 @@ bool AlsaPlayback::reset()
break;
}
- bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", true)};
+ bool allowmmap{GetConfigValueBool(mDevice->DeviceName, "alsa", "mmap", true)};
uint periodLen{static_cast<uint>(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)};
uint bufferLen{static_cast<uint>(mDevice->BufferSize * 1000000_u64 / mDevice->Frequency)};
uint rate{mDevice->Frequency};
@@ -700,7 +702,8 @@ bool AlsaPlayback::reset()
int err{};
HwParamsPtr hp{CreateHwParams()};
#define CHECK(x) do { \
- if((err=(x)) < 0) \
+ err = (x); \
+ if(err < 0) \
throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
snd_strerror(err)}; \
} while(0)
@@ -715,17 +718,18 @@ bool AlsaPlayback::reset()
/* test and set format (implicitly sets sample bits) */
if(snd_pcm_hw_params_test_format(mPcmHandle, hp.get(), format) < 0)
{
- static const struct {
+ struct FormatMap {
snd_pcm_format_t format;
DevFmtType fmttype;
- } formatlist[] = {
- { SND_PCM_FORMAT_FLOAT, DevFmtFloat },
- { SND_PCM_FORMAT_S32, DevFmtInt },
- { SND_PCM_FORMAT_U32, DevFmtUInt },
- { SND_PCM_FORMAT_S16, DevFmtShort },
- { SND_PCM_FORMAT_U16, DevFmtUShort },
- { SND_PCM_FORMAT_S8, DevFmtByte },
- { SND_PCM_FORMAT_U8, DevFmtUByte },
+ };
+ static constexpr std::array formatlist{
+ FormatMap{SND_PCM_FORMAT_FLOAT, DevFmtFloat },
+ FormatMap{SND_PCM_FORMAT_S32, DevFmtInt },
+ FormatMap{SND_PCM_FORMAT_U32, DevFmtUInt },
+ FormatMap{SND_PCM_FORMAT_S16, DevFmtShort },
+ FormatMap{SND_PCM_FORMAT_U16, DevFmtUShort},
+ FormatMap{SND_PCM_FORMAT_S8, DevFmtByte },
+ FormatMap{SND_PCM_FORMAT_U8, DevFmtUByte },
};
for(const auto &fmt : formatlist)
@@ -750,7 +754,7 @@ bool AlsaPlayback::reset()
else mDevice->FmtChans = DevFmtStereo;
}
/* set rate (implicitly constrains period/buffer parameters) */
- if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "allow-resampler", false)
+ if(!GetConfigValueBool(mDevice->DeviceName, "alsa", "allow-resampler", false)
|| !mDevice->Flags.test(FrequencyRequest))
{
if(snd_pcm_hw_params_set_rate_resample(mPcmHandle, hp.get(), 0) < 0)
@@ -760,11 +764,11 @@ bool AlsaPlayback::reset()
WARN("Failed to enable ALSA resampler\n");
CHECK(snd_pcm_hw_params_set_rate_near(mPcmHandle, hp.get(), &rate, nullptr));
/* set period time (implicitly constrains period/buffer parameters) */
- if((err=snd_pcm_hw_params_set_period_time_near(mPcmHandle, hp.get(), &periodLen, nullptr)) < 0)
- ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
+ err = snd_pcm_hw_params_set_period_time_near(mPcmHandle, hp.get(), &periodLen, nullptr);
+ if(err < 0) ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
/* set buffer time (implicitly sets buffer size/bytes/time and period size/bytes) */
- if((err=snd_pcm_hw_params_set_buffer_time_near(mPcmHandle, hp.get(), &bufferLen, nullptr)) < 0)
- ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
+ err = snd_pcm_hw_params_set_buffer_time_near(mPcmHandle, hp.get(), &bufferLen, nullptr);
+ if(err < 0) ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
/* install and prepare hardware configuration */
CHECK(snd_pcm_hw_params(mPcmHandle, hp.get()));
@@ -802,7 +806,8 @@ void AlsaPlayback::start()
snd_pcm_access_t access{};
HwParamsPtr hp{CreateHwParams()};
#define CHECK(x) do { \
- if((err=(x)) < 0) \
+ err = (x); \
+ if(err < 0) \
throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
snd_strerror(err)}; \
} while(0)
@@ -852,7 +857,7 @@ ClockLatency AlsaPlayback::getClockLatency()
ClockLatency ret;
std::lock_guard<std::mutex> _{mMutex};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
snd_pcm_sframes_t delay{};
int err{snd_pcm_delay(mPcmHandle, &delay)};
if(err < 0)
@@ -886,8 +891,6 @@ struct AlsaCapture final : public BackendBase {
RingBufferPtr mRing{nullptr};
snd_pcm_sframes_t mLastAvail{0};
-
- DEF_NEWDEL(AlsaCapture)
};
AlsaCapture::~AlsaCapture()
@@ -916,7 +919,7 @@ void AlsaCapture::open(std::string_view name)
else
{
name = alsaDevice;
- if(auto driveropt = ConfigValueStr(nullptr, "alsa", "capture"))
+ if(auto driveropt = ConfigValueStr({}, "alsa", "capture"))
driver = std::move(driveropt).value();
}
@@ -961,7 +964,8 @@ void AlsaCapture::open(std::string_view name)
bool needring{false};
HwParamsPtr hp{CreateHwParams()};
#define CHECK(x) do { \
- if((err=(x)) < 0) \
+ err = (x); \
+ if(err < 0) \
throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
snd_strerror(err)}; \
} while(0)
@@ -1039,7 +1043,7 @@ void AlsaCapture::captureSamples(std::byte *buffer, uint samples)
{
if(mRing)
{
- mRing->read(buffer, samples);
+ std::ignore = mRing->read(buffer, samples);
return;
}
@@ -1068,7 +1072,8 @@ void AlsaCapture::captureSamples(std::byte *buffer, uint samples)
if(amt == -EAGAIN)
continue;
- if((amt=snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1)) >= 0)
+ amt = snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1);
+ if(amt >= 0)
{
amt = snd_pcm_start(mPcmHandle);
if(amt >= 0)
@@ -1105,7 +1110,8 @@ uint AlsaCapture::availableSamples()
{
ERR("avail update failed: %s\n", snd_strerror(static_cast<int>(avail)));
- if((avail=snd_pcm_recover(mPcmHandle, static_cast<int>(avail), 1)) >= 0)
+ avail = snd_pcm_recover(mPcmHandle, static_cast<int>(avail), 1);
+ if(avail >= 0)
{
if(mDoCapture)
avail = snd_pcm_start(mPcmHandle);
@@ -1141,7 +1147,8 @@ uint AlsaCapture::availableSamples()
if(amt == -EAGAIN)
continue;
- if((amt=snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1)) >= 0)
+ amt = snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1);
+ if(amt >= 0)
{
if(mDoCapture)
amt = snd_pcm_start(mPcmHandle);
@@ -1170,7 +1177,7 @@ ClockLatency AlsaCapture::getClockLatency()
{
ClockLatency ret;
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
snd_pcm_sframes_t delay{};
int err{snd_pcm_delay(mPcmHandle, &delay)};
if(err < 0)
@@ -1189,13 +1196,9 @@ ClockLatency AlsaCapture::getClockLatency()
bool AlsaBackendFactory::init()
{
- bool error{false};
-
#ifdef HAVE_DYNLOAD
if(!alsa_handle)
{
- std::string missing_funcs;
-
alsa_handle = LoadLib("libasound.so.2");
if(!alsa_handle)
{
@@ -1203,27 +1206,25 @@ bool AlsaBackendFactory::init()
return false;
}
- error = false;
+ std::string missing_funcs;
#define LOAD_FUNC(f) do { \
- p##f = al::bit_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f)); \
- if(p##f == nullptr) { \
- error = true; \
- missing_funcs += "\n" #f; \
- } \
+ p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f)); \
+ if(p##f == nullptr) missing_funcs += "\n" #f; \
} while(0)
ALSA_FUNCS(LOAD_FUNC);
#undef LOAD_FUNC
- if(error)
+ if(!missing_funcs.empty())
{
WARN("Missing expected functions:%s\n", missing_funcs.c_str());
CloseLib(alsa_handle);
alsa_handle = nullptr;
+ return false;
}
}
#endif
- return !error;
+ return true;
}
bool AlsaBackendFactory::querySupport(BackendType type)