/* compile: gcc -L/usr/lib `sdl-config --cflags --libs` sound.c -o sound */ #include #include #include #include #include typedef struct { SDL_AudioSpec spec; Uint8 *sound; /* ptr to wave data */ Uint32 soundlen; /* length of wave data */ int soundpos; /* current play position */ } WAVE_T; static int volume = SDL_MIX_MAXVOLUME; static int done = 0; static int spid; static WAVE_T wave; void play (void *unused, Uint8 *stream, int len) { Uint8 *waveptr; int waveleft; /* set up the pointers */ waveptr = wave.sound + wave.soundpos; waveleft = wave.soundlen - wave.soundpos; /* play sound */ while (waveleft <= len) { SDL_MixAudio (stream, waveptr, waveleft, volume); stream += waveleft; len -= waveleft; waveptr = wave.sound; waveleft = wave.soundlen; wave.soundpos = 0; } SDL_MixAudio(stream, waveptr, len, volume); wave.soundpos += len; } void quit (int sig) { done = 1; } void play_sound_clip (char *fn) { char name [32]; /* load the SDL library */ if (SDL_Init (SDL_INIT_AUDIO) < 0 ) { fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError ()); exit (1); } atexit (SDL_Quit); /* load the wave file into memory */ if (SDL_LoadWAV (fn, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { fprintf (stderr, "Couldn't load %s: %s\n", fn, SDL_GetError ()); exit (1); } wave.spec.callback = play; while (!done) { printf("Playing sound with volume = %d\n", volume); /* initialize play () variables */ if (SDL_OpenAudio (&wave.spec, NULL) < 0) { fprintf (stderr, "Couldn't open audio: %s\n", SDL_GetError ()); SDL_FreeWAV (wave.sound); exit (2); } /* enable audio to play */ SDL_PauseAudio (0); /* let the audio run */ printf ("Using audio driver: %s\n", SDL_AudioDriverName (name, 32)); while (!done && (SDL_GetAudioStatus () == SDL_AUDIO_PLAYING)) SDL_Delay (1000); } } void close_sound () { printf ("closing down audio\n"); SDL_CloseAudio (); SDL_FreeWAV (wave.sound); kill (spid, SIGKILL); } void main () { switch (spid = fork ()) { case -1: printf ("OOPS - Sound failed, no fork!\n"); exit(1); case 0: play_sound_clip ("nature.wav"); default: /* calling process -- return and keep processing */ sleep (10); close_sound (); } }