Backport from 1.3: most of the audio drivers can now handle data
conversion at a higher level when they can't open the hardware in the
exact format requested.
--- a/src/audio/amigaos/SDL_ahiaudio.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/amigaos/SDL_ahiaudio.c Fri Sep 01 22:50:24 2006 +0000
@@ -220,47 +220,50 @@
static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
-// int width;
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ int valid_datatype = 1;
- D(bug("AHI opening...\n"));
-
- /* Determine the audio parameters from the AudioSpec */
- switch ( spec->format & 0xFF ) {
+ D(bug("AHI opening...\n"));
- case 8: { /* Signed 8 bit audio data */
- D(bug("Samples a 8 bit...\n"));
- spec->format = AUDIO_S8;
- this->hidden->bytespersample=1;
- if(spec->channels<2)
- this->hidden->type = AHIST_M8S;
- else
- this->hidden->type = AHIST_S8S;
- }
- break;
+ /* Determine the audio parameters from the AudioSpec */
+ while ((!valid_datatype) && (test_format)) {
+ valid_datatype = 1;
+ switch (test_format) {
+ case AUDIO_S8:
+ D(bug("AUDIO_S8...\n"));
+ spec->format = AUDIO_S8;
+ this->hidden->bytespersample = 1;
+ if (spec->channels < 2)
+ this->hidden->type = AHIST_M8S;
+ else
+ this->hidden->type = AHIST_S8S;
+ break;
- case 16: { /* Signed 16 bit audio data */
- D(bug("Samples a 16 bit...\n"));
- spec->format = AUDIO_S16MSB;
- this->hidden->bytespersample=2;
- if(spec->channels<2)
- this->hidden->type = AHIST_M16S;
- else
- this->hidden->type = AHIST_S16S;
- }
- break;
+ case AUDIO_S16MSB:
+ D(bug("AUDIO_S16MSB...\n"));
+ spec->format = AUDIO_S16MSB;
+ this->hidden->bytespersample = 2;
+ if (spec->channels < 2)
+ this->hidden->type = AHIST_M16S;
+ else
+ this->hidden->type = AHIST_S16S;
+ break;
- default: {
- SDL_SetError("Unsupported audio format");
- return(-1);
- }
- }
+ default:
+ valid_datatype = 0;
+ test_format = SDL_NextAudioFormat();
+ break;
+ }
+ }
- if(spec->channels!=1 && spec->channels!=2)
- {
- D(bug("Wrong channel number!\n"));
- SDL_SetError("Channel number non supported");
- return -1;
- }
+ if (!valid_datatype) { /* shouldn't happen, but just in case... */
+ SDL_SetError("Unsupported audio format");
+ return (-1);
+ }
+
+ if (spec->channels > 2) {
+ spec->channels = 2; /* will convert at higher level. */
+ }
D(bug("Before CalculateAudioSpec\n"));
/* Update the fragment size as size in bytes */
--- a/src/audio/baudio/SDL_beaudio.cc Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.cc Fri Sep 01 22:50:24 2006 +0000
@@ -152,38 +152,55 @@
int BE_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
- media_raw_audio_format format;
+ int valid_datatype = 0;
+ media_raw_audio_format format;
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
- /* Initialize the Be Application, if it's not already started */
- if ( SDL_InitBeApp() < 0 ) {
- return(-1);
- }
+ /* Parse the audio format and fill the Be raw audio format */
+ memset(&format, '\0', sizeof (media_raw_audio_format));
+ format.byte_order = B_MEDIA_LITTLE_ENDIAN;
+ format.frame_rate = (float) spec->freq;
+ format.channel_count = spec->channels; /* !!! FIXME: support > 2? */
+ while ((!valid_datatype) && (test_format)) {
+ valid_datatype = 1;
+ spec->format = test_format;
+ switch (test_format) {
+ case AUDIO_S8:
+ format.format = media_raw_audio_format::B_AUDIO_CHAR;
+ break;
+
+ case AUDIO_U8:
+ format.format = media_raw_audio_format::B_AUDIO_UCHAR;
+ break;
+
+ case AUDIO_S16LSB:
+ format.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
- /* Parse the audio format and fill the Be raw audio format */
- format.frame_rate = (float)spec->freq;
- format.channel_count = spec->channels;
- switch (spec->format&~0x1000) {
- case AUDIO_S8:
- /* Signed 8-bit audio unsupported, convert to U8 */
- spec->format = AUDIO_U8;
- case AUDIO_U8:
- format.format = media_raw_audio_format::B_AUDIO_UCHAR;
- format.byte_order = 0;
- break;
- case AUDIO_U16:
- /* Unsigned 16-bit audio unsupported, convert to S16 */
- spec->format ^= 0x8000;
- case AUDIO_S16:
- format.format = media_raw_audio_format::B_AUDIO_SHORT;
- if ( spec->format & 0x1000 ) {
- format.byte_order = 1; /* Big endian */
- } else {
- format.byte_order = 2; /* Little endian */
- }
- break;
- }
- format.buffer_size = spec->samples;
-
+ case AUDIO_S16MSB:
+ format.format = media_raw_audio_format::B_AUDIO_SHORT;
+ format.byte_order = B_MEDIA_BIG_ENDIAN;
+ break;
+
+ default:
+ valid_datatype = 0;
+ test_format = SDL_NextAudioFormat();
+ break;
+ }
+ }
+
+ if (!valid_datatype) { /* shouldn't happen, but just in case... */
+ SDL_SetError("Unsupported audio format");
+ return (-1);
+ }
+
+ /* Initialize the Be Application, if it's not already started */
+ if (SDL_InitBeApp() < 0) {
+ return (-1);
+ }
+
+ format.buffer_size = spec->samples;
+
/* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(spec);
--- a/src/audio/dart/SDL_dart.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/dart/SDL_dart.c Fri Sep 01 22:50:24 2006 +0000
@@ -75,6 +75,8 @@
int DART_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ int valid_datatype = 0;
MCI_AMP_OPEN_PARMS AmpOpenParms;
MCI_GENERIC_PARMS GenericParms;
int iDeviceOrd = 0; // Default device to be used
@@ -106,26 +108,39 @@
iDeviceOrd = AmpOpenParms.usDeviceID;
// Determine the audio parameters from the AudioSpec
- switch ( spec->format & 0xFF )
- {
- case 8:
- /* Unsigned 8 bit audio data */
- spec->format = AUDIO_U8;
+ if (spec->channels > 2)
+ spec->channels = 2; // !!! FIXME: more than stereo support in OS/2?
+
+ while ((!valid_datatype) && (test_format)) {
+ spec->format = test_format;
+ valid_datatype = 1;
+ switch (test_format) {
+ case AUDIO_U8:
+ // Unsigned 8 bit audio data
iSilence = 0x80;
iBits = 8;
break;
- case 16:
- /* Signed 16 bit audio data */
- spec->format = AUDIO_S16;
+
+ case AUDIO_S16LSB:
+ // Signed 16 bit audio data
iSilence = 0x00;
iBits = 16;
break;
- default:
- // Close DART, and exit with error code!
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
- SDL_SetError("Unsupported audio format");
- return(-1);
+
+ default:
+ valid_datatype = 0;
+ test_format = SDL_NextAudioFormat();
+ break;
+ }
}
+
+ if (!valid_datatype) { // shouldn't happen, but just in case...
+ // Close DART, and exit with error code!
+ mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ SDL_SetError("Unsupported audio format");
+ return (-1);
+ }
+
iFreq = spec->freq;
iChannels = spec->channels;
/* Update the fragment size as size in bytes */
--- a/src/audio/dc/SDL_dcaudio.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/dc/SDL_dcaudio.c Fri Sep 01 22:50:24 2006 +0000
@@ -201,13 +201,30 @@
static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
- switch(spec->format&0xff) {
- case 8: spec->format = AUDIO_S8; break;
- case 16: spec->format = AUDIO_S16LSB; break;
- default:
- SDL_SetError("Unsupported audio format");
- return(-1);
- }
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ int valid_datatype = 0;
+ while ((!valid_datatype) && (test_format)) {
+ spec->format = test_format;
+ switch (test_format) {
+ /* only formats Dreamcast accepts... */
+ case AUDIO_S8:
+ case AUDIO_S16LSB:
+ valid_datatype = 1;
+ break;
+
+ default:
+ test_format = SDL_NextAudioFormat();
+ break;
+ }
+ }
+
+ if (!valid_datatype) { /* shouldn't happen, but just in case... */
+ SDL_SetError("Unsupported audio format");
+ return (-1);
+ }
+
+ if (spec->channels > 2)
+ spec->channels = 2; /* no more than stereo on the Dreamcast. */
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(spec);
--- a/src/audio/dmedia/SDL_irixaudio.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/dmedia/SDL_irixaudio.c Fri Sep 01 22:50:24 2006 +0000
@@ -139,78 +139,104 @@
}
}
-static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec)
+static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec)
{
- ALconfig audio_config;
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ long width = 0;
+ long fmt = 0;
+ int valid = 0;
+
#ifdef OLD_IRIX_AUDIO
- long audio_param[2];
+ {
+ long audio_param[2];
+ audio_param[0] = AL_OUTPUT_RATE;
+ audio_param[1] = spec->freq;
+ valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
+ }
#else
- ALpv audio_param;
+ {
+ ALpv audio_param;
+ audio_param.param = AL_RATE;
+ audio_param.value.i = spec->freq;
+ valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
+ }
#endif
- int width;
+
+ while ((!valid) && (test_format)) {
+ valid = 1;
+ spec->format = test_format;
- /* Determine the audio parameters from the AudioSpec */
- switch ( spec->format & 0xFF ) {
+ switch (test_format) {
+ case AUDIO_S8:
+ width = AL_SAMPLE_8;
+ fmt = AL_SAMPFMT_TWOSCOMP;
+ break;
+
+ case AUDIO_S16SYS:
+ width = AL_SAMPLE_16;
+ fmt = AL_SAMPFMT_TWOSCOMP;
+ break;
- case 8: { /* Signed 8 bit audio data */
- spec->format = AUDIO_S8;
- width = AL_SAMPLE_8;
+ default:
+ valid = 0;
+ test_format = SDL_NextAudioFormat();
+ break;
}
- break;
+
+ if (valid) {
+ ALconfig audio_config = alNewConfig();
+ valid = 0;
+ if (audio_config) {
+ if (alSetChannels(audio_config, spec->channels) < 0) {
+ if (spec->channels > 2) { /* can't handle > stereo? */
+ spec->channels = 2; /* try again below. */
+ }
+ }
+
+ if ((alSetSampFmt(audio_config, fmt) >= 0) &&
+ ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
+ (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
+ (alSetChannels(audio_config, spec->channels) >= 0)) {
- case 16: { /* Signed 16 bit audio data */
- spec->format = AUDIO_S16MSB;
- width = AL_SAMPLE_16;
+ audio_port = alOpenPort("SDL audio", "w", audio_config);
+ if (audio_port == NULL) {
+ /* docs say AL_BAD_CHANNELS happens here, too. */
+ int err = oserror();
+ if (err == AL_BAD_CHANNELS) {
+ spec->channels = 2;
+ alSetChannels(audio_config, spec->channels);
+ audio_port = alOpenPort("SDL audio", "w",
+ audio_config);
+ }
+ }
+
+ if (audio_port != NULL) {
+ valid = 1;
+ }
+ }
+
+ alFreeConfig(audio_config);
+ }
}
- break;
+ }
- default: {
- SDL_SetError("Unsupported audio format");
- return(-1);
- }
+ if (!valid) {
+ SDL_SetError("Unsupported audio format");
+ return (-1);
}
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(spec);
- /* Set output frequency */
-#ifdef OLD_IRIX_AUDIO
- audio_param[0] = AL_OUTPUT_RATE;
- audio_param[1] = spec->freq;
- if( ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0 ) {
-#else
- audio_param.param = AL_RATE;
- audio_param.value.i = spec->freq;
- if( alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0 ) {
-#endif
- SDL_SetError("alSetParams failed");
- return(-1);
- }
-
- /* Open the audio port with the requested frequency */
- audio_port = NULL;
- audio_config = alNewConfig();
- if ( audio_config &&
- (alSetSampFmt(audio_config, AL_SAMPFMT_TWOSCOMP) >= 0) &&
- (alSetWidth(audio_config, width) >= 0) &&
- (alSetQueueSize(audio_config, spec->samples*2) >= 0) &&
- (alSetChannels(audio_config, spec->channels) >= 0) ) {
- audio_port = alOpenPort("SDL audio", "w", audio_config);
- }
- alFreeConfig(audio_config);
- if( audio_port == NULL ) {
- SDL_SetError("Unable to open audio port");
- return(-1);
- }
-
/* Allocate mixing buffer */
- mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size);
- if ( mixbuf == NULL ) {
+ mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
+ if (mixbuf == NULL) {
SDL_OutOfMemory();
- return(-1);
+ return (-1);
}
SDL_memset(mixbuf, spec->silence, spec->size);
/* We're ready to rock and roll. :-) */
- return(0);
+ return (0);
}
+
--- a/src/audio/mint/SDL_mintaudio_dma8.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_dma8.c Fri Sep 01 22:50:24 2006 +0000
@@ -217,6 +217,9 @@
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
+ if (spec->channels > 2)
+ spec->channels = 2;
+
/* Check formats available */
spec->format = AUDIO_S8;
--- a/src/audio/mint/SDL_mintaudio_gsxb.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c Fri Sep 01 22:50:24 2006 +0000
@@ -201,6 +201,8 @@
{
long snd_format;
int i, resolution, format_signed, format_bigendian;
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ int valid_datatype = 0;
resolution = spec->format & 0x00ff;
format_signed = ((spec->format & 0x8000)!=0);
@@ -212,28 +214,46 @@
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
- /* Check formats available */
- snd_format = Sndstatus(SND_QUERYFORMATS);
- switch (resolution) {
- case 8:
- if ((snd_format & SND_FORMAT8)==0) {
- SDL_SetError("Mint_CheckAudio: 8 bits samples not supported");
- return -1;
- }
- snd_format = Sndstatus(SND_QUERY8BIT);
- break;
- case 16:
- if ((snd_format & SND_FORMAT16)==0) {
- SDL_SetError("Mint_CheckAudio: 16 bits samples not supported");
- return -1;
- }
- snd_format = Sndstatus(SND_QUERY16BIT);
- break;
- default:
- SDL_SetError("Mint_CheckAudio: Unsupported sample resolution");
- return -1;
- break;
- }
+ if (spec->channels > 2) {
+ spec->channels = 2; /* no more than stereo! */
+ }
+
+ while ((!valid_datatype) && (test_format)) {
+ /* Check formats available */
+ snd_format = Sndstatus(SND_QUERYFORMATS);
+ spec->format = test_format;
+ resolution = SDL_AUDIO_BITSIZE(spec->format);
+ format_signed = SDL_AUDIO_ISSIGNED(spec->format);
+ format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format);
+ switch (test_format) {
+ case AUDIO_U8:
+ case AUDIO_S8:
+ if (snd_format & SND_FORMAT8) {
+ valid_datatype = 1;
+ snd_format = Sndstatus(SND_QUERY8BIT);
+ }
+ break;
+
+ case AUDIO_U16LSB:
+ case AUDIO_S16LSB:
+ case AUDIO_U16MSB:
+ case AUDIO_S16MSB:
+ if (snd_format & SND_FORMAT16) {
+ valid_datatype = 1;
+ snd_format = Sndstatus(SND_QUERY16BIT);
+ }
+ break;
+
+ default:
+ test_format = SDL_NextAudioFormat();
+ break;
+ }
+ }
+
+ if (!valid_datatype) {
+ SDL_SetError("Unsupported audio format");
+ return (-1);
+ }
/* Check signed/unsigned format */
if (format_signed) {
--- a/src/audio/mint/SDL_mintaudio_mcsn.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c Fri Sep 01 22:50:24 2006 +0000
@@ -224,6 +224,10 @@
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
+ if (spec->channels > 2) {
+ spec->channels = 2; /* no more than stereo! */
+ }
+
/* Check formats available */
MINTAUDIO_freqcount=0;
switch(cookie_mcsn->play) {
--- a/src/audio/mint/SDL_mintaudio_stfa.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_stfa.c Fri Sep 01 22:50:24 2006 +0000
@@ -205,6 +205,10 @@
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
+ if (spec->channels > 2) {
+ spec->channels = 2; /* no more than stereo! */
+ }
+
/* Check formats available */
MINTAUDIO_freqcount=0;
for (i=0;i<16;i++) {
--- a/src/audio/mint/SDL_mintaudio_xbios.c Wed Aug 02 21:26:31 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_xbios.c Fri Sep 01 22:50:24 2006 +0000
@@ -341,6 +341,10 @@
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
+ if (spec->channels > 2) {
+ spec->channels = 2; /* no more than stereo! */
+ }
+
spec->format |= 0x8000; /* Audio is always signed */
if ((spec->format & 0x00ff)==16) {
spec->format |= 0x1000; /* Audio is always big endian */