aboutsummaryrefslogtreecommitdiff
path: root/sokol_audio.h
diff options
context:
space:
mode:
authorCrackedPixel <5776225+CrackedPixel@users.noreply.github.com>2025-11-11 17:04:19 -0600
committerCrackedPixel <5776225+CrackedPixel@users.noreply.github.com>2025-11-12 13:08:02 -0600
commit5b16e7adaef629603d6458c444cc22e22a27f7c1 (patch)
tree1a79dc613489e362bb825a6cba7913ed5fc4911c /sokol_audio.h
parentb45fa956933cbee1dcd0b50bf40529e3745e7df7 (diff)
pr feedback changes
Diffstat (limited to 'sokol_audio.h')
-rw-r--r--sokol_audio.h186
1 files changed, 87 insertions, 99 deletions
diff --git a/sokol_audio.h b/sokol_audio.h
index 11551d1b..20d74a59 100644
--- a/sokol_audio.h
+++ b/sokol_audio.h
@@ -418,7 +418,7 @@
or sped up.
The queue size and other NDSP specific parameters can be chosen by
- the provided 'user_data_3ds_t' user_data. Defaults will be used if
+ the provided 'saudio_n3ds_desc' type. Defaults will be used if
nothing is provided.
There is a known issue of a noticeable delay when starting a new
@@ -588,7 +588,6 @@ extern "C" {
_SAUDIO_LOGITEM_XMACRO(VITA_SCEAUDIO_OPEN_FAILED, "sceAudioOutOpenPort() failed") \
_SAUDIO_LOGITEM_XMACRO(VITA_PTHREAD_CREATE_FAILED, "pthread_create() failed") \
_SAUDIO_LOGITEM_XMACRO(N3DS_NDSP_OPEN_FAILED, "ndspInit() failed") \
- _SAUDIO_LOGITEM_XMACRO(N3DS_USERDATA_DEFAULT_MALLOC_FAILED, "user_data not provided, default malloc failed") \
#define _SAUDIO_LOGITEM_XMACRO(item,msg) SAUDIO_LOGITEM_##item,
typedef enum saudio_log_item {
@@ -628,6 +627,31 @@ typedef struct saudio_allocator {
void* user_data;
} saudio_allocator;
+typedef enum saudio_n3ds_ndspinterptype {
+ SAUDIO_N3DS_DSP_INTERP_POLYPHASE = 0,
+ SAUDIO_N3DS_DSP_INTERP_LINEAR = 1,
+ SAUDIO_N3DS_DSP_INTERP_NONE = 2,
+} saudio_n3ds_ndspinterptype;
+
+typedef struct saudio_n3ds_desc {
+ /* the 3DS requires multiple queues that it alternates between. */
+ /* a single buffer will "work" but is choppy due to a slight */
+ /* delay when it changes queues. */
+ int queue_count; /* default value = 2 */
+
+ /* NDSP_INTERP_POLYPHASE = 0 (high quality, slower) */
+ /* NDSP_INTERP_LINEAR = 1 (med quality, medium) */
+ /* NDSP_INTERP_NONE = 2 (low quality, fast) */
+ saudio_n3ds_ndspinterptype interpolation_type; /* default value = 0, expected as type ndspInterpType enum */
+
+ /* 3DS supports different audio channels. they can be used */
+ /* in a variety of ways as independent streams etc. */
+ /* this implementation in sokol does NOT allow multiple */
+ /* due to calling the global ndspInit/ndspExit functions. */
+ /* valid range 0-23 */
+ int channel_id; /* default value = 0 */
+} saudio_n3ds_desc;
+
typedef struct saudio_desc {
int sample_rate; // requested sample rate
int num_channels; // number of channels, default: 1 (mono)
@@ -637,6 +661,7 @@ typedef struct saudio_desc {
void (*stream_cb)(float* buffer, int num_frames, int num_channels); // optional streaming callback (no user data)
void (*stream_userdata_cb)(float* buffer, int num_frames, int num_channels, void* user_data); //... and with user data
void* user_data; // optional user data argument for stream_userdata_cb
+ saudio_n3ds_desc n3ds; // optional data for use on n3ds
saudio_allocator allocator; // optional allocation override functions
saudio_logger logger; // optional logging function (default: NO LOGGING!)
} saudio_desc;
@@ -742,6 +767,9 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
#elif defined(PSP2_SDK_VERSION)
#define _SAUDIO_VITA (1)
#include <psp2/audioout.h>
+#elif defined(__3DS__)
+ #define _SAUDIO_N3DS (1)
+ #include <3ds.h>
#else
#error "sokol_audio.h: Unknown platform"
#endif
@@ -840,9 +868,8 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
#elif defined(_SAUDIO_VITA)
#define _SAUDIO_PTHREADS (1)
#include <pthread.h>
-#elif defined(__3DS__)
- #define _SAUDIO_3DS (1)
- #include <3ds.h>
+#elif defined(_SAUDIO_N3DS)
+ #define _SAUDIO_NOTHREADS (1)
#endif
#define _saudio_def(val, def) (((val) == 0) ? (def) : (val))
@@ -1055,35 +1082,17 @@ typedef struct {
bool thread_stop;
} _saudio_vita_backend_t;
-#elif defined(_SAUDIO_3DS)
-
-typedef struct {
- /* the 3DS requires multiple queues that it alternates between. */
- /* a single buffer will "work" but is choppy due to a slight */
- /* delay when it changes queues. */
- int queue_count; /* default value = 2 */
-
- /* NDSP_INTERP_POLYPHASE = 0 (high quality, slower) */
- /* NDSP_INTERP_LINEAR = 1 (med quality, medium) */
- /* NDSP_INTERP_NONE = 2 (low quality, fast) */
- ndspInterpType interpolation_type; /* default value = 0 */
-
- /* 3DS supports different audio channels. they can be used */
- /* in a variety of ways as independent streams etc. */
- /* this implementation in sokol does NOT allow multiple */
- /* due to calling the global ndspInit/ndspExit functions. */
- /* valid range 0-23 */
- int channel_id; /* default value = 0 */
-} user_data_3ds_t;
+#elif defined(_SAUDIO_N3DS)
typedef struct {
- int channel_id; /* 3ds channel id */
- float* buffer; /* used by sokol as floats */
- int16_t* buffer_3ds; /* sokol buffer converted to int16 */
- ndspWaveBuf* queue_3ds; /* device queues on 3DS */
+ saudio_n3ds_desc n3ds_desc; /* n3ds specific data */
+ float* buffer; /* used by sokol as floats */
+ int16_t* buffer_n3ds; /* sokol buffer converted to int16 */
+ ndspWaveBuf* queue_n3ds; /* device queues on 3DS */
+ int samples_per_buffer; /* frames * channel count */
int buffer_byte_size;
bool thread_stop;
-} _saudio_3ds_backend_t;
+} _saudio_n3ds_backend_t;
#else
#error "unknown platform"
@@ -1103,8 +1112,8 @@ typedef _saudio_aaudio_backend_t _saudio_backend_t;
typedef _saudio_alsa_backend_t _saudio_backend_t;
#elif defined(_SAUDIO_VITA)
typedef _saudio_vita_backend_t _saudio_backend_t;
-#elif defined(_SAUDIO_3DS)
-typedef _saudio_3ds_backend_t _saudio_backend_t;
+#elif defined(_SAUDIO_N3DS)
+typedef _saudio_n3ds_backend_t _saudio_backend_t;
#endif
/* a ringbuffer structure */
@@ -2354,23 +2363,24 @@ _SOKOL_PRIVATE void _saudio_vita_backend_shutdown(void) {
// ███████ ██████ ███████
//
// >>3ds
-#elif defined(_SAUDIO_3DS)
+#elif defined(_SAUDIO_N3DS)
+
+/* NDSP triggers a callback for _saudio_n3ds_cb on the main thread */
+_SOKOL_PRIVATE void _saudio_n3ds_cb(void*) {
+ if(_saudio.backend.thread_stop) {
+ return;
+ }
-/* NDSP triggers a callback for _saudio_3ds_cb on the main thread */
-_SOKOL_PRIVATE void _saudio_3ds_cb(void*) {
- const user_data_3ds_t* user_data = (user_data_3ds_t*)_saudio.desc.user_data;
- /* can probably move these 2 below to _saudio.backend? */
- static const int totalSamples = _saudio.buffer_frames * _saudio.num_channels;
- static const float scale = 32767.0f;
+ const float scale = 32767.0f;
- ndspWaveBuf* bufferPtr = NULL;
- bufferPtr = NULL;
+ ndspWaveBuf* bufferPtr = 0;
+ bufferPtr = 0;
int i = 0;
/* pick an available queue */
- for (i = 0; i < user_data->queue_count; ++i) {
- if (_saudio.backend.queue_3ds[i].status == NDSP_WBUF_DONE) {
- bufferPtr = &_saudio.backend.queue_3ds[i];
+ for (i = 0; i < _saudio.backend.n3ds_desc.queue_count; ++i) {
+ if (_saudio.backend.queue_n3ds[i].status == NDSP_WBUF_DONE) {
+ bufferPtr = &_saudio.backend.queue_n3ds[i];
break;
}
}
@@ -2383,13 +2393,13 @@ _SOKOL_PRIVATE void _saudio_3ds_cb(void*) {
int16_t* target_buffer = bufferPtr->data_pcm16;
const float* source_buffer = _saudio.backend.buffer;
- for (i = 0; i < totalSamples; i++) {
- /* data_pcm16 points to a region in the linear alloc _saudio.backend.buffer_3ds */
+ for (i = 0; i < _saudio.backend.samples_per_buffer; i++) {
+ /* data_pcm16 points to a region in the linear alloc _saudio.backend.buffer_n3ds */
target_buffer[i] = (int16_t)(source_buffer[i] * scale);
}
bufferPtr->nsamples = _saudio.buffer_frames; /* nsamples is actually frames */
- ndspChnWaveBufAdd(user_data->channel_id, bufferPtr);
+ ndspChnWaveBufAdd(_saudio.backend.n3ds_desc.channel_id, bufferPtr);
DSP_FlushDataCache(target_buffer, bufferPtr->nsamples * sizeof(int16_t));
/* fill the streaming buffer with new data */
@@ -2404,48 +2414,28 @@ _SOKOL_PRIVATE void _saudio_3ds_cb(void*) {
}
}
-_SOKOL_PRIVATE void _saudio_3ds_ndsptrigger_cb(void*) {
- if(_saudio.backend.thread_stop) {
- return;
- }
-
- /* ndsp requested more data. trigger cb */
- _saudio_3ds_cb(NULL);
-}
-
-_SOKOL_PRIVATE bool _saudio_3ds_backend_init(void) {
+_SOKOL_PRIVATE bool _saudio_n3ds_backend_init(void) {
int rc = ndspInit();
if (rc != 0) {
_SAUDIO_ERROR(N3DS_NDSP_OPEN_FAILED);
return false;
}
- if (_saudio.desc.user_data == NULL) {
- user_data_3ds_t* defaultUserData = (user_data_3ds_t*)_saudio_malloc(sizeof(user_data_3ds_t));
- if (defaultUserData == NULL) {
- _SAUDIO_ERROR(N3DS_USERDATA_DEFAULT_MALLOC_FAILED);
- return false;
- }
-
- defaultUserData->queue_count = 2;
- defaultUserData->interpolation_type = NDSP_INTERP_POLYPHASE;
- defaultUserData->channel_id = 0;
-
- _saudio.desc.user_data = defaultUserData;
- }
-
- user_data_3ds_t* user_data = (user_data_3ds_t*)_saudio.desc.user_data;
+ /* set defaults if not provided */
+ _saudio.backend.n3ds_desc.queue_count = _saudio_def(_saudio.desc.n3ds.queue_count, 2);
+ _saudio.backend.n3ds_desc.interpolation_type = _saudio_def(_saudio.desc.n3ds.interpolation_type, SAUDIO_N3DS_DSP_INTERP_POLYPHASE);
+ _saudio.backend.n3ds_desc.channel_id = _saudio_def(_saudio.desc.n3ds.channel_id, 0);
/* clamp to 2 channels max */
if (_saudio.num_channels > 2) {
_saudio.num_channels = 2;
}
- ndspChnReset(user_data->channel_id);
- ndspChnWaveBufClear(user_data->channel_id);
- ndspChnSetInterp(user_data->channel_id, user_data->interpolation_type);
- ndspChnSetRate(user_data->channel_id, _saudio.sample_rate);
- ndspChnSetFormat(user_data->channel_id, _saudio.num_channels == 1 ? NDSP_FORMAT_MONO_PCM16 : NDSP_FORMAT_STEREO_PCM16);
+ ndspChnReset(_saudio.backend.n3ds_desc.channel_id);
+ ndspChnWaveBufClear(_saudio.backend.n3ds_desc.channel_id);
+ ndspChnSetInterp(_saudio.backend.n3ds_desc.channel_id, (ndspInterpType)_saudio.backend.n3ds_desc.interpolation_type); /* cast to n3ds enum */
+ ndspChnSetRate(_saudio.backend.n3ds_desc.channel_id, _saudio.sample_rate);
+ ndspChnSetFormat(_saudio.backend.n3ds_desc.channel_id, _saudio.num_channels == 1 ? NDSP_FORMAT_MONO_PCM16 : NDSP_FORMAT_STEREO_PCM16);
ndspSetOutputMode(_saudio.num_channels == 1 ? NDSP_OUTPUT_MONO : NDSP_OUTPUT_STEREO);
/* read back actual sample rate and channels */
@@ -2453,42 +2443,40 @@ _SOKOL_PRIVATE bool _saudio_3ds_backend_init(void) {
_saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
/* allocate the streaming buffer */
+ _saudio.backend.samples_per_buffer = _saudio.buffer_frames * _saudio.num_channels;
_saudio.backend.buffer_byte_size = _saudio.buffer_frames * _saudio.bytes_per_frame;
_saudio.backend.buffer = (float*) _saudio_malloc_clear((size_t)_saudio.backend.buffer_byte_size);
- _saudio.backend.buffer_3ds = (int16_t*)linearAlloc(user_data->queue_count * _saudio.buffer_frames * _saudio.num_channels * sizeof(int16_t));
- _saudio.backend.queue_3ds = (ndspWaveBuf*)_saudio_malloc(user_data->queue_count * sizeof(ndspWaveBuf));
+ _saudio.backend.buffer_n3ds = (int16_t*)linearAlloc(_saudio.backend.n3ds_desc.queue_count * _saudio.backend.samples_per_buffer * sizeof(int16_t));
+ _saudio.backend.queue_n3ds = (ndspWaveBuf*)_saudio_malloc(_saudio.backend.n3ds_desc.queue_count * sizeof(ndspWaveBuf));
/* prepare the 3ds audio queues */
- int16_t* bufferPtrCopy = _saudio.backend.buffer_3ds;
- for (int i = 0; i < user_data->queue_count; ++i) {
- _saudio.backend.queue_3ds[i].data_vaddr = bufferPtrCopy; /* point the queue at the section of the linear buffer */
- _saudio.backend.queue_3ds[i].looping = false; /* the user should handle looping on their end */
- _saudio.backend.queue_3ds[i].status = NDSP_WBUF_DONE; /* default to done status for buffering logic */
+ int16_t* bufferPtrCopy = _saudio.backend.buffer_n3ds;
+ for (int i = 0; i < _saudio.backend.n3ds_desc.queue_count; ++i) {
+ _saudio.backend.queue_n3ds[i].data_vaddr = bufferPtrCopy; /* point the queue at the section of the linear buffer */
+ _saudio.backend.queue_n3ds[i].looping = false; /* the user should handle looping on their end */
+ _saudio.backend.queue_n3ds[i].status = NDSP_WBUF_DONE; /* default to done status for buffering logic */
- bufferPtrCopy += _saudio.buffer_frames * _saudio.num_channels;
+ bufferPtrCopy += _saudio.backend.samples_per_buffer;
}
- /* misc settings */
- _saudio.backend.channel_id = user_data->channel_id;
-
/* instead of a thread, ndsp will trigger a callback */
/* when it needs more data. */
- ndspSetCallback(_saudio_3ds_ndsptrigger_cb, NULL);
+ ndspSetCallback(_saudio_n3ds_cb, 0);
return true;
}
-_SOKOL_PRIVATE void _saudio_3ds_backend_shutdown(void) {
+_SOKOL_PRIVATE void _saudio_n3ds_backend_shutdown(void) {
_saudio.backend.thread_stop = true;
- if (_saudio.backend.channel_id >= 0) {
- ndspChnWaveBufClear(_saudio.backend.channel_id);
+ if (_saudio.backend.n3ds_desc.channel_id >= 0) {
+ ndspChnWaveBufClear(_saudio.backend.n3ds_desc.channel_id);
ndspExit();
- _saudio.backend.channel_id = -1;
+ _saudio.backend.n3ds_desc.channel_id = -1;
}
- _saudio_free(_saudio.backend.queue_3ds);
- _saudio_free(_saudio.backend.buffer_3ds);
+ _saudio_free(_saudio.backend.queue_n3ds);
+ _saudio_free(_saudio.backend.buffer_n3ds);
_saudio_free(_saudio.backend.buffer);
}
#else
@@ -2510,8 +2498,8 @@ bool _saudio_backend_init(void) {
return _saudio_coreaudio_backend_init();
#elif defined(_SAUDIO_VITA)
return _saudio_vita_backend_init();
- #elif defined(_SAUDIO_3DS)
- return _saudio_3ds_backend_init();
+ #elif defined(_SAUDIO_N3DS)
+ return _saudio_n3ds_backend_init();
#else
#error "unknown platform"
#endif
@@ -2532,8 +2520,8 @@ void _saudio_backend_shutdown(void) {
_saudio_coreaudio_backend_shutdown();
#elif defined(_SAUDIO_VITA)
_saudio_vita_backend_shutdown();
- #elif defined(_SAUDIO_3DS)
- _saudio_3ds_backend_shutdown();
+ #elif defined(_SAUDIO_N3DS)
+ _saudio_n3ds_backend_shutdown();
#else
#error "unknown platform"
#endif