[SDL] [Need help] Why this code crached?
Mike Shal
marfey at gmail.com
Sun Jan 21 08:47:29 PST 2007
On 1/20/07, Igor Mironchick <imironchick at gmail.com> wrote:
> 2007/1/20, Mike Shal <marfey at gmail.com>:
> > 3) The check to see if SDL_BuildAudioCVT() doesn't work (at least in
> > SDL1.2.7 - maybe this changed). The man page says it returns 1 on
> > success and -1 on error, but it's checking for != 0 to determine an
> > error condition.
>
> Where I can read about reasons of craches SDL_BuildAudioCVT()?
I'm not sure where you could read about it - SDL_BuildAudioCVT() only
crashed for me if SDL_OpenAudio() failed (which made everything 0 in
m_dev_spec). Once I set m_desired_spec.channels, SDL_OpenAudio
succeeded and SDL_BuildAudioCVT() didn't crash.
>
> > 4) And I believe this is the main issue: In the audio callback, you
> > call SDL_MixAudio with the amount of data left in your wave file. This
> > doesn't necessarily fit within the mix buffer (defined by the 'len'
> > argument in the callback). I think you want to pass in the min of
> > 'waveleft' and 'len' to SDL_MixAudio.
>
> May be.. I fix it. But I still can't play any WAV files. Why? How
> audio_callback() calles? Is len parameter always equal length of the WAV?
> Or this is something another?
The 'len' parameter isn't the size of the WAV, it's the size of the
mix buffer. You can't write more than 'len' bytes to the mix buffer,
and you can't read past the end of the WAV. This is why you have to
find the minimum of the two and pass that to SDL_MixAudio().
>
> How I can play all types of WAV files?
Not really sure what you mean here - if you're looking for other
formats (like mp3, ogg, or whatever) you may want to look into some
add-on libraries like SDL_Mixer. Anyway, here's your program with some
changes (look for the /* MARF */ comments). This ran for me and played
test.wav:
#include <iostream>
#include "cpl_audio.hpp"
namespace cpl_audio {
SDL_AudioSpec cpl_audio_t::m_dev_spec;
SDL_AudioSpec cpl_audio_t::m_desired_spec;
sample_t cpl_audio_t::m_sample;
size_t cpl_audio_t::m_volume( SDL_MIX_MAXVOLUME );
bool cpl_audio_t::m_done( false );
cpl_audio_t::cpl_audio_t()
{
m_desired_spec.freq = 22050;
m_desired_spec.format = AUDIO_S16LSB;
m_desired_spec.samples = 8192;
m_desired_spec.callback = audio_callback;
m_desired_spec.userdata = NULL;
m_desired_spec.channels = 2; /* MARF */
m_sample.m_spec.callback = audio_callback;
m_sample.m_sound = 0;
if ( SDL_OpenAudio( &m_desired_spec, &m_dev_spec ) < 0 ) {
std::cout << SDL_GetError() << std::endl;
}
SDL_PauseAudio(0);
}
cpl_audio_t::~cpl_audio_t()
{
SDL_CloseAudio();
SDL_FreeWAV( m_sample.m_sound );
}
void
cpl_audio_t::set_volume( const size_t vol )
{
SDL_LockAudio();
m_volume = vol;
SDL_UnlockAudio();
}
void
cpl_audio_t::play_sound( const char * file )
{
SDL_AudioCVT cvt;
SDL_AudioSpec spec;
Uint8 *data;
Uint32 dlen;
if ( SDL_LoadWAV( file, &spec, &data, &dlen ) == NULL )
return;
if( SDL_BuildAudioCVT( &cvt, spec.format, spec.channels, spec.freq,
m_dev_spec.format, m_dev_spec.channels, m_dev_spec.freq ) ==
-1 /* MARF */) {
return;
}
cvt.buf = new Uint8[dlen * cvt.len_mult];
memcpy( cvt.buf, data, dlen );
cvt.len = dlen;
if( SDL_ConvertAudio( &cvt ) != 0 )
{
SDL_FreeWAV( data );
delete [] cvt.buf;
return;
}
SDL_FreeWAV( data );
SDL_LockAudio();
free( m_sample.m_sound );
m_sample.m_sound = cvt.buf;
m_sample.m_soundlen = cvt.len_cvt;
m_sample.m_soundpos = 0;
m_done = false;
SDL_UnlockAudio();
}
void
cpl_audio_t::audio_callback( void *userdata, Uint8 *stream, int len )
{
if( m_sample.m_sound && !m_done )
{
Uint8 *waveptr;
Uint32 waveleft;
if( m_sample.m_soundpos < m_sample.m_soundlen )
{
int mix_size; /* MARF */
waveptr = m_sample.m_sound + m_sample.m_soundpos;
waveleft = m_sample.m_soundlen - m_sample.m_soundpos;
if(waveleft < len) /* MARF */
mix_size = waveleft; /* MARF */
else /* MARF */
mix_size = len; /* MARF */
SDL_MixAudio( stream, waveptr, mix_size /* MARF */, m_volume );
m_sample.m_soundpos += mix_size; /* MARF */
if( m_sample.m_soundpos >= m_sample.m_soundlen )
m_done = true;
}
}
}// void audio_callback(...)
}// namespace cpl_audio
#include "cpl_audio.hpp"
#include "SDL.h"
int main(int argc, char *argv[])
{
if ( SDL_Init( SDL_INIT_AUDIO ) < 0 )
return 1;
cpl_audio::cpl_audio_t audio;
audio.play_sound( "test.wav" );
while ( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING )
SDL_Delay(1000);
SDL_Quit();
return 0;
}
Hope that helps,
-Mike
More information about the SDL
mailing list