include/SDL_audio.h
author Sam Lantinga <slouken@libsdl.org>
Mon, 12 Jun 2017 16:39:15 -0700
changeset 11096 819384789a7a
parent 10920 ffdf6433884c
child 11319 86b1fde471c6
permissions -rw-r--r--
Fixed bug 3668 - Overflow of SDL_AudioCVT.filters with some downmixes

Simon Hug

There's a chance that an audio conversion from many channels to a few can use more than 9 audio filters. SDL_AudioCVT has 10 SDL_AudioFilter pointers of which one has to be the terminating NULL pointer. The SDL code has no checks for this limit. If it overflows there can be stack or heap corruption or a call to 0xa.

Attached patch adds a function that checks for this limit and throws an error if it is reached. Also adds some documentation.

Test parameters that trigger this issue:
AUDIO_U16MSB with 224 channels at 46359 Hz
V
AUDIO_S16MSB with 6 channels at 27463 Hz

The fuzzer program I uploaded in bug 3667 has more of them.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@0
    21
slouken@1895
    22
/**
slouken@3407
    23
 *  \file SDL_audio.h
slouken@7191
    24
 *
slouken@3407
    25
 *  Access to the raw audio mixing buffer for the SDL library.
slouken@1895
    26
 */
slouken@0
    27
slouken@10638
    28
#ifndef SDL_audio_h_
slouken@10638
    29
#define SDL_audio_h_
slouken@0
    30
slouken@1353
    31
#include "SDL_stdinc.h"
slouken@0
    32
#include "SDL_error.h"
slouken@1358
    33
#include "SDL_endian.h"
slouken@1358
    34
#include "SDL_mutex.h"
slouken@1358
    35
#include "SDL_thread.h"
slouken@0
    36
#include "SDL_rwops.h"
slouken@0
    37
slouken@0
    38
#include "begin_code.h"
slouken@0
    39
/* Set up for C function definitions, even when using C++ */
slouken@0
    40
#ifdef __cplusplus
slouken@0
    41
extern "C" {
slouken@0
    42
#endif
slouken@0
    43
slouken@3407
    44
/**
slouken@3407
    45
 *  \brief Audio format flags.
slouken@7191
    46
 *
slouken@3407
    47
 *  These are what the 16 bits in SDL_AudioFormat currently mean...
slouken@3407
    48
 *  (Unspecified bits are always zero).
slouken@7191
    49
 *
slouken@3407
    50
 *  \verbatim
slouken@3407
    51
    ++-----------------------sample is signed if set
slouken@3407
    52
    ||
slouken@3407
    53
    ||       ++-----------sample is bigendian if set
slouken@3407
    54
    ||       ||
slouken@3407
    55
    ||       ||          ++---sample is float if set
slouken@3407
    56
    ||       ||          ||
slouken@3407
    57
    ||       ||          || +---sample bit size---+
slouken@3407
    58
    ||       ||          || |                     |
slouken@3407
    59
    15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
slouken@3407
    60
    \endverbatim
slouken@7191
    61
 *
slouken@6251
    62
 *  There are macros in SDL 2.0 and later to query these bits.
slouken@3407
    63
 */
icculus@1964
    64
typedef Uint16 SDL_AudioFormat;
icculus@1964
    65
slouken@3407
    66
/**
slouken@3407
    67
 *  \name Audio flags
slouken@3407
    68
 */
gabomdq@7678
    69
/* @{ */
icculus@1964
    70
icculus@1964
    71
#define SDL_AUDIO_MASK_BITSIZE       (0xFF)
icculus@1964
    72
#define SDL_AUDIO_MASK_DATATYPE      (1<<8)
icculus@1964
    73
#define SDL_AUDIO_MASK_ENDIAN        (1<<12)
icculus@1964
    74
#define SDL_AUDIO_MASK_SIGNED        (1<<15)
icculus@1964
    75
#define SDL_AUDIO_BITSIZE(x)         (x & SDL_AUDIO_MASK_BITSIZE)
icculus@1964
    76
#define SDL_AUDIO_ISFLOAT(x)         (x & SDL_AUDIO_MASK_DATATYPE)
icculus@1964
    77
#define SDL_AUDIO_ISBIGENDIAN(x)     (x & SDL_AUDIO_MASK_ENDIAN)
icculus@1964
    78
#define SDL_AUDIO_ISSIGNED(x)        (x & SDL_AUDIO_MASK_SIGNED)
icculus@1964
    79
#define SDL_AUDIO_ISINT(x)           (!SDL_AUDIO_ISFLOAT(x))
icculus@1964
    80
#define SDL_AUDIO_ISLITTLEENDIAN(x)  (!SDL_AUDIO_ISBIGENDIAN(x))
icculus@1964
    81
#define SDL_AUDIO_ISUNSIGNED(x)      (!SDL_AUDIO_ISSIGNED(x))
icculus@1964
    82
slouken@7191
    83
/**
slouken@3407
    84
 *  \name Audio format flags
slouken@3407
    85
 *
slouken@3407
    86
 *  Defaults to LSB byte order.
slouken@3407
    87
 */
gabomdq@7678
    88
/* @{ */
slouken@7191
    89
#define AUDIO_U8        0x0008  /**< Unsigned 8-bit samples */
slouken@7191
    90
#define AUDIO_S8        0x8008  /**< Signed 8-bit samples */
slouken@7191
    91
#define AUDIO_U16LSB    0x0010  /**< Unsigned 16-bit samples */
slouken@7191
    92
#define AUDIO_S16LSB    0x8010  /**< Signed 16-bit samples */
slouken@7191
    93
#define AUDIO_U16MSB    0x1010  /**< As above, but big-endian byte order */
slouken@7191
    94
#define AUDIO_S16MSB    0x9010  /**< As above, but big-endian byte order */
slouken@7191
    95
#define AUDIO_U16       AUDIO_U16LSB
slouken@7191
    96
#define AUDIO_S16       AUDIO_S16LSB
gabomdq@7678
    97
/* @} */
slouken@0
    98
slouken@3407
    99
/**
slouken@3407
   100
 *  \name int32 support
slouken@3407
   101
 */
gabomdq@7678
   102
/* @{ */
slouken@7191
   103
#define AUDIO_S32LSB    0x8020  /**< 32-bit integer samples */
slouken@7191
   104
#define AUDIO_S32MSB    0x9020  /**< As above, but big-endian byte order */
slouken@7191
   105
#define AUDIO_S32       AUDIO_S32LSB
gabomdq@7678
   106
/* @} */
icculus@1964
   107
slouken@3407
   108
/**
slouken@3407
   109
 *  \name float32 support
slouken@3407
   110
 */
gabomdq@7678
   111
/* @{ */
slouken@7191
   112
#define AUDIO_F32LSB    0x8120  /**< 32-bit floating point samples */
slouken@7191
   113
#define AUDIO_F32MSB    0x9120  /**< As above, but big-endian byte order */
slouken@7191
   114
#define AUDIO_F32       AUDIO_F32LSB
gabomdq@7678
   115
/* @} */
icculus@1964
   116
slouken@3407
   117
/**
slouken@3407
   118
 *  \name Native audio byte ordering
slouken@3407
   119
 */
gabomdq@7678
   120
/* @{ */
slouken@0
   121
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
slouken@7191
   122
#define AUDIO_U16SYS    AUDIO_U16LSB
slouken@7191
   123
#define AUDIO_S16SYS    AUDIO_S16LSB
slouken@7191
   124
#define AUDIO_S32SYS    AUDIO_S32LSB
slouken@7191
   125
#define AUDIO_F32SYS    AUDIO_F32LSB
slouken@0
   126
#else
slouken@7191
   127
#define AUDIO_U16SYS    AUDIO_U16MSB
slouken@7191
   128
#define AUDIO_S16SYS    AUDIO_S16MSB
slouken@7191
   129
#define AUDIO_S32SYS    AUDIO_S32MSB
slouken@7191
   130
#define AUDIO_F32SYS    AUDIO_F32MSB
slouken@0
   131
#endif
gabomdq@7678
   132
/* @} */
slouken@0
   133
slouken@7191
   134
/**
slouken@3407
   135
 *  \name Allow change flags
slouken@7191
   136
 *
slouken@3407
   137
 *  Which audio format changes are allowed when opening a device.
slouken@3407
   138
 */
gabomdq@7678
   139
/* @{ */
slouken@2866
   140
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE    0x00000001
slouken@2866
   141
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE       0x00000002
slouken@2866
   142
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE     0x00000004
slouken@2866
   143
#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
gabomdq@7678
   144
/* @} */
slouken@0
   145
gabomdq@7678
   146
/* @} *//* Audio flags */
slouken@3407
   147
slouken@3407
   148
/**
slouken@3554
   149
 *  This function is called when the audio device needs more data.
slouken@3554
   150
 *
slouken@3554
   151
 *  \param userdata An application-specific parameter saved in
slouken@3554
   152
 *                  the SDL_AudioSpec structure
slouken@3554
   153
 *  \param stream A pointer to the audio data buffer.
slouken@3554
   154
 *  \param len    The length of that buffer in bytes.
slouken@3554
   155
 *
slouken@3554
   156
 *  Once the callback returns, the buffer will no longer be valid.
slouken@3554
   157
 *  Stereo samples are stored in a LRLRLR ordering.
icculus@9012
   158
 *
icculus@9012
   159
 *  You can choose to avoid callbacks and use SDL_QueueAudio() instead, if
icculus@9012
   160
 *  you like. Just open your audio device with a NULL callback.
slouken@3554
   161
 */
slouken@3554
   162
typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream,
slouken@3554
   163
                                            int len);
slouken@3554
   164
slouken@3554
   165
/**
slouken@3407
   166
 *  The calculated values in this structure are calculated by SDL_OpenAudio().
slouken@3407
   167
 */
slouken@3407
   168
typedef struct SDL_AudioSpec
slouken@3407
   169
{
slouken@3407
   170
    int freq;                   /**< DSP frequency -- samples per second */
slouken@3407
   171
    SDL_AudioFormat format;     /**< Audio data format */
slouken@3407
   172
    Uint8 channels;             /**< Number of channels: 1 mono, 2 stereo */
slouken@3407
   173
    Uint8 silence;              /**< Audio buffer silence value (calculated) */
icculus@10920
   174
    Uint16 samples;             /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */
slouken@3407
   175
    Uint16 padding;             /**< Necessary for some compile environments */
slouken@3407
   176
    Uint32 size;                /**< Audio buffer size in bytes (calculated) */
icculus@9012
   177
    SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */
icculus@9012
   178
    void *userdata;             /**< Userdata passed to callback (ignored for NULL callbacks). */
slouken@3407
   179
} SDL_AudioSpec;
slouken@3407
   180
slouken@3407
   181
icculus@1983
   182
struct SDL_AudioCVT;
slouken@1985
   183
typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt,
slouken@1985
   184
                                          SDL_AudioFormat format);
icculus@1983
   185
slouken@3407
   186
/**
slouken@11096
   187
 *  \brief Upper limit of filters in SDL_AudioCVT
slouken@11096
   188
 *
slouken@11096
   189
 *  The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is
slouken@11096
   190
 *  currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers,
slouken@11096
   191
 *  one of which is the terminating NULL pointer.
slouken@11096
   192
 */
slouken@11096
   193
#define SDL_AUDIOCVT_MAX_FILTERS 9
slouken@11096
   194
slouken@11096
   195
/**
slouken@11096
   196
 *  \struct SDL_AudioCVT
slouken@11096
   197
 *  \brief A structure to hold a set of audio conversion filters and buffers.
icculus@10845
   198
 *
icculus@10845
   199
 *  Note that various parts of the conversion pipeline can take advantage
icculus@10845
   200
 *  of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require
icculus@10845
   201
 *  you to pass it aligned data, but can possibly run much faster if you
icculus@10845
   202
 *  set both its (buf) field to a pointer that is aligned to 16 bytes, and its
icculus@10845
   203
 *  (len) field to something that's a multiple of 16, if possible.
slouken@3407
   204
 */
slouken@7546
   205
#ifdef __GNUC__
slouken@7546
   206
/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't
slouken@7546
   207
   pad it out to 88 bytes to guarantee ABI compatibility between compilers.
slouken@7546
   208
   vvv
slouken@7546
   209
   The next time we rev the ABI, make sure to size the ints and add padding.
slouken@7546
   210
*/
slouken@7546
   211
#define SDL_AUDIOCVT_PACKED __attribute__((packed))
slouken@7546
   212
#else
slouken@7546
   213
#define SDL_AUDIOCVT_PACKED
slouken@7546
   214
#endif
slouken@7546
   215
/* */
slouken@1895
   216
typedef struct SDL_AudioCVT
slouken@1895
   217
{
slouken@3407
   218
    int needed;                 /**< Set to 1 if conversion possible */
slouken@3407
   219
    SDL_AudioFormat src_format; /**< Source audio format */
slouken@3407
   220
    SDL_AudioFormat dst_format; /**< Target audio format */
slouken@3407
   221
    double rate_incr;           /**< Rate conversion increment */
slouken@3407
   222
    Uint8 *buf;                 /**< Buffer to hold entire audio data */
slouken@3407
   223
    int len;                    /**< Length of original audio buffer */
slouken@3407
   224
    int len_cvt;                /**< Length of converted audio buffer */
slouken@3407
   225
    int len_mult;               /**< buffer must be len*len_mult big */
slouken@3407
   226
    double len_ratio;           /**< Given len, final size is len*len_ratio */
slouken@11096
   227
    SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */
slouken@3407
   228
    int filter_index;           /**< Current audio conversion function */
slouken@7546
   229
} SDL_AUDIOCVT_PACKED SDL_AudioCVT;
slouken@0
   230
slouken@0
   231
slouken@0
   232
/* Function prototypes */
slouken@0
   233
slouken@3407
   234
/**
slouken@3407
   235
 *  \name Driver discovery functions
slouken@7191
   236
 *
slouken@3407
   237
 *  These functions return the list of built in audio drivers, in the
slouken@3407
   238
 *  order that they are normally initialized by default.
slouken@1895
   239
 */
gabomdq@7678
   240
/* @{ */
slouken@1895
   241
extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
slouken@1895
   242
extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index);
gabomdq@7678
   243
/* @} */
slouken@1895
   244
slouken@3407
   245
/**
slouken@3407
   246
 *  \name Initialization and cleanup
slouken@7191
   247
 *
slouken@3407
   248
 *  \internal These functions are used internally, and should not be used unless
slouken@7191
   249
 *            you have a specific need to specify the audio driver you want to
slouken@3407
   250
 *            use.  You should normally use SDL_Init() or SDL_InitSubSystem().
slouken@0
   251
 */
gabomdq@7678
   252
/* @{ */
slouken@337
   253
extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name);
slouken@337
   254
extern DECLSPEC void SDLCALL SDL_AudioQuit(void);
gabomdq@7678
   255
/* @} */
slouken@0
   256
slouken@3407
   257
/**
slouken@3407
   258
 *  This function returns the name of the current audio driver, or NULL
slouken@3407
   259
 *  if no driver has been initialized.
slouken@0
   260
 */
slouken@1895
   261
extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void);
slouken@0
   262
slouken@3407
   263
/**
slouken@3407
   264
 *  This function opens the audio device with the desired parameters, and
slouken@3407
   265
 *  returns 0 if successful, placing the actual hardware parameters in the
slouken@3407
   266
 *  structure pointed to by \c obtained.  If \c obtained is NULL, the audio
slouken@3407
   267
 *  data passed to the callback function will be guaranteed to be in the
slouken@3407
   268
 *  requested format, and will be automatically converted to the hardware
slouken@7191
   269
 *  audio format if necessary.  This function returns -1 if it failed
slouken@3407
   270
 *  to open the audio device, or couldn't set up the audio thread.
slouken@7191
   271
 *
slouken@3407
   272
 *  When filling in the desired audio spec structure,
slouken@3407
   273
 *    - \c desired->freq should be the desired audio frequency in samples-per-
slouken@3407
   274
 *      second.
slouken@3407
   275
 *    - \c desired->format should be the desired audio format.
slouken@7191
   276
 *    - \c desired->samples is the desired size of the audio buffer, in
slouken@7191
   277
 *      samples.  This number should be a power of two, and may be adjusted by
slouken@3407
   278
 *      the audio driver to a value more suitable for the hardware.  Good values
slouken@7191
   279
 *      seem to range between 512 and 8096 inclusive, depending on the
slouken@7191
   280
 *      application and CPU speed.  Smaller values yield faster response time,
slouken@7191
   281
 *      but can lead to underflow if the application is doing heavy processing
slouken@7191
   282
 *      and cannot fill the audio buffer in time.  A stereo sample consists of
slouken@3407
   283
 *      both right and left channels in LR ordering.
slouken@3407
   284
 *      Note that the number of samples is directly related to time by the
slouken@3407
   285
 *      following formula:  \code ms = (samples*1000)/freq \endcode
slouken@3407
   286
 *    - \c desired->size is the size in bytes of the audio buffer, and is
slouken@3407
   287
 *      calculated by SDL_OpenAudio().
slouken@3407
   288
 *    - \c desired->silence is the value used to set the buffer to silence,
slouken@3407
   289
 *      and is calculated by SDL_OpenAudio().
slouken@3407
   290
 *    - \c desired->callback should be set to a function that will be called
slouken@3407
   291
 *      when the audio device is ready for more data.  It is passed a pointer
slouken@3407
   292
 *      to the audio buffer, and the length in bytes of the audio buffer.
slouken@3407
   293
 *      This function usually runs in a separate thread, and so you should
slouken@3407
   294
 *      protect data structures that it accesses by calling SDL_LockAudio()
icculus@9012
   295
 *      and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL
icculus@9012
   296
 *      pointer here, and call SDL_QueueAudio() with some frequency, to queue
icculus@10262
   297
 *      more audio samples to be played (or for capture devices, call
icculus@10262
   298
 *      SDL_DequeueAudio() with some frequency, to obtain audio samples).
slouken@3407
   299
 *    - \c desired->userdata is passed as the first parameter to your callback
icculus@9012
   300
 *      function. If you passed a NULL callback, this value is ignored.
slouken@7191
   301
 *
slouken@3407
   302
 *  The audio device starts out playing silence when it's opened, and should
slouken@3407
   303
 *  be enabled for playing by calling \c SDL_PauseAudio(0) when you are ready
slouken@3407
   304
 *  for your audio callback function to be called.  Since the audio driver
slouken@3407
   305
 *  may modify the requested size of the audio buffer, you should allocate
slouken@3407
   306
 *  any local mixing buffers after you open the audio device.
slouken@0
   307
 */
slouken@2866
   308
extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired,
slouken@1895
   309
                                          SDL_AudioSpec * obtained);
slouken@0
   310
slouken@3407
   311
/**
slouken@3407
   312
 *  SDL Audio Device IDs.
slouken@7191
   313
 *
slouken@3407
   314
 *  A successful call to SDL_OpenAudio() is always device id 1, and legacy
icculus@1964
   315
 *  SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls
icculus@1964
   316
 *  always returns devices >= 2 on success. The legacy calls are good both
icculus@1964
   317
 *  for backwards compatibility and when you don't care about multiple,
icculus@1964
   318
 *  specific, or capture devices.
icculus@1964
   319
 */
icculus@1964
   320
typedef Uint32 SDL_AudioDeviceID;
icculus@1964
   321
slouken@3407
   322
/**
slouken@3407
   323
 *  Get the number of available devices exposed by the current driver.
icculus@1964
   324
 *  Only valid after a successfully initializing the audio subsystem.
icculus@2049
   325
 *  Returns -1 if an explicit list of devices can't be determined; this is
icculus@2049
   326
 *  not an error. For example, if SDL is set up to talk to a remote audio
icculus@2049
   327
 *  server, it can't list every one available on the Internet, but it will
icculus@2049
   328
 *  still allow a specific host to be specified to SDL_OpenAudioDevice().
slouken@7191
   329
 *
slouken@3407
   330
 *  In many common cases, when this function returns a value <= 0, it can still
icculus@2049
   331
 *  successfully open the default device (NULL for first argument of
icculus@2049
   332
 *  SDL_OpenAudioDevice()).
icculus@1964
   333
 */
icculus@1964
   334
extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture);
icculus@1964
   335
slouken@3407
   336
/**
slouken@3407
   337
 *  Get the human-readable name of a specific audio device.
icculus@1964
   338
 *  Must be a value between 0 and (number of audio devices-1).
icculus@1964
   339
 *  Only valid after a successfully initializing the audio subsystem.
icculus@2049
   340
 *  The values returned by this function reflect the latest call to
icculus@2049
   341
 *  SDL_GetNumAudioDevices(); recall that function to redetect available
icculus@2049
   342
 *  hardware.
slouken@7191
   343
 *
slouken@3407
   344
 *  The string returned by this function is UTF-8 encoded, read-only, and
icculus@2049
   345
 *  managed internally. You are not to free it. If you need to keep the
icculus@2049
   346
 *  string for any length of time, you should make your own copy of it, as it
icculus@2049
   347
 *  will be invalid next time any of several other SDL functions is called.
icculus@1964
   348
 */
icculus@2049
   349
extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index,
icculus@2049
   350
                                                           int iscapture);
icculus@1964
   351
icculus@1964
   352
slouken@3407
   353
/**
slouken@3407
   354
 *  Open a specific audio device. Passing in a device name of NULL requests
icculus@2049
   355
 *  the most reasonable default (and is equivalent to calling SDL_OpenAudio()).
slouken@7191
   356
 *
slouken@3407
   357
 *  The device name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but
icculus@2049
   358
 *  some drivers allow arbitrary and driver-specific strings, such as a
icculus@2049
   359
 *  hostname/IP address for a remote audio server, or a filename in the
icculus@2049
   360
 *  diskaudio driver.
slouken@7191
   361
 *
slouken@3407
   362
 *  \return 0 on error, a valid device ID that is >= 2 on success.
slouken@7191
   363
 *
icculus@2049
   364
 *  SDL_OpenAudio(), unlike this function, always acts on device ID 1.
icculus@1964
   365
 */
slouken@1967
   366
extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(const char
slouken@1967
   367
                                                              *device,
slouken@1967
   368
                                                              int iscapture,
slouken@1967
   369
                                                              const
slouken@1967
   370
                                                              SDL_AudioSpec *
slouken@1967
   371
                                                              desired,
slouken@1967
   372
                                                              SDL_AudioSpec *
slouken@2866
   373
                                                              obtained,
slouken@2866
   374
                                                              int
slouken@2866
   375
                                                              allowed_changes);
icculus@1964
   376
icculus@1964
   377
icculus@1964
   378
slouken@3407
   379
/**
slouken@3407
   380
 *  \name Audio state
slouken@7191
   381
 *
slouken@3407
   382
 *  Get the current audio state.
slouken@0
   383
 */
gabomdq@7678
   384
/* @{ */
slouken@1895
   385
typedef enum
slouken@1895
   386
{
slouken@1895
   387
    SDL_AUDIO_STOPPED = 0,
slouken@1895
   388
    SDL_AUDIO_PLAYING,
slouken@1895
   389
    SDL_AUDIO_PAUSED
slouken@3537
   390
} SDL_AudioStatus;
slouken@3537
   391
extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void);
slouken@0
   392
slouken@3537
   393
extern DECLSPEC SDL_AudioStatus SDLCALL
slouken@1967
   394
SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev);
gabomdq@7678
   395
/* @} *//* Audio State */
icculus@1964
   396
slouken@3407
   397
/**
slouken@3407
   398
 *  \name Pause audio functions
slouken@7191
   399
 *
slouken@3407
   400
 *  These functions pause and unpause the audio callback processing.
slouken@3407
   401
 *  They should be called with a parameter of 0 after opening the audio
slouken@3407
   402
 *  device to start playing sound.  This is so you can safely initialize
slouken@3407
   403
 *  data for your callback function after opening the audio device.
slouken@3407
   404
 *  Silence will be written to the audio device during the pause.
slouken@0
   405
 */
gabomdq@7678
   406
/* @{ */
slouken@337
   407
extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on);
icculus@1964
   408
extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev,
icculus@1964
   409
                                                  int pause_on);
gabomdq@7678
   410
/* @} *//* Pause audio functions */
slouken@0
   411
slouken@3407
   412
/**
slouken@3407
   413
 *  This function loads a WAVE from the data source, automatically freeing
slouken@3407
   414
 *  that source if \c freesrc is non-zero.  For example, to load a WAVE file,
slouken@3407
   415
 *  you could do:
slouken@3407
   416
 *  \code
slouken@7191
   417
 *      SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...);
slouken@3407
   418
 *  \endcode
slouken@0
   419
 *
slouken@3407
   420
 *  If this function succeeds, it returns the given SDL_AudioSpec,
slouken@3407
   421
 *  filled with the audio data format of the wave data, and sets
slouken@3407
   422
 *  \c *audio_buf to a malloc()'d buffer containing the audio data,
slouken@3407
   423
 *  and sets \c *audio_len to the length of that audio buffer, in bytes.
slouken@7191
   424
 *  You need to free the audio buffer with SDL_FreeWAV() when you are
slouken@3407
   425
 *  done with it.
slouken@0
   426
 *
slouken@7191
   427
 *  This function returns NULL and sets the SDL error message if the
slouken@7191
   428
 *  wave file cannot be opened, uses an unknown data format, or is
slouken@3407
   429
 *  corrupt.  Currently raw and MS-ADPCM WAVE files are supported.
slouken@0
   430
 */
slouken@1895
   431
extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src,
slouken@1895
   432
                                                      int freesrc,
slouken@1895
   433
                                                      SDL_AudioSpec * spec,
slouken@1895
   434
                                                      Uint8 ** audio_buf,
slouken@1895
   435
                                                      Uint32 * audio_len);
slouken@0
   436
slouken@7191
   437
/**
slouken@3407
   438
 *  Loads a WAV from a file.
slouken@3407
   439
 *  Compatibility convenience function.
slouken@3407
   440
 */
slouken@0
   441
#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \
slouken@7191
   442
    SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len)
slouken@0
   443
slouken@3407
   444
/**
slouken@3407
   445
 *  This function frees data previously allocated with SDL_LoadWAV_RW()
slouken@0
   446
 */
slouken@1895
   447
extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf);
slouken@0
   448
slouken@3407
   449
/**
slouken@3407
   450
 *  This function takes a source format and rate and a destination format
slouken@3407
   451
 *  and rate, and initializes the \c cvt structure with information needed
slouken@3407
   452
 *  by SDL_ConvertAudio() to convert a buffer of audio data from one format
slouken@3407
   453
 *  to the other.
slouken@7191
   454
 *
slouken@3407
   455
 *  \return -1 if the format conversion is not supported, 0 if there's
icculus@1964
   456
 *  no conversion needed, or 1 if the audio filter is set up.
slouken@0
   457
 */
slouken@1895
   458
extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
icculus@1983
   459
                                              SDL_AudioFormat src_format,
slouken@1895
   460
                                              Uint8 src_channels,
slouken@1895
   461
                                              int src_rate,
icculus@1983
   462
                                              SDL_AudioFormat dst_format,
slouken@1895
   463
                                              Uint8 dst_channels,
slouken@1895
   464
                                              int dst_rate);
slouken@0
   465
slouken@3407
   466
/**
slouken@3407
   467
 *  Once you have initialized the \c cvt structure using SDL_BuildAudioCVT(),
slouken@3407
   468
 *  created an audio buffer \c cvt->buf, and filled it with \c cvt->len bytes of
slouken@3407
   469
 *  audio data in the source format, this function will convert it in-place
slouken@3407
   470
 *  to the desired format.
slouken@7191
   471
 *
slouken@3407
   472
 *  The data conversion may expand the size of the audio data, so the buffer
slouken@3407
   473
 *  \c cvt->buf should be allocated after the \c cvt structure is initialized by
slouken@3407
   474
 *  SDL_BuildAudioCVT(), and should be \c cvt->len*cvt->len_mult bytes long.
slouken@0
   475
 */
slouken@1895
   476
extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt);
slouken@0
   477
slouken@3407
   478
#define SDL_MIX_MAXVOLUME 128
slouken@3407
   479
/**
slouken@3407
   480
 *  This takes two audio buffers of the playing audio format and mixes
slouken@3407
   481
 *  them, performing addition, volume adjustment, and overflow clipping.
slouken@3407
   482
 *  The volume ranges from 0 - 128, and should be set to ::SDL_MIX_MAXVOLUME
slouken@3407
   483
 *  for full audio volume.  Note this does not change hardware volume.
slouken@3407
   484
 *  This is provided for convenience -- you can mix your own audio data.
slouken@0
   485
 */
slouken@1895
   486
extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src,
slouken@1895
   487
                                          Uint32 len, int volume);
slouken@0
   488
slouken@3407
   489
/**
slouken@3407
   490
 *  This works like SDL_MixAudio(), but you specify the audio format instead of
icculus@1964
   491
 *  using the format of audio device 1. Thus it can be used when no audio
icculus@1964
   492
 *  device is open at all.
icculus@1964
   493
 */
slouken@1967
   494
extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst,
slouken@1967
   495
                                                const Uint8 * src,
icculus@1964
   496
                                                SDL_AudioFormat format,
icculus@1964
   497
                                                Uint32 len, int volume);
icculus@1964
   498
slouken@3407
   499
/**
icculus@9012
   500
 *  Queue more audio on non-callback devices.
icculus@9012
   501
 *
icculus@10262
   502
 *  (If you are looking to retrieve queued audio from a non-callback capture
icculus@10262
   503
 *  device, you want SDL_DequeueAudio() instead. This will return -1 to
icculus@10262
   504
 *  signify an error if you use it with capture devices.)
icculus@10262
   505
 *
icculus@9012
   506
 *  SDL offers two ways to feed audio to the device: you can either supply a
icculus@9012
   507
 *  callback that SDL triggers with some frequency to obtain more audio
icculus@9012
   508
 *  (pull method), or you can supply no callback, and then SDL will expect
icculus@9012
   509
 *  you to supply data at regular intervals (push method) with this function.
icculus@9012
   510
 *
icculus@9012
   511
 *  There are no limits on the amount of data you can queue, short of
icculus@9012
   512
 *  exhaustion of address space. Queued data will drain to the device as
icculus@9012
   513
 *  necessary without further intervention from you. If the device needs
icculus@9012
   514
 *  audio but there is not enough queued, it will play silence to make up
icculus@9012
   515
 *  the difference. This means you will have skips in your audio playback
icculus@9012
   516
 *  if you aren't routinely queueing sufficient data.
icculus@9012
   517
 *
icculus@9012
   518
 *  This function copies the supplied data, so you are safe to free it when
icculus@9012
   519
 *  the function returns. This function is thread-safe, but queueing to the
icculus@9012
   520
 *  same device from two threads at once does not promise which buffer will
icculus@9012
   521
 *  be queued first.
icculus@9012
   522
 *
icculus@9012
   523
 *  You may not queue audio on a device that is using an application-supplied
icculus@9012
   524
 *  callback; doing so returns an error. You have to use the audio callback
icculus@9012
   525
 *  or queue audio with this function, but not both.
icculus@9012
   526
 *
icculus@9012
   527
 *  You should not call SDL_LockAudio() on the device before queueing; SDL
icculus@9012
   528
 *  handles locking internally for this function.
icculus@9012
   529
 *
icculus@9012
   530
 *  \param dev The device ID to which we will queue audio.
icculus@9012
   531
 *  \param data The data to queue to the device for later playback.
icculus@9012
   532
 *  \param len The number of bytes (not samples!) to which (data) points.
icculus@9012
   533
 *  \return zero on success, -1 on error.
icculus@9012
   534
 *
icculus@9012
   535
 *  \sa SDL_GetQueuedAudioSize
icculus@9012
   536
 *  \sa SDL_ClearQueuedAudio
icculus@9012
   537
 */
icculus@9012
   538
extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len);
icculus@9012
   539
icculus@9012
   540
/**
icculus@10262
   541
 *  Dequeue more audio on non-callback devices.
icculus@10262
   542
 *
icculus@10262
   543
 *  (If you are looking to queue audio for output on a non-callback playback
icculus@10262
   544
 *  device, you want SDL_QueueAudio() instead. This will always return 0
icculus@10262
   545
 *  if you use it with playback devices.)
icculus@10262
   546
 *
icculus@10262
   547
 *  SDL offers two ways to retrieve audio from a capture device: you can
icculus@10262
   548
 *  either supply a callback that SDL triggers with some frequency as the
icculus@10262
   549
 *  device records more audio data, (push method), or you can supply no
icculus@10262
   550
 *  callback, and then SDL will expect you to retrieve data at regular
icculus@10262
   551
 *  intervals (pull method) with this function.
icculus@10262
   552
 *
icculus@10262
   553
 *  There are no limits on the amount of data you can queue, short of
icculus@10262
   554
 *  exhaustion of address space. Data from the device will keep queuing as
icculus@10262
   555
 *  necessary without further intervention from you. This means you will
icculus@10262
   556
 *  eventually run out of memory if you aren't routinely dequeueing data.
icculus@10262
   557
 *
icculus@10262
   558
 *  Capture devices will not queue data when paused; if you are expecting
icculus@10262
   559
 *  to not need captured audio for some length of time, use
icculus@10262
   560
 *  SDL_PauseAudioDevice() to stop the capture device from queueing more
icculus@10262
   561
 *  data. This can be useful during, say, level loading times. When
icculus@10262
   562
 *  unpaused, capture devices will start queueing data from that point,
icculus@10262
   563
 *  having flushed any capturable data available while paused.
icculus@10262
   564
 *
icculus@10262
   565
 *  This function is thread-safe, but dequeueing from the same device from
icculus@10262
   566
 *  two threads at once does not promise which thread will dequeued data
icculus@10262
   567
 *  first.
icculus@10262
   568
 *
icculus@10262
   569
 *  You may not dequeue audio from a device that is using an
icculus@10262
   570
 *  application-supplied callback; doing so returns an error. You have to use
icculus@10262
   571
 *  the audio callback, or dequeue audio with this function, but not both.
icculus@10262
   572
 *
icculus@10262
   573
 *  You should not call SDL_LockAudio() on the device before queueing; SDL
icculus@10262
   574
 *  handles locking internally for this function.
icculus@10262
   575
 *
icculus@10262
   576
 *  \param dev The device ID from which we will dequeue audio.
icculus@10262
   577
 *  \param data A pointer into where audio data should be copied.
icculus@10262
   578
 *  \param len The number of bytes (not samples!) to which (data) points.
icculus@10262
   579
 *  \return number of bytes dequeued, which could be less than requested.
icculus@10262
   580
 *
icculus@10262
   581
 *  \sa SDL_GetQueuedAudioSize
icculus@10262
   582
 *  \sa SDL_ClearQueuedAudio
icculus@10262
   583
 */
icculus@10262
   584
extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len);
icculus@10262
   585
icculus@10262
   586
/**
icculus@9012
   587
 *  Get the number of bytes of still-queued audio.
icculus@9012
   588
 *
icculus@10262
   589
 *  For playback device:
icculus@9012
   590
 *
icculus@10262
   591
 *    This is the number of bytes that have been queued for playback with
icculus@10262
   592
 *    SDL_QueueAudio(), but have not yet been sent to the hardware. This
icculus@10262
   593
 *    number may shrink at any time, so this only informs of pending data.
icculus@10262
   594
 *
icculus@10262
   595
 *    Once we've sent it to the hardware, this function can not decide the
icculus@10262
   596
 *    exact byte boundary of what has been played. It's possible that we just
icculus@10262
   597
 *    gave the hardware several kilobytes right before you called this
icculus@10262
   598
 *    function, but it hasn't played any of it yet, or maybe half of it, etc.
icculus@10262
   599
 *
icculus@10262
   600
 *  For capture devices:
icculus@10262
   601
 *
icculus@10262
   602
 *    This is the number of bytes that have been captured by the device and
icculus@10262
   603
 *    are waiting for you to dequeue. This number may grow at any time, so
icculus@10262
   604
 *    this only informs of the lower-bound of available data.
icculus@9012
   605
 *
icculus@9012
   606
 *  You may not queue audio on a device that is using an application-supplied
icculus@9012
   607
 *  callback; calling this function on such a device always returns 0.
icculus@10262
   608
 *  You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
icculus@10262
   609
 *  the audio callback, but not both.
icculus@9012
   610
 *
icculus@9012
   611
 *  You should not call SDL_LockAudio() on the device before querying; SDL
icculus@9012
   612
 *  handles locking internally for this function.
icculus@9012
   613
 *
icculus@9012
   614
 *  \param dev The device ID of which we will query queued audio size.
icculus@9012
   615
 *  \return Number of bytes (not samples!) of queued audio.
icculus@9012
   616
 *
icculus@9012
   617
 *  \sa SDL_QueueAudio
icculus@9012
   618
 *  \sa SDL_ClearQueuedAudio
icculus@9012
   619
 */
icculus@9012
   620
extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
icculus@9012
   621
icculus@9012
   622
/**
icculus@10262
   623
 *  Drop any queued audio data. For playback devices, this is any queued data
icculus@10262
   624
 *  still waiting to be submitted to the hardware. For capture devices, this
icculus@10262
   625
 *  is any data that was queued by the device that hasn't yet been dequeued by
icculus@10262
   626
 *  the application.
icculus@9012
   627
 *
icculus@10262
   628
 *  Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For
icculus@10262
   629
 *  playback devices, the hardware will start playing silence if more audio
icculus@10262
   630
 *  isn't queued. Unpaused capture devices will start filling the queue again
icculus@10262
   631
 *  as soon as they have more data available (which, depending on the state
icculus@10262
   632
 *  of the hardware and the thread, could be before this function call
icculus@10262
   633
 *  returns!).
icculus@9012
   634
 *
icculus@9012
   635
 *  This will not prevent playback of queued audio that's already been sent
icculus@9012
   636
 *  to the hardware, as we can not undo that, so expect there to be some
icculus@9012
   637
 *  fraction of a second of audio that might still be heard. This can be
icculus@9012
   638
 *  useful if you want to, say, drop any pending music during a level change
icculus@9012
   639
 *  in your game.
icculus@9012
   640
 *
icculus@9012
   641
 *  You may not queue audio on a device that is using an application-supplied
icculus@9012
   642
 *  callback; calling this function on such a device is always a no-op.
icculus@10262
   643
 *  You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
icculus@10262
   644
 *  the audio callback, but not both.
icculus@9012
   645
 *
icculus@9012
   646
 *  You should not call SDL_LockAudio() on the device before clearing the
icculus@9012
   647
 *  queue; SDL handles locking internally for this function.
icculus@9012
   648
 *
icculus@9012
   649
 *  This function always succeeds and thus returns void.
icculus@9012
   650
 *
icculus@9012
   651
 *  \param dev The device ID of which to clear the audio queue.
icculus@9012
   652
 *
icculus@9012
   653
 *  \sa SDL_QueueAudio
icculus@9012
   654
 *  \sa SDL_GetQueuedAudioSize
icculus@9012
   655
 */
icculus@9012
   656
extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev);
icculus@9012
   657
icculus@9012
   658
icculus@9012
   659
/**
slouken@3407
   660
 *  \name Audio lock functions
slouken@7191
   661
 *
slouken@3407
   662
 *  The lock manipulated by these functions protects the callback function.
slouken@7191
   663
 *  During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that
slouken@3407
   664
 *  the callback function is not running.  Do not call these from the callback
slouken@3407
   665
 *  function or you will cause deadlock.
slouken@0
   666
 */
gabomdq@7678
   667
/* @{ */
slouken@337
   668
extern DECLSPEC void SDLCALL SDL_LockAudio(void);
icculus@1964
   669
extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev);
slouken@337
   670
extern DECLSPEC void SDLCALL SDL_UnlockAudio(void);
icculus@1964
   671
extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev);
gabomdq@7678
   672
/* @} *//* Audio lock functions */
slouken@0
   673
slouken@3407
   674
/**
slouken@3407
   675
 *  This function shuts down audio processing and closes the audio device.
slouken@0
   676
 */
slouken@337
   677
extern DECLSPEC void SDLCALL SDL_CloseAudio(void);
icculus@1964
   678
extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev);
icculus@1964
   679
slouken@0
   680
/* Ends C function definitions when using C++ */
slouken@0
   681
#ifdef __cplusplus
slouken@0
   682
}
slouken@0
   683
#endif
slouken@0
   684
#include "close_code.h"
slouken@0
   685
slouken@10638
   686
#endif /* SDL_audio_h_ */
slouken@1895
   687
slouken@1895
   688
/* vi: set ts=4 sw=4 expandtab: */