Filling up variable of type SDL_AudioSpec for a wav file

Hi,
I have a wav file with following properties:
RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 11025 Hz
I am populating the variable of type SDL_AudioSpec for this file as follows:
desired->freq=11025;
desired->channels=1;
desired->samples=4096;
desired->format = AUDIO_S16;

SDL_OpenAudio(desired, &hwspec);

I can play the above mentioned wav file with format AUDIO_S16 only.
Why it works only with AUDIO_S16 format? why it is not working with AUDIO_U8/AUDIO_S8 as file property tells that it is 8 bit.
Also it works well in one linux system but it does not work properly with other linux system (it seems that it is playing in fast forward mode in other system) though both system configuration is same.
Any help/suggestion will be helpful.
Thanks in advance.
regards,
Sanjay

SDL_OpenAudio(desired, &hwspec);
[…]
I can play the above mentioned wav file with format AUDIO_S16 only.
Why it works only with AUDIO_S16 format? why it is not working with
AUDIO_U8/AUDIO_S8 as file property tells that it is 8 bit.

Be careful in specifying a second argument to SDL_OpenAudio() that isn’t
NULL. If it’s NULL, it says, “I can only feed the audio device with data
in exactly (desired) format.”

Passing (&hwspec) there says, “I prefer to write (desired) data to the
audio hardware since it’s most efficient for me, but I’ll be able to
handle whatever format the audio device actually turns out to be.”

Most applications should specify NULL for the second parameter unless
they plan to supply a full mixer of their own (as some games and
libraries do).

SDL always tries to set the hardware to the closest thing to (desired),
but if the second parameter is NULL, it’ll convert as necessary
internally so you always feed it data in the format you requested. If
you don’t specify NULL, you are expected to feed data in the format it
reports, and it will do bad things (sound runs too fast/slow, sounds
like static, crashes) without warning if you don’t.

–ryan.

Hi Ryan,
Thanks for your reply. now I am passing second parameter of SDL_OpenAudio() as NULL and it works with ADUIO format AUDIO_S16 (does not work with any other SDL audio format).
my question is:

  1. When wav file is “PCM, 8 bit, mono” then i think it should work with with formats like AUDIO_U8/AUDIO_S8 but it is not. it is working only with AUDIO_S16. please clarify how do i know what SDL format I should use to play by seeing the header of pcm wav file.
  2. with format AUDIO_S16, it is working properly in one linux FC6 system but not working properly in other linux FC6 system. In second system, it seems it is playing correctly but in fast forward mode. What could be the problem? do I need to do some setting in other system?
    Please give your suggestion. Thanks in advance.

Thanks & Regards,
Sanjay

On Wed, 14 Mar 2007 Ryan C.Gordon wrote :>

SDL_OpenAudio(desired, &hwspec);
[…]
I can play the above mentioned wav file with format AUDIO_S16 only.
Why it works only with AUDIO_S16 format? why it is not working with
AUDIO_U8/AUDIO_S8 as file property tells that it is 8 bit.

Be careful in specifying a second argument to SDL_OpenAudio() that isn’t
NULL. If it’s NULL, it says, “I can only feed the audio device with data
in exactly (desired) format.”

Passing (&hwspec) there says, “I prefer to write (desired) data to the
audio hardware since it’s most efficient for me, but I’ll be able to
handle whatever format the audio device actually turns out to be.”

Most applications should specify NULL for the second parameter unless
they plan to supply a full mixer of their own (as some games and
libraries do).

SDL always tries to set the hardware to the closest thing to (desired),
but if the second parameter is NULL, it’ll convert as necessary
internally so you always feed it data in the format you requested. If
you don’t specify NULL, you are expected to feed data in the format it
reports, and it will do bad things (sound runs too fast/slow, sounds
like static, crashes) without warning if you don’t.

–ryan.

Hi Ryan,
Thanks for your reply. now I am passing second parameter of
SDL_OpenAudio() as NULL and it works with ADUIO format AUDIO_S16 (does not
work with any other SDL audio format).
my question is:

  1. When wav file is “PCM, 8 bit, mono” then i think it should work with
    with formats like AUDIO_U8/AUDIO_S8 but it is not. it is working only with
    AUDIO_S16. please clarify how do i know what SDL format I should use to play
    by seeing the header of pcm wav file.

How I can understand SDL_OpenAudio initialize audio hardware. And
desired/obtained SDL_AudioSpec describe hardware parametres and not sample
parametres. In that way I use next code in my apps:

SDL_AudioSpec desired_spec;
desired_spec.freq = 22050;
desired_spec.format = AUDIO_S16LSB;
desired_spec.samples = 8192;
desired_spec.channels = 2;
desired_spec.callback = audio_callback;
desired_spec.userdata = this;
m_sample.m_spec.callback = audio_callback;

m_sample.m_sound = 0;

if ( SDL_OpenAudio( &desired_spec, &m_dev_spec ) < 0 ) {
    m_last_error = SDL_GetError();
}

And when prepare sample for playing u need to convert sample to obtaned
format. For example…

SDL_AudioCVT cvt;
SDL_AudioSpec spec;
Uint8 *data;
Uint32 dlen;

if ( SDL_LoadWAV( file, &spec, &data, &dlen ) == NULL )
{
    m_last_error = SDL_GetError();
    return;
}

SDL_BuildAudioCVT( &cvt, spec.format, spec.channels, spec.freq,
    m_dev_spec.format, m_dev_spec.channels, m_dev_spec.freq );

SDL_PauseAudio( 1 );
if( cvt.needed )
{
    cvt.buf = new Uint8[dlen * cvt.len_mult];
    memcpy( cvt.buf, data, dlen );
    cvt.len = dlen;

    if( SDL_ConvertAudio( &cvt ) != 0 )
    {
        m_last_error = SDL_GetError();
        SDL_FreeWAV( data );
        delete [] cvt.buf;
        return;
    }

    SDL_FreeWAV( data );

    SDL_LockAudio();

    SDL_FreeWAV( m_sample.m_sound );

    m_sample.m_sound = cvt.buf;
    m_sample.m_soundlen = cvt.len_cvt;
}
else
{
    SDL_LockAudio();

    SDL_FreeWAV( m_sample.m_sound );

    m_sample.m_sound = data;
    m_sample.m_soundlen = dlen;
}

m_sample.m_soundpos = 0;
m_done = false;

SDL_UnlockAudio();
SDL_PauseAudio( 0 );

This is copy/paste of my C++ wrapper for SDL_Audio.

  1. with format AUDIO_S16, it is working properly in one linux FC6 system but

not working properly in other linux FC6 system. In second system, it seems
it is playing correctly but in fast forward mode. What could be the problem?
do I need to do some setting in other system?
Please give your suggestion. Thanks in advance.

Differences betwen hardware??? May be…–
Regards,
Igor Mironchick,
Intervale (c)
#ICQ 492-597-570