aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-06-12 14:15:06 -0700
committerChris Robinson <[email protected]>2021-06-12 14:19:55 -0700
commit76a9fdae75f3200aef81c69f3e901c9951d05616 (patch)
treed4b852549ef3cd21826217e5234660fad50f7309 /alc/backends
parent7e3247832745e4fa30803e69a2d6069960110344 (diff)
Use a unique_ptr to auto-free the jack ports list
Diffstat (limited to 'alc/backends')
-rw-r--r--alc/backends/jack.cpp44
1 files changed, 24 insertions, 20 deletions
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index 079de441..9ab0a639 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -99,6 +99,8 @@ decltype(jack_error_callback) * pjack_error_callback;
#endif
+constexpr char JackDefaultAudioType[] = JACK_DEFAULT_AUDIO_TYPE;
+
jack_options_t ClientOptions = JackNullOption;
bool jack_load()
@@ -150,6 +152,11 @@ bool jack_load()
}
+struct JackDeleter {
+ void operator()(void *ptr) { jack_free(ptr); }
+};
+using JackPortsPtr = std::unique_ptr<const char*[],JackDeleter>;
+
struct DeviceEntry {
std::string mName;
std::string mPattern;
@@ -162,8 +169,7 @@ void EnumerateDevices(jack_client_t *client, al::vector<DeviceEntry> &list)
{
std::remove_reference_t<decltype(list)>{}.swap(list);
- const char **ports{jack_get_ports(client, nullptr, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput)};
- if(ports)
+ if(JackPortsPtr ports{jack_get_ports(client, nullptr, JackDefaultAudioType, JackPortIsInput)})
{
for(size_t i{0};ports[i];++i)
{
@@ -193,11 +199,9 @@ void EnumerateDevices(jack_client_t *client, al::vector<DeviceEntry> &list)
WARN("No device names found in available ports, adding a generic name.\n");
list.emplace_back(DeviceEntry{"JACK", ""});
}
- jack_free(ports);
}
- auto listopt = ConfigValueStr(nullptr, "jack", "custom-devices");
- if(listopt)
+ if(auto listopt = ConfigValueStr(nullptr, "jack", "custom-devices"))
{
for(size_t strpos{0};strpos < listopt->size();)
{
@@ -525,18 +529,20 @@ bool JackPlayback::reset()
/* Force 32-bit float output. */
mDevice->FmtType = DevFmtFloat;
+ int port_num{0};
auto ports_end = mPort.begin() + mDevice->channelsFromFmt();
- auto bad_port = std::find_if_not(mPort.begin(), ports_end,
- [this](jack_port_t *&port) -> bool
- {
- std::string name{"channel_" + std::to_string(&port - &mPort[0] + 1)};
- port = jack_port_register(mClient, name.c_str(), JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput | JackPortIsTerminal, 0);
- return port != nullptr;
- });
+ auto bad_port = mPort.begin();
+ while(bad_port != ports_end)
+ {
+ std::string name{"channel_" + std::to_string(++port_num)};
+ *bad_port = jack_port_register(mClient, name.c_str(), JackDefaultAudioType,
+ JackPortIsOutput | JackPortIsTerminal, 0);
+ if(!*bad_port) break;
+ ++bad_port;
+ }
if(bad_port != ports_end)
{
- ERR("Not enough JACK ports available for %s output\n",
+ ERR("Failed to register enough JACK ports for %s output\n",
DevFmtChannelsString(mDevice->FmtChans));
if(bad_port == mPort.begin()) return false;
@@ -567,13 +573,12 @@ void JackPlayback::start()
const char *devname{mDevice->DeviceName.c_str()};
if(ConfigValueBool(devname, "jack", "connect-ports").value_or(true))
{
- const char **ports{jack_get_ports(mClient, mPortPattern.c_str(), JACK_DEFAULT_AUDIO_TYPE,
+ JackPortsPtr ports{jack_get_ports(mClient, mPortPattern.c_str(), JackDefaultAudioType,
JackPortIsInput)};
- if(ports == nullptr)
+ if(!ports)
{
jack_deactivate(mClient);
- throw al::backend_exception{al::backend_error::DeviceError,
- "No physical playback ports found"};
+ throw al::backend_exception{al::backend_error::DeviceError, "No playback ports found"};
}
auto connect_port = [this](const jack_port_t *port, const char *pname) -> bool
{
@@ -588,8 +593,7 @@ void JackPlayback::start()
pname);
return true;
};
- std::mismatch(mPort.begin(), mPort.end(), ports, connect_port);
- jack_free(ports);
+ std::mismatch(mPort.begin(), mPort.end(), ports.get(), connect_port);
}
/* Reconfigure buffer metrics in case the server changed it since the reset