Skip to content

Commit

Permalink
jack: cleanup, remove usage of static variables
Browse files Browse the repository at this point in the history
  • Loading branch information
lyrra committed Sep 1, 2023
1 parent 1ed130f commit ce43ca7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 59 deletions.
91 changes: 34 additions & 57 deletions src/framework/audio/internal/platform/jack/jackaudiodriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,16 @@ static constexpr char DEFAULT_DEVICE_ID[] = "default";

using namespace mu::audio;

//namespace {
struct JackData
int mu::audio::jack_process_callback(jack_nframes_t nframes, void* args)
{
float* buffer = nullptr;
jack_client_t* jackDeviceHandle = nullptr;
unsigned long samples = 0;
int channels = 0;
std::vector<jack_port_t*> outputPorts;
IAudioDriver::Callback callback;
void* userdata = nullptr;
};

static JackData* s_jackData{ nullptr };
IAudioDriver::Spec s_format;

int mu::audio::jack_process_callback(jack_nframes_t nframes, void*)
{
JackData* data = s_jackData;
JackDriverState* state = static_cast<JackDriverState*>(args);

jack_default_audio_sample_t* l = (float*)jack_port_get_buffer(data->outputPorts[0], nframes);
jack_default_audio_sample_t* r = (float*)jack_port_get_buffer(data->outputPorts[1], nframes);
jack_default_audio_sample_t* l = (float*)jack_port_get_buffer(state->outputPorts[0], nframes);
jack_default_audio_sample_t* r = (float*)jack_port_get_buffer(state->outputPorts[1], nframes);

uint8_t* stream = (uint8_t*)data->buffer;
data->callback(data->userdata, stream, nframes * data->channels * sizeof(float));
float* sp = data->buffer;
uint8_t* stream = (uint8_t*)state->buffer;
state->callback(state->userdata, stream, nframes * state->channels * sizeof(float));
float* sp = state->buffer;
for (size_t i = 0; i < nframes; i++) {
*l++ = *sp++;
*r++ = *sp++;
Expand All @@ -73,28 +58,15 @@ void mu::audio::jack_cleanup_callback(void*)
{
}

void jackCleanup()
{
if (!s_jackData) {
return;
}

if (nullptr != s_jackData->buffer) {
delete[] s_jackData->buffer;
}

delete s_jackData;
s_jackData = nullptr;
}

JackAudioDriver::JackAudioDriver()
{
m_jackDriverState = std::make_shared<JackDriverState>();
m_deviceId = DEFAULT_DEVICE_ID;
}

JackAudioDriver::~JackAudioDriver()
{
jackCleanup();
delete[] m_jackDriverState->buffer;
}

void JackAudioDriver::init()
Expand Down Expand Up @@ -123,11 +95,14 @@ int jack_srate_callback(jack_nframes_t nframes, void* args)

bool JackAudioDriver::open(const Spec& spec, Spec* activeSpec)
{
s_jackData = new JackData();
if (isOpened()) {
LOGW() << "Jack is already opened";
return false;
}
// s_jackData->samples = spec.samples; // client doesn't set sample-rate
s_jackData->channels = spec.channels;
s_jackData->callback = spec.callback;
s_jackData->userdata = spec.userdata;
m_jackDriverState->channels = spec.channels;
m_jackDriverState->callback = spec.callback;
m_jackDriverState->userdata = spec.userdata;
// FIX: "default" is not a good name for jack-clients
// const char *clientName =
// outputDevice().c_str() == "default" ? "MuseScore" :
Expand All @@ -144,15 +119,15 @@ bool JackAudioDriver::open(const Spec& spec, Spec* activeSpec)

jack_set_sample_rate_callback(handle, jack_srate_callback, (void*)&spec);

s_jackData->jackDeviceHandle = handle;
m_jackDriverState->jackDeviceHandle = handle;

jack_port_t* output_port_left = jack_port_register(handle, "audio_out_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
s_jackData->outputPorts.push_back(output_port_left);
m_jackDriverState->outputPorts.push_back(output_port_left);
jack_port_t* output_port_right = jack_port_register(handle, "audio_out_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
s_jackData->outputPorts.push_back(output_port_right);
m_jackDriverState->outputPorts.push_back(output_port_right);

s_jackData->samples = jack_get_buffer_size(handle);
LOGI() << "buffer size (in samples): " << s_jackData->samples;
m_jackDriverState->samples = jack_get_buffer_size(handle);
LOGI() << "buffer size (in samples): " << m_jackDriverState->samples;

unsigned int jackSamplerate = jack_get_sample_rate(handle);
LOGI() << "sampleRate used by jack: " << jackSamplerate;
Expand All @@ -163,17 +138,17 @@ bool JackAudioDriver::open(const Spec& spec, Spec* activeSpec)
//return false;
}

s_jackData->buffer = new float[s_jackData->samples * s_jackData->channels];
m_jackDriverState->buffer = new float[m_jackDriverState->samples * m_jackDriverState->channels];

if (activeSpec) {
*activeSpec = spec;
activeSpec->format = Format::AudioF32;
activeSpec->sampleRate = jackSamplerate;
s_format = *activeSpec;
m_jackDriverState->format = *activeSpec;
}

jack_on_shutdown(handle, jack_cleanup_callback, 0);
jack_set_process_callback(handle, jack_process_callback, (void*)&s_jackData);
jack_on_shutdown(handle, jack_cleanup_callback, (void*)m_jackDriverState.get());
jack_set_process_callback(handle, jack_process_callback, (void*)m_jackDriverState.get());

if (jack_activate(handle)) {
LOGE() << "cannot activate client";
Expand All @@ -185,12 +160,14 @@ bool JackAudioDriver::open(const Spec& spec, Spec* activeSpec)

void JackAudioDriver::close()
{
jackCleanup();
jack_client_t* jackDeviceHandle = static_cast<jack_client_t*>(m_jackDriverState->jackDeviceHandle);
jack_client_close(jackDeviceHandle);
delete[] m_jackDriverState->buffer;
}

bool JackAudioDriver::isOpened() const
{
return s_jackData != nullptr;
return m_jackDriverState->jackDeviceHandle != nullptr;
}

AudioDeviceID JackAudioDriver::outputDevice() const
Expand All @@ -210,7 +187,7 @@ bool JackAudioDriver::selectOutputDevice(const AudioDeviceID& deviceId)

bool ok = true;
if (reopen) {
ok = open(s_format, &s_format);
ok = open(m_jackDriverState->format, &m_jackDriverState->format);
}

if (ok) {
Expand Down Expand Up @@ -245,22 +222,22 @@ mu::async::Notification JackAudioDriver::availableOutputDevicesChanged() const

unsigned int JackAudioDriver::outputDeviceBufferSize() const
{
return s_format.samples;
return m_jackDriverState->format.samples;
}

bool JackAudioDriver::setOutputDeviceBufferSize(unsigned int bufferSize)
{
if (s_format.samples == bufferSize) {
if (m_jackDriverState->format.samples == bufferSize) {
return true;
}

bool reopen = isOpened();
close();
s_format.samples = bufferSize;
m_jackDriverState->format.samples = bufferSize;

bool ok = true;
if (reopen) {
ok = open(s_format, &s_format);
ok = open(m_jackDriverState->format, &m_jackDriverState->format);
}

if (ok) {
Expand Down
13 changes: 13 additions & 0 deletions src/framework/audio/internal/platform/jack/jackaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ namespace mu::audio {
int jack_process_callback(jack_nframes_t nframes, void* jackParam);
void jack_cleanup_callback(void* args);

struct JackDriverState {
float* buffer = nullptr;
void* jackDeviceHandle = nullptr;
unsigned long samples = 0;
int channels = 0;
std::vector<jack_port_t*> outputPorts;
IAudioDriver::Callback callback;
void* userdata = nullptr;
IAudioDriver::Spec format;
};

class JackAudioDriver : public IAudioDriver, public async::Asyncable
{
public:
Expand Down Expand Up @@ -74,6 +85,8 @@ class JackAudioDriver : public IAudioDriver, public async::Asyncable

async::Notification m_bufferSizeChanged;
async::Notification m_sampleRateChanged;

std::shared_ptr<JackDriverState> m_jackDriverState;
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/framework/audio/internal/platform/osx/osxaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class OSXAudioDriver : public IAudioDriver

struct Data;

std::shared_ptr<Data> m_data = nullptr;
std::shared_ptr<Data> m_data;
std::map<unsigned int, std::string> m_outputDevices = {}, m_inputDevices = {};
mutable std::mutex m_devicesMutex;
async::Notification m_outputDeviceChanged;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
};

OSXAudioDriver::OSXAudioDriver()
: m_data(nullptr)
{
m_data = std::make_shared<Data>();
m_data->audioQueue = nullptr;
Expand Down

0 comments on commit ce43ca7

Please sign in to comment.