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
This commit is contained in:
parent
d5e84bbf7c
commit
212dbcb764
10 changed files with 273 additions and 160 deletions
|
@ -220,47 +220,50 @@ 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"));
|
||||
D(bug("AHI opening...\n"));
|
||||
|
||||
/* Determine the audio parameters from the AudioSpec */
|
||||
switch ( spec->format & 0xFF ) {
|
||||
/* 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 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;
|
||||
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;
|
||||
|
||||
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;
|
||||
default:
|
||||
valid_datatype = 0;
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
SDL_SetError("Unsupported audio format");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
if (!valid_datatype) { /* shouldn't happen, but just in case... */
|
||||
SDL_SetError("Unsupported audio format");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if(spec->channels!=1 && spec->channels!=2)
|
||||
{
|
||||
D(bug("Wrong channel number!\n"));
|
||||
SDL_SetError("Channel number non supported");
|
||||
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 */
|
||||
|
|
|
@ -152,38 +152,55 @@ void BE_CloseAudio(_THIS)
|
|||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Calculate the final parameters for this audio specification */
|
||||
SDL_CalculateAudioSpec(spec);
|
||||
|
||||
|
|
|
@ -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:
|
||||
// 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 */
|
||||
|
|
|
@ -201,13 +201,30 @@ 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;
|
||||
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);
|
||||
|
|
|
@ -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];
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
width = AL_SAMPLE_8;
|
||||
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;
|
||||
|
||||
default:
|
||||
valid = 0;
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16: { /* Signed 16 bit audio data */
|
||||
spec->format = AUDIO_S16MSB;
|
||||
width = AL_SAMPLE_16;
|
||||
}
|
||||
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. */
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
SDL_SetError("Unsupported audio format");
|
||||
return(-1);
|
||||
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)) {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
/* 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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue