- /* gcc -g -Wall `sdl-config --cflags` my_test.c `sdl-config --libs` */
- #include "SDL.h"
- #include <stdlib.h>
- typedef struct sound_s {
- Uint8 *samples; /* raw PCM sample data */
- Uint32 length; /* size of sound data in bytes */
- } sound_t;
- /* Structure for a currently playing sound. */
- typedef struct playing_s {
- int active; /* 1 if this sound should be played */
- sound_t sound; /* sound data to play */
- Uint32 position; /* current position in the sound buffer */
- } playing_t;
- playing_t play_music;
- void play_callback(void *user_data, Uint8 *stream, int length)
- {
- int len, pos;
- user_data = NULL;
- pos = play_music.position;
- memset(stream, 0, length);
- if (pos < play_music.sound.length)
- {
- if (pos + length < play_music.sound.length)
- len = length;
- else
- len = play_music.sound.length - pos;
- fprintf(stderr, "%d---->%d\\n", play_music.sound.length, pos);
- SDL_MixAudio(stream, play_music.sound.samples + pos, len, SDL_MIX_MAXVOLUME);
- if (pos + length < play_music.sound.length)
- play_music.position += len;
- else
- play_music.position = play_music.sound.length;
- }
- }
- int LoadAndConvertSound(char *filename, SDL_AudioSpec *spec,
- sound_t sound)
- {
- SDL_AudioCVT cvt; /* audio format conversion structure */
- SDL_AudioSpec loaded; /* format of the loaded data */
- Uint8 *new_buf;
- /* Load the WAV file in its original sample format. */
- if (SDL_LoadWAV(filename,
- &loaded, &sound.samples, &sound.length) == NULL) {
- printf("Unable to load sound: %s\\n", SDL_GetError());
- return 1;
- }
- /* Build a conversion structure for converting the samples.
- This structure contains the data SDL needs to quickly
- convert between sample formats. */
- if (SDL_BuildAudioCVT(&cvt, loaded.format,
- loaded.channels,
- loaded.freq,
- spec->format, spec->channels, spec->freq) < 0) {
- printf("Unable to convert sound: %s\\n", SDL_GetError());
- return 1;
- }
- /* Since converting PCM samples can result in more data
- (for instance, converting 8-bit mono to 16-bit stereo),
- we need to allocate a new buffer for the converted data.
- Fortunately SDL_BuildAudioCVT supplied the necessary
- information. */
- cvt.len = sound.length;
- new_buf = (Uint8 *) malloc(cvt.len * cvt.len_mult);
- if (new_buf == NULL) {
- printf("Memory allocation failed.\\n");
- SDL_FreeWAV(sound.samples);
- return 1;
- }
- /* Copy the sound samples into the new buffer. */
- memcpy(new_buf, sound.samples, sound.length);
- /* Perform the conversion on the new buffer. */
- cvt.buf = new_buf;
- if (SDL_ConvertAudio(&cvt) < 0) {
- printf("Audio conversion error: %s\\n", SDL_GetError());
- free(new_buf);
- SDL_FreeWAV(sound.samples);
- return 1;
- }
- /* Swap the converted data for the original. */
- SDL_FreeWAV(sound.samples);
- sound.samples = new_buf;
- sound.length = sound.length * cvt.len_mult;
- play_music.sound = sound; /* XXXXXXXXXXXXXXXXXXXXXXXXX */
- /* Success! */
- printf("'%s' was loaded and converted successfully.\\n", filename);
- return 0;
- }
- int main(int argc, char *argv[])
- {
- /* Audio format specifications. */
- SDL_AudioSpec desired, obtained;
- /* Our loaded sounds and their formats. */
- sound_t cannon;
- /* Initialize SDL's video and audio subsystems.
- Video is necessary to receive events. */
- if (SDL_Init(SDL_INIT_AUDIO) != 0) {
- printf("Unable to initialize SDL: %s\\n", SDL_GetError());
- return 1;
- }
- /* Make sure SDL_Quit gets called when the program exits. */
- atexit(SDL_Quit);
- /* We also need to call this before we exit. SDL_Quit does
- not properly close the audio device for us. */
- atexit(SDL_CloseAudio);
- /* Open the audio device. The sound driver will try to give us
- the requested format, but it might not succeed. The 'obtained'
- structure will be filled in with the actual format data. */
- desired.freq = 44100; /* desired output sample rate */
- desired.format = AUDIO_S16; /* request signed 16-bit samples */
- desired.samples = 4096; /* this is more or less discretionary */
- desired.channels = 2; /* ask for stereo */
- desired.callback = play_callback;
- desired.userdata = NULL; /* we don't need this */
- if (SDL_OpenAudio(&desired, &obtained) < 0) {
- printf("Unable to open audio device: %s\\n", SDL_GetError());
- return 1;
- }
- /* Load our sound files and convert them to the sound card's format. */
- if (LoadAndConvertSound(argv[1], &obtained, cannon) != 0) {
- printf("Unable to load sound.\\n");
- return 1;
- }
- /* SDL's audio is initially paused. Start it. */
- SDL_PauseAudio(0);
- while (play_music.position <= play_music.sound.length)
- ;
- /* Pause and lock the sound system so we can safely delete our sound data. */
- SDL_PauseAudio(1);
- /* At this point the output is paused and we know for certain that the
- callback is not active, so we can safely unlock the audio system. */
- SDL_UnlockAudio();
- return 0;
- }
- //该片段来自于http://www.codesnippet.cn/detail/220920136031.html
来源: http://www.codesnippet.cn/detail/220920136031.html