aaudio: Use the callback interface.
This is allegedly lower-latency than the AAudioStream_write interface, but more importantly, it let me set this up to block in WaitDevice. Also turned on the low-latency performance mode, which trades battery life for a more efficient audio thread to some unspecified degree.main
parent
b49ce86765
commit
32a3fc3783
|
@ -37,10 +37,8 @@
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
AAudioStream *stream;
|
AAudioStream *stream;
|
||||||
|
|
||||||
Uint8 *mixbuf; // Raw mixing buffer
|
Uint8 *mixbuf; // Raw mixing buffer
|
||||||
int frame_size;
|
SDL_Semaphore *semaphore;
|
||||||
|
|
||||||
int resume; // Resume device if it was paused automatically
|
int resume; // Resume device if it was paused automatically
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,8 +73,13 @@ static int AAUDIO_LoadFunctions(AAUDIO_Data *data)
|
||||||
static void AAUDIO_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error)
|
static void AAUDIO_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error)
|
||||||
{
|
{
|
||||||
LOGI("SDL AAUDIO_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error));
|
LOGI("SDL AAUDIO_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error));
|
||||||
|
// !!! FIXME: you MUST NOT close the audio stream from this callback, so we cannot call SDL_AudioDeviceDisconnected here.
|
||||||
|
// !!! FIXME: but we should flag the device and kill it in WaitDevice/PlayDevice.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static aaudio_data_callback_result_t AAUDIO_dataCallback(AAudioStream *stream, void *userData, void *audioData, int32_t numFrames);
|
||||||
|
|
||||||
|
|
||||||
#define LIB_AAUDIO_SO "libaaudio.so"
|
#define LIB_AAUDIO_SO "libaaudio.so"
|
||||||
|
|
||||||
static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
|
@ -132,21 +135,39 @@ static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.AAudioStreamBuilder_setFormat(builder, format);
|
ctx.AAudioStreamBuilder_setFormat(builder, format);
|
||||||
|
ctx.AAudioStreamBuilder_setErrorCallback(builder, AAUDIO_errorCallback, device);
|
||||||
ctx.AAudioStreamBuilder_setErrorCallback(builder, AAUDIO_errorCallback, hidden);
|
ctx.AAudioStreamBuilder_setDataCallback(builder, AAUDIO_dataCallback, device);
|
||||||
|
ctx.AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
|
||||||
|
|
||||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||||
device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->sample_frames);
|
device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames);
|
||||||
|
|
||||||
res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream);
|
res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream);
|
||||||
ctx.AAudioStreamBuilder_delete(builder);
|
|
||||||
|
|
||||||
if (res != AAUDIO_OK) {
|
if (res != AAUDIO_OK) {
|
||||||
LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
|
LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
|
||||||
|
ctx.AAudioStreamBuilder_delete(builder);
|
||||||
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device->sample_frames = (int) ctx.AAudioStream_getFramesPerDataCallback(hidden->stream);
|
||||||
|
if (device->sample_frames == AAUDIO_UNSPECIFIED) {
|
||||||
|
// if this happens, figure out a reasonable sample frame count, tear down this stream and force it in a new stream.
|
||||||
|
device->sample_frames = (int) (ctx.AAudioStream_getBufferCapacityInFrames(hidden->stream) / 4);
|
||||||
|
LOGI("AAUDIO: Got a stream with unspecified sample frames per data callback! Retrying with %d frames...", device->sample_frames);
|
||||||
|
ctx.AAudioStream_close(hidden->stream);
|
||||||
|
ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames);
|
||||||
|
res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream);
|
||||||
|
if (res != AAUDIO_OK) { // oh well, we tried.
|
||||||
|
LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
|
||||||
|
ctx.AAudioStreamBuilder_delete(builder);
|
||||||
|
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.AAudioStreamBuilder_delete(builder);
|
||||||
|
|
||||||
device->spec.freq = ctx.AAudioStream_getSampleRate(hidden->stream);
|
device->spec.freq = ctx.AAudioStream_getSampleRate(hidden->stream);
|
||||||
device->spec.channels = ctx.AAudioStream_getChannelCount(hidden->stream);
|
device->spec.channels = ctx.AAudioStream_getChannelCount(hidden->stream);
|
||||||
|
|
||||||
|
@ -161,9 +182,7 @@ static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
return SDL_SetError("Got unexpected audio format %d from AAudioStream_getFormat", (int) format);
|
return SDL_SetError("Got unexpected audio format %d from AAudioStream_getFormat", (int) format);
|
||||||
}
|
}
|
||||||
|
|
||||||
device->sample_frames = ctx.AAudioStream_getBufferCapacityInFrames(hidden->stream) / 2;
|
LOGI("AAudio Actually opened %u hz %u bit chan %u %s samples %u",
|
||||||
|
|
||||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
|
||||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||||
device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames);
|
device->spec.channels, SDL_AUDIO_ISBIGENDIAN(device->spec.format) ? "BE" : "LE", device->sample_frames);
|
||||||
|
|
||||||
|
@ -178,7 +197,11 @@ static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
SDL_memset(hidden->mixbuf, device->silence_value, device->buffer_size);
|
SDL_memset(hidden->mixbuf, device->silence_value, device->buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden->frame_size = device->spec.channels * (SDL_AUDIO_BITSIZE(device->spec.format) / 8);
|
hidden->semaphore = SDL_CreateSemaphore(0);
|
||||||
|
if (!hidden->semaphore) {
|
||||||
|
LOGI("SDL Failed SDL_CreateSemaphore %s iscapture:%d", SDL_GetError(), iscapture);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
res = ctx.AAudioStream_requestStart(hidden->stream);
|
res = ctx.AAudioStream_requestStart(hidden->stream);
|
||||||
if (res != AAUDIO_OK) {
|
if (res != AAUDIO_OK) {
|
||||||
|
@ -193,20 +216,42 @@ static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
static void AAUDIO_CloseDevice(SDL_AudioDevice *device)
|
static void AAUDIO_CloseDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||||
if (hidden) {
|
|
||||||
LOGI(__func__);
|
LOGI(__func__);
|
||||||
|
|
||||||
|
if (hidden) {
|
||||||
if (hidden->stream) {
|
if (hidden->stream) {
|
||||||
ctx.AAudioStream_requestStop(hidden->stream);
|
ctx.AAudioStream_requestStop(hidden->stream);
|
||||||
|
// !!! FIXME: do we have to wait for the state to change to make sure all buffered audio has played, or will close do this (or will the system do this after the close)?
|
||||||
|
// !!! FIXME: also, will this definitely wait for a running data callback to finish, and then stop the callback from firing again?
|
||||||
ctx.AAudioStream_close(hidden->stream);
|
ctx.AAudioStream_close(hidden->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hidden->semaphore) {
|
||||||
|
SDL_DestroySemaphore(hidden->semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_free(hidden->mixbuf);
|
SDL_free(hidden->mixbuf);
|
||||||
SDL_free(hidden);
|
SDL_free(hidden);
|
||||||
device->hidden = NULL;
|
device->hidden = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// due to the way the aaudio data callback works, PlayDevice is a no-op. The callback collects audio while SDL camps in WaitDevice and
|
||||||
|
// fires a semaphore that will unblock WaitDevice and start a new iteration, so when the callback runs again, WaitDevice is ready
|
||||||
|
// to hand it more data.
|
||||||
|
static aaudio_data_callback_result_t AAUDIO_dataCallback(AAudioStream *stream, void *userData, void *audioData, int32_t numFrames)
|
||||||
|
{
|
||||||
|
SDL_AudioDevice *device = (SDL_AudioDevice *) userData;
|
||||||
|
SDL_assert(numFrames == device->sample_frames);
|
||||||
|
if (device->iscapture) {
|
||||||
|
SDL_memcpy(device->hidden->mixbuf, audioData, device->buffer_size);
|
||||||
|
} else {
|
||||||
|
SDL_memcpy(audioData, device->hidden->mixbuf, device->buffer_size);
|
||||||
|
}
|
||||||
|
SDL_PostSemaphore(device->hidden->semaphore);
|
||||||
|
return AAUDIO_CALLBACK_RESULT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
||||||
{
|
{
|
||||||
return device->hidden->mixbuf;
|
return device->hidden->mixbuf;
|
||||||
|
@ -214,44 +259,20 @@ static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
||||||
|
|
||||||
static void AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static void AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
AAudioStream *stream = device->hidden->stream;
|
SDL_WaitSemaphore(device->hidden->semaphore);
|
||||||
while (!SDL_AtomicGet(&device->shutdown) && ((int) ctx.AAudioStream_getBufferSizeInFrames(stream)) < device->sample_frames) {
|
|
||||||
SDL_Delay(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static void AAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
{
|
{
|
||||||
AAudioStream *stream = device->hidden->stream;
|
// AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice.
|
||||||
const aaudio_result_t res = ctx.AAudioStream_write(stream, buffer, device->sample_frames, 0);
|
|
||||||
if (res < 0) {
|
|
||||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
|
||||||
} else {
|
|
||||||
LOGI("SDL AAudio play: %d frames, wanted:%d frames", (int)res, sample_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Log under-run count
|
|
||||||
{
|
|
||||||
static int prev = 0;
|
|
||||||
int32_t cnt = ctx.AAudioStream_getXRunCount(hidden->stream);
|
|
||||||
if (cnt != prev) {
|
|
||||||
SDL_Log("AAudio underrun: %d - total: %d", cnt - prev, cnt);
|
|
||||||
prev = cnt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no need for a FlushCapture implementation, just don't read mixbuf until the next iteration.
|
||||||
static int AAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
static int AAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
const aaudio_result_t res = ctx.AAudioStream_read(device->hidden->stream, buffer, device->sample_frames, 0);
|
const int cpy = SDL_min(buflen, device->buffer_size);
|
||||||
if (res < 0) {
|
SDL_memcpy(buffer, device->hidden->mixbuf, cpy);
|
||||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
return cpy;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
LOGI("SDL AAudio capture:%d frames, wanted:%d frames", (int)res, buflen / device->hidden->frame_size);
|
|
||||||
return res * device->hidden->frame_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AAUDIO_Deinitialize(void)
|
static void AAUDIO_Deinitialize(void)
|
||||||
|
@ -377,6 +398,7 @@ void AAUDIO_ResumeDevices(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!! FIXME: do we need this now that we use the callback?
|
||||||
/*
|
/*
|
||||||
We can sometimes get into a state where AAudioStream_write() will just block forever until we pause and unpause.
|
We can sometimes get into a state where AAudioStream_write() will just block forever until we pause and unpause.
|
||||||
None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called.
|
None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called.
|
||||||
|
|
|
@ -32,15 +32,15 @@ SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aa
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
|
||||||
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
|
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
|
SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) /* API 28 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) /* API 28 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) /* API 28 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) /* API 28 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) /* API 28 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) /* API 28 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder * builder, aaudio_session_id_t sessionId)) /* API 28 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder * builder, aaudio_session_id_t sessionId)) /* API 28 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder * builder, bool privacySensitive)) /* API 30 */
|
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder * builder, bool privacySensitive)) /* API 30 */
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData))
|
SDL_PROC(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData))
|
||||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder * builder, int32_t numFrames))
|
SDL_PROC(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||||
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder * builder, AAudioStream_errorCallback callback, void *userData))
|
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder * builder, AAudioStream_errorCallback callback, void *userData))
|
||||||
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_openStream, (AAudioStreamBuilder * builder, AAudioStream **stream))
|
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_openStream, (AAudioStreamBuilder * builder, AAudioStream **stream))
|
||||||
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_delete, (AAudioStreamBuilder * builder))
|
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_delete, (AAudioStreamBuilder * builder))
|
||||||
|
@ -52,14 +52,14 @@ SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_requestFlush, (AAudioStream * stre
|
||||||
SDL_PROC(aaudio_result_t, AAudioStream_requestStop, (AAudioStream * stream))
|
SDL_PROC(aaudio_result_t, AAudioStream_requestStop, (AAudioStream * stream))
|
||||||
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream * stream))
|
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream * stream))
|
||||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream * stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream * stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
||||||
SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||||
SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream * stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_write, (AAudioStream * stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream * stream, int32_t numFrames))
|
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream * stream, int32_t numFrames))
|
||||||
SDL_PROC(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream * stream))
|
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream * stream))
|
||||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream * stream))
|
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream * stream))
|
||||||
SDL_PROC(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream * stream))
|
SDL_PROC(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream * stream))
|
||||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream))
|
SDL_PROC(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream))
|
||||||
SDL_PROC(int32_t, AAudioStream_getXRunCount, (AAudioStream * stream))
|
SDL_PROC_UNUSED(int32_t, AAudioStream_getXRunCount, (AAudioStream * stream))
|
||||||
SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream * stream))
|
SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream * stream))
|
||||||
SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream * stream))
|
SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream * stream))
|
||||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream * stream))
|
SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream * stream))
|
||||||
|
|
Loading…
Reference in New Issue