Added audio stream conversion functions:

SDL_NewAudioStream
    SDL_AudioStreamPut
    SDL_AudioStreamGet
    SDL_AudioStreamAvailable
    SDL_AudioStreamClear
    SDL_FreeAudioStream
This commit is contained in:
Sam Lantinga
2017-10-18 15:54:05 -07:00
parent 9fd0d6191c
commit 80f8464d97
6 changed files with 140 additions and 62 deletions

View File

@@ -74,46 +74,6 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S32;
extern int SDL_PrepareResampleFilter(void);
extern void SDL_FreeResampleFilter(void);
/* SDL_AudioStream is a new audio conversion interface. It
might eventually become a public API.
The benefits vs SDL_AudioCVT:
- it can handle resampling data in chunks without generating
artifacts, when it doesn't have the complete buffer available.
- it can handle incoming data in any variable size.
- You push data as you have it, and pull it when you need it
(Note that currently this converts as data is put into the stream, so
you need to push more than a handful of bytes if you want decent
resampling. This can be changed later.)
*/
/* this is opaque to the outside world. */
typedef struct SDL_AudioStream SDL_AudioStream;
/* create a new stream */
extern SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format,
const Uint8 src_channels,
const int src_rate,
const SDL_AudioFormat dst_format,
const Uint8 dst_channels,
const int dst_rate);
/* add data to be converted/resampled to the stream */
extern int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 len);
/* get converted/resampled data from the stream */
extern int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len);
/* clear any pending data in the stream without converting it. */
extern void SDL_AudioStreamClear(SDL_AudioStream *stream);
/* number of converted/resampled bytes available */
extern int SDL_AudioStreamAvailable(SDL_AudioStream *stream);
/* dispose of a stream */
extern void SDL_FreeAudioStream(SDL_AudioStream *stream);
#endif /* SDL_audio_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1077,7 +1077,7 @@ typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *
typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream);
typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream);
struct SDL_AudioStream
struct _SDL_AudioStream
{
SDL_AudioCVT cvt_before_resampling;
SDL_AudioCVT cvt_after_resampling;
@@ -1349,9 +1349,9 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
}
int
SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
{
int buflen = (int) _buflen;
int buflen = len;
int workbuflen;
Uint8 *workbuf;
Uint8 *resamplebuf = NULL;
@@ -1495,34 +1495,19 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle
return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0;
}
void
SDL_AudioStreamClear(SDL_AudioStream *stream)
{
if (!stream) {
SDL_InvalidParamError("stream");
} else {
SDL_ClearDataQueue(stream->queue, stream->packetlen * 2);
if (stream->reset_resampler_func) {
stream->reset_resampler_func(stream);
}
stream->first_run = SDL_TRUE;
}
}
/* get converted/resampled data from the stream */
int
SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len)
SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
{
#if DEBUG_AUDIOSTREAM
printf("AUDIOSTREAM: want to get %u converted bytes\n", (unsigned int) len);
printf("AUDIOSTREAM: want to get %d converted bytes\n", len);
#endif
if (!stream) {
return SDL_InvalidParamError("stream");
} else if (!buf) {
return SDL_InvalidParamError("buf");
} else if (len == 0) {
} else if (len <= 0) {
return 0; /* nothing to do. */
} else if ((len % stream->dst_sample_frame_size) != 0) {
return SDL_SetError("Can't request partial sample frames");
@@ -1538,6 +1523,20 @@ SDL_AudioStreamAvailable(SDL_AudioStream *stream)
return stream ? (int) SDL_CountDataQueue(stream->queue) : 0;
}
void
SDL_AudioStreamClear(SDL_AudioStream *stream)
{
if (!stream) {
SDL_InvalidParamError("stream");
} else {
SDL_ClearDataQueue(stream->queue, stream->packetlen * 2);
if (stream->reset_resampler_func) {
stream->reset_resampler_func(stream);
}
stream->first_run = SDL_TRUE;
}
}
/* dispose of a stream */
void
SDL_FreeAudioStream(SDL_AudioStream *stream)

View File

@@ -640,3 +640,9 @@
#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL
#define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL
#define SDL_GetNumAllocations SDL_GetNumAllocations_REAL
#define SDL_NewAudioStream SDL_NewAudioStream_REAL
#define SDL_AudioStreamPut SDL_AudioStreamPut_REAL
#define SDL_AudioStreamGet SDL_AudioStreamGet_REAL
#define SDL_AudioStreamClear SDL_AudioStreamClear_REAL
#define SDL_AudioStreamAvailable SDL_AudioStreamAvailable_REAL
#define SDL_FreeAudioStream SDL_FreeAudioStream_REAL

View File

@@ -674,3 +674,9 @@ SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),)
SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
SDL_DYNAPI_PROC(int,SDL_SetMemoryFunctions,(SDL_malloc_func a, SDL_calloc_func b, SDL_realloc_func c, SDL_free_func d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return)
SDL_DYNAPI_PROC(SDL_AudioStream*,SDL_NewAudioStream,(const SDL_AudioFormat a, const Uint8 b, const int c, const SDL_AudioFormat d, const Uint8 e, const int f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(int,SDL_AudioStreamPut,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_AudioStreamGet,(SDL_AudioStream *a, void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_AudioStreamClear,(SDL_AudioStream *a),(a),)
SDL_DYNAPI_PROC(int,SDL_AudioStreamAvailable,(SDL_AudioStream *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_FreeAudioStream,(SDL_AudioStream *a),(a),)