aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends
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
parentfd5269bec9a5fe4815974b1786a037e6a247bfd2 (diff)
parentb82cd2e60edb8fbe5fdd3567105ae76a016a554c (diff)
Merge remote-tracking branch 'upstream/master'HEADmaster
Diffstat (limited to 'alc/backends')
-rw-r--r--alc/backends/alsa.cpp121
-rw-r--r--alc/backends/base.cpp9
-rw-r--r--alc/backends/base.h23
-rw-r--r--alc/backends/coreaudio.cpp8
-rw-r--r--alc/backends/dsound.cpp16
-rw-r--r--alc/backends/jack.cpp47
-rw-r--r--alc/backends/loopback.cpp2
-rw-r--r--alc/backends/null.cpp3
-rw-r--r--alc/backends/oboe.cpp13
-rw-r--r--alc/backends/opensl.cpp77
-rw-r--r--alc/backends/oss.cpp28
-rw-r--r--alc/backends/pipewire.cpp132
-rw-r--r--alc/backends/portaudio.cpp74
-rw-r--r--alc/backends/pulseaudio.cpp75
-rw-r--r--alc/backends/sdl2.cpp27
-rw-r--r--alc/backends/sndio.cpp164
-rw-r--r--alc/backends/solaris.cpp20
-rw-r--r--alc/backends/wasapi.cpp62
-rw-r--r--alc/backends/wave.cpp117
-rw-r--r--alc/backends/winmm.cpp36
20 files changed, 474 insertions, 580 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)
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp
index ab3ad028..b287b6d9 100644
--- a/alc/backends/base.cpp
+++ b/alc/backends/base.cpp
@@ -45,21 +45,20 @@ uint BackendBase::availableSamples()
ClockLatency BackendBase::getClockLatency()
{
- ClockLatency ret;
+ ClockLatency ret{};
uint refcount;
do {
refcount = mDevice->waitForMix();
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
std::atomic_thread_fence(std::memory_order_acquire);
- } while(refcount != ReadRef(mDevice->MixCount));
+ } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
/* NOTE: The device will generally have about all but one periods filled at
* any given time during playback. Without a more accurate measurement from
* the output, this is an okay approximation.
*/
- ret.Latency = std::max(std::chrono::seconds{mDevice->BufferSize-mDevice->UpdateSize},
- std::chrono::seconds::zero());
+ ret.Latency = std::chrono::seconds{mDevice->BufferSize - mDevice->UpdateSize};
ret.Latency /= mDevice->Frequency;
return ret;
diff --git a/alc/backends/base.h b/alc/backends/base.h
index eea0d238..6726cd9a 100644
--- a/alc/backends/base.h
+++ b/alc/backends/base.h
@@ -52,18 +52,6 @@ enum class BackendType {
};
-/* Helper to get the current clock time from the device's ClockBase, and
- * SamplesDone converted from the sample rate.
- */
-inline std::chrono::nanoseconds GetDeviceClockTime(DeviceBase *device)
-{
- using std::chrono::seconds;
- using std::chrono::nanoseconds;
-
- auto ns = nanoseconds{seconds{device->SamplesDone}} / device->Frequency;
- return device->ClockBase + ns;
-}
-
/* Helper to get the device latency from the backend, including any fixed
* latency from post-processing.
*/
@@ -76,6 +64,8 @@ inline ClockLatency GetClockLatency(DeviceBase *device, BackendBase *backend)
struct BackendFactory {
+ virtual ~BackendFactory() = default;
+
virtual bool init() = 0;
virtual bool querySupport(BackendType type) = 0;
@@ -86,9 +76,6 @@ struct BackendFactory {
virtual std::string probe(BackendType type) = 0;
virtual BackendPtr createBackend(DeviceBase *device, BackendType type) = 0;
-
-protected:
- virtual ~BackendFactory() = default;
};
namespace al {
@@ -103,15 +90,15 @@ class backend_exception final : public base_exception {
backend_error mErrorCode;
public:
-#ifdef __USE_MINGW_ANSI_STDIO
- [[gnu::format(gnu_printf, 3, 4)]]
+#ifdef __MINGW32__
+ [[gnu::format(__MINGW_PRINTF_FORMAT, 3, 4)]]
#else
[[gnu::format(printf, 3, 4)]]
#endif
backend_exception(backend_error code, const char *msg, ...);
~backend_exception() override;
- backend_error errorCode() const noexcept { return mErrorCode; }
+ [[nodiscard]] auto errorCode() const noexcept -> backend_error { return mErrorCode; }
};
} // namespace al
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 16b0781e..86c4b89b 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -337,8 +337,6 @@ struct CoreAudioPlayback final : public BackendBase {
uint mFrameSize{0u};
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
-
- DEF_NEWDEL(CoreAudioPlayback)
};
CoreAudioPlayback::~CoreAudioPlayback()
@@ -623,8 +621,6 @@ struct CoreAudioCapture final : public BackendBase {
std::vector<char> mCaptureData;
RingBufferPtr mRing{nullptr};
-
- DEF_NEWDEL(CoreAudioCapture)
};
CoreAudioCapture::~CoreAudioCapture()
@@ -657,7 +653,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags *ioActionFlags,
return err;
}
- mRing->write(mCaptureData.data(), inNumberFrames);
+ std::ignore = mRing->write(mCaptureData.data(), inNumberFrames);
return noErr;
}
@@ -924,7 +920,7 @@ void CoreAudioCapture::captureSamples(std::byte *buffer, uint samples)
{
if(!mConverter)
{
- mRing->read(buffer, samples);
+ std::ignore = mRing->read(buffer, samples);
return;
}
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 58aa69b2..e51c7ab5 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -35,11 +35,11 @@
#include <algorithm>
#include <atomic>
#include <cassert>
+#include <cstdio>
+#include <cstdlib>
#include <functional>
#include <memory.h>
#include <mutex>
-#include <stdlib.h>
-#include <stdio.h>
#include <string>
#include <thread>
#include <vector>
@@ -191,8 +191,6 @@ struct DSoundPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(DSoundPlayback)
};
DSoundPlayback::~DSoundPlayback()
@@ -560,8 +558,6 @@ struct DSoundCapture final : public BackendBase {
DWORD mCursor{0u};
RingBufferPtr mRing;
-
- DEF_NEWDEL(DSoundCapture)
};
DSoundCapture::~DSoundCapture()
@@ -717,7 +713,7 @@ void DSoundCapture::stop()
}
void DSoundCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
uint DSoundCapture::availableSamples()
{
@@ -740,9 +736,9 @@ uint DSoundCapture::availableSamples()
}
if(SUCCEEDED(hr))
{
- mRing->write(ReadPtr1, ReadCnt1/FrameSize);
+ std::ignore = mRing->write(ReadPtr1, ReadCnt1/FrameSize);
if(ReadPtr2 != nullptr && ReadCnt2 > 0)
- mRing->write(ReadPtr2, ReadCnt2/FrameSize);
+ std::ignore = mRing->write(ReadPtr2, ReadCnt2/FrameSize);
hr = mDSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
mCursor = ReadCursor;
}
@@ -778,7 +774,7 @@ bool DSoundBackendFactory::init()
}
#define LOAD_FUNC(f) do { \
- p##f = al::bit_cast<decltype(p##f)>(GetSymbol(ds_handle, #f)); \
+ p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(ds_handle, #f)); \
if(!p##f) \
{ \
CloseLib(ds_handle); \
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index a0a5c440..529bb9fe 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -102,19 +102,16 @@ decltype(jack_error_callback) * pjack_error_callback;
#endif
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char JackDefaultAudioType[] = JACK_DEFAULT_AUDIO_TYPE;
jack_options_t ClientOptions = JackNullOption;
bool jack_load()
{
- bool error{false};
-
#ifdef HAVE_DYNLOAD
if(!jack_handle)
{
- std::string missing_funcs;
-
#ifdef _WIN32
#define JACKLIB "libjack.dll"
#else
@@ -127,38 +124,36 @@ bool jack_load()
return false;
}
- error = false;
+ std::string missing_funcs;
#define LOAD_FUNC(f) do { \
- p##f = al::bit_cast<decltype(p##f)>(GetSymbol(jack_handle, #f)); \
- if(p##f == nullptr) { \
- error = true; \
- missing_funcs += "\n" #f; \
- } \
+ p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f)); \
+ if(p##f == nullptr) missing_funcs += "\n" #f; \
} while(0)
JACK_FUNCS(LOAD_FUNC);
#undef LOAD_FUNC
/* Optional symbols. These don't exist in all versions of JACK. */
-#define LOAD_SYM(f) p##f = al::bit_cast<decltype(p##f)>(GetSymbol(jack_handle, #f))
+#define LOAD_SYM(f) p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f))
LOAD_SYM(jack_error_callback);
#undef LOAD_SYM
- if(error)
+ if(!missing_funcs.empty())
{
WARN("Missing expected functions:%s\n", missing_funcs.c_str());
CloseLib(jack_handle);
jack_handle = nullptr;
+ return false;
}
}
#endif
- return !error;
+ return true;
}
struct JackDeleter {
void operator()(void *ptr) { jack_free(ptr); }
};
-using JackPortsPtr = std::unique_ptr<const char*[],JackDeleter>;
+using JackPortsPtr = std::unique_ptr<const char*[],JackDeleter>; /* NOLINT(*-avoid-c-arrays) */
struct DeviceEntry {
std::string mName;
@@ -209,7 +204,7 @@ void EnumerateDevices(jack_client_t *client, std::vector<DeviceEntry> &list)
}
}
- if(auto listopt = ConfigValueStr(nullptr, "jack", "custom-devices"))
+ if(auto listopt = ConfigValueStr({}, "jack", "custom-devices"))
{
for(size_t strpos{0};strpos < listopt->size();)
{
@@ -307,7 +302,7 @@ struct JackPlayback final : public BackendBase {
std::string mPortPattern;
jack_client_t *mClient{nullptr};
- std::array<jack_port_t*,MAX_OUTPUT_CHANNELS> mPort{};
+ std::array<jack_port_t*,MaxOutputChannels> mPort{};
std::mutex mMutex;
@@ -318,8 +313,6 @@ struct JackPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(JackPlayback)
};
JackPlayback::~JackPlayback()
@@ -339,7 +332,7 @@ JackPlayback::~JackPlayback()
int JackPlayback::processRt(jack_nframes_t numframes) noexcept
{
- std::array<jack_default_audio_sample_t*,MAX_OUTPUT_CHANNELS> out;
+ std::array<jack_default_audio_sample_t*,MaxOutputChannels> out;
size_t numchans{0};
for(auto port : mPort)
{
@@ -363,7 +356,7 @@ int JackPlayback::processRt(jack_nframes_t numframes) noexcept
int JackPlayback::process(jack_nframes_t numframes) noexcept
{
- std::array<jack_default_audio_sample_t*,MAX_OUTPUT_CHANNELS> out;
+ std::array<jack_default_audio_sample_t*,MaxOutputChannels> out;
size_t numchans{0};
for(auto port : mPort)
{
@@ -378,7 +371,7 @@ int JackPlayback::process(jack_nframes_t numframes) noexcept
jack_nframes_t todo{minu(numframes, static_cast<uint>(data.first.len))};
auto write_first = [&data,numchans,todo](float *outbuf) -> float*
{
- const float *RESTRICT in = reinterpret_cast<float*>(data.first.buf);
+ const auto *RESTRICT in = reinterpret_cast<const float*>(data.first.buf);
auto deinterlace_input = [&in,numchans]() noexcept -> float
{
float ret{*in};
@@ -397,7 +390,7 @@ int JackPlayback::process(jack_nframes_t numframes) noexcept
{
auto write_second = [&data,numchans,todo](float *outbuf) -> float*
{
- const float *RESTRICT in = reinterpret_cast<float*>(data.second.buf);
+ const auto *RESTRICT in = reinterpret_cast<const float*>(data.second.buf);
auto deinterlace_input = [&in,numchans]() noexcept -> float
{
float ret{*in};
@@ -510,7 +503,7 @@ bool JackPlayback::reset()
std::for_each(mPort.begin(), mPort.end(), unregister_port);
mPort.fill(nullptr);
- mRTMixing = GetConfigValueBool(mDevice->DeviceName.c_str(), "jack", "rt-mix", true);
+ mRTMixing = GetConfigValueBool(mDevice->DeviceName, "jack", "rt-mix", true);
jack_set_process_callback(mClient,
mRTMixing ? &JackPlayback::processRtC : &JackPlayback::processC, this);
@@ -528,7 +521,7 @@ bool JackPlayback::reset()
}
else
{
- const char *devname{mDevice->DeviceName.c_str()};
+ const std::string_view devname{mDevice->DeviceName};
uint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
@@ -578,7 +571,7 @@ void JackPlayback::start()
if(jack_activate(mClient))
throw al::backend_exception{al::backend_error::DeviceError, "Failed to activate client"};
- const char *devname{mDevice->DeviceName.c_str()};
+ const std::string_view devname{mDevice->DeviceName};
if(ConfigValueBool(devname, "jack", "connect-ports").value_or(true))
{
JackPortsPtr pnames{jack_get_ports(mClient, mPortPattern.c_str(), JackDefaultAudioType,
@@ -657,7 +650,7 @@ ClockLatency JackPlayback::getClockLatency()
ClockLatency ret;
std::lock_guard<std::mutex> _{mMutex};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
ret.Latency = std::chrono::seconds{mRing ? mRing->readSpace() : mDevice->UpdateSize};
ret.Latency /= mDevice->Frequency;
@@ -677,7 +670,7 @@ bool JackBackendFactory::init()
if(!jack_load())
return false;
- if(!GetConfigValueBool(nullptr, "jack", "spawn-server", false))
+ if(!GetConfigValueBool({}, "jack", "spawn-server", false))
ClientOptions = static_cast<jack_options_t>(ClientOptions | JackNoStartServer);
const PathNamePair &binname = GetProcBinary();
diff --git a/alc/backends/loopback.cpp b/alc/backends/loopback.cpp
index 2972fc01..e42e35b0 100644
--- a/alc/backends/loopback.cpp
+++ b/alc/backends/loopback.cpp
@@ -34,8 +34,6 @@ struct LoopbackBackend final : public BackendBase {
bool reset() override;
void start() override;
void stop() override;
-
- DEF_NEWDEL(LoopbackBackend)
};
diff --git a/alc/backends/null.cpp b/alc/backends/null.cpp
index 3c68e4ce..f28eaa47 100644
--- a/alc/backends/null.cpp
+++ b/alc/backends/null.cpp
@@ -42,6 +42,7 @@ using std::chrono::seconds;
using std::chrono::milliseconds;
using std::chrono::nanoseconds;
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char nullDevice[] = "No Output";
@@ -57,8 +58,6 @@ struct NullBackend final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(NullBackend)
};
int NullBackend::mixerProc()
diff --git a/alc/backends/oboe.cpp b/alc/backends/oboe.cpp
index b7bab19a..d55a7066 100644
--- a/alc/backends/oboe.cpp
+++ b/alc/backends/oboe.cpp
@@ -4,8 +4,8 @@
#include "oboe.h"
#include <cassert>
+#include <cstdint>
#include <cstring>
-#include <stdint.h>
#include "alnumeric.h"
#include "core/device.h"
@@ -17,6 +17,7 @@
namespace {
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char device_name[] = "Oboe Default";
@@ -48,11 +49,10 @@ oboe::DataCallbackResult OboePlayback::onAudioReady(oboe::AudioStream *oboeStrea
return oboe::DataCallbackResult::Continue;
}
-void OboePlayback::onErrorAfterClose(oboe::AudioStream* audioStream, oboe::Result error)
+void OboePlayback::onErrorAfterClose(oboe::AudioStream*, oboe::Result error)
{
- if (error == oboe::Result::ErrorDisconnected) {
+ if(error == oboe::Result::ErrorDisconnected)
mDevice->handleDisconnect("Oboe AudioStream was disconnected: %s", oboe::convertToText(error));
- }
TRACE("Error was %s", oboe::convertToText(error));
}
@@ -81,6 +81,7 @@ bool OboePlayback::reset()
oboe::AudioStreamBuilder builder;
builder.setDirection(oboe::Direction::Output);
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
+ builder.setUsage(oboe::Usage::Game);
/* Don't let Oboe convert. We should be able to handle anything it gives
* back.
*/
@@ -230,7 +231,7 @@ struct OboeCapture final : public BackendBase, public oboe::AudioStreamCallback
oboe::DataCallbackResult OboeCapture::onAudioReady(oboe::AudioStream*, void *audioData,
int32_t numFrames)
{
- mRing->write(audioData, static_cast<uint32_t>(numFrames));
+ std::ignore = mRing->write(audioData, static_cast<uint32_t>(numFrames));
return oboe::DataCallbackResult::Continue;
}
@@ -330,7 +331,7 @@ uint OboeCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
void OboeCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
} // namespace
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp
index 61e3c9a7..6b2de909 100644
--- a/alc/backends/opensl.cpp
+++ b/alc/backends/opensl.cpp
@@ -23,10 +23,10 @@
#include "opensl.h"
-#include <stdlib.h>
#include <jni.h>
#include <array>
+#include <cstdlib>
#include <cstring>
#include <mutex>
#include <new>
@@ -56,6 +56,7 @@ namespace {
#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char opensl_device[] = "OpenSL";
@@ -189,8 +190,6 @@ struct OpenSLPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(OpenSLPlayback)
};
OpenSLPlayback::~OpenSLPlayback()
@@ -375,74 +374,6 @@ bool OpenSLPlayback::reset()
mRing = nullptr;
-#if 0
- if(!mDevice->Flags.get<FrequencyRequest>())
- {
- /* FIXME: Disabled until I figure out how to get the Context needed for
- * the getSystemService call.
- */
- JNIEnv *env = Android_GetJNIEnv();
- jobject jctx = Android_GetContext();
-
- /* Get necessary stuff for using java.lang.Integer,
- * android.content.Context, and android.media.AudioManager.
- */
- jclass int_cls = JCALL(env,FindClass)("java/lang/Integer");
- jmethodID int_parseint = JCALL(env,GetStaticMethodID)(int_cls,
- "parseInt", "(Ljava/lang/String;)I"
- );
- TRACE("Integer: %p, parseInt: %p\n", int_cls, int_parseint);
-
- jclass ctx_cls = JCALL(env,FindClass)("android/content/Context");
- jfieldID ctx_audsvc = JCALL(env,GetStaticFieldID)(ctx_cls,
- "AUDIO_SERVICE", "Ljava/lang/String;"
- );
- jmethodID ctx_getSysSvc = JCALL(env,GetMethodID)(ctx_cls,
- "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"
- );
- TRACE("Context: %p, AUDIO_SERVICE: %p, getSystemService: %p\n",
- ctx_cls, ctx_audsvc, ctx_getSysSvc);
-
- jclass audmgr_cls = JCALL(env,FindClass)("android/media/AudioManager");
- jfieldID audmgr_prop_out_srate = JCALL(env,GetStaticFieldID)(audmgr_cls,
- "PROPERTY_OUTPUT_SAMPLE_RATE", "Ljava/lang/String;"
- );
- jmethodID audmgr_getproperty = JCALL(env,GetMethodID)(audmgr_cls,
- "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"
- );
- TRACE("AudioManager: %p, PROPERTY_OUTPUT_SAMPLE_RATE: %p, getProperty: %p\n",
- audmgr_cls, audmgr_prop_out_srate, audmgr_getproperty);
-
- const char *strchars;
- jstring strobj;
-
- /* Now make the calls. */
- //AudioManager audMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
- strobj = JCALL(env,GetStaticObjectField)(ctx_cls, ctx_audsvc);
- jobject audMgr = JCALL(env,CallObjectMethod)(jctx, ctx_getSysSvc, strobj);
- strchars = JCALL(env,GetStringUTFChars)(strobj, nullptr);
- TRACE("Context.getSystemService(%s) = %p\n", strchars, audMgr);
- JCALL(env,ReleaseStringUTFChars)(strobj, strchars);
-
- //String srateStr = audMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
- strobj = JCALL(env,GetStaticObjectField)(audmgr_cls, audmgr_prop_out_srate);
- jstring srateStr = JCALL(env,CallObjectMethod)(audMgr, audmgr_getproperty, strobj);
- strchars = JCALL(env,GetStringUTFChars)(strobj, nullptr);
- TRACE("audMgr.getProperty(%s) = %p\n", strchars, srateStr);
- JCALL(env,ReleaseStringUTFChars)(strobj, strchars);
-
- //int sampleRate = Integer.parseInt(srateStr);
- sampleRate = JCALL(env,CallStaticIntMethod)(int_cls, int_parseint, srateStr);
-
- strchars = JCALL(env,GetStringUTFChars)(srateStr, nullptr);
- TRACE("Got system sample rate %uhz (%s)\n", sampleRate, strchars);
- JCALL(env,ReleaseStringUTFChars)(srateStr, strchars);
-
- if(!sampleRate) sampleRate = device->Frequency;
- else sampleRate = maxu(sampleRate, MIN_OUTPUT_RATE);
- }
-#endif
-
mDevice->FmtChans = DevFmtStereo;
mDevice->FmtType = DevFmtShort;
@@ -631,7 +562,7 @@ ClockLatency OpenSLPlayback::getClockLatency()
ClockLatency ret;
std::lock_guard<std::mutex> _{mMutex};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
ret.Latency = std::chrono::seconds{mRing->readSpace() * mDevice->UpdateSize};
ret.Latency /= mDevice->Frequency;
@@ -662,8 +593,6 @@ struct OpenSLCapture final : public BackendBase {
uint mSplOffset{0u};
uint mFrameSize{0};
-
- DEF_NEWDEL(OpenSLCapture)
};
OpenSLCapture::~OpenSLCapture()
diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index 87d3ba35..d541b534 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -79,7 +79,9 @@
namespace {
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char DefaultName[] = "OSS Default";
+
std::string DefaultPlayback{"/dev/dsp"};
std::string DefaultCapture{"/dev/dsp"};
@@ -238,8 +240,6 @@ struct OSSPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(OSSPlayback)
};
OSSPlayback::~OSSPlayback()
@@ -367,11 +367,9 @@ bool OSSPlayback::reset()
uint numFragmentsLogSize{(periods << 16) | log2FragmentSize};
audio_buf_info info{};
- const char *err;
-#define CHECKERR(func) if((func) < 0) { \
- err = #func; \
- goto err; \
-}
+#define CHECKERR(func) if((func) < 0) \
+ throw al::backend_exception{al::backend_error::DeviceError, "%s failed: %s\n", #func, strerror(errno)};
+
/* Don't fail if SETFRAGMENT fails. We can handle just about anything
* that's reported back via GETOSPACE */
ioctl(mFd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
@@ -379,12 +377,6 @@ bool OSSPlayback::reset()
CHECKERR(ioctl(mFd, SNDCTL_DSP_CHANNELS, &numChannels));
CHECKERR(ioctl(mFd, SNDCTL_DSP_SPEED, &ossSpeed));
CHECKERR(ioctl(mFd, SNDCTL_DSP_GETOSPACE, &info));
- if(0)
- {
- err:
- ERR("%s failed: %s\n", err, strerror(errno));
- return false;
- }
#undef CHECKERR
if(mDevice->channelsFromFmt() != numChannels)
@@ -409,7 +401,7 @@ bool OSSPlayback::reset()
setDefaultChannelOrder();
- mMixData.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
+ mMixData.resize(size_t{mDevice->UpdateSize} * mDevice->frameSizeFromFmt());
return true;
}
@@ -455,8 +447,6 @@ struct OSScapture final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(OSScapture)
};
OSScapture::~OSScapture()
@@ -617,7 +607,7 @@ void OSScapture::stop()
}
void OSScapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
uint OSScapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
@@ -633,9 +623,9 @@ BackendFactory &OSSBackendFactory::getFactory()
bool OSSBackendFactory::init()
{
- if(auto devopt = ConfigValueStr(nullptr, "oss", "device"))
+ if(auto devopt = ConfigValueStr({}, "oss", "device"))
DefaultPlayback = std::move(*devopt);
- if(auto capopt = ConfigValueStr(nullptr, "oss", "capture"))
+ if(auto capopt = ConfigValueStr({}, "oss", "capture"))
DefaultCapture = std::move(*capopt);
return true;
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 6a001d7a..55bcf6f4 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -28,12 +28,12 @@
#include <cstring>
#include <cerrno>
#include <chrono>
+#include <cstdint>
#include <ctime>
#include <list>
#include <memory>
#include <mutex>
#include <optional>
-#include <stdint.h>
#include <thread>
#include <type_traits>
#include <utility>
@@ -76,6 +76,10 @@ _Pragma("GCC diagnostic ignored \"-Weverything\"")
#include "spa/pod/builder.h"
#include "spa/utils/json.h"
+/* NOLINTBEGIN : All kinds of unsafe C stuff here from PipeWire headers
+ * (function-like macros, C style casts in macros, etc), which we can't do
+ * anything about except wrap into inline functions.
+ */
namespace {
/* Wrap some nasty macros here too... */
template<typename ...Args>
@@ -117,6 +121,7 @@ constexpr auto make_pod_builder(void *data, uint32_t size) noexcept
constexpr auto PwIdAny = PW_ID_ANY;
} // namespace
+/* NOLINTEND */
_Pragma("GCC diagnostic pop")
namespace {
@@ -169,8 +174,10 @@ using std::chrono::milliseconds;
using std::chrono::nanoseconds;
using uint = unsigned int;
+/* NOLINTBEGIN(*-avoid-c-arrays) */
constexpr char pwireDevice[] = "PipeWire Output";
constexpr char pwireInput[] = "PipeWire Input";
+/* NOLINTEND(*-avoid-c-arrays) */
bool check_version(const char *version)
@@ -238,7 +245,7 @@ bool pwire_load()
if(pwire_handle)
return true;
- static constexpr char pwire_library[] = "libpipewire-0.3.so.0";
+ const char *pwire_library{"libpipewire-0.3.so.0"};
std::string missing_funcs;
pwire_handle = LoadLib(pwire_library);
@@ -249,7 +256,7 @@ bool pwire_load()
}
#define LOAD_FUNC(f) do { \
- p##f = al::bit_cast<decltype(p##f)>(GetSymbol(pwire_handle, #f)); \
+ p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(pwire_handle, #f)); \
if(p##f == nullptr) missing_funcs += "\n" #f; \
} while(0);
PWIRE_FUNCS(LOAD_FUNC)
@@ -367,11 +374,11 @@ To as(From) noexcept = delete;
* - pw_metadata
*/
template<>
-pw_proxy* as(pw_registry *reg) noexcept { return al::bit_cast<pw_proxy*>(reg); }
+pw_proxy* as(pw_registry *reg) noexcept { return reinterpret_cast<pw_proxy*>(reg); }
template<>
-pw_proxy* as(pw_node *node) noexcept { return al::bit_cast<pw_proxy*>(node); }
+pw_proxy* as(pw_node *node) noexcept { return reinterpret_cast<pw_proxy*>(node); }
template<>
-pw_proxy* as(pw_metadata *mdata) noexcept { return al::bit_cast<pw_proxy*>(mdata); }
+pw_proxy* as(pw_metadata *mdata) noexcept { return reinterpret_cast<pw_proxy*>(mdata); }
struct PwContextDeleter {
@@ -434,9 +441,11 @@ public:
explicit operator bool() const noexcept { return mLoop != nullptr; }
+ [[nodiscard]]
auto start() const { return pw_thread_loop_start(mLoop); }
auto stop() const { return pw_thread_loop_stop(mLoop); }
+ [[nodiscard]]
auto getLoop() const { return pw_thread_loop_get_loop(mLoop); }
auto lock() const { return pw_thread_loop_lock(mLoop); }
@@ -501,8 +510,8 @@ struct NodeProxy {
/* Track changes to the enumerable and current formats (indicates the
* default and active format, which is what we're interested in).
*/
- uint32_t fmtids[]{SPA_PARAM_EnumFormat, SPA_PARAM_Format};
- ppw_node_subscribe_params(mNode.get(), std::data(fmtids), std::size(fmtids));
+ std::array<uint32_t,2> fmtids{{SPA_PARAM_EnumFormat, SPA_PARAM_Format}};
+ ppw_node_subscribe_params(mNode.get(), fmtids.data(), fmtids.size());
}
~NodeProxy()
{ spa_hook_remove(&mListener); }
@@ -765,25 +774,32 @@ void DeviceNode::Remove(uint32_t id)
}
-const spa_audio_channel MonoMap[]{
+constexpr std::array MonoMap{
SPA_AUDIO_CHANNEL_MONO
-}, StereoMap[] {
+};
+constexpr std::array StereoMap{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR
-}, QuadMap[]{
+};
+constexpr std::array QuadMap{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR
-}, X51Map[]{
+};
+constexpr std::array X51Map{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X51RearMap[]{
+};
+constexpr std::array X51RearMap{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR
-}, X61Map[]{
+};
+constexpr std::array X61Map{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_RC, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X71Map[]{
+};
+constexpr std::array X71Map{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X714Map[]{
+};
+constexpr std::array X714Map{
SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR,
SPA_AUDIO_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFR, SPA_AUDIO_CHANNEL_TRL, SPA_AUDIO_CHANNEL_TRR
@@ -793,10 +809,10 @@ const spa_audio_channel MonoMap[]{
* Checks if every channel in 'map1' exists in 'map0' (that is, map0 is equal
* to or a superset of map1).
*/
-template<size_t N>
-bool MatchChannelMap(const al::span<const uint32_t> map0, const spa_audio_channel (&map1)[N])
+bool MatchChannelMap(const al::span<const uint32_t> map0,
+ const al::span<const spa_audio_channel> map1)
{
- if(map0.size() < N)
+ if(map0.size() < map1.size())
return false;
for(const spa_audio_channel chid : map1)
{
@@ -831,7 +847,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
/* [0] is the default, [1] is the min, and [2] is the max. */
TRACE(" sample rate: %d (range: %d -> %d)\n", srates[0], srates[1], srates[2]);
if(!mSampleRate || force_update)
- mSampleRate = static_cast<uint>(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE));
+ mSampleRate = static_cast<uint>(clampi(srates[0], MinOutputRate, MaxOutputRate));
return;
}
@@ -857,7 +873,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
*/
for(const auto &rate : srates)
{
- if(rate >= MIN_OUTPUT_RATE && rate <= MAX_OUTPUT_RATE)
+ if(rate >= int{MinOutputRate} && rate <= int{MaxOutputRate})
{
if(!mSampleRate || force_update)
mSampleRate = static_cast<uint>(rate);
@@ -878,7 +894,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
TRACE(" sample rate: %d\n", srates[0]);
if(!mSampleRate || force_update)
- mSampleRate = static_cast<uint>(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE));
+ mSampleRate = static_cast<uint>(clampi(srates[0], MinOutputRate, MaxOutputRate));
return;
}
@@ -956,6 +972,7 @@ void DeviceNode::parseChannelCount(const spa_pod *value, bool force_update) noex
}
+/* NOLINTBEGIN(*-avoid-c-arrays) */
constexpr char MonitorPrefix[]{"Monitor of "};
constexpr auto MonitorPrefixLen = std::size(MonitorPrefix) - 1;
constexpr char AudioSinkClass[]{"Audio/Sink"};
@@ -963,6 +980,7 @@ constexpr char AudioSourceClass[]{"Audio/Source"};
constexpr char AudioSourceVirtualClass[]{"Audio/Source/Virtual"};
constexpr char AudioDuplexClass[]{"Audio/Duplex"};
constexpr char StreamClass[]{"Stream/"};
+/* NOLINTEND(*-avoid-c-arrays) */
void NodeProxy::infoCallback(const pw_node_info *info) noexcept
{
@@ -1070,8 +1088,11 @@ void NodeProxy::paramCallback(int, uint32_t id, uint32_t, uint32_t, const spa_po
if(const spa_pod_prop *prop{spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_position)})
node->parsePositions(&prop->value, force_update);
- else if((prop=spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_channels)) != nullptr)
- node->parseChannelCount(&prop->value, force_update);
+ else
+ {
+ prop = spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_channels);
+ if(prop) node->parseChannelCount(&prop->value, force_update);
+ }
}
}
@@ -1103,8 +1124,8 @@ int MetadataProxy::propertyCallback(uint32_t id, const char *key, const char *ty
return 0;
}
- spa_json it[2]{};
- spa_json_init(&it[0], value, strlen(value));
+ std::array<spa_json,2> it{};
+ spa_json_init(it.data(), value, strlen(value));
if(spa_json_enter_object(&it[0], &it[1]) <= 0)
return 0;
@@ -1407,8 +1428,7 @@ class PipeWirePlayback final : public BackendBase {
PwStreamPtr mStream;
spa_hook mStreamListener{};
spa_io_rate_match *mRateMatch{};
- std::unique_ptr<float*[]> mChannelPtrs;
- uint mNumChannels{};
+ std::vector<float*> mChannelPtrs;
static constexpr pw_stream_events CreateEvents()
{
@@ -1425,13 +1445,11 @@ class PipeWirePlayback final : public BackendBase {
public:
PipeWirePlayback(DeviceBase *device) noexcept : BackendBase{device} { }
- ~PipeWirePlayback()
+ ~PipeWirePlayback() final
{
/* Stop the mainloop so the stream can be properly destroyed. */
if(mLoop) mLoop.stop();
}
-
- DEF_NEWDEL(PipeWirePlayback)
};
@@ -1455,7 +1473,7 @@ void PipeWirePlayback::outputCallback() noexcept
if(!pw_buf) UNLIKELY return;
const al::span<spa_data> datas{pw_buf->buffer->datas,
- minu(mNumChannels, pw_buf->buffer->n_datas)};
+ minz(mChannelPtrs.size(), pw_buf->buffer->n_datas)};
#if PW_CHECK_VERSION(0,3,49)
/* In 0.3.49, pw_buffer::requested specifies the number of samples needed
* by the resampler/graph for this audio update.
@@ -1475,7 +1493,7 @@ void PipeWirePlayback::outputCallback() noexcept
* buffer length in any one channel is smaller than we wanted (shouldn't
* be, but just in case).
*/
- float **chanptr_end{mChannelPtrs.get()};
+ auto chanptr_end = mChannelPtrs.begin();
for(const auto &data : datas)
{
length = minu(length, data.maxsize/sizeof(float));
@@ -1487,7 +1505,7 @@ void PipeWirePlayback::outputCallback() noexcept
data.chunk->size = length * sizeof(float);
}
- mDevice->renderSamples({mChannelPtrs.get(), chanptr_end}, length);
+ mDevice->renderSamples(mChannelPtrs, length);
pw_buf->size = length;
pw_stream_queue_buffer(mStream.get(), pw_buf);
@@ -1590,7 +1608,7 @@ bool PipeWirePlayback::reset()
}
mStreamListener = {};
mRateMatch = nullptr;
- mTimeBase = GetDeviceClockTime(mDevice);
+ mTimeBase = mDevice->getClockTime();
/* If connecting to a specific device, update various device parameters to
* match its format.
@@ -1611,11 +1629,12 @@ bool PipeWirePlayback::reset()
{
/* Scale the update size if the sample rate changes. */
const double scale{static_cast<double>(match->mSampleRate) / mDevice->Frequency};
- const double numbufs{static_cast<double>(mDevice->BufferSize)/mDevice->UpdateSize};
+ const double updatesize{std::round(mDevice->UpdateSize * scale)};
+ const double buffersize{std::round(mDevice->BufferSize * scale)};
+
mDevice->Frequency = match->mSampleRate;
- mDevice->UpdateSize = static_cast<uint>(clampd(mDevice->UpdateSize*scale + 0.5,
- 64.0, 8192.0));
- mDevice->BufferSize = static_cast<uint>(numbufs*mDevice->UpdateSize + 0.5);
+ mDevice->UpdateSize = static_cast<uint>(clampd(updatesize, 64.0, 8192.0));
+ mDevice->BufferSize = static_cast<uint>(maxd(buffersize, 128.0));
}
if(!mDevice->Flags.test(ChannelsRequest) && match->mChannels != InvalidChannelConfig)
mDevice->FmtChans = match->mChannels;
@@ -1673,7 +1692,7 @@ bool PipeWirePlayback::reset()
pw_stream_flags flags{PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE
| PW_STREAM_FLAG_MAP_BUFFERS};
- if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pipewire", "rt-mix", true))
+ if(GetConfigValueBool(mDevice->DeviceName, "pipewire", "rt-mix", false))
flags |= PW_STREAM_FLAG_RT_PROCESS;
if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_OUTPUT, PwIdAny, flags, &params, 1)})
throw al::backend_exception{al::backend_error::DeviceError,
@@ -1698,8 +1717,7 @@ bool PipeWirePlayback::reset()
*/
plock.unlock();
- mNumChannels = mDevice->channelsFromFmt();
- mChannelPtrs = std::make_unique<float*[]>(mNumChannels);
+ mChannelPtrs.resize(mDevice->channelsFromFmt());
setDefaultWFXChannelOrder();
@@ -1757,7 +1775,7 @@ void PipeWirePlayback::start()
mDevice->UpdateSize = updatesize;
mDevice->BufferSize = static_cast<uint>(ptime.buffered + delay +
- totalbuffers*updatesize);
+ uint64_t{totalbuffers}*updatesize);
break;
}
#else
@@ -1791,8 +1809,7 @@ void PipeWirePlayback::stop()
{
MainloopUniqueLock plock{mLoop};
if(int res{pw_stream_set_active(mStream.get(), false)})
- throw al::backend_exception{al::backend_error::DeviceError,
- "Failed to stop PipeWire stream (res: %d)", res};
+ ERR("Failed to stop PipeWire stream (res: %d)\n", res);
/* Wait for the stream to stop playing. */
plock.wait([stream=mStream.get()]()
@@ -1824,10 +1841,10 @@ ClockLatency PipeWirePlayback::getClockLatency()
uint refcount;
do {
refcount = mDevice->waitForMix();
- mixtime = GetDeviceClockTime(mDevice);
+ mixtime = mDevice->getClockTime();
clock_gettime(CLOCK_MONOTONIC, &tspec);
std::atomic_thread_fence(std::memory_order_acquire);
- } while(refcount != ReadRef(mDevice->MixCount));
+ } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
/* Convert the monotonic clock, stream ticks, and stream delay to
* nanoseconds.
@@ -1916,9 +1933,7 @@ class PipeWireCapture final : public BackendBase {
public:
PipeWireCapture(DeviceBase *device) noexcept : BackendBase{device} { }
- ~PipeWireCapture() { if(mLoop) mLoop.stop(); }
-
- DEF_NEWDEL(PipeWireCapture)
+ ~PipeWireCapture() final { if(mLoop) mLoop.stop(); }
};
@@ -1934,7 +1949,8 @@ void PipeWireCapture::inputCallback() noexcept
const uint offset{minu(bufdata->chunk->offset, bufdata->maxsize)};
const uint size{minu(bufdata->chunk->size, bufdata->maxsize - offset)};
- mRing->write(static_cast<char*>(bufdata->data) + offset, size / mRing->getElemSize());
+ std::ignore = mRing->write(static_cast<char*>(bufdata->data) + offset,
+ size / mRing->getElemSize());
pw_stream_queue_buffer(mStream.get(), pw_buf);
}
@@ -2057,7 +2073,8 @@ void PipeWireCapture::open(std::string_view name)
static constexpr uint32_t pod_buffer_size{1024};
PodDynamicBuilder b(pod_buffer_size);
- const spa_pod *params[]{spa_format_audio_raw_build(b.get(), SPA_PARAM_EnumFormat, &info)};
+ std::array params{static_cast<const spa_pod*>(spa_format_audio_raw_build(b.get(),
+ SPA_PARAM_EnumFormat, &info))};
if(!params[0])
throw al::backend_exception{al::backend_error::DeviceError,
"Failed to set PipeWire audio format parameters"};
@@ -2099,7 +2116,7 @@ void PipeWireCapture::open(std::string_view name)
constexpr pw_stream_flags Flags{PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE
| PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS};
- if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_INPUT, PwIdAny, Flags, params, 1)})
+ if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_INPUT, PwIdAny, Flags, params.data(), 1)})
throw al::backend_exception{al::backend_error::DeviceError,
"Error connecting PipeWire stream (res: %d)", res};
@@ -2145,8 +2162,7 @@ void PipeWireCapture::stop()
{
MainloopUniqueLock plock{mLoop};
if(int res{pw_stream_set_active(mStream.get(), false)})
- throw al::backend_exception{al::backend_error::DeviceError,
- "Failed to stop PipeWire stream (res: %d)", res};
+ ERR("Failed to stop PipeWire stream (res: %d)\n", res);
plock.wait([stream=mStream.get()]()
{ return pw_stream_get_state(stream, nullptr) != PW_STREAM_STATE_STREAMING; });
@@ -2156,7 +2172,7 @@ uint PipeWireCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
void PipeWireCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
} // namespace
@@ -2175,11 +2191,11 @@ bool PipeWireBackendFactory::init()
}
TRACE("Found PipeWire version \"%s\" (%s or newer)\n", version, pw_get_headers_version());
- pw_init(0, nullptr);
+ pw_init(nullptr, nullptr);
if(!gEventHandler.init())
return false;
- if(!GetConfigValueBool(nullptr, "pipewire", "assume-audio", false)
+ if(!GetConfigValueBool({}, "pipewire", "assume-audio", false)
&& !gEventHandler.waitForAudio())
{
gEventHandler.kill();
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 979a54d6..7c61e134 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -39,7 +39,8 @@
namespace {
-constexpr char pa_device[] = "PortAudio Default";
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
+constexpr char pa_device[]{"PortAudio Default"};
#ifdef HAVE_DYNLOAD
@@ -78,13 +79,6 @@ struct PortPlayback final : public BackendBase {
int writeCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags) noexcept;
- static int writeCallbackC(const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
- const PaStreamCallbackFlags statusFlags, void *userData) noexcept
- {
- return static_cast<PortPlayback*>(userData)->writeCallback(inputBuffer, outputBuffer,
- framesPerBuffer, timeInfo, statusFlags);
- }
void open(std::string_view name) override;
bool reset() override;
@@ -94,8 +88,6 @@ struct PortPlayback final : public BackendBase {
PaStream *mStream{nullptr};
PaStreamParameters mParams{};
uint mUpdateSize{0u};
-
- DEF_NEWDEL(PortPlayback)
};
PortPlayback::~PortPlayback()
@@ -125,7 +117,7 @@ void PortPlayback::open(std::string_view name)
static_cast<int>(name.length()), name.data()};
PaStreamParameters params{};
- auto devidopt = ConfigValueInt(nullptr, "port", "device");
+ auto devidopt = ConfigValueInt({}, "port", "device");
if(devidopt && *devidopt >= 0) params.device = *devidopt;
else params.device = Pa_GetDefaultOutputDevice();
params.suggestedLatency = mDevice->BufferSize / static_cast<double>(mDevice->Frequency);
@@ -156,19 +148,21 @@ void PortPlayback::open(std::string_view name)
break;
}
-retry_open:
+ static constexpr auto writeCallback = [](const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
+ const PaStreamCallbackFlags statusFlags, void *userData) noexcept
+ {
+ return static_cast<PortPlayback*>(userData)->writeCallback(inputBuffer, outputBuffer,
+ framesPerBuffer, timeInfo, statusFlags);
+ };
PaStream *stream{};
- PaError err{Pa_OpenStream(&stream, nullptr, &params, mDevice->Frequency, mDevice->UpdateSize,
- paNoFlag, &PortPlayback::writeCallbackC, this)};
- if(err != paNoError)
+ while(PaError err{Pa_OpenStream(&stream, nullptr, &params, mDevice->Frequency,
+ mDevice->UpdateSize, paNoFlag, writeCallback, this)})
{
- if(params.sampleFormat == paFloat32)
- {
- params.sampleFormat = paInt16;
- goto retry_open;
- }
- throw al::backend_exception{al::backend_error::NoDevice, "Failed to open stream: %s",
- Pa_GetErrorText(err)};
+ if(params.sampleFormat != paFloat32)
+ throw al::backend_exception{al::backend_error::NoDevice, "Failed to open stream: %s",
+ Pa_GetErrorText(err)};
+ params.sampleFormat = paInt16;
}
Pa_CloseStream(mStream);
@@ -237,13 +231,6 @@ struct PortCapture final : public BackendBase {
int readCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags) noexcept;
- static int readCallbackC(const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
- const PaStreamCallbackFlags statusFlags, void *userData) noexcept
- {
- return static_cast<PortCapture*>(userData)->readCallback(inputBuffer, outputBuffer,
- framesPerBuffer, timeInfo, statusFlags);
- }
void open(std::string_view name) override;
void start() override;
@@ -252,11 +239,9 @@ struct PortCapture final : public BackendBase {
uint availableSamples() override;
PaStream *mStream{nullptr};
- PaStreamParameters mParams;
+ PaStreamParameters mParams{};
RingBufferPtr mRing{nullptr};
-
- DEF_NEWDEL(PortCapture)
};
PortCapture::~PortCapture()
@@ -271,7 +256,7 @@ PortCapture::~PortCapture()
int PortCapture::readCallback(const void *inputBuffer, void*, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept
{
- mRing->write(inputBuffer, framesPerBuffer);
+ std::ignore = mRing->write(inputBuffer, framesPerBuffer);
return 0;
}
@@ -290,7 +275,7 @@ void PortCapture::open(std::string_view name)
mRing = RingBuffer::Create(samples, frame_size, false);
- auto devidopt = ConfigValueInt(nullptr, "port", "capture");
+ auto devidopt = ConfigValueInt({}, "port", "capture");
if(devidopt && *devidopt >= 0) mParams.device = *devidopt;
else mParams.device = Pa_GetDefaultOutputDevice();
mParams.suggestedLatency = 0.0f;
@@ -320,8 +305,15 @@ void PortCapture::open(std::string_view name)
}
mParams.channelCount = static_cast<int>(mDevice->channelsFromFmt());
+ static constexpr auto readCallback = [](const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
+ const PaStreamCallbackFlags statusFlags, void *userData) noexcept
+ {
+ return static_cast<PortCapture*>(userData)->readCallback(inputBuffer, outputBuffer,
+ framesPerBuffer, timeInfo, statusFlags);
+ };
PaError err{Pa_OpenStream(&mStream, &mParams, nullptr, mDevice->Frequency,
- paFramesPerBufferUnspecified, paNoFlag, &PortCapture::readCallbackC, this)};
+ paFramesPerBufferUnspecified, paNoFlag, readCallback, this)};
if(err != paNoError)
throw al::backend_exception{al::backend_error::NoDevice, "Failed to open stream: %s",
Pa_GetErrorText(err)};
@@ -350,15 +342,13 @@ uint PortCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
void PortCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
} // namespace
bool PortBackendFactory::init()
{
- PaError err;
-
#ifdef HAVE_DYNLOAD
if(!pa_handle)
{
@@ -377,7 +367,7 @@ bool PortBackendFactory::init()
return false;
#define LOAD_FUNC(f) do { \
- p##f = al::bit_cast<decltype(p##f)>(GetSymbol(pa_handle, #f)); \
+ p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(pa_handle, #f)); \
if(p##f == nullptr) \
{ \
CloseLib(pa_handle); \
@@ -397,7 +387,8 @@ bool PortBackendFactory::init()
LOAD_FUNC(Pa_GetStreamInfo);
#undef LOAD_FUNC
- if((err=Pa_Initialize()) != paNoError)
+ const PaError err{Pa_Initialize()};
+ if(err != paNoError)
{
ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
CloseLib(pa_handle);
@@ -406,7 +397,8 @@ bool PortBackendFactory::init()
}
}
#else
- if((err=Pa_Initialize()) != paNoError)
+ const PaError err{Pa_Initialize()};
+ if(err != paNoError)
{
ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
return false;
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index bebc182d..e976fc27 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -28,12 +28,12 @@
#include <atomic>
#include <bitset>
#include <chrono>
+#include <cstdint>
+#include <cstdlib>
#include <cstring>
#include <limits>
#include <mutex>
#include <optional>
-#include <stdint.h>
-#include <stdlib.h>
#include <string>
#include <sys/types.h>
#include <utility>
@@ -320,11 +320,12 @@ public:
explicit operator bool() const noexcept { return mLoop != nullptr; }
+ [[nodiscard]]
auto start() const { return pa_threaded_mainloop_start(mLoop); }
auto stop() const { return pa_threaded_mainloop_stop(mLoop); }
- auto getApi() const { return pa_threaded_mainloop_get_api(mLoop); }
- auto getContext() const noexcept { return mContext; }
+ [[nodiscard]] auto getApi() const { return pa_threaded_mainloop_get_api(mLoop); }
+ [[nodiscard]] auto getContext() const noexcept { return mContext; }
auto lock() const { return pa_threaded_mainloop_lock(mLoop); }
auto unlock() const { return pa_threaded_mainloop_unlock(mLoop); }
@@ -509,8 +510,8 @@ void MainloopUniqueLock::connectContext()
pa_context_set_state_callback(mutex()->mContext, [](pa_context *ctx, void *pdata) noexcept
{ return static_cast<MainloopUniqueLock*>(pdata)->contextStateCallback(ctx); }, this);
- int err;
- if((err=pa_context_connect(mutex()->mContext, nullptr, pulse_ctx_flags, nullptr)) >= 0)
+ int err{pa_context_connect(mutex()->mContext, nullptr, pulse_ctx_flags, nullptr)};
+ if(err >= 0)
{
pa_context_state_t state;
while((state=pa_context_get_state(mutex()->mContext)) != PA_CONTEXT_READY)
@@ -657,14 +658,12 @@ struct PulsePlayback final : public BackendBase {
std::optional<std::string> mDeviceName{std::nullopt};
bool mIs51Rear{false};
- pa_buffer_attr mAttr;
- pa_sample_spec mSpec;
+ pa_buffer_attr mAttr{};
+ pa_sample_spec mSpec{};
pa_stream *mStream{nullptr};
uint mFrameSize{0u};
-
- DEF_NEWDEL(PulsePlayback)
};
PulsePlayback::~PulsePlayback()
@@ -753,9 +752,9 @@ void PulsePlayback::sinkInfoCallback(pa_context*, const pa_sink_info *info, int
else
{
mIs51Rear = false;
- char chanmap_str[PA_CHANNEL_MAP_SNPRINT_MAX]{};
- pa_channel_map_snprint(chanmap_str, sizeof(chanmap_str), &info->channel_map);
- WARN("Failed to find format for channel map:\n %s\n", chanmap_str);
+ std::array<char,PA_CHANNEL_MAP_SNPRINT_MAX> chanmap_str{};
+ pa_channel_map_snprint(chanmap_str.data(), chanmap_str.size(), &info->channel_map);
+ WARN("Failed to find format for channel map:\n %s\n", chanmap_str.data());
}
if(info->active_port)
@@ -784,7 +783,9 @@ void PulsePlayback::streamMovedCallback(pa_stream *stream) noexcept
void PulsePlayback::open(std::string_view name)
{
mMainloop = PulseMainloop::Create();
- mMainloop.start();
+ if(mMainloop.start() != 0)
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "Failed to start device mainloop"};
const char *pulse_name{nullptr};
const char *dev_name{nullptr};
@@ -807,7 +808,7 @@ void PulsePlayback::open(std::string_view name)
pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
PA_STREAM_FIX_CHANNELS};
- if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+ if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
flags |= PA_STREAM_DONT_MOVE;
pa_sample_spec spec{};
@@ -866,9 +867,9 @@ bool PulsePlayback::reset()
pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING |
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_EARLY_REQUESTS};
- if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+ if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
flags |= PA_STREAM_DONT_MOVE;
- if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "adjust-latency", false))
+ if(GetConfigValueBool(mDevice->DeviceName, "pulse", "adjust-latency", false))
{
/* ADJUST_LATENCY can't be specified with EARLY_REQUESTS, for some
* reason. So if the user wants to adjust the overall device latency,
@@ -877,7 +878,7 @@ bool PulsePlayback::reset()
flags &= ~PA_STREAM_EARLY_REQUESTS;
flags |= PA_STREAM_ADJUST_LATENCY;
}
- if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "fix-rate", false)
+ if(GetConfigValueBool(mDevice->DeviceName, "pulse", "fix-rate", false)
|| !mDevice->Flags.test(FrequencyRequest))
flags |= PA_STREAM_FIX_RATE;
@@ -967,8 +968,9 @@ bool PulsePlayback::reset()
const auto scale = static_cast<double>(mSpec.rate) / mDevice->Frequency;
const auto perlen = static_cast<uint>(clampd(scale*mDevice->UpdateSize + 0.5, 64.0,
8192.0));
- const auto buflen = static_cast<uint>(clampd(scale*mDevice->BufferSize + 0.5, perlen*2,
- std::numeric_limits<int>::max()/mFrameSize));
+ const auto bufmax = uint{std::numeric_limits<int>::max() / mFrameSize};
+ const auto buflen = static_cast<uint>(clampd(scale*mDevice->BufferSize + 0.5, perlen*2.0,
+ bufmax));
mAttr.maxlength = ~0u;
mAttr.tlength = buflen * mFrameSize;
@@ -1034,7 +1036,7 @@ ClockLatency PulsePlayback::getClockLatency()
{
MainloopUniqueLock plock{mMainloop};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
err = pa_stream_get_latency(mStream, &latency, &neg);
}
@@ -1087,8 +1089,6 @@ struct PulseCapture final : public BackendBase {
pa_sample_spec mSpec{};
pa_stream *mStream{nullptr};
-
- DEF_NEWDEL(PulseCapture)
};
PulseCapture::~PulseCapture()
@@ -1127,7 +1127,9 @@ void PulseCapture::open(std::string_view name)
if(!mMainloop)
{
mMainloop = PulseMainloop::Create();
- mMainloop.start();
+ if(mMainloop.start() != 0)
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "Failed to start device mainloop"};
}
const char *pulse_name{nullptr};
@@ -1214,7 +1216,7 @@ void PulseCapture::open(std::string_view name)
mAttr.fragsize = minu(samples, 50*mDevice->Frequency/1000) * frame_size;
pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY};
- if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+ if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
flags |= PA_STREAM_DONT_MOVE;
TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
@@ -1362,7 +1364,7 @@ ClockLatency PulseCapture::getClockLatency()
{
MainloopUniqueLock plock{mMainloop};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
err = pa_stream_get_latency(mStream, &latency, &neg);
}
@@ -1387,9 +1389,6 @@ bool PulseBackendFactory::init()
#ifdef HAVE_DYNLOAD
if(!pulse_handle)
{
- bool ret{true};
- std::string missing_funcs;
-
#ifdef _WIN32
#define PALIB "libpulse-0.dll"
#elif defined(__APPLE__) && defined(__MACH__)
@@ -1404,17 +1403,15 @@ bool PulseBackendFactory::init()
return false;
}
+ std::string missing_funcs;
#define LOAD_FUNC(x) do { \
- p##x = al::bit_cast<decltype(p##x)>(GetSymbol(pulse_handle, #x)); \
- if(!(p##x)) { \
- ret = false; \
- missing_funcs += "\n" #x; \
- } \
+ p##x = reinterpret_cast<decltype(p##x)>(GetSymbol(pulse_handle, #x)); \
+ if(!(p##x)) missing_funcs += "\n" #x; \
} while(0)
PULSE_FUNCS(LOAD_FUNC)
#undef LOAD_FUNC
- if(!ret)
+ if(!missing_funcs.empty())
{
WARN("Missing expected functions:%s\n", missing_funcs.c_str());
CloseLib(pulse_handle);
@@ -1425,14 +1422,18 @@ bool PulseBackendFactory::init()
#endif /* HAVE_DYNLOAD */
pulse_ctx_flags = PA_CONTEXT_NOFLAGS;
- if(!GetConfigValueBool(nullptr, "pulse", "spawn-server", false))
+ if(!GetConfigValueBool({}, "pulse", "spawn-server", false))
pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;
try {
if(!gGlobalMainloop)
{
gGlobalMainloop = PulseMainloop::Create();
- gGlobalMainloop.start();
+ if(gGlobalMainloop.start() != 0)
+ {
+ gGlobalMainloop = nullptr;
+ return false;
+ }
}
MainloopUniqueLock plock{gGlobalMainloop};
diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp
index f5ed4316..b69f17fd 100644
--- a/alc/backends/sdl2.cpp
+++ b/alc/backends/sdl2.cpp
@@ -26,6 +26,7 @@
#include <cstdlib>
#include <cstring>
#include <string>
+#include <string_view>
#include "almalloc.h"
#include "alnumeric.h"
@@ -46,7 +47,9 @@ namespace {
#define DEVNAME_PREFIX ""
#endif
-constexpr char defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
+constexpr auto getDevicePrefix() noexcept -> std::string_view { return DEVNAME_PREFIX; }
+constexpr auto getDefaultDeviceName() noexcept -> std::string_view
+{ return DEVNAME_PREFIX "Default Device"; }
struct Sdl2Backend final : public BackendBase {
Sdl2Backend(DeviceBase *device) noexcept : BackendBase{device} { }
@@ -66,8 +69,6 @@ struct Sdl2Backend final : public BackendBase {
DevFmtChannels mFmtChans{};
DevFmtType mFmtType{};
uint mUpdateSize{0u};
-
- DEF_NEWDEL(Sdl2Backend)
};
Sdl2Backend::~Sdl2Backend()
@@ -108,6 +109,7 @@ void Sdl2Backend::open(std::string_view name)
/* Passing nullptr to SDL_OpenAudioDevice opens a default, which isn't
* necessarily the first in the list.
*/
+ const auto defaultDeviceName = getDefaultDeviceName();
SDL_AudioDeviceID devid;
if(name.empty() || name == defaultDeviceName)
{
@@ -116,13 +118,13 @@ void Sdl2Backend::open(std::string_view name)
}
else
{
- const size_t prefix_len = strlen(DEVNAME_PREFIX);
- if(name.length() >= prefix_len && strncmp(name.data(), DEVNAME_PREFIX, prefix_len) == 0)
+ const auto namePrefix = getDevicePrefix();
+ if(name.size() >= namePrefix.size() && name.substr(0, namePrefix.size()) == namePrefix)
{
/* Copy the string_view to a string to ensure it's null terminated
* for this call.
*/
- const std::string devname{name.substr(prefix_len)};
+ const std::string devname{name.substr(namePrefix.size())};
devid = SDL_OpenAudioDevice(devname.c_str(), SDL_FALSE, &want, &have,
SDL_AUDIO_ALLOW_ANY_CHANGE);
}
@@ -217,13 +219,16 @@ std::string SDL2BackendFactory::probe(BackendType type)
int num_devices{SDL_GetNumAudioDevices(SDL_FALSE)};
/* Includes null char. */
- outnames.append(defaultDeviceName, sizeof(defaultDeviceName));
+ outnames += getDefaultDeviceName();
+ outnames += '\0';
for(int i{0};i < num_devices;++i)
{
- std::string name{DEVNAME_PREFIX};
- name += SDL_GetAudioDeviceName(i, SDL_FALSE);
- if(!name.empty())
- outnames.append(name.c_str(), name.length()+1);
+ outnames += getDevicePrefix();
+ if(const char *name = SDL_GetAudioDeviceName(i, SDL_FALSE))
+ outnames += name;
+ else
+ outnames += "Unknown Device Name #"+std::to_string(i);
+ outnames += '\0';
}
return outnames;
}
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index d54c337b..ce3de366 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -23,11 +23,11 @@
#include "sndio.h"
#include <cinttypes>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <functional>
#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <thread>
#include <vector>
@@ -43,10 +43,11 @@
namespace {
-static const char sndio_device[] = "SndIO Default";
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
+constexpr char sndio_device[] = "SndIO Default";
struct SioPar : public sio_par {
- SioPar() { sio_initpar(this); }
+ SioPar() : sio_par{} { sio_initpar(this); }
void clear() { sio_initpar(this); }
};
@@ -69,8 +70,6 @@ struct SndioPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(SndioPlayback)
};
SndioPlayback::~SndioPlayback()
@@ -136,72 +135,75 @@ bool SndioPlayback::reset()
SioPar par;
auto tryfmt = mDevice->FmtType;
-retry_params:
- switch(tryfmt)
+ while(true)
{
- case DevFmtByte:
- par.bits = 8;
- par.sig = 1;
- break;
- case DevFmtUByte:
- par.bits = 8;
- par.sig = 0;
- break;
- case DevFmtShort:
- par.bits = 16;
- par.sig = 1;
- break;
- case DevFmtUShort:
- par.bits = 16;
- par.sig = 0;
- break;
- case DevFmtFloat:
- case DevFmtInt:
- par.bits = 32;
- par.sig = 1;
- break;
- case DevFmtUInt:
- par.bits = 32;
- par.sig = 0;
- break;
- }
- par.bps = SIO_BPS(par.bits);
- par.le = SIO_LE_NATIVE;
- par.msb = 1;
-
- par.rate = mDevice->Frequency;
- par.pchan = mDevice->channelsFromFmt();
-
- par.round = mDevice->UpdateSize;
- par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
- if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
+ switch(tryfmt)
+ {
+ case DevFmtByte:
+ par.bits = 8;
+ par.sig = 1;
+ break;
+ case DevFmtUByte:
+ par.bits = 8;
+ par.sig = 0;
+ break;
+ case DevFmtShort:
+ par.bits = 16;
+ par.sig = 1;
+ break;
+ case DevFmtUShort:
+ par.bits = 16;
+ par.sig = 0;
+ break;
+ case DevFmtFloat:
+ case DevFmtInt:
+ par.bits = 32;
+ par.sig = 1;
+ break;
+ case DevFmtUInt:
+ par.bits = 32;
+ par.sig = 0;
+ break;
+ }
+ par.bps = SIO_BPS(par.bits);
+ par.le = SIO_LE_NATIVE;
+ par.msb = 1;
+
+ par.rate = mDevice->Frequency;
+ par.pchan = mDevice->channelsFromFmt();
+
+ par.round = mDevice->UpdateSize;
+ par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
+ if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
+
+ try {
+ if(!sio_setpar(mSndHandle, &par))
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "Failed to set device parameters"};
+
+ par.clear();
+ if(!sio_getpar(mSndHandle, &par))
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "Failed to get device parameters"};
+
+ if(par.bps > 1 && par.le != SIO_LE_NATIVE)
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "%s-endian samples not supported", par.le ? "Little" : "Big"};
+ if(par.bits < par.bps*8 && !par.msb)
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "MSB-padded samples not supported (%u of %u bits)", par.bits, par.bps*8};
+ if(par.pchan < 1)
+ throw al::backend_exception{al::backend_error::DeviceError,
+ "No playback channels on device"};
- try {
- if(!sio_setpar(mSndHandle, &par))
- throw al::backend_exception{al::backend_error::DeviceError,
- "Failed to set device parameters"};
-
- par.clear();
- if(!sio_getpar(mSndHandle, &par))
- throw al::backend_exception{al::backend_error::DeviceError,
- "Failed to get device parameters"};
-
- if(par.bps > 1 && par.le != SIO_LE_NATIVE)
- throw al::backend_exception{al::backend_error::DeviceError,
- "%s-endian samples not supported", par.le ? "Little" : "Big"};
- if(par.bits < par.bps*8 && !par.msb)
- throw al::backend_exception{al::backend_error::DeviceError,
- "MSB-padded samples not supported (%u of %u bits)", par.bits, par.bps*8};
- if(par.pchan < 1)
- throw al::backend_exception{al::backend_error::DeviceError,
- "No playback channels on device"};
- }
- catch(al::backend_exception &e) {
- if(tryfmt == DevFmtShort)
- throw;
- par.clear();
- tryfmt = DevFmtShort;
- goto retry_params;
+ break;
+ }
+ catch(al::backend_exception &e) {
+ if(tryfmt == DevFmtShort)
+ throw;
+ par.clear();
+ tryfmt = DevFmtShort;
+ }
}
if(par.bps == 1)
@@ -229,7 +231,7 @@ retry_params:
mDevice->UpdateSize = par.round;
mDevice->BufferSize = par.bufsz + par.round;
- mBuffer.resize(mDevice->UpdateSize * par.pchan*par.bps);
+ mBuffer.resize(size_t{mDevice->UpdateSize} * par.pchan*par.bps);
if(par.sig == 1)
std::fill(mBuffer.begin(), mBuffer.end(), std::byte{});
else if(par.bits == 8)
@@ -292,8 +294,6 @@ struct SndioCapture final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(SndioCapture)
};
SndioCapture::~SndioCapture()
@@ -317,19 +317,19 @@ int SndioCapture::recordProc()
return 1;
}
- auto fds = std::make_unique<pollfd[]>(static_cast<uint>(nfds_pre));
+ auto fds = std::vector<pollfd>(static_cast<uint>(nfds_pre));
while(!mKillNow.load(std::memory_order_acquire)
&& mDevice->Connected.load(std::memory_order_acquire))
{
/* Wait until there's some samples to read. */
- const int nfds{sio_pollfd(mSndHandle, fds.get(), POLLIN)};
+ const int nfds{sio_pollfd(mSndHandle, fds.data(), POLLIN)};
if(nfds <= 0)
{
mDevice->handleDisconnect("Failed to get polling fds: %d", nfds);
break;
}
- int pollres{::poll(fds.get(), static_cast<uint>(nfds), 2000)};
+ int pollres{::poll(fds.data(), fds.size(), 2000)};
if(pollres < 0)
{
if(errno == EINTR) continue;
@@ -339,7 +339,7 @@ int SndioCapture::recordProc()
if(pollres == 0)
continue;
- const int revents{sio_revents(mSndHandle, fds.get())};
+ const int revents{sio_revents(mSndHandle, fds.data())};
if((revents&POLLHUP))
{
mDevice->handleDisconnect("Got POLLHUP from poll events");
@@ -373,8 +373,8 @@ int SndioCapture::recordProc()
if(buffer.empty())
{
/* Got samples to read, but no place to store it. Drop it. */
- static char junk[4096];
- sio_read(mSndHandle, junk, sizeof(junk) - (sizeof(junk)%frameSize));
+ static std::array<char,4096> junk;
+ sio_read(mSndHandle, junk.data(), junk.size() - (junk.size()%frameSize));
}
}
@@ -461,7 +461,7 @@ void SndioCapture::open(std::string_view name)
DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
mDevice->Frequency, par.sig?'s':'u', par.bps*8, par.rchan, par.rate};
- mRing = RingBuffer::Create(mDevice->BufferSize, par.bps*par.rchan, false);
+ mRing = RingBuffer::Create(mDevice->BufferSize, size_t{par.bps}*par.rchan, false);
mDevice->BufferSize = static_cast<uint>(mRing->writeSpace());
mDevice->UpdateSize = par.round;
@@ -497,7 +497,7 @@ void SndioCapture::stop()
}
void SndioCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
uint SndioCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/backends/solaris.cpp b/alc/backends/solaris.cpp
index 38f9db19..c7387284 100644
--- a/alc/backends/solaris.cpp
+++ b/alc/backends/solaris.cpp
@@ -51,6 +51,7 @@
namespace {
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char solaris_device[] = "Solaris Default";
std::string solaris_driver{"/dev/audio"};
@@ -74,8 +75,6 @@ struct SolarisBackend final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(SolarisBackend)
};
SolarisBackend::~SolarisBackend()
@@ -91,7 +90,7 @@ int SolarisBackend::mixerProc()
althrd_setname(MIXER_THREAD_NAME);
const size_t frame_step{mDevice->channelsFromFmt()};
- const uint frame_size{mDevice->frameSizeFromFmt()};
+ const size_t frame_size{mDevice->frameSizeFromFmt()};
while(!mKillNow.load(std::memory_order_acquire)
&& mDevice->Connected.load(std::memory_order_acquire))
@@ -115,12 +114,12 @@ int SolarisBackend::mixerProc()
continue;
}
- std::byte *write_ptr{mBuffer.data()};
- size_t to_write{mBuffer.size()};
- mDevice->renderSamples(write_ptr, static_cast<uint>(to_write/frame_size), frame_step);
- while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
+ al::span<std::byte> buffer{mBuffer};
+ mDevice->renderSamples(buffer.data(), static_cast<uint>(buffer.size()/frame_size),
+ frame_step);
+ while(!buffer.empty() && !mKillNow.load(std::memory_order_acquire))
{
- ssize_t wrote{write(mFd, write_ptr, to_write)};
+ ssize_t wrote{write(mFd, buffer.data(), buffer.size())};
if(wrote < 0)
{
if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
@@ -130,8 +129,7 @@ int SolarisBackend::mixerProc()
break;
}
- to_write -= static_cast<size_t>(wrote);
- write_ptr += wrote;
+ buffer = buffer.subspan(static_cast<size_t>(wrote));
}
}
@@ -267,7 +265,7 @@ BackendFactory &SolarisBackendFactory::getFactory()
bool SolarisBackendFactory::init()
{
- if(auto devopt = ConfigValueStr(nullptr, "solaris", "device"))
+ if(auto devopt = ConfigValueStr({}, "solaris", "device"))
solaris_driver = std::move(*devopt);
return true;
}
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index 3ee98457..4fcae59c 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -25,8 +25,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <stdlib.h>
-#include <stdio.h>
+#include <cstdio>
+#include <cstdlib>
#include <memory.h>
#include <wtypes.h>
@@ -171,7 +171,7 @@ constexpr AudioObjectType ChannelMask_X714{AudioObjectType_FrontLeft | AudioObje
| AudioObjectType_TopFrontLeft | AudioObjectType_TopFrontRight | AudioObjectType_TopBackLeft
| AudioObjectType_TopBackRight};
-
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char DevNameHead[] = "OpenAL Soft on ";
constexpr size_t DevNameHeadLen{std::size(DevNameHead) - 1};
@@ -201,16 +201,16 @@ constexpr uint RefTime2Samples(const ReferenceTime &val, T srate) noexcept
class GuidPrinter {
- char mMsg[64];
+ std::array<char,64> mMsg;
public:
GuidPrinter(const GUID &guid)
{
- std::snprintf(mMsg, std::size(mMsg), "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ std::snprintf(mMsg.data(), mMsg.size(), "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
DWORD{guid.Data1}, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2],
guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}
- const char *c_str() const { return mMsg; }
+ [[nodiscard]] auto c_str() const -> const char* { return mMsg.data(); }
};
struct PropVariant {
@@ -270,13 +270,13 @@ private:
struct DeviceListLock : public std::unique_lock<DeviceList> {
using std::unique_lock<DeviceList>::unique_lock;
- auto& getPlaybackList() const noexcept { return mutex()->mPlayback; }
- auto& getCaptureList() const noexcept { return mutex()->mCapture; }
+ [[nodiscard]] auto& getPlaybackList() const noexcept { return mutex()->mPlayback; }
+ [[nodiscard]] auto& getCaptureList() const noexcept { return mutex()->mCapture; }
void setPlaybackDefaultId(std::wstring_view devid) const { mutex()->mPlaybackDefaultId = devid; }
- std::wstring_view getPlaybackDefaultId() const noexcept { return mutex()->mPlaybackDefaultId; }
+ [[nodiscard]] auto getPlaybackDefaultId() const noexcept -> std::wstring_view { return mutex()->mPlaybackDefaultId; }
void setCaptureDefaultId(std::wstring_view devid) const { mutex()->mCaptureDefaultId = devid; }
- std::wstring_view getCaptureDefaultId() const noexcept { return mutex()->mCaptureDefaultId; }
+ [[nodiscard]] auto getCaptureDefaultId() const noexcept -> std::wstring_view { return mutex()->mCaptureDefaultId; }
};
DeviceList gDeviceList;
@@ -302,8 +302,10 @@ using DeviceHandle = ComPtr<IMMDevice>;
using NameGUIDPair = std::pair<std::string,std::string>;
static NameGUIDPair GetDeviceNameAndGuid(const DeviceHandle &device)
{
+ /* NOLINTBEGIN(*-avoid-c-arrays) */
static constexpr char UnknownName[]{"Unknown Device Name"};
static constexpr char UnknownGuid[]{"Unknown Device GUID"};
+ /* NOLINTEND(*-avoid-c-arrays) */
#if !defined(ALSOFT_UWP)
std::string name, guid;
@@ -384,9 +386,9 @@ struct DeviceHelper final : public IActivateAudioInterfaceCompletionHandler
struct DeviceHelper final : private IMMNotificationClient
#endif
{
+#if defined(ALSOFT_UWP)
DeviceHelper()
{
-#if defined(ALSOFT_UWP)
/* TODO: UWP also needs to watch for device added/removed events and
* dynamically add/remove devices from the lists.
*/
@@ -411,8 +413,10 @@ struct DeviceHelper final : private IMMNotificationClient
msg);
}
});
-#endif
}
+#else
+ DeviceHelper() = default;
+#endif
~DeviceHelper()
{
#if defined(ALSOFT_UWP)
@@ -1071,7 +1075,7 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy {
HANDLE mNotifyEvent{nullptr};
UINT32 mOrigBufferSize{}, mOrigUpdateSize{};
- std::unique_ptr<char[]> mResampleBuffer{};
+ std::vector<char> mResampleBuffer{};
uint mBufferFilled{0};
SampleConverterPtr mResampler;
@@ -1082,8 +1086,6 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(WasapiPlayback)
};
WasapiPlayback::~WasapiPlayback()
@@ -1151,9 +1153,9 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
{
if(mBufferFilled == 0)
{
- mDevice->renderSamples(mResampleBuffer.get(), mDevice->UpdateSize,
+ mDevice->renderSamples(mResampleBuffer.data(), mDevice->UpdateSize,
mFormat.Format.nChannels);
- resbufferptr = mResampleBuffer.get();
+ resbufferptr = mResampleBuffer.data();
mBufferFilled = mDevice->UpdateSize;
}
@@ -1249,7 +1251,7 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
tmpbuffers.resize(buffers.size());
resbuffers.resize(buffers.size());
for(size_t i{0};i < tmpbuffers.size();++i)
- resbuffers[i] = reinterpret_cast<float*>(mResampleBuffer.get()) +
+ resbuffers[i] = reinterpret_cast<float*>(mResampleBuffer.data()) +
mDevice->UpdateSize*i;
}
}
@@ -1496,7 +1498,7 @@ void WasapiPlayback::prepareFormat(WAVEFORMATEXTENSIBLE &OutputType)
void WasapiPlayback::finalizeFormat(WAVEFORMATEXTENSIBLE &OutputType)
{
- if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "allow-resampler", true))
+ if(!GetConfigValueBool(mDevice->DeviceName, "wasapi", "allow-resampler", true))
mDevice->Frequency = OutputType.Format.nSamplesPerSec;
else
mDevice->Frequency = minu(mDevice->Frequency, OutputType.Format.nSamplesPerSec);
@@ -1610,7 +1612,7 @@ bool WasapiPlayback::reset()
HRESULT WasapiPlayback::resetProxy()
{
- if(GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "spatial-api", false))
+ if(GetConfigValueBool(mDevice->DeviceName, "wasapi", "spatial-api", false))
{
auto &audio = mAudio.emplace<SpatialDevice>();
HRESULT hr{sDeviceHelper->activateAudioClient(mMMDev, __uuidof(ISpatialAudioClient),
@@ -1775,7 +1777,7 @@ HRESULT WasapiPlayback::resetProxy()
mDevice->Flags.reset(DirectEar).set(Virtualization);
if(streamParams.StaticObjectTypeMask == ChannelMask_Stereo)
mDevice->FmtChans = DevFmtStereo;
- if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "allow-resampler", true))
+ if(!GetConfigValueBool(mDevice->DeviceName, "wasapi", "allow-resampler", true))
mDevice->Frequency = OutputType.Format.nSamplesPerSec;
else
mDevice->Frequency = minu(mDevice->Frequency, OutputType.Format.nSamplesPerSec);
@@ -1819,7 +1821,8 @@ HRESULT WasapiPlayback::resetProxy()
mDevice->BufferSize = mDevice->UpdateSize*2;
mResampler = nullptr;
- mResampleBuffer = nullptr;
+ mResampleBuffer.clear();
+ mResampleBuffer.shrink_to_fit();
mBufferFilled = 0;
if(mDevice->Frequency != mFormat.Format.nSamplesPerSec)
{
@@ -1828,7 +1831,7 @@ HRESULT WasapiPlayback::resetProxy()
mResampler = SampleConverter::Create(mDevice->FmtType, mDevice->FmtType,
channelCount, mDevice->Frequency, mFormat.Format.nSamplesPerSec,
Resampler::FastBSinc24);
- mResampleBuffer = std::make_unique<char[]>(size_t{mDevice->UpdateSize} * channelCount *
+ mResampleBuffer.resize(size_t{mDevice->UpdateSize} * channelCount *
mFormat.Format.wBitsPerSample / 8);
TRACE("Created converter for %s/%s format, dst: %luhz (%u), src: %uhz (%u)\n",
@@ -1950,15 +1953,16 @@ no_spatial:
mDevice->BufferSize/2);
mResampler = nullptr;
- mResampleBuffer = nullptr;
+ mResampleBuffer.clear();
+ mResampleBuffer.shrink_to_fit();
mBufferFilled = 0;
if(mDevice->Frequency != mFormat.Format.nSamplesPerSec)
{
mResampler = SampleConverter::Create(mDevice->FmtType, mDevice->FmtType,
mFormat.Format.nChannels, mDevice->Frequency, mFormat.Format.nSamplesPerSec,
Resampler::FastBSinc24);
- mResampleBuffer = std::make_unique<char[]>(size_t{mDevice->UpdateSize} *
- mFormat.Format.nChannels * mFormat.Format.wBitsPerSample / 8);
+ mResampleBuffer.resize(size_t{mDevice->UpdateSize} * mFormat.Format.nChannels *
+ mFormat.Format.wBitsPerSample / 8);
TRACE("Created converter for %s/%s format, dst: %luhz (%u), src: %uhz (%u)\n",
DevFmtChannelsString(mDevice->FmtChans), DevFmtTypeString(mDevice->FmtType),
@@ -2072,7 +2076,7 @@ ClockLatency WasapiPlayback::getClockLatency()
ClockLatency ret;
std::lock_guard<std::mutex> _{mMutex};
- ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.ClockTime = mDevice->getClockTime();
ret.Latency = seconds{mPadding.load(std::memory_order_relaxed)};
ret.Latency /= mFormat.Format.nSamplesPerSec;
if(mResampler)
@@ -2117,8 +2121,6 @@ struct WasapiCapture final : public BackendBase, WasapiProxy {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(WasapiCapture)
};
WasapiCapture::~WasapiCapture()
@@ -2651,7 +2653,7 @@ void WasapiCapture::stopProxy()
void WasapiCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
uint WasapiCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index 794d5cb8..985bb539 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -55,38 +55,44 @@ using std::chrono::nanoseconds;
using ubyte = unsigned char;
using ushort = unsigned short;
+struct FileDeleter {
+ void operator()(gsl::owner<FILE*> f) { fclose(f); }
+};
+using FilePtr = std::unique_ptr<FILE,FileDeleter>;
+
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char waveDevice[] = "Wave File Writer";
-constexpr ubyte SUBTYPE_PCM[]{
+constexpr std::array<ubyte,16> SUBTYPE_PCM{{
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71
-};
-constexpr ubyte SUBTYPE_FLOAT[]{
+}};
+constexpr std::array<ubyte,16> SUBTYPE_FLOAT{{
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71
-};
+}};
-constexpr ubyte SUBTYPE_BFORMAT_PCM[]{
+constexpr std::array<ubyte,16> SUBTYPE_BFORMAT_PCM{{
0x01, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
0xca, 0x00, 0x00, 0x00
-};
+}};
-constexpr ubyte SUBTYPE_BFORMAT_FLOAT[]{
+constexpr std::array<ubyte,16> SUBTYPE_BFORMAT_FLOAT{{
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
0xca, 0x00, 0x00, 0x00
-};
+}};
void fwrite16le(ushort val, FILE *f)
{
- ubyte data[2]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff) };
- fwrite(data, 1, 2, f);
+ std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff)};
+ fwrite(data.data(), 1, data.size(), f);
}
void fwrite32le(uint val, FILE *f)
{
- ubyte data[4]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
- static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff) };
- fwrite(data, 1, 4, f);
+ std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
+ static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff)};
+ fwrite(data.data(), 1, data.size(), f);
}
@@ -101,23 +107,16 @@ struct WaveBackend final : public BackendBase {
void start() override;
void stop() override;
- FILE *mFile{nullptr};
+ FilePtr mFile{nullptr};
long mDataStart{-1};
std::vector<std::byte> mBuffer;
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(WaveBackend)
};
-WaveBackend::~WaveBackend()
-{
- if(mFile)
- fclose(mFile);
- mFile = nullptr;
-}
+WaveBackend::~WaveBackend() = default;
int WaveBackend::mixerProc()
{
@@ -169,8 +168,8 @@ int WaveBackend::mixerProc()
}
}
- const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile)};
- if(fs < mDevice->UpdateSize || ferror(mFile))
+ const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile.get())};
+ if(fs < mDevice->UpdateSize || ferror(mFile.get()))
{
ERR("Error writing to file\n");
mDevice->handleDisconnect("Failed to write playback samples");
@@ -196,7 +195,7 @@ int WaveBackend::mixerProc()
void WaveBackend::open(std::string_view name)
{
- auto fname = ConfigValueStr(nullptr, "wave", "file");
+ auto fname = ConfigValueStr({}, "wave", "file");
if(!fname) throw al::backend_exception{al::backend_error::NoDevice,
"No wave output filename"};
@@ -212,10 +211,10 @@ void WaveBackend::open(std::string_view name)
#ifdef _WIN32
{
std::wstring wname{utf8_to_wstr(fname.value())};
- mFile = _wfopen(wname.c_str(), L"wb");
+ mFile = FilePtr{_wfopen(wname.c_str(), L"wb")};
}
#else
- mFile = fopen(fname->c_str(), "wb");
+ mFile = FilePtr{fopen(fname->c_str(), "wb")};
#endif
if(!mFile)
throw al::backend_exception{al::backend_error::DeviceError, "Could not open file '%s': %s",
@@ -228,12 +227,11 @@ bool WaveBackend::reset()
{
uint channels{0}, bytes{0}, chanmask{0};
bool isbformat{false};
- size_t val;
- fseek(mFile, 0, SEEK_SET);
- clearerr(mFile);
+ fseek(mFile.get(), 0, SEEK_SET);
+ clearerr(mFile.get());
- if(GetConfigValueBool(nullptr, "wave", "bformat", false))
+ if(GetConfigValueBool({}, "wave", "bformat", false))
{
mDevice->FmtChans = DevFmtAmbi3D;
mDevice->mAmbiOrder = 1;
@@ -282,49 +280,48 @@ bool WaveBackend::reset()
bytes = mDevice->bytesFromFmt();
channels = mDevice->channelsFromFmt();
- rewind(mFile);
+ rewind(mFile.get());
- fputs("RIFF", mFile);
- fwrite32le(0xFFFFFFFF, mFile); // 'RIFF' header len; filled in at close
+ fputs("RIFF", mFile.get());
+ fwrite32le(0xFFFFFFFF, mFile.get()); // 'RIFF' header len; filled in at close
- fputs("WAVE", mFile);
+ fputs("WAVE", mFile.get());
- fputs("fmt ", mFile);
- fwrite32le(40, mFile); // 'fmt ' header len; 40 bytes for EXTENSIBLE
+ fputs("fmt ", mFile.get());
+ fwrite32le(40, mFile.get()); // 'fmt ' header len; 40 bytes for EXTENSIBLE
// 16-bit val, format type id (extensible: 0xFFFE)
- fwrite16le(0xFFFE, mFile);
+ fwrite16le(0xFFFE, mFile.get());
// 16-bit val, channel count
- fwrite16le(static_cast<ushort>(channels), mFile);
+ fwrite16le(static_cast<ushort>(channels), mFile.get());
// 32-bit val, frequency
- fwrite32le(mDevice->Frequency, mFile);
+ fwrite32le(mDevice->Frequency, mFile.get());
// 32-bit val, bytes per second
- fwrite32le(mDevice->Frequency * channels * bytes, mFile);
+ fwrite32le(mDevice->Frequency * channels * bytes, mFile.get());
// 16-bit val, frame size
- fwrite16le(static_cast<ushort>(channels * bytes), mFile);
+ fwrite16le(static_cast<ushort>(channels * bytes), mFile.get());
// 16-bit val, bits per sample
- fwrite16le(static_cast<ushort>(bytes * 8), mFile);
+ fwrite16le(static_cast<ushort>(bytes * 8), mFile.get());
// 16-bit val, extra byte count
- fwrite16le(22, mFile);
+ fwrite16le(22, mFile.get());
// 16-bit val, valid bits per sample
- fwrite16le(static_cast<ushort>(bytes * 8), mFile);
+ fwrite16le(static_cast<ushort>(bytes * 8), mFile.get());
// 32-bit val, channel mask
- fwrite32le(chanmask, mFile);
+ fwrite32le(chanmask, mFile.get());
// 16 byte GUID, sub-type format
- val = fwrite((mDevice->FmtType == DevFmtFloat) ?
- (isbformat ? SUBTYPE_BFORMAT_FLOAT : SUBTYPE_FLOAT) :
- (isbformat ? SUBTYPE_BFORMAT_PCM : SUBTYPE_PCM), 1, 16, mFile);
- (void)val;
+ std::ignore = fwrite((mDevice->FmtType == DevFmtFloat) ?
+ (isbformat ? SUBTYPE_BFORMAT_FLOAT.data() : SUBTYPE_FLOAT.data()) :
+ (isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile.get());
- fputs("data", mFile);
- fwrite32le(0xFFFFFFFF, mFile); // 'data' header len; filled in at close
+ fputs("data", mFile.get());
+ fwrite32le(0xFFFFFFFF, mFile.get()); // 'data' header len; filled in at close
- if(ferror(mFile))
+ if(ferror(mFile.get()))
{
ERR("Error writing header: %s\n", strerror(errno));
return false;
}
- mDataStart = ftell(mFile);
+ mDataStart = ftell(mFile.get());
setDefaultWFXChannelOrder();
@@ -336,7 +333,7 @@ bool WaveBackend::reset()
void WaveBackend::start()
{
- if(mDataStart > 0 && fseek(mFile, 0, SEEK_END) != 0)
+ if(mDataStart > 0 && fseek(mFile.get(), 0, SEEK_END) != 0)
WARN("Failed to seek on output file\n");
try {
mKillNow.store(false, std::memory_order_release);
@@ -356,14 +353,14 @@ void WaveBackend::stop()
if(mDataStart > 0)
{
- long size{ftell(mFile)};
+ long size{ftell(mFile.get())};
if(size > 0)
{
long dataLen{size - mDataStart};
- if(fseek(mFile, 4, SEEK_SET) == 0)
- fwrite32le(static_cast<uint>(size-8), mFile); // 'WAVE' header len
- if(fseek(mFile, mDataStart-4, SEEK_SET) == 0)
- fwrite32le(static_cast<uint>(dataLen), mFile); // 'data' header len
+ if(fseek(mFile.get(), 4, SEEK_SET) == 0)
+ fwrite32le(static_cast<uint>(size-8), mFile.get()); // 'WAVE' header len
+ if(fseek(mFile.get(), mDataStart-4, SEEK_SET) == 0)
+ fwrite32le(static_cast<uint>(dataLen), mFile.get()); // 'data' header len
}
}
}
diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp
index f0fb0a1c..e593defb 100644
--- a/alc/backends/winmm.cpp
+++ b/alc/backends/winmm.cpp
@@ -22,8 +22,8 @@
#include "winmm.h"
-#include <stdlib.h>
-#include <stdio.h>
+#include <cstdlib>
+#include <cstdio>
#include <memory.h>
#include <windows.h>
@@ -46,6 +46,7 @@
#include "core/logging.h"
#include "ringbuffer.h"
#include "strutils.h"
+#include "vector.h"
#ifndef WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
@@ -62,7 +63,7 @@ std::vector<std::string> CaptureDevices;
bool checkName(const std::vector<std::string> &list, const std::string &name)
{ return std::find(list.cbegin(), list.cend(), name) != list.cend(); }
-void ProbePlaybackDevices(void)
+void ProbePlaybackDevices()
{
PlaybackDevices.clear();
@@ -93,7 +94,7 @@ void ProbePlaybackDevices(void)
}
}
-void ProbeCaptureDevices(void)
+void ProbeCaptureDevices()
{
CaptureDevices.clear();
@@ -144,6 +145,7 @@ struct WinMMPlayback final : public BackendBase {
al::semaphore mSem;
uint mIdx{0u};
std::array<WAVEHDR,4> mWaveBuffer{};
+ al::vector<char,16> mBuffer;
HWAVEOUT mOutHdl{nullptr};
@@ -151,8 +153,6 @@ struct WinMMPlayback final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(WinMMPlayback)
};
WinMMPlayback::~WinMMPlayback()
@@ -160,9 +160,6 @@ WinMMPlayback::~WinMMPlayback()
if(mOutHdl)
waveOutClose(mOutHdl);
mOutHdl = nullptr;
-
- al_free(mWaveBuffer[0].lpData);
- std::fill(mWaveBuffer.begin(), mWaveBuffer.end(), WAVEHDR{});
}
/* WinMMPlayback::waveOutProc
@@ -313,11 +310,11 @@ bool WinMMPlayback::reset()
}
setDefaultWFXChannelOrder();
- uint BufferSize{mDevice->UpdateSize * mFormat.nChannels * mDevice->bytesFromFmt()};
+ const uint BufferSize{mDevice->UpdateSize * mFormat.nChannels * mDevice->bytesFromFmt()};
- al_free(mWaveBuffer[0].lpData);
+ decltype(mBuffer)(BufferSize*mWaveBuffer.size()).swap(mBuffer);
mWaveBuffer[0] = WAVEHDR{};
- mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16, BufferSize * mWaveBuffer.size()));
+ mWaveBuffer[0].lpData = mBuffer.data();
mWaveBuffer[0].dwBufferLength = BufferSize;
for(size_t i{1};i < mWaveBuffer.size();i++)
{
@@ -380,6 +377,7 @@ struct WinMMCapture final : public BackendBase {
al::semaphore mSem;
uint mIdx{0};
std::array<WAVEHDR,4> mWaveBuffer{};
+ al::vector<char,16> mBuffer;
HWAVEIN mInHdl{nullptr};
@@ -389,8 +387,6 @@ struct WinMMCapture final : public BackendBase {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-
- DEF_NEWDEL(WinMMCapture)
};
WinMMCapture::~WinMMCapture()
@@ -399,9 +395,6 @@ WinMMCapture::~WinMMCapture()
if(mInHdl)
waveInClose(mInHdl);
mInHdl = nullptr;
-
- al_free(mWaveBuffer[0].lpData);
- std::fill(mWaveBuffer.begin(), mWaveBuffer.end(), WAVEHDR{});
}
/* WinMMCapture::waveInProc
@@ -435,7 +428,8 @@ int WinMMCapture::captureProc()
WAVEHDR &waveHdr = mWaveBuffer[widx];
widx = (widx+1) % mWaveBuffer.size();
- mRing->write(waveHdr.lpData, waveHdr.dwBytesRecorded / mFormat.nBlockAlign);
+ std::ignore = mRing->write(waveHdr.lpData,
+ waveHdr.dwBytesRecorded / mFormat.nBlockAlign);
mReadable.fetch_sub(1, std::memory_order_acq_rel);
waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR));
} while(--todo);
@@ -519,9 +513,9 @@ void WinMMCapture::open(std::string_view name)
mRing = RingBuffer::Create(CapturedDataSize, mFormat.nBlockAlign, false);
- al_free(mWaveBuffer[0].lpData);
+ decltype(mBuffer)(BufferSize*mWaveBuffer.size()).swap(mBuffer);
mWaveBuffer[0] = WAVEHDR{};
- mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16, BufferSize * mWaveBuffer.size()));
+ mWaveBuffer[0].lpData = mBuffer.data();
mWaveBuffer[0].dwBufferLength = BufferSize;
for(size_t i{1};i < mWaveBuffer.size();++i)
{
@@ -573,7 +567,7 @@ void WinMMCapture::stop()
}
void WinMMCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
uint WinMMCapture::availableSamples()
{ return static_cast<uint>(mRing->readSpace()); }