Commit 80f8464d97e94f81aba726430678dda0b941a23a

Sam Lantinga 2017-10-18T15:54:05

Added audio stream conversion functions: SDL_NewAudioStream SDL_AudioStreamPut SDL_AudioStreamGet SDL_AudioStreamAvailable SDL_AudioStreamClear SDL_FreeAudioStream

diff --git a/WhatsNew.txt b/WhatsNew.txt
index 04eeaad..3910359 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -6,6 +6,13 @@ This is a list of major changes in SDL's version history.
 ---------------------------------------------------------------------------
 
 General:
+* Added audio stream conversion functions:
+	SDL_NewAudioStream
+	SDL_AudioStreamPut
+	SDL_AudioStreamGet
+	SDL_AudioStreamAvailable
+	SDL_AudioStreamClear
+	SDL_FreeAudioStream
 * Added functions to query and set the SDL memory allocation functions:
 	SDL_GetMemoryFunctions()
 	SDL_SetMemoryFunctions()
diff --git a/include/SDL_audio.h b/include/SDL_audio.h
index 53277cb..b30c409 100644
--- a/include/SDL_audio.h
+++ b/include/SDL_audio.h
@@ -477,6 +477,106 @@ extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
  */
 extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt);
 
+/* SDL_AudioStream is a new audio conversion interface.
+   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
+ */
+/* this is opaque to the outside world. */
+struct _SDL_AudioStream;
+typedef struct _SDL_AudioStream SDL_AudioStream;
+
+/**
+ *  Create a new audio stream
+ *
+ *  \param src_format The format of the source audio
+ *  \param src_channels The number of channels of the source audio
+ *  \param src_rate The sampling rate of the source audio
+ *  \param dst_format The format of the desired audio output
+ *  \param dst_channels The number of channels of the desired audio output
+ *  \param dst_rate The sampling rate of the desired audio output
+ *  \return 0 on success, or -1 on error.
+ *
+ *  \sa SDL_AudioStreamPut
+ *  \sa SDL_AudioStreamGet
+ *  \sa SDL_AudioStreamAvailable
+ *  \sa SDL_AudioStreamClear
+ *  \sa SDL_FreeAudioStream
+ */
+extern DECLSPEC SDL_AudioStream * SDLCALL 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
+ *
+ *  \param stream The stream the audio data is being added to
+ *  \param buf A pointer to the audio data to add
+ *  \param int The number of bytes to write to the stream
+ *  \return 0 on success, or -1 on error.
+ *
+ *  \sa SDL_NewAudioStream
+ *  \sa SDL_AudioStreamGet
+ *  \sa SDL_AudioStreamAvailable
+ *  \sa SDL_AudioStreamClear
+ *  \sa SDL_FreeAudioStream
+ */
+extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len);
+
+/**
+ *  Get converted/resampled data from the stream
+ *
+ *  \param stream The stream the audio is being requested from
+ *  \param buf A buffer to fill with audio data
+ *  \param len The maximum number of bytes to fill
+ *  \return The number of bytes read from the stream, or -1 on error
+ *
+ *  \sa SDL_NewAudioStream
+ *  \sa SDL_AudioStreamPut
+ *  \sa SDL_AudioStreamAvailable
+ *  \sa SDL_AudioStreamClear
+ *  \sa SDL_FreeAudioStream
+ */
+extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len);
+
+/**
+ * Get the number of converted/resampled bytes available
+ *
+ *  \sa SDL_NewAudioStream
+ *  \sa SDL_AudioStreamPut
+ *  \sa SDL_AudioStreamGet
+ *  \sa SDL_AudioStreamClear
+ *  \sa SDL_FreeAudioStream
+ */
+extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream);
+
+/**
+ *  Clear any pending data in the stream without converting it
+ *
+ *  \sa SDL_NewAudioStream
+ *  \sa SDL_AudioStreamPut
+ *  \sa SDL_AudioStreamGet
+ *  \sa SDL_AudioStreamAvailable
+ *  \sa SDL_FreeAudioStream
+ */
+extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream);
+
+/**
+ * Free an audio stream
+ *
+ *  \sa SDL_NewAudioStream
+ *  \sa SDL_AudioStreamPut
+ *  \sa SDL_AudioStreamGet
+ *  \sa SDL_AudioStreamAvailable
+ *  \sa SDL_AudioStreamClear
+ */
+extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream);
+
 #define SDL_MIX_MAXVOLUME 128
 /**
  *  This takes two audio buffers of the playing audio format and mixes
@@ -532,7 +632,7 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst,
  *  \param dev The device ID to which we will queue audio.
  *  \param data The data to queue to the device for later playback.
  *  \param len The number of bytes (not samples!) to which (data) points.
- *  \return zero on success, -1 on error.
+ *  \return 0 on success, or -1 on error.
  *
  *  \sa SDL_GetQueuedAudioSize
  *  \sa SDL_ClearQueuedAudio
diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h
index 58ecf10..38c5bbb 100644
--- a/src/audio/SDL_audio_c.h
+++ b/src/audio/SDL_audio_c.h
@@ -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: */
diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c
index 3f505d7..25fe903 100644
--- a/src/audio/SDL_audiocvt.c
+++ b/src/audio/SDL_audiocvt.c
@@ -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)
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index a079e92..0770512 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -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
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 237c54a..e1372ef 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -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),)