audio: Add channel remapping to SDL_AudioSpec and SDL_AudioStream.

Fixes #8367.
This commit is contained in:
Ryan C. Gordon 2024-07-03 03:19:00 -04:00
parent 0367f1af19
commit 16e7fdc4f2
12 changed files with 254 additions and 193 deletions

View file

@ -43,20 +43,41 @@
* if you aren't reading from a file) as a basic means to load sound data into
* your program.
*
* For multi-channel audio, data is interleaved (one sample for each channel,
* then repeat). The SDL channel order is:
* ## Channel layouts as SDL expects them
*
* - Stereo: FL, FR
* - 2.1 surround: FL, FR, LFE
* - Quad: FL, FR, BL, BR
* - 4.1 surround: FL, FR, LFE, BL, BR
* - 5.1 surround: FL, FR, FC, LFE, SL, SR (last two can also be BL BR)
* - 6.1 surround: FL, FR, FC, LFE, BC, SL, SR
* - 7.1 surround: FL, FR, FC, LFE, BL, BR, SL, SR
* Abbreviations:
*
* - FRONT = single mono speaker
* - FL = front left speaker
* - FR = front right speaker
* - FC = front center speaker
* - BL = back left speaker
* - BR = back right speaker
* - SR = surround right speaker
* - SL = surround left speaker
* - BC = back center speaker
* - LFE = low-frequency speaker
*
* These are listed in the order they are laid out in
* memory, so "FL, FR" means "the front left speaker is
* laid out in memory first, then the front right, then
* it repeats for the next audio frame".
*
* - 1 channel (mono) layout: FRONT
* - 2 channels (stereo) layout: FL, FR
* - 3 channels (2.1) layout: FL, FR, LFE
* - 4 channels (quad) layout: FL, FR, BL, BR
* - 5 channels (4.1) layout: FL, FR, LFE, BL, BR
* - 6 channels (5.1) layout: FL, FR, FC, LFE, BL, BR (last two can also be BL, BR)
* - 7 channels (6.1) layout: FL, FR, FC, LFE, BC, SL, SR
* - 8 channels (7.1) layout: FL, FR, FC, LFE, BL, BR, SL, SR
*
* This is the same order as DirectSound expects, but applied to all
* 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
* to whatever is necessary, in other audio processing scenarios.
*/
#ifndef SDL_audio_h_
@ -280,6 +301,18 @@ 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.
*
@ -292,6 +325,8 @@ 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;
/**
@ -318,6 +353,7 @@ typedef struct SDL_AudioSpec
* when it doesn't have the complete buffer available.
* - It can handle incoming data in any variable size.
* - It can handle input/output format changes on the fly.
* - It can remap audio channels between inputs and outputs.
* - You push data as you have it, and pull it when you need it
* - It can also function as a basic audio data queue even if you just have
* sound that needs to pass from one place to another.