Commit 212dbcb7 authored by Ryan C. Gordon's avatar Ryan C. Gordon

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.

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402063
parent d5e84bbf
......@@ -220,46 +220,49 @@ static void AHI_CloseAudio(_THIS)
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 ) {
case 8: { /* Signed 8 bit audio data */
D(bug("Samples a 8 bit...\n"));
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->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"));
case AUDIO_S16MSB:
D(bug("AUDIO_S16MSB...\n"));
spec->format = AUDIO_S16MSB;
this->hidden->bytespersample=2;
if(spec->channels<2)
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"));
......
......@@ -152,36 +152,53 @@ void BE_CloseAudio(_THIS)
int BE_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
int valid_datatype = 0;
media_raw_audio_format format;
/* Initialize the Be Application, if it's not already started */
if ( SDL_InitBeApp() < 0 ) {
return(-1);
}
SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
/* 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) {
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:
/* Signed 8-bit audio unsupported, convert to U8 */
spec->format = AUDIO_U8;
format.format = media_raw_audio_format::B_AUDIO_CHAR;
break;
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:
case AUDIO_S16LSB:
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;
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 */
......
......@@ -75,6 +75,8 @@ LONG APIENTRY DARTEventFunc(ULONG ulStatus,
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 @@ int DART_OpenAudio(_THIS, SDL_AudioSpec *spec)
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:
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);
return (-1);
}
iFreq = spec->freq;
iChannels = spec->channels;
/* Update the fragment size as size in bytes */
......
......@@ -201,14 +201,31 @@ static void DCAUD_CloseAudio(_THIS)
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;
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);
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);
......
......@@ -139,78 +139,104 @@ static void AL_CloseAudio(_THIS)
}
}
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];
audio_param[0] = AL_OUTPUT_RATE;
audio_param[1] = spec->freq;
valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
}
#else
{
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;
/* Determine the audio parameters from the AudioSpec */
switch ( spec->format & 0xFF ) {
while ((!valid) && (test_format)) {
valid = 1;
spec->format = test_format;
case 8: { /* Signed 8 bit audio data */
spec->format = AUDIO_S8;
switch (test_format) {
case AUDIO_S8:
width = AL_SAMPLE_8;
}
fmt = AL_SAMPFMT_TWOSCOMP;
break;
case 16: { /* Signed 16 bit audio data */
spec->format = AUDIO_S16MSB;
case AUDIO_S16SYS:
width = AL_SAMPLE_16;
}
fmt = AL_SAMPFMT_TWOSCOMP;
break;
default: {
SDL_SetError("Unsupported audio format");
return(-1);
default:
valid = 0;
test_format = SDL_NextAudioFormat();
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. */
}
}
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(spec);
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)) {
/* 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);
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);
}
}
/* 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);
if (audio_port != NULL) {
valid = 1;
}
}
alFreeConfig(audio_config);
if( audio_port == NULL ) {
SDL_SetError("Unable to open audio port");
return(-1);
}
}
}
if (!valid) {
SDL_SetError("Unsupported audio format");
return (-1);
}
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(spec);
/* 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);
}
......@@ -217,6 +217,9 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
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;
......
......@@ -201,6 +201,8 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
{
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 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
DEBUG_PRINT(("channels=%d, ", spec->channels));
DEBUG_PRINT(("freq=%d\n", spec->freq));
if (spec->channels > 2) {
spec->channels = 2; /* no more than stereo! */
}
while ((!valid_datatype) && (test_format)) {
/* 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;
}
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 16:
if ((snd_format & SND_FORMAT16)==0) {
SDL_SetError("Mint_CheckAudio: 16 bits samples not supported");
return -1;
}
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:
SDL_SetError("Mint_CheckAudio: Unsupported sample resolution");
return -1;
test_format = SDL_NextAudioFormat();
break;
}
}
if (!valid_datatype) {
SDL_SetError("Unsupported audio format");
return (-1);
}
/* Check signed/unsigned format */
if (format_signed) {
......
......@@ -224,6 +224,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
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) {
......
......@@ -205,6 +205,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
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++) {
......
......@@ -341,6 +341,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment