Anthony Kolb <ajkolb hotmail.com> writes:
Hi,
I wrote a simple SDL program that loads a .wav specified by the user, and
plays it. That worked fine. Then, I tried to add a second thread to the
program to respond to user input, and the audio stopped working. The program
ran for the right length of time; the callback was being called; the right
values were being written to the stream. There were no errors, no seg
fault.
Still, silence.
So I commented out everything I’d added, until I finally found that the
culprit was ORing the SDL_INIT_VIDEO flag with the SDL_INIT_AUDIO flag.
Without the video flag, it works fine.
[…]
I’m working on a Pentium 2 running Win2K. This is SDL 1.2.8. I’m
developing/compiling in Dev-C++. I don’t know if it matters, but I believe I
have the latest version of DirectX.
Update:
I tried running the executable generated on my P2 on my laptop (an AMD
Duron, also Win2K), and it had the same problem. I tried compiling the same
code on my laptop, with the same results. The sound cards, etc. are totally
different, so it doesn’t seem like a driver problem.
So, I set Dev-C++ to compile it as a win32 GUI, not a console program, but
the results were (again) the same.
Has anyone run into anything like this before? It’s just happened on two
different platforms, so it can’t just be me. Here is the code in question:
/Begin code/
#include <stdlib.h>
#include <stdio.h>
#include “SDL.h”
void myFreeWAV(void);
void myAudioCallback(void *data, Uint8 *stream, int len);
typedef struct _soundInfo{
Uint8 *sound_buffer;
Uint8 silence;
unsigned length;
unsigned pos;
} soundInfo;
Uint8 *wav_buffer; //This has to be global so myFreeWAV() can access it.
int main(int argc, char *argv[]){
SDL_AudioSpec wav_spec;
Uint8 *temp;
Uint32 num_bytes, subsystem_init;
soundInfo sound;
unsigned i;
if(argc != 2){
fprintf(stderr, “USAGE: “%s (filename.wav)”\n”, argv[0]);
exit(-1);
}
/NOTE: If you uncomment the SDL_INIT_VIDEO flag (below), audio is silenced/
if(SDL_Init(/SDL_INIT_VIDEO |/ SDL_INIT_AUDIO)){
fprintf(stderr, “Could not initialize SDL.\nExiting…\n”);
exit(1);
}
atexit(SDL_Quit);
// SDL_InitSubSystem(SDL_INIT_AUDIO);
subsystem_init=SDL_WasInit(SDL_INIT_EVERYTHING);
if(subsystem_init&SDL_INIT_VIDEO) printf(“Video is initialized.\n”);
else printf(“Video is not initialized.\n”);
if(subsystem_init&SDL_INIT_AUDIO) printf(“Audio is initialized.\n”);
else printf(“Audio is not initialized.\n”);
if( SDL_LoadWAV(argv[1], &wav_spec, &wav_buffer, &num_bytes) == NULL ){
fprintf(stderr, “Could not open %s: %s\n”, argv[1], SDL_GetError());
exit(1);
}
atexit(myFreeWAV);
sound.sound_buffer = wav_buffer;
sound.length = num_bytes;
sound.pos = 0;
sound.silence = wav_spec.silence;
wav_spec.samples = 2048;
wav_spec.callback = myAudioCallback;
wav_spec.userdata = (void *)&sound;
if(SDL_OpenAudio(&wav_spec, NULL)==-1){
fprintf(stderr, “Failed to open audio stream.\nExiting…\n”);
exit(1);
}
atexit(SDL_CloseAudio);
SDL_PauseAudio(0);
while(sound.pos < sound.length){
SDL_Delay(50);
}
SDL_PauseAudio(1);
return 0;
}
// This function simply allows us to register SDL_FreeWAV() with atexit().
void myFreeWAV(void){
SDL_FreeWAV(wav_buffer);
return;
}
/*If there is data left in our sound buffer, it’s written to the stream;
otherwise, silence is written. */
void myAudioCallback(void *data, Uint8 *stream, int len){
unsigned i;
soundInfo *sound;
sound = (soundInfo *)data;
for(i=0; i<len; i++){
if(sound->pos < sound->length){
stream[i] = (sound->sound_buffer)[sound->pos];
sound->pos++;
}
else stream[i] = sound->silence;
}
return;
}
/End code/
There’s a comment that points out where the offending flag is. Note that
the .wav you want to play is passed as a command line argument.
I hope posting a code sample this long isn’t considered bad etiquette. I
know it’s a lot to ask, but if someone compiled it (with the SDL_INIT_VIDEO
flag uncommented!) and it worked, I’d love to know about your setup.
Thanks!
Anthony