audio: Implemented buffer queueing for capture devices (SDL_DequeueAudio()).
parent
7bfe494c62
commit
7315390171
|
@ -278,7 +278,8 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void);
|
||||||
* protect data structures that it accesses by calling SDL_LockAudio()
|
* protect data structures that it accesses by calling SDL_LockAudio()
|
||||||
* and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL
|
* and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL
|
||||||
* pointer here, and call SDL_QueueAudio() with some frequency, to queue
|
* pointer here, and call SDL_QueueAudio() with some frequency, to queue
|
||||||
* more audio samples to be played.
|
* more audio samples to be played (or for capture devices, call
|
||||||
|
* SDL_DequeueAudio() with some frequency, to obtain audio samples).
|
||||||
* - \c desired->userdata is passed as the first parameter to your callback
|
* - \c desired->userdata is passed as the first parameter to your callback
|
||||||
* function. If you passed a NULL callback, this value is ignored.
|
* function. If you passed a NULL callback, this value is ignored.
|
||||||
*
|
*
|
||||||
|
@ -482,6 +483,10 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst,
|
||||||
/**
|
/**
|
||||||
* Queue more audio on non-callback devices.
|
* Queue more audio on non-callback devices.
|
||||||
*
|
*
|
||||||
|
* (If you are looking to retrieve queued audio from a non-callback capture
|
||||||
|
* device, you want SDL_DequeueAudio() instead. This will return -1 to
|
||||||
|
* signify an error if you use it with capture devices.)
|
||||||
|
*
|
||||||
* SDL offers two ways to feed audio to the device: you can either supply a
|
* SDL offers two ways to feed audio to the device: you can either supply a
|
||||||
* callback that SDL triggers with some frequency to obtain more audio
|
* callback that SDL triggers with some frequency to obtain more audio
|
||||||
* (pull method), or you can supply no callback, and then SDL will expect
|
* (pull method), or you can supply no callback, and then SDL will expect
|
||||||
|
@ -516,21 +521,76 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst,
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len);
|
extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dequeue more audio on non-callback devices.
|
||||||
|
*
|
||||||
|
* (If you are looking to queue audio for output on a non-callback playback
|
||||||
|
* device, you want SDL_QueueAudio() instead. This will always return 0
|
||||||
|
* if you use it with playback devices.)
|
||||||
|
*
|
||||||
|
* SDL offers two ways to retrieve audio from a capture device: you can
|
||||||
|
* either supply a callback that SDL triggers with some frequency as the
|
||||||
|
* device records more audio data, (push method), or you can supply no
|
||||||
|
* callback, and then SDL will expect you to retrieve data at regular
|
||||||
|
* intervals (pull method) with this function.
|
||||||
|
*
|
||||||
|
* There are no limits on the amount of data you can queue, short of
|
||||||
|
* exhaustion of address space. Data from the device will keep queuing as
|
||||||
|
* necessary without further intervention from you. This means you will
|
||||||
|
* eventually run out of memory if you aren't routinely dequeueing data.
|
||||||
|
*
|
||||||
|
* Capture devices will not queue data when paused; if you are expecting
|
||||||
|
* to not need captured audio for some length of time, use
|
||||||
|
* SDL_PauseAudioDevice() to stop the capture device from queueing more
|
||||||
|
* data. This can be useful during, say, level loading times. When
|
||||||
|
* unpaused, capture devices will start queueing data from that point,
|
||||||
|
* having flushed any capturable data available while paused.
|
||||||
|
*
|
||||||
|
* This function is thread-safe, but dequeueing from the same device from
|
||||||
|
* two threads at once does not promise which thread will dequeued data
|
||||||
|
* first.
|
||||||
|
*
|
||||||
|
* You may not dequeue audio from a device that is using an
|
||||||
|
* application-supplied callback; doing so returns an error. You have to use
|
||||||
|
* the audio callback, or dequeue audio with this function, but not both.
|
||||||
|
*
|
||||||
|
* You should not call SDL_LockAudio() on the device before queueing; SDL
|
||||||
|
* handles locking internally for this function.
|
||||||
|
*
|
||||||
|
* \param dev The device ID from which we will dequeue audio.
|
||||||
|
* \param data A pointer into where audio data should be copied.
|
||||||
|
* \param len The number of bytes (not samples!) to which (data) points.
|
||||||
|
* \return number of bytes dequeued, which could be less than requested.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetQueuedAudioSize
|
||||||
|
* \sa SDL_ClearQueuedAudio
|
||||||
|
*/
|
||||||
|
extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of bytes of still-queued audio.
|
* Get the number of bytes of still-queued audio.
|
||||||
*
|
*
|
||||||
* This is the number of bytes that have been queued for playback with
|
* For playback device:
|
||||||
* SDL_QueueAudio(), but have not yet been sent to the hardware.
|
|
||||||
*
|
*
|
||||||
* Once we've sent it to the hardware, this function can not decide the exact
|
* This is the number of bytes that have been queued for playback with
|
||||||
* byte boundary of what has been played. It's possible that we just gave the
|
* SDL_QueueAudio(), but have not yet been sent to the hardware. This
|
||||||
* hardware several kilobytes right before you called this function, but it
|
* number may shrink at any time, so this only informs of pending data.
|
||||||
* hasn't played any of it yet, or maybe half of it, etc.
|
*
|
||||||
|
* Once we've sent it to the hardware, this function can not decide the
|
||||||
|
* exact byte boundary of what has been played. It's possible that we just
|
||||||
|
* gave the hardware several kilobytes right before you called this
|
||||||
|
* function, but it hasn't played any of it yet, or maybe half of it, etc.
|
||||||
|
*
|
||||||
|
* For capture devices:
|
||||||
|
*
|
||||||
|
* This is the number of bytes that have been captured by the device and
|
||||||
|
* are waiting for you to dequeue. This number may grow at any time, so
|
||||||
|
* this only informs of the lower-bound of available data.
|
||||||
*
|
*
|
||||||
* You may not queue audio on a device that is using an application-supplied
|
* You may not queue audio on a device that is using an application-supplied
|
||||||
* callback; calling this function on such a device always returns 0.
|
* callback; calling this function on such a device always returns 0.
|
||||||
* You have to use the audio callback or queue audio with SDL_QueueAudio(),
|
* You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
|
||||||
* but not both.
|
* the audio callback, but not both.
|
||||||
*
|
*
|
||||||
* You should not call SDL_LockAudio() on the device before querying; SDL
|
* You should not call SDL_LockAudio() on the device before querying; SDL
|
||||||
* handles locking internally for this function.
|
* handles locking internally for this function.
|
||||||
|
@ -544,10 +604,17 @@ extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *da
|
||||||
extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
|
extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop any queued audio data waiting to be sent to the hardware.
|
* Drop any queued audio data. For playback devices, this is any queued data
|
||||||
|
* still waiting to be submitted to the hardware. For capture devices, this
|
||||||
|
* is any data that was queued by the device that hasn't yet been dequeued by
|
||||||
|
* the application.
|
||||||
*
|
*
|
||||||
* Immediately after this call, SDL_GetQueuedAudioSize() will return 0 and
|
* Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For
|
||||||
* the hardware will start playing silence if more audio isn't queued.
|
* playback devices, the hardware will start playing silence if more audio
|
||||||
|
* isn't queued. Unpaused capture devices will start filling the queue again
|
||||||
|
* as soon as they have more data available (which, depending on the state
|
||||||
|
* of the hardware and the thread, could be before this function call
|
||||||
|
* returns!).
|
||||||
*
|
*
|
||||||
* This will not prevent playback of queued audio that's already been sent
|
* This will not prevent playback of queued audio that's already been sent
|
||||||
* to the hardware, as we can not undo that, so expect there to be some
|
* to the hardware, as we can not undo that, so expect there to be some
|
||||||
|
@ -557,8 +624,8 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
|
||||||
*
|
*
|
||||||
* You may not queue audio on a device that is using an application-supplied
|
* You may not queue audio on a device that is using an application-supplied
|
||||||
* callback; calling this function on such a device is always a no-op.
|
* callback; calling this function on such a device is always a no-op.
|
||||||
* You have to use the audio callback or queue audio with SDL_QueueAudio(),
|
* You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
|
||||||
* but not both.
|
* the audio callback, but not both.
|
||||||
*
|
*
|
||||||
* You should not call SDL_LockAudio() on the device before clearing the
|
* You should not call SDL_LockAudio() on the device before clearing the
|
||||||
* queue; SDL handles locking internally for this function.
|
* queue; SDL handles locking internally for this function.
|
||||||
|
|
|
@ -433,77 +433,24 @@ SDL_RemoveAudioDevice(const int iscapture, void *handle)
|
||||||
|
|
||||||
/* this expects that you managed thread safety elsewhere. */
|
/* this expects that you managed thread safety elsewhere. */
|
||||||
static void
|
static void
|
||||||
free_audio_queue(SDL_AudioBufferQueue *buffer)
|
free_audio_queue(SDL_AudioBufferQueue *packet)
|
||||||
{
|
{
|
||||||
while (buffer) {
|
while (packet) {
|
||||||
SDL_AudioBufferQueue *next = buffer->next;
|
SDL_AudioBufferQueue *next = packet->next;
|
||||||
SDL_free(buffer);
|
SDL_free(packet);
|
||||||
buffer = next;
|
packet = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDLCALL
|
/* NOTE: This assumes you'll hold the mixer lock before calling! */
|
||||||
SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int _len)
|
static int
|
||||||
|
queue_audio_to_device(SDL_AudioDevice *device, const Uint8 *data, Uint32 len)
|
||||||
{
|
{
|
||||||
/* this function always holds the mixer lock before being called. */
|
|
||||||
Uint32 len = (Uint32) _len;
|
|
||||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
|
||||||
SDL_AudioBufferQueue *buffer;
|
|
||||||
|
|
||||||
SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
|
|
||||||
SDL_assert(_len >= 0); /* this shouldn't ever happen, right?! */
|
|
||||||
|
|
||||||
while ((len > 0) && ((buffer = device->buffer_queue_head) != NULL)) {
|
|
||||||
const Uint32 avail = buffer->datalen - buffer->startpos;
|
|
||||||
const Uint32 cpy = SDL_min(len, avail);
|
|
||||||
SDL_assert(device->queued_bytes >= avail);
|
|
||||||
|
|
||||||
SDL_memcpy(stream, buffer->data + buffer->startpos, cpy);
|
|
||||||
buffer->startpos += cpy;
|
|
||||||
stream += cpy;
|
|
||||||
device->queued_bytes -= cpy;
|
|
||||||
len -= cpy;
|
|
||||||
|
|
||||||
if (buffer->startpos == buffer->datalen) { /* packet is done, put it in the pool. */
|
|
||||||
device->buffer_queue_head = buffer->next;
|
|
||||||
SDL_assert((buffer->next != NULL) || (buffer == device->buffer_queue_tail));
|
|
||||||
buffer->next = device->buffer_queue_pool;
|
|
||||||
device->buffer_queue_pool = buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
|
|
||||||
|
|
||||||
if (len > 0) { /* fill any remaining space in the stream with silence. */
|
|
||||||
SDL_assert(device->buffer_queue_head == NULL);
|
|
||||||
SDL_memset(stream, device->spec.silence, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->buffer_queue_head == NULL) {
|
|
||||||
device->buffer_queue_tail = NULL; /* in case we drained the queue entirely. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
|
|
||||||
{
|
|
||||||
SDL_AudioDevice *device = get_audio_device(devid);
|
|
||||||
const Uint8 *data = (const Uint8 *) _data;
|
|
||||||
SDL_AudioBufferQueue *orighead;
|
SDL_AudioBufferQueue *orighead;
|
||||||
SDL_AudioBufferQueue *origtail;
|
SDL_AudioBufferQueue *origtail;
|
||||||
Uint32 origlen;
|
Uint32 origlen;
|
||||||
Uint32 datalen;
|
Uint32 datalen;
|
||||||
|
|
||||||
if (!device) {
|
|
||||||
return -1; /* get_audio_device() will have set the error state */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->spec.callback != SDL_BufferQueueDrainCallback) {
|
|
||||||
return SDL_SetError("Audio device has a callback, queueing not allowed");
|
|
||||||
}
|
|
||||||
|
|
||||||
current_audio.impl.LockDevice(device);
|
|
||||||
|
|
||||||
orighead = device->buffer_queue_head;
|
orighead = device->buffer_queue_head;
|
||||||
origtail = device->buffer_queue_tail;
|
origtail = device->buffer_queue_tail;
|
||||||
origlen = origtail ? origtail->datalen : 0;
|
origlen = origtail ? origtail->datalen : 0;
|
||||||
|
@ -533,8 +480,6 @@ SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
|
||||||
device->buffer_queue_tail = origtail;
|
device->buffer_queue_tail = origtail;
|
||||||
device->buffer_queue_pool = NULL;
|
device->buffer_queue_pool = NULL;
|
||||||
|
|
||||||
current_audio.impl.UnlockDevice(device);
|
|
||||||
|
|
||||||
free_audio_queue(packet); /* give back what we can. */
|
free_audio_queue(packet); /* give back what we can. */
|
||||||
|
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
|
@ -561,22 +506,142 @@ SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
|
||||||
device->queued_bytes += datalen;
|
device->queued_bytes += datalen;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_audio.impl.UnlockDevice(device);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: This assumes you'll hold the mixer lock before calling! */
|
||||||
|
static Uint32
|
||||||
|
dequeue_audio_from_device(SDL_AudioDevice *device, Uint8 *stream, Uint32 len)
|
||||||
|
{
|
||||||
|
SDL_AudioBufferQueue *packet;
|
||||||
|
Uint8 *ptr = stream;
|
||||||
|
|
||||||
|
while ((len > 0) && ((packet = device->buffer_queue_head) != NULL)) {
|
||||||
|
const Uint32 avail = packet->datalen - packet->startpos;
|
||||||
|
const Uint32 cpy = SDL_min(len, avail);
|
||||||
|
SDL_assert(device->queued_bytes >= avail);
|
||||||
|
|
||||||
|
SDL_memcpy(ptr, packet->data + packet->startpos, cpy);
|
||||||
|
packet->startpos += cpy;
|
||||||
|
ptr += cpy;
|
||||||
|
device->queued_bytes -= cpy;
|
||||||
|
len -= cpy;
|
||||||
|
|
||||||
|
if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */
|
||||||
|
device->buffer_queue_head = packet->next;
|
||||||
|
SDL_assert((packet->next != NULL) || (packet == device->buffer_queue_tail));
|
||||||
|
packet->next = device->buffer_queue_pool;
|
||||||
|
device->buffer_queue_pool = packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
|
||||||
|
|
||||||
|
if (device->buffer_queue_head == NULL) {
|
||||||
|
device->buffer_queue_tail = NULL; /* in case we drained the queue entirely. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Uint32) (ptr - stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLCALL
|
||||||
|
SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
|
||||||
|
{
|
||||||
|
/* this function always holds the mixer lock before being called. */
|
||||||
|
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||||
|
Uint32 written;
|
||||||
|
|
||||||
|
SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
|
||||||
|
SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */
|
||||||
|
SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */
|
||||||
|
|
||||||
|
written = dequeue_audio_from_device(device, stream, (Uint32) len);
|
||||||
|
stream += written;
|
||||||
|
len -= (int) written;
|
||||||
|
|
||||||
|
if (len > 0) { /* fill any remaining space in the stream with silence. */
|
||||||
|
SDL_assert(device->buffer_queue_head == NULL);
|
||||||
|
SDL_memset(stream, device->spec.silence, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLCALL
|
||||||
|
SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
|
||||||
|
{
|
||||||
|
/* this function always holds the mixer lock before being called. */
|
||||||
|
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||||
|
|
||||||
|
SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
|
||||||
|
SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */
|
||||||
|
SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */
|
||||||
|
|
||||||
|
/* note that if this needs to allocate more space and run out of memory,
|
||||||
|
we have no choice but to quietly drop the data and hope it works out
|
||||||
|
later, but you probably have bigger problems in this case anyhow. */
|
||||||
|
queue_audio_to_device(device, stream, (Uint32) len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
|
||||||
|
{
|
||||||
|
SDL_AudioDevice *device = get_audio_device(devid);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
return -1; /* get_audio_device() will have set the error state */
|
||||||
|
} else if (device->iscapture) {
|
||||||
|
return SDL_SetError("This is a capture device, queueing not allowed");
|
||||||
|
} else if (device->spec.callback != SDL_BufferQueueDrainCallback) {
|
||||||
|
return SDL_SetError("Audio device has a callback, queueing not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
current_audio.impl.LockDevice(device);
|
||||||
|
rc = queue_audio_to_device(device, data, len);
|
||||||
|
current_audio.impl.UnlockDevice(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32
|
||||||
|
SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len)
|
||||||
|
{
|
||||||
|
SDL_AudioDevice *device = get_audio_device(devid);
|
||||||
|
Uint32 rc;
|
||||||
|
|
||||||
|
if ( (len == 0) || /* nothing to do? */
|
||||||
|
(!device) || /* called with bogus device id */
|
||||||
|
(!device->iscapture) || /* playback devices can't dequeue */
|
||||||
|
(device->spec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */
|
||||||
|
return 0; /* just report zero bytes dequeued. */
|
||||||
|
}
|
||||||
|
|
||||||
|
current_audio.impl.LockDevice(device);
|
||||||
|
rc = dequeue_audio_from_device(device, data, len);
|
||||||
|
current_audio.impl.UnlockDevice(device);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
Uint32
|
Uint32
|
||||||
SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
|
SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
|
||||||
{
|
{
|
||||||
Uint32 retval = 0;
|
Uint32 retval = 0;
|
||||||
SDL_AudioDevice *device = get_audio_device(devid);
|
SDL_AudioDevice *device = get_audio_device(devid);
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Nothing to do unless we're set up for queueing. */
|
/* Nothing to do unless we're set up for queueing. */
|
||||||
if (device && (device->spec.callback == SDL_BufferQueueDrainCallback)) {
|
if (device->spec.callback == SDL_BufferQueueDrainCallback) {
|
||||||
current_audio.impl.LockDevice(device);
|
current_audio.impl.LockDevice(device);
|
||||||
retval = device->queued_bytes + current_audio.impl.GetPendingBytes(device);
|
retval = device->queued_bytes + current_audio.impl.GetPendingBytes(device);
|
||||||
current_audio.impl.UnlockDevice(device);
|
current_audio.impl.UnlockDevice(device);
|
||||||
|
} else if (device->spec.callback == SDL_BufferQueueFillCallback) {
|
||||||
|
current_audio.impl.LockDevice(device);
|
||||||
|
retval = device->queued_bytes;
|
||||||
|
current_audio.impl.UnlockDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1305,7 +1370,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device->spec.callback = SDL_BufferQueueDrainCallback;
|
device->spec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback;
|
||||||
device->spec.userdata = device;
|
device->spec.userdata = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,7 +1384,9 @@ open_audio_device(const char *devname, int iscapture,
|
||||||
/* !!! FIXME: we don't force the audio thread stack size here because it calls into user code, but maybe we should? */
|
/* !!! FIXME: we don't force the audio thread stack size here because it calls into user code, but maybe we should? */
|
||||||
/* buffer queueing callback only needs a few bytes, so make the stack tiny. */
|
/* buffer queueing callback only needs a few bytes, so make the stack tiny. */
|
||||||
char name[64];
|
char name[64];
|
||||||
const SDL_bool is_internal_thread = (device->spec.callback == SDL_BufferQueueDrainCallback);
|
const SDL_bool is_internal_thread =
|
||||||
|
(device->spec.callback == SDL_BufferQueueDrainCallback) ||
|
||||||
|
(device->spec.callback == SDL_BufferQueueFillCallback);
|
||||||
const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
|
const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
|
||||||
|
|
||||||
SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
|
SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
|
||||||
|
|
|
@ -605,3 +605,4 @@
|
||||||
#define SDL_SetWindowModalFor SDL_SetWindowModalFor_REAL
|
#define SDL_SetWindowModalFor SDL_SetWindowModalFor_REAL
|
||||||
#define SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale_REAL
|
#define SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale_REAL
|
||||||
#define SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale_REAL
|
#define SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale_REAL
|
||||||
|
#define SDL_DequeueAudio SDL_DequeueAudio_REAL
|
||||||
|
|
|
@ -639,3 +639,4 @@ SDL_DYNAPI_PROC(int,SDL_SetWindowInputFocus,(SDL_Window *a),(a),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_SetWindowModalFor,(SDL_Window *a, SDL_Window *b),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_SetWindowModalFor,(SDL_Window *a, SDL_Window *b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderSetIntegerScale,(SDL_Renderer *a, SDL_bool b),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderSetIntegerScale,(SDL_Renderer *a, SDL_bool b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderGetIntegerScale,(SDL_Renderer *a),(a),return)
|
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderGetIntegerScale,(SDL_Renderer *a),(a),return)
|
||||||
|
SDL_DYNAPI_PROC(Uint32,SDL_DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return)
|
||||||
|
|
Loading…
Reference in New Issue