mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-04-22 23:35:39 +00:00
audio: Separate channel maps out of SDL_AudioSpec.
This commit is contained in:
@@ -43,7 +43,12 @@
|
||||
* if you aren't reading from a file) as a basic means to load sound data into
|
||||
* your program.
|
||||
*
|
||||
* ## Channel layouts as SDL expects them
|
||||
* ## Channel layouts
|
||||
*
|
||||
* Audio data passing through SDL is uncompressed PCM data, interleaved.
|
||||
* One can provide their own decompression through an MP3, etc, decoder, but
|
||||
* SDL does not provide this directly. Each interleaved channel of data is
|
||||
* meant to be in a specific order.
|
||||
*
|
||||
* Abbreviations:
|
||||
*
|
||||
@@ -76,7 +81,7 @@
|
||||
* platforms; SDL will swizzle the channels as necessary if a platform expects
|
||||
* something different.
|
||||
*
|
||||
* SDL_AudioStream can also be provided a channel map to change this ordering
|
||||
* SDL_AudioStream can also be provided channel maps to change this ordering
|
||||
* to whatever is necessary, in other audio processing scenarios.
|
||||
*/
|
||||
|
||||
@@ -301,18 +306,6 @@ typedef Uint32 SDL_AudioDeviceID;
|
||||
*/
|
||||
#define SDL_AUDIO_DEVICE_DEFAULT_RECORDING ((SDL_AudioDeviceID) 0xFFFFFFFE)
|
||||
|
||||
/**
|
||||
* Maximum channels that an SDL_AudioSpec channel map can handle.
|
||||
*
|
||||
* This is (currently) double the number of channels that SDL supports, to
|
||||
* allow for future expansion while maintaining binary compatibility.
|
||||
*
|
||||
* \since This macro is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_AudioSpec
|
||||
*/
|
||||
#define SDL_MAX_CHANNEL_MAP_SIZE 16
|
||||
|
||||
/**
|
||||
* Format specifier for audio data.
|
||||
*
|
||||
@@ -325,8 +318,6 @@ typedef struct SDL_AudioSpec
|
||||
SDL_AudioFormat format; /**< Audio data format */
|
||||
int channels; /**< Number of channels: 1 mono, 2 stereo, etc */
|
||||
int freq; /**< sample rate: sample frames per second */
|
||||
SDL_bool use_channel_map; /**< If SDL_FALSE, ignore `channel_map` and use default order. */
|
||||
Uint8 channel_map[SDL_MAX_CHANNEL_MAP_SIZE]; /**< `channels` items of channel order. */
|
||||
} SDL_AudioSpec;
|
||||
|
||||
/**
|
||||
@@ -560,6 +551,29 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(SDL_AudioDeviceID
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames);
|
||||
|
||||
/**
|
||||
* Get the current channel map of an audio device.
|
||||
*
|
||||
* Channel maps are optional; most things do not need them, instead passing
|
||||
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
|
||||
*
|
||||
* Audio devices usually have no remapping applied. This is represented by
|
||||
* returning NULL, and does not signify an error.
|
||||
*
|
||||
* The returned array follows the SDL_GetStringRule (even though, strictly
|
||||
* speaking, it isn't a string, it has the same memory manangement rules).
|
||||
*
|
||||
* \param devid the instance ID of the device to query.
|
||||
* \param count On output, set to number of channels in the map. Can be NULL.
|
||||
* \returns an array of the current channel mapping, with as many elements as the current output spec's channels, or NULL if default.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetAudioStreamInputChannelMap
|
||||
*/
|
||||
extern SDL_DECLSPEC const int * SDLCALL SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count);
|
||||
|
||||
/**
|
||||
* Open a specific audio device.
|
||||
@@ -1081,6 +1095,151 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetAudioStreamGain(SDL_AudioStream *stream
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamGain(SDL_AudioStream *stream, float gain);
|
||||
|
||||
/**
|
||||
* Get the current input channel map of an audio stream.
|
||||
*
|
||||
* Channel maps are optional; most things do not need them, instead passing
|
||||
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
|
||||
*
|
||||
* Audio streams default to no remapping applied. This is represented by
|
||||
* returning NULL, and does not signify an error.
|
||||
*
|
||||
* The returned array follows the SDL_GetStringRule (even though, strictly
|
||||
* speaking, it isn't a string, it has the same memory manangement rules).
|
||||
*
|
||||
* \param stream the SDL_AudioStream to query.
|
||||
* \param count On output, set to number of channels in the map. Can be NULL.
|
||||
* \returns an array of the current channel mapping, with as many elements as the current output spec's channels, or NULL if default.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, as it holds
|
||||
* a stream-specific mutex while running.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetAudioStreamInputChannelMap
|
||||
*/
|
||||
extern SDL_DECLSPEC const int * SDLCALL SDL_GetAudioStreamInputChannelMap(SDL_AudioStream *stream, int *count);
|
||||
|
||||
/**
|
||||
* Get the current output channel map of an audio stream.
|
||||
*
|
||||
* Channel maps are optional; most things do not need them, instead passing
|
||||
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
|
||||
*
|
||||
* Audio streams default to no remapping applied. This is represented by
|
||||
* returning NULL, and does not signify an error.
|
||||
*
|
||||
* The returned array follows the SDL_GetStringRule (even though, strictly
|
||||
* speaking, it isn't a string, it has the same memory manangement rules).
|
||||
*
|
||||
* \param stream the SDL_AudioStream to query.
|
||||
* \param count On output, set to number of channels in the map. Can be NULL.
|
||||
* \returns an array of the current channel mapping, with as many elements as the current output spec's channels, or NULL if default.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, as it holds
|
||||
* a stream-specific mutex while running.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetAudioStreamInputChannelMap
|
||||
*/
|
||||
extern SDL_DECLSPEC const int * SDLCALL SDL_GetAudioStreamOutputChannelMap(SDL_AudioStream *stream, int *count);
|
||||
|
||||
/**
|
||||
* Set the current input channel map of an audio stream.
|
||||
*
|
||||
* Channel maps are optional; most things do not need them, instead passing
|
||||
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
|
||||
*
|
||||
* The input channel map reorders data that is added to a stream via
|
||||
* SDL_PutAudioStreamData. Future calls to SDL_PutAudioStreamData
|
||||
* must provide data in the new channel order.
|
||||
*
|
||||
* Each item in the array represents an input channel, and its value is the
|
||||
* channel that it should be remapped to. To reverse a stereo signal's left
|
||||
* and right values, you'd have an array of `{ 1, 0 }`. It is legal to remap
|
||||
* multiple channels to the same thing, so `{ 1, 1 }` would duplicate the
|
||||
* right channel to both channels of a stereo signal. You cannot change the
|
||||
* number of channels through a channel map, just reorder them.
|
||||
*
|
||||
* Data that was previously queued in the stream will still be operated on in
|
||||
* the order that was current when it was added, which is to say you can put
|
||||
* the end of a sound file in one order to a stream, change orders for the
|
||||
* next sound file, and start putting that new data while the previous sound
|
||||
* file is still queued, and everything will still play back correctly.
|
||||
*
|
||||
* Audio streams default to no remapping applied. Passing a NULL channel map
|
||||
* is legal, and turns off remapping.
|
||||
*
|
||||
* SDL will copy the channel map; the caller does not have to save this array
|
||||
* after this call.
|
||||
*
|
||||
* If `count` is not equal to the current number of channels in the audio
|
||||
* stream's format, this will fail. This is a safety measure to make sure a
|
||||
* a race condition hasn't changed the format while you this call is setting
|
||||
* the channel map.
|
||||
*
|
||||
* \param stream the SDL_AudioStream to change.
|
||||
* \param chmap the new channel map, NULL to reset to default.
|
||||
* \param count The number of channels in the map.
|
||||
* \returns 0 on success, -1 on error.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, as it holds
|
||||
* a stream-specific mutex while running. Don't change the
|
||||
* stream's format to have a different number of channels from a
|
||||
* a different thread at the same time, though!
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetAudioStreamInputChannelMap
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamInputChannelMap(SDL_AudioStream *stream, const int *chmap, int count);
|
||||
|
||||
/**
|
||||
* Set the current output channel map of an audio stream.
|
||||
*
|
||||
* Channel maps are optional; most things do not need them, instead passing
|
||||
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
|
||||
*
|
||||
* The output channel map reorders data that leaving a stream via
|
||||
* SDL_GetAudioStreamData.
|
||||
*
|
||||
* Each item in the array represents an output channel, and its value is the
|
||||
* channel that it should be remapped to. To reverse a stereo signal's left
|
||||
* and right values, you'd have an array of `{ 1, 0 }`. It is legal to remap
|
||||
* multiple channels to the same thing, so `{ 1, 1 }` would duplicate the
|
||||
* right channel to both channels of a stereo signal. You cannot change the
|
||||
* number of channels through a channel map, just reorder them.
|
||||
*
|
||||
* The output channel map can be changed at any time, as output remapping is
|
||||
* applied during SDL_GetAudioStreamData.
|
||||
*
|
||||
* Audio streams default to no remapping applied. Passing a NULL channel map
|
||||
* is legal, and turns off remapping.
|
||||
*
|
||||
* SDL will copy the channel map; the caller does not have to save this array
|
||||
* after this call.
|
||||
*
|
||||
* If `count` is not equal to the current number of channels in the audio
|
||||
* stream's format, this will fail. This is a safety measure to make sure a
|
||||
* a race condition hasn't changed the format while you this call is setting
|
||||
* the channel map.
|
||||
*
|
||||
* \param stream the SDL_AudioStream to change.
|
||||
* \param chmap the new channel map, NULL to reset to default.
|
||||
* \param count The number of channels in the map.
|
||||
* \returns 0 on success, -1 on error.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, as it holds
|
||||
* a stream-specific mutex while running. Don't change the
|
||||
* stream's format to have a different number of channels from a
|
||||
* a different thread at the same time, though!
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetAudioStreamInputChannelMap
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamOutputChannelMap(SDL_AudioStream *stream, const int *chmap, int count);
|
||||
|
||||
/**
|
||||
* Add data to the stream.
|
||||
@@ -1505,7 +1664,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream)
|
||||
* Also unlike other functions, the audio device begins paused. This is to map
|
||||
* more closely to SDL2-style behavior, since there is no extra step here to
|
||||
* bind a stream to begin audio flowing. The audio device should be resumed
|
||||
* with `SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));`
|
||||
* with `SDL_ResumeAudioStreamDevice(stream);`
|
||||
*
|
||||
* This function works with both playback and recording devices.
|
||||
*
|
||||
@@ -1547,7 +1706,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream)
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetAudioStreamDevice
|
||||
* \sa SDL_ResumeAudioDevice
|
||||
* \sa SDL_ResumeAudioStreamDevice
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_AudioStream *SDLCALL SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec, SDL_AudioStreamCallback callback, void *userdata);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user