mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-01 23:48:29 +00:00
audio: Added SDL_PutAudioStreamDataNoCopy.
This commit is contained in:
@@ -1414,6 +1414,82 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamOutputChannelMap(SDL_AudioStr
|
|||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len);
|
extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback that fires for completed SDL_PutAudioStreamDataNoCopy() data.
|
||||||
|
*
|
||||||
|
* When using SDL_PutAudioStreamDataNoCopy() to provide data to an
|
||||||
|
* SDL_AudioStream, it's not safe to dispose of the data until the stream
|
||||||
|
* has completely consumed it. Often times it's difficult to know exactly
|
||||||
|
* when this has happened.
|
||||||
|
*
|
||||||
|
* This callback fires once when the stream no longer needs the buffer,
|
||||||
|
* allowing the app to easily free or reuse it.
|
||||||
|
*
|
||||||
|
* \param userdata an opaque pointer provided by the app for their personal
|
||||||
|
* use.
|
||||||
|
* \param buf the pointer provided to SDL_PutAudioStreamDataNoCopy().
|
||||||
|
* \param buflen the size of buffer, in bytes, provided to
|
||||||
|
* SDL_PutAudioStreamDataNoCopy().
|
||||||
|
*
|
||||||
|
* \threadsafety This callbacks may run from any thread, so if you need to
|
||||||
|
* protect shared data, you should use SDL_LockAudioStream to
|
||||||
|
* serialize access; this lock will be held before your callback
|
||||||
|
* is called, so your callback does not need to manage the lock
|
||||||
|
* explicitly.
|
||||||
|
*
|
||||||
|
* \since This datatype is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetAudioStreamGetCallback
|
||||||
|
* \sa SDL_SetAudioStreamPutCallback
|
||||||
|
*/
|
||||||
|
typedef void (SDLCALL *SDL_AudioStreamDataCompleteCallback)(void *userdata, const void *buf, int buflen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add constant data to the stream.
|
||||||
|
*
|
||||||
|
* Unlike SDL_PutAudioStreamData(), this function does not make a copy of the
|
||||||
|
* provided data, instead storing the provided pointer. This means that the
|
||||||
|
* put operation does not need to allocate and copy the data, but the original
|
||||||
|
* data must remain available until the stream is done with it, either by
|
||||||
|
* being read from the stream in its entirety, or a call to
|
||||||
|
* SDL_ClearAudioStream() or SDL_DestroyAudioStream().
|
||||||
|
*
|
||||||
|
* The data must match the format/channels/samplerate specified in the latest
|
||||||
|
* call to SDL_SetAudioStreamFormat, or the format specified when creating the
|
||||||
|
* stream if it hasn't been changed.
|
||||||
|
*
|
||||||
|
* An optional callback may be provided, which is called when the stream no
|
||||||
|
* longer needs the data. Once this callback fires, the stream will not
|
||||||
|
* access the data again.
|
||||||
|
*
|
||||||
|
* Note that there is still an allocation to store tracking information,
|
||||||
|
* so this function is more efficient for larger blocks of data. If you're
|
||||||
|
* planning to put a few samples at a time, it will be more efficient to use
|
||||||
|
* SDL_PutAudioStreamData(), which allocates and buffers in blocks.
|
||||||
|
*
|
||||||
|
* \param stream the stream the audio data is being added to.
|
||||||
|
* \param buf a pointer to the audio data to add.
|
||||||
|
* \param len the number of bytes to write to the stream.
|
||||||
|
* \param callback the callback function to call when the data is no longer
|
||||||
|
* needed by the stream. May be NULL.
|
||||||
|
* \param userdata an opaque pointer provided to the callback for its own
|
||||||
|
* personal use.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread, but if the
|
||||||
|
* stream has a callback set, the caller might need to manage
|
||||||
|
* extra locking.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ClearAudioStream
|
||||||
|
* \sa SDL_FlushAudioStream
|
||||||
|
* \sa SDL_GetAudioStreamData
|
||||||
|
* \sa SDL_GetAudioStreamQueued
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_PutAudioStreamDataNoCopy(SDL_AudioStream *stream, const void *buf, int len, SDL_AudioStreamDataCompleteCallback callback, void *userdata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add data to the stream with each channel in a separate array.
|
* Add data to the stream with each channel in a separate array.
|
||||||
*
|
*
|
||||||
|
@@ -1026,6 +1026,29 @@ bool SDL_PutAudioStreamPlanarData(SDL_AudioStream *stream, const void * const *c
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SDLCALL DontFreeThisAudioBuffer(void *userdata, const void *buf, int len)
|
||||||
|
{
|
||||||
|
// We don't own the buffer, but know it will outlive the stream
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDL_PutAudioStreamDataNoCopy(SDL_AudioStream *stream, const void *buf, int len, SDL_AudioStreamDataCompleteCallback callback, void *userdata)
|
||||||
|
{
|
||||||
|
if (!stream) {
|
||||||
|
return SDL_InvalidParamError("stream");
|
||||||
|
} else if (!buf) {
|
||||||
|
return SDL_InvalidParamError("buf");
|
||||||
|
} else if (len < 0) {
|
||||||
|
return SDL_InvalidParamError("len");
|
||||||
|
} else if (len == 0) {
|
||||||
|
if (callback) {
|
||||||
|
callback(userdata, buf, len);
|
||||||
|
}
|
||||||
|
return true; // nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
return PutAudioStreamBuffer(stream, buf, len, callback ? callback : DontFreeThisAudioBuffer, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
bool SDL_FlushAudioStream(SDL_AudioStream *stream)
|
bool SDL_FlushAudioStream(SDL_AudioStream *stream)
|
||||||
{
|
{
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
@@ -1483,11 +1506,6 @@ void SDL_DestroyAudioStream(SDL_AudioStream *stream)
|
|||||||
SDL_free(stream);
|
SDL_free(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDLCALL DontFreeThisAudioBuffer(void *userdata, const void *buf, int len)
|
|
||||||
{
|
|
||||||
// We don't own the buffer, but know it will outlive the stream
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len)
|
bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_data, int src_len, const SDL_AudioSpec *dst_spec, Uint8 **dst_data, int *dst_len)
|
||||||
{
|
{
|
||||||
if (dst_data) {
|
if (dst_data) {
|
||||||
@@ -1514,8 +1532,7 @@ bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_dat
|
|||||||
|
|
||||||
SDL_AudioStream *stream = SDL_CreateAudioStream(src_spec, dst_spec);
|
SDL_AudioStream *stream = SDL_CreateAudioStream(src_spec, dst_spec);
|
||||||
if (stream) {
|
if (stream) {
|
||||||
if (PutAudioStreamBuffer(stream, src_data, src_len, DontFreeThisAudioBuffer, NULL) &&
|
if (SDL_PutAudioStreamDataNoCopy(stream, src_data, src_len, NULL, NULL) && SDL_FlushAudioStream(stream)) {
|
||||||
SDL_FlushAudioStream(stream)) {
|
|
||||||
dstlen = SDL_GetAudioStreamAvailable(stream);
|
dstlen = SDL_GetAudioStreamAvailable(stream);
|
||||||
if (dstlen >= 0) {
|
if (dstlen >= 0) {
|
||||||
dst = (Uint8 *)SDL_malloc(dstlen);
|
dst = (Uint8 *)SDL_malloc(dstlen);
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Internal functions used by SDL_AudioStream for queueing audio.
|
// Internal functions used by SDL_AudioStream for queueing audio.
|
||||||
|
|
||||||
typedef void (SDLCALL *SDL_ReleaseAudioBufferCallback)(void *userdata, const void *buffer, int buflen);
|
typedef SDL_AudioStreamDataCompleteCallback SDL_ReleaseAudioBufferCallback;
|
||||||
|
|
||||||
typedef struct SDL_AudioQueue SDL_AudioQueue;
|
typedef struct SDL_AudioQueue SDL_AudioQueue;
|
||||||
typedef struct SDL_AudioTrack SDL_AudioTrack;
|
typedef struct SDL_AudioTrack SDL_AudioTrack;
|
||||||
|
@@ -1253,6 +1253,7 @@ SDL3_0.0.0 {
|
|||||||
SDL_PutAudioStreamPlanarData;
|
SDL_PutAudioStreamPlanarData;
|
||||||
SDL_SetAudioIterationCallbacks;
|
SDL_SetAudioIterationCallbacks;
|
||||||
SDL_GetEventDescription;
|
SDL_GetEventDescription;
|
||||||
|
SDL_PutAudioStreamDataNoCopy;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
@@ -1278,3 +1278,4 @@
|
|||||||
#define SDL_PutAudioStreamPlanarData SDL_PutAudioStreamPlanarData_REAL
|
#define SDL_PutAudioStreamPlanarData SDL_PutAudioStreamPlanarData_REAL
|
||||||
#define SDL_SetAudioIterationCallbacks SDL_SetAudioIterationCallbacks_REAL
|
#define SDL_SetAudioIterationCallbacks SDL_SetAudioIterationCallbacks_REAL
|
||||||
#define SDL_GetEventDescription SDL_GetEventDescription_REAL
|
#define SDL_GetEventDescription SDL_GetEventDescription_REAL
|
||||||
|
#define SDL_PutAudioStreamDataNoCopy SDL_PutAudioStreamDataNoCopy_REAL
|
||||||
|
@@ -1286,3 +1286,4 @@ SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateGPURenderer,(SDL_Window *a,SDL_GPUShader
|
|||||||
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void * const*b,int c,int d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void * const*b,int c,int d),(a,b,c,d),return)
|
||||||
SDL_DYNAPI_PROC(bool,SDL_SetAudioIterationCallbacks,(SDL_AudioDeviceID a,SDL_AudioIterationCallback b,SDL_AudioIterationCallback c,void *d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(bool,SDL_SetAudioIterationCallbacks,(SDL_AudioDeviceID a,SDL_AudioIterationCallback b,SDL_AudioIterationCallback c,void *d),(a,b,c,d),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return)
|
||||||
|
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamDataNoCopy,(SDL_AudioStream *a,const void *b,int c,SDL_AudioStreamDataCompleteCallback d,void *e),(a,b,c,d,e),return)
|
||||||
|
Reference in New Issue
Block a user