Skip to content

Commit

Permalink
Merge pull request #858 from samhocevar-forks/patch/a2-mutex
Browse files Browse the repository at this point in the history
Protect the audio2 callbacks with a mutex
  • Loading branch information
RobDangerous authored Feb 16, 2024
2 parents 6db4eb7 + 5a7b77f commit f861f63
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 156 deletions.
10 changes: 2 additions & 8 deletions Backends/Audio2/DirectSound/Sources/kinc/backend/DirectSound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ namespace {
const int gap = 10 * 1024;
DWORD writePos = gap;

void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = nullptr;
void *a2_userdata = nullptr;
kinc_a2_buffer_t a2_buffer;
}

Expand All @@ -33,6 +31,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
initialized = true;

a2_buffer.read_location = 0;
Expand Down Expand Up @@ -81,11 +80,6 @@ uint32_t kinc_a2_samples_per_second(void) {
return samplesPerSecond;
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

namespace {
void copySample(uint8_t *buffer, DWORD &index, bool left) {
float value = *(float *)&a2_buffer.channels[left ? 0 : 1][a2_buffer.read_location];
Expand Down Expand Up @@ -133,7 +127,7 @@ void kinc_a2_update() {
}
}

a2_callback(&a2_buffer, (uint32_t)(gap / 4), a2_userdata);
kinc_a2_internal_callback(&a2_buffer, (uint32_t)(gap / 4));

DWORD size1;
uint8_t *buffer1;
Expand Down
23 changes: 4 additions & 19 deletions Backends/Audio2/WASAPI/Sources/kinc/backend/wasapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0x
#endif

// based on the implementation in soloud and Microsoft sample code
static void (*volatile a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
static void *a2_userdata = NULL;
static kinc_a2_buffer_t a2_buffer;

static IMMDeviceEnumerator *deviceEnumerator;
Expand All @@ -83,18 +81,11 @@ static WAVEFORMATEX requestedFormat;
static WAVEFORMATEX *closestFormat;
static WAVEFORMATEX *format;
static uint32_t samples_per_second = 44100;
static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback_userdata = userdata;
sample_rate_callback = kinc_a2_sample_rate_callback;
}

static bool initDefaultDevice() {
if (renderClient != NULL) {
renderClient->lpVtbl->Release(renderClient);
Expand Down Expand Up @@ -150,8 +141,8 @@ static bool initDefaultDevice() {

uint32_t old_samples_per_second = samples_per_second;
samples_per_second = format->nSamplesPerSec;
if (samples_per_second != old_samples_per_second && sample_rate_callback != NULL) {
sample_rate_callback(sample_rate_callback_userdata);
if (samples_per_second != old_samples_per_second) {
kinc_a2_internal_sample_rate_callback();
}
a2_buffer.channel_count = 2;

Expand Down Expand Up @@ -218,9 +209,7 @@ static void submitBuffer(unsigned frames) {
return;
}

if (a2_callback != NULL) {
a2_callback(&a2_buffer, frames, a2_userdata);
memset(buffer, 0, frames * format->nBlockAlign);
if (kinc_a2_internal_callback(&a2_buffer, frames)) {
if (format->wFormatTag == WAVE_FORMAT_PCM) {
for (UINT32 i = 0; i < frames; ++i) {
copyS16Sample((int16_t *)&buffer[i * format->nBlockAlign], (int16_t *)&buffer[i * format->nBlockAlign + 2]);
Expand Down Expand Up @@ -276,6 +265,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
initialized = true;

a2_buffer.read_location = 0;
Expand All @@ -296,11 +286,6 @@ void kinc_a2_init() {
}
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

void kinc_a2_update() {}

#define SAFE_RELEASE(punk) \
Expand Down
22 changes: 4 additions & 18 deletions Backends/Audio2/WASAPI_WinRT/Sources/kinc/backend/WASAPI.winrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ template <class T> void SafeRelease(__deref_inout_opt T **ppT) {
// based on the implementation in soloud and Microsoft sample code
namespace {
kinc_thread_t thread;
void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
void *a2_userdata = nullptr;
kinc_a2_buffer_t a2_buffer;

IMMDeviceEnumerator *deviceEnumerator;
Expand All @@ -55,8 +53,6 @@ namespace {
WAVEFORMATEX *closestFormat;
WAVEFORMATEX *format;
static uint32_t samples_per_second = 44100;
static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

bool initDefaultDevice();
void audioThread(LPVOID);
Expand Down Expand Up @@ -138,8 +134,8 @@ namespace {

uint32_t old_samples_per_second = samples_per_second;
samples_per_second = format->nSamplesPerSec;
if (samples_per_second != old_samples_per_second && sample_rate_callback != NULL) {
sample_rate_callback(sample_rate_callback_userdata);
if (samples_per_second != old_samples_per_second) {
kinc_a2_internal_sample_rate_callback();
}
a2_buffer.channel_count = 2;

Expand Down Expand Up @@ -206,9 +202,7 @@ namespace {
return;
}

if (a2_callback != nullptr) {
a2_callback(&a2_buffer, frames, a2_userdata);
memset(buffer, 0, frames * format->nBlockAlign);
if (kinc_a2_internal_callback(&a2_buffer, frames)) {
if (format->wFormatTag == WAVE_FORMAT_PCM) {
for (UINT32 i = 0; i < frames; ++i) {
copyS16Sample((int16_t *)&buffer[i * format->nBlockAlign], (int16_t *)&buffer[i * format->nBlockAlign + 2]);
Expand Down Expand Up @@ -267,6 +261,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
initialized = true;

a2_buffer.read_location = 0;
Expand Down Expand Up @@ -297,19 +292,10 @@ void kinc_a2_init() {
#endif
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback = kinc_a2_sample_rate_callback;
}

void kinc_a2_update() {}

void kinc_a2_shutdown() {
Expand Down
22 changes: 3 additions & 19 deletions Backends/System/Android/Sources/kinc/backend/audio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <stdlib.h>
#include <string.h>

static void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
static void *a2_userdata = NULL;
static kinc_a2_buffer_t a2_buffer;

static SLObjectItf engineObject;
Expand All @@ -31,17 +29,15 @@ static void copySample(void *buffer) {
}

static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf caller, void *context) {
if (a2_callback != NULL) {
a2_callback(&a2_buffer, AUDIO_BUFFER_SIZE / 2, a2_userdata);
if (kinc_a2_internal_callback(&a2_buffer, AUDIO_BUFFER_SIZE / 2)) {
for (int i = 0; i < AUDIO_BUFFER_SIZE; i += 2) {
copySample(&tempBuffer[i]);
}
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
}
else {
memset(tempBuffer, 0, sizeof(tempBuffer));
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
}
SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
}

static bool initialized = false;
Expand All @@ -51,6 +47,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
initialized = true;

a2_buffer.read_location = 0;
Expand Down Expand Up @@ -131,19 +128,6 @@ void kinc_a2_shutdown() {
}
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

uint32_t kinc_a2_samples_per_second(void) {
return 44100;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback_userdata = userdata;
sample_rate_callback = kinc_a2_sample_rate_callback;
}
19 changes: 2 additions & 17 deletions Backends/System/Emscripten/Sources/kinc/backend/audio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <stdio.h>
#include <stdlib.h>

static void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
static void *a2_userdata = NULL;
static kinc_a2_buffer_t a2_buffer;

static ALCdevice *device = NULL;
Expand Down Expand Up @@ -36,8 +34,7 @@ static void copySample(void *buffer) {
}

static void streamBuffer(ALuint buffer) {
if (a2_callback != NULL) {
a2_callback(&a2_buffer, BUFSIZE / 2, a2_userdata);
if (kinc_a2_internal_callback(&a2_buffer, BUFSIZE / 2)) {
for (int i = 0; i < BUFSIZE; i += 2) {
copySample(&buf[i]);
}
Expand Down Expand Up @@ -78,6 +75,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
a2_initialized = true;

a2_buffer.read_location = 0;
Expand Down Expand Up @@ -115,19 +113,6 @@ void kinc_a2_shutdown() {
audioRunning = false;
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback_userdata = userdata;
sample_rate_callback = kinc_a2_sample_rate_callback;
}
19 changes: 2 additions & 17 deletions Backends/System/Linux/Sources/kinc/backend/sound.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

// apt-get install libasound2-dev

void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
void *a2_userdata = NULL;
kinc_a2_buffer_t a2_buffer;

pthread_t threadid;
Expand All @@ -20,18 +18,10 @@ short buf[4096 * 4];

static unsigned int samples_per_second = 44100;

static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback_userdata = userdata;
sample_rate_callback = kinc_a2_sample_rate_callback;
}

void copySample(void *buffer) {
float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
Expand All @@ -45,8 +35,7 @@ void copySample(void *buffer) {

int playback_callback(snd_pcm_sframes_t nframes) {
int err = 0;
if (a2_callback != NULL) {
a2_callback(&a2_buffer, nframes, a2_userdata);
if (kinc_a2_internal_callback(&a2_buffer, nframes)) {
int ni = 0;
while (ni < nframes) {
int i = 0;
Expand Down Expand Up @@ -223,6 +212,7 @@ void kinc_a2_init() {
return;
}

kinc_a2_internal_init();
initialized = true;

a2_buffer.read_location = 0;
Expand All @@ -241,8 +231,3 @@ void kinc_a2_update() {}
void kinc_a2_shutdown() {
audioRunning = false;
}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}
18 changes: 3 additions & 15 deletions Backends/System/Wasm/Sources/kinc/backend/audio.c.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
#include <kinc/audio2/audio.h>
#include <stdlib.h>

static void (*a2_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
static void *a2_userdata = NULL;
static kinc_a2_buffer_t a2_buffer;

void kinc_a2_init() {}
void kinc_a2_init() {
kinc_a2_internal_init();
}

void kinc_a2_update() {}

void kinc_a2_shutdown() {}

void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
a2_callback = kinc_a2_audio_callback;
a2_userdata = userdata;
}

static uint32_t samples_per_second = 44100;
static void (*sample_rate_callback)(void *userdata) = NULL;
static void *sample_rate_callback_userdata = NULL;

uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}

void kinc_a2_set_sample_rate_callback(void (*kinc_a2_sample_rate_callback)(void *userdata), void *userdata) {
sample_rate_callback_userdata = userdata;
sample_rate_callback = kinc_a2_sample_rate_callback;
}
Loading

0 comments on commit f861f63

Please sign in to comment.