aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/jack.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-27 20:28:58 -0800
committerChris Robinson <[email protected]>2018-11-27 20:29:54 -0800
commitff8c6949576b40d11c3cb4276390d355d1b0231f (patch)
tree7fd743d95d1079f68d04e58f34341ab7f48949eb /Alc/backends/jack.cpp
parent0116e763ea22538b6cac2b78acc918185f54e2f9 (diff)
Clean up the JACK backend
Diffstat (limited to 'Alc/backends/jack.cpp')
-rw-r--r--Alc/backends/jack.cpp355
1 files changed, 186 insertions, 169 deletions
diff --git a/Alc/backends/jack.cpp b/Alc/backends/jack.cpp
index 0679dd73..d141f991 100644
--- a/Alc/backends/jack.cpp
+++ b/Alc/backends/jack.cpp
@@ -39,7 +39,9 @@
#include <jack/ringbuffer.h>
-static const ALCchar jackDevice[] = "JACK Default";
+namespace {
+
+constexpr ALCchar jackDevice[] = "JACK Default";
#ifdef HAVE_DYNLOAD
@@ -64,10 +66,10 @@ static const ALCchar jackDevice[] = "JACK Default";
MAGIC(jack_set_buffer_size); \
MAGIC(jack_get_buffer_size);
-static void *jack_handle;
-#define MAKE_FUNC(f) static decltype(f) * p##f
+void *jack_handle;
+#define MAKE_FUNC(f) decltype(f) * p##f
JACK_FUNCS(MAKE_FUNC);
-static decltype(jack_error_callback) * pjack_error_callback;
+decltype(jack_error_callback) * pjack_error_callback;
#undef MAKE_FUNC
#ifndef IN_IDE_PARSER
@@ -95,9 +97,9 @@ static decltype(jack_error_callback) * pjack_error_callback;
#endif
-static jack_options_t ClientOptions = JackNullOption;
+jack_options_t ClientOptions = JackNullOption;
-static ALCboolean jack_load(void)
+ALCboolean jack_load(void)
{
ALCboolean error = ALC_FALSE;
@@ -137,7 +139,7 @@ static ALCboolean jack_load(void)
{
WARN("Missing expected functions:%s\n", missing_funcs.c_str());
CloseLib(jack_handle);
- jack_handle = NULL;
+ jack_handle = nullptr;
}
}
#endif
@@ -147,56 +149,55 @@ static ALCboolean jack_load(void)
struct ALCjackPlayback final : public ALCbackend {
- jack_client_t *Client{nullptr};
- jack_port_t *Port[MAX_OUTPUT_CHANNELS]{};
+ jack_client_t *mClient{nullptr};
+ jack_port_t *mPort[MAX_OUTPUT_CHANNELS]{};
- ll_ringbuffer_t *Ring{nullptr};
- al::semaphore Sem;
+ RingBufferPtr mRing;
+ al::semaphore mSem;
- std::atomic<ALenum> mKillNow{AL_TRUE};
+ std::atomic<bool> mKillNow{true};
std::thread mThread;
};
-static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg);
-
-static int ALCjackPlayback_process(jack_nframes_t numframes, void *arg);
-static int ALCjackPlayback_mixerProc(ALCjackPlayback *self);
-
-static void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device);
-static void ALCjackPlayback_Destruct(ALCjackPlayback *self);
-static ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name);
-static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self);
-static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self);
-static void ALCjackPlayback_stop(ALCjackPlayback *self);
-static DECLARE_FORWARD2(ALCjackPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-static DECLARE_FORWARD(ALCjackPlayback, ALCbackend, ALCuint, availableSamples)
-static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self);
-static DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, unlock)
+int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg);
+
+int ALCjackPlayback_process(jack_nframes_t numframes, void *arg);
+int ALCjackPlayback_mixerProc(ALCjackPlayback *self);
+
+void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device);
+void ALCjackPlayback_Destruct(ALCjackPlayback *self);
+ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name);
+ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self);
+ALCboolean ALCjackPlayback_start(ALCjackPlayback *self);
+void ALCjackPlayback_stop(ALCjackPlayback *self);
+DECLARE_FORWARD2(ALCjackPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
+DECLARE_FORWARD(ALCjackPlayback, ALCbackend, ALCuint, availableSamples)
+ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self);
+DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, lock)
+DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(ALCjackPlayback)
DEFINE_ALCBACKEND_VTABLE(ALCjackPlayback);
-static void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device)
+void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device)
{
new (self) ALCjackPlayback{};
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(ALCjackPlayback, ALCbackend, self);
}
-static void ALCjackPlayback_Destruct(ALCjackPlayback *self)
+void ALCjackPlayback_Destruct(ALCjackPlayback *self)
{
- if(self->Client)
+ if(self->mClient)
{
- for(ALsizei i{0};i < MAX_OUTPUT_CHANNELS;i++)
- {
- if(self->Port[i])
- jack_port_unregister(self->Client, self->Port[i]);
- self->Port[i] = NULL;
- }
- jack_client_close(self->Client);
- self->Client = NULL;
+ std::for_each(std::begin(self->mPort), std::end(self->mPort),
+ [self](jack_port_t *port) -> void
+ { if(port) jack_port_unregister(self->mClient, port); }
+ );
+ std::fill(std::begin(self->mPort), std::end(self->mPort), nullptr);
+ jack_client_close(self->mClient);
+ self->mClient = nullptr;
}
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
@@ -204,29 +205,28 @@ static void ALCjackPlayback_Destruct(ALCjackPlayback *self)
}
-static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg)
+int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg)
{
- ALCjackPlayback *self = static_cast<ALCjackPlayback*>(arg);
- ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
- ALuint bufsize;
+ auto self = static_cast<ALCjackPlayback*>(arg);
+ ALCdevice *device{STATIC_CAST(ALCbackend,self)->mDevice};
ALCjackPlayback_lock(self);
device->UpdateSize = numframes;
device->NumUpdates = 2;
- bufsize = device->UpdateSize;
+ ALuint bufsize{device->UpdateSize};
if(ConfigValueUInt(device->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
bufsize = maxu(NextPowerOf2(bufsize), device->UpdateSize);
device->NumUpdates = (bufsize+device->UpdateSize) / device->UpdateSize;
TRACE("%u update size x%u\n", device->UpdateSize, device->NumUpdates);
- ll_ringbuffer_free(self->Ring);
- self->Ring = ll_ringbuffer_create(bufsize,
+ self->mRing = nullptr;
+ self->mRing.reset(ll_ringbuffer_create(bufsize,
FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->mAmbiOrder),
true
- );
- if(!self->Ring)
+ ));
+ if(!self->mRing)
{
ERR("Failed to reallocate ringbuffer\n");
aluHandleDisconnect(device, "Failed to reallocate %u-sample buffer", bufsize);
@@ -236,62 +236,81 @@ static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg)
}
-static int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
+int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
{
- ALCjackPlayback *self = static_cast<ALCjackPlayback*>(arg);
- jack_default_audio_sample_t *out[MAX_OUTPUT_CHANNELS];
- jack_nframes_t total{0};
- jack_nframes_t todo;
- ALsizei i, c, numchans;
-
- auto data = ll_ringbuffer_get_read_vector(self->Ring);
+ auto self = static_cast<ALCjackPlayback*>(arg);
- for(c = 0;c < MAX_OUTPUT_CHANNELS && self->Port[c];c++)
- out[c] = static_cast<float*>(jack_port_get_buffer(self->Port[c], numframes));
- numchans = c;
-
- todo = minu(numframes, data.first.len);
- for(c = 0;c < numchans;c++)
+ jack_default_audio_sample_t *out[MAX_OUTPUT_CHANNELS];
+ ALsizei numchans{0};
+ for(auto port : self->mPort)
{
- const ALfloat *RESTRICT in = ((ALfloat*)data.first.buf) + c;
- for(i = 0;(jack_nframes_t)i < todo;i++)
- out[c][i] = in[i*numchans];
- out[c] += todo;
+ if(!port) break;
+ out[numchans++] = static_cast<float*>(jack_port_get_buffer(port, numframes));
}
- total += todo;
+
+ auto data = ll_ringbuffer_get_read_vector(self->mRing.get());
+ jack_nframes_t todo{minu(numframes, data.first.len)};
+ std::transform(out, out+numchans, out,
+ [&data,numchans,todo](ALfloat *outbuf) -> ALfloat*
+ {
+ const ALfloat *RESTRICT in = reinterpret_cast<ALfloat*>(data.first.buf);
+ std::generate_n(outbuf, todo,
+ [&in,numchans]() noexcept -> ALfloat
+ {
+ ALfloat ret{*in};
+ in += numchans;
+ return ret;
+ }
+ );
+ data.first.buf += sizeof(ALfloat);
+ return outbuf + todo;
+ }
+ );
+ jack_nframes_t total{todo};
todo = minu(numframes-total, data.second.len);
if(todo > 0)
{
- for(c = 0;c < numchans;c++)
- {
- const ALfloat *RESTRICT in = ((ALfloat*)data.second.buf) + c;
- for(i = 0;(jack_nframes_t)i < todo;i++)
- out[c][i] = in[i*numchans];
- out[c] += todo;
- }
+ std::transform(out, out+numchans, out,
+ [&data,numchans,todo](ALfloat *outbuf) -> ALfloat*
+ {
+ const ALfloat *RESTRICT in = reinterpret_cast<ALfloat*>(data.second.buf);
+ std::generate_n(outbuf, todo,
+ [&in,numchans]() noexcept -> ALfloat
+ {
+ ALfloat ret{*in};
+ in += numchans;
+ return ret;
+ }
+ );
+ data.second.buf += sizeof(ALfloat);
+ return outbuf + todo;
+ }
+ );
total += todo;
}
- ll_ringbuffer_read_advance(self->Ring, total);
- self->Sem.post();
+ ll_ringbuffer_read_advance(self->mRing.get(), total);
+ self->mSem.post();
if(numframes > total)
{
todo = numframes-total;
- for(c = 0;c < numchans;c++)
- {
- for(i = 0;(jack_nframes_t)i < todo;i++)
- out[c][i] = 0.0f;
- }
+ std::transform(out, out+numchans, out,
+ [todo](ALfloat *outbuf) -> ALfloat*
+ {
+ std::fill_n(outbuf, todo, 0.0f);
+ return outbuf + todo;
+ }
+ );
}
return 0;
}
-static int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
+int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
+ ALCdevice *device{STATIC_CAST(ALCbackend,self)->mDevice};
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -300,27 +319,25 @@ static int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
while(!self->mKillNow.load(std::memory_order_acquire) &&
device->Connected.load(std::memory_order_acquire))
{
- ALuint todo, len1, len2;
-
- if(ll_ringbuffer_write_space(self->Ring) < device->UpdateSize)
+ if(ll_ringbuffer_write_space(self->mRing.get()) < device->UpdateSize)
{
ALCjackPlayback_unlock(self);
- self->Sem.wait();
+ self->mSem.wait();
ALCjackPlayback_lock(self);
continue;
}
- auto data = ll_ringbuffer_get_write_vector(self->Ring);
- todo = data.first.len + data.second.len;
+ auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto todo = static_cast<ALuint>(data.first.len + data.second.len);
todo -= todo%device->UpdateSize;
- len1 = minu(data.first.len, todo);
- len2 = minu(data.second.len, todo-len1);
+ ALuint len1{minu(data.first.len, todo)};
+ ALuint len2{minu(data.second.len, todo-len1)};
aluMixData(device, data.first.buf, len1);
if(len2 > 0)
aluMixData(device, data.second.buf, len2);
- ll_ringbuffer_write_advance(self->Ring, todo);
+ ll_ringbuffer_write_advance(self->mRing.get(), todo);
}
ALCjackPlayback_unlock(self);
@@ -328,19 +345,17 @@ static int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
}
-static ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
+ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- const char *client_name = "alsoft";
- jack_status_t status;
-
if(!name)
name = jackDevice;
else if(strcmp(name, jackDevice) != 0)
return ALC_INVALID_VALUE;
- self->Client = jack_client_open(client_name, ClientOptions, &status, NULL);
- if(self->Client == NULL)
+ const char *client_name{"alsoft"};
+ jack_status_t status;
+ self->mClient = jack_client_open(client_name, ClientOptions, &status, nullptr);
+ if(self->mClient == nullptr)
{
ERR("jack_client_open() failed, status = 0x%02x\n", status);
return ALC_INVALID_VALUE;
@@ -349,38 +364,35 @@ static ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
TRACE("JACK server started\n");
if((status&JackNameNotUnique))
{
- client_name = jack_get_client_name(self->Client);
+ client_name = jack_get_client_name(self->mClient);
TRACE("Client name not unique, got `%s' instead\n", client_name);
}
- jack_set_process_callback(self->Client, ALCjackPlayback_process, self);
- jack_set_buffer_size_callback(self->Client, ALCjackPlayback_bufferSizeNotify, self);
+ jack_set_process_callback(self->mClient, ALCjackPlayback_process, self);
+ jack_set_buffer_size_callback(self->mClient, ALCjackPlayback_bufferSizeNotify, self);
+ ALCdevice *device{self->mDevice};
device->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
+ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- ALsizei numchans, i;
- ALuint bufsize;
-
- for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
- {
- if(self->Port[i])
- jack_port_unregister(self->Client, self->Port[i]);
- self->Port[i] = NULL;
- }
+ std::for_each(std::begin(self->mPort), std::end(self->mPort),
+ [self](jack_port_t *port) -> void
+ { if(port) jack_port_unregister(self->mClient, port); }
+ );
+ std::fill(std::begin(self->mPort), std::end(self->mPort), nullptr);
/* Ignore the requested buffer metrics and just keep one JACK-sized buffer
* ready for when requested.
*/
- device->Frequency = jack_get_sample_rate(self->Client);
- device->UpdateSize = jack_get_buffer_size(self->Client);
+ ALCdevice *device{self->mDevice};
+ device->Frequency = jack_get_sample_rate(self->mClient);
+ device->UpdateSize = jack_get_buffer_size(self->mClient);
device->NumUpdates = 2;
- bufsize = device->UpdateSize;
+ ALuint bufsize{device->UpdateSize};
if(ConfigValueUInt(device->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
bufsize = maxu(NextPowerOf2(bufsize), device->UpdateSize);
device->NumUpdates = (bufsize+device->UpdateSize) / device->UpdateSize;
@@ -388,40 +400,43 @@ static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
/* Force 32-bit float output. */
device->FmtType = DevFmtFloat;
- numchans = ChannelsFromDevFmt(device->FmtChans, device->mAmbiOrder);
- for(i = 0;i < numchans;i++)
- {
- char name[64];
- snprintf(name, sizeof(name), "channel_%d", i+1);
- self->Port[i] = jack_port_register(self->Client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- if(self->Port[i] == NULL)
+ ALsizei numchans{ChannelsFromDevFmt(device->FmtChans, device->mAmbiOrder)};
+ auto ports_end = std::begin(self->mPort) + numchans;
+ auto bad_port = std::find_if_not(std::begin(self->mPort), ports_end,
+ [self](jack_port_t *&port) -> bool
{
- ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(device->FmtChans));
- if(i == 0) return ALC_FALSE;
- break;
+ std::string name{"channel_" + std::to_string(&port - self->mPort + 1)};
+ port = jack_port_register(self->mClient, name.c_str(), JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsOutput, 0);
+ return port != nullptr;
}
- }
- if(i < numchans)
+ );
+ if(bad_port != ports_end)
{
- if(i == 1)
+ ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(device->FmtChans));
+ if(bad_port == std::begin(self->mPort)) return ALC_FALSE;
+
+ if(bad_port == std::begin(self->mPort)+1)
device->FmtChans = DevFmtMono;
else
{
- for(--i;i >= 2;i--)
+ ports_end = self->mPort+2;
+ while(bad_port != ports_end)
{
- jack_port_unregister(self->Client, self->Port[i]);
- self->Port[i] = NULL;
+ jack_port_unregister(self->mClient, *(--bad_port));
+ *bad_port = nullptr;
}
device->FmtChans = DevFmtStereo;
}
+ numchans = std::distance(std::begin(self->mPort), bad_port);
}
- ll_ringbuffer_free(self->Ring);
- self->Ring = ll_ringbuffer_create(bufsize,
+ self->mRing = nullptr;
+ self->mRing.reset(ll_ringbuffer_create(bufsize,
FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->mAmbiOrder),
true
- );
- if(!self->Ring)
+ ));
+ if(!self->mRing)
{
ERR("Failed to allocate ringbuffer\n");
return ALC_FALSE;
@@ -432,38 +447,41 @@ static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
return ALC_TRUE;
}
-static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
+ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
{
- const char **ports;
- ALsizei i;
-
- if(jack_activate(self->Client))
+ if(jack_activate(self->mClient))
{
ERR("Failed to activate client\n");
return ALC_FALSE;
}
- ports = jack_get_ports(self->Client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
- if(ports == NULL)
+ const char **ports{jack_get_ports(self->mClient, nullptr, nullptr,
+ JackPortIsPhysical|JackPortIsInput)};
+ if(ports == nullptr)
{
ERR("No physical playback ports found\n");
- jack_deactivate(self->Client);
+ jack_deactivate(self->mClient);
return ALC_FALSE;
}
- for(i = 0;i < MAX_OUTPUT_CHANNELS && self->Port[i];i++)
- {
- if(!ports[i])
+ std::mismatch(std::begin(self->mPort), std::end(self->mPort), ports,
+ [self](const jack_port_t *port, const char *pname) -> bool
{
- ERR("No physical playback port for \"%s\"\n", jack_port_name(self->Port[i]));
- break;
+ if(!port) return false;
+ if(!pname)
+ {
+ ERR("No physical playback port for \"%s\"\n", jack_port_name(port));
+ return false;
+ }
+ if(jack_connect(self->mClient, jack_port_name(port), pname))
+ ERR("Failed to connect output port \"%s\" to \"%s\"\n", jack_port_name(port),
+ pname);
+ return true;
}
- if(jack_connect(self->Client, jack_port_name(self->Port[i]), ports[i]))
- ERR("Failed to connect output port \"%s\" to \"%s\"\n", jack_port_name(self->Port[i]), ports[i]);
- }
+ );
jack_free(ports);
try {
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
+ self->mKillNow.store(false, std::memory_order_release);
self->mThread = std::thread(ALCjackPlayback_mixerProc, self);
return ALC_TRUE;
}
@@ -472,30 +490,30 @@ static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
}
catch(...) {
}
- jack_deactivate(self->Client);
+ jack_deactivate(self->mClient);
return ALC_FALSE;
}
-static void ALCjackPlayback_stop(ALCjackPlayback *self)
+void ALCjackPlayback_stop(ALCjackPlayback *self)
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
return;
- self->Sem.post();
+ self->mSem.post();
self->mThread.join();
- jack_deactivate(self->Client);
+ jack_deactivate(self->mClient);
}
-static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
+ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
ClockLatency ret;
ALCjackPlayback_lock(self);
+ ALCdevice *device{self->mDevice};
ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->Ring)};
+ ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing.get())};
ret.Latency /= device->Frequency;
ALCjackPlayback_unlock(self);
@@ -503,26 +521,25 @@ static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
}
-static void jack_msg_handler(const char *message)
+void jack_msg_handler(const char *message)
{
WARN("%s\n", message);
}
+} // namespace
+
bool JackBackendFactory::init()
{
- void (*old_error_cb)(const char*);
- jack_client_t *client;
- jack_status_t status;
-
if(!jack_load())
return false;
- if(!GetConfigValueBool(NULL, "jack", "spawn-server", 0))
+ if(!GetConfigValueBool(nullptr, "jack", "spawn-server", 0))
ClientOptions = static_cast<jack_options_t>(ClientOptions | JackNoStartServer);
- old_error_cb = (&jack_error_callback ? jack_error_callback : NULL);
+ void (*old_error_cb)(const char*){&jack_error_callback ? jack_error_callback : nullptr};
jack_set_error_function(jack_msg_handler);
- client = jack_client_open("alsoft", ClientOptions, &status, NULL);
+ jack_status_t status;
+ jack_client_t *client{jack_client_open("alsoft", ClientOptions, &status, nullptr)};
jack_set_error_function(old_error_cb);
if(!client)
{