SDL2.0中循环播放一段声音文件 ,并且添加上注释。
/* 加载并且循环播放一个WAV文件*/ /* loopwaves.c is much more robust in handling WAVE files -- This is only for simple WAVEs */ #include "SDL_config.h" #include <stdio.h> #include <stdlib.h> #if HAVE_SIGNAL_H #include <signal.h> #endif #include "SDL.h" #include "SDL_audio.h" //sdl 播放缓冲区定义 struct { SDL_AudioSpec spec; Uint8 *sound; /*指向声音数据指针 */ Uint32 soundlen; /* Length of wave data */ int soundpos; /* Current play position */ } wave; /* 调用这个函数退出SDL子系统 */ static void quit(int rc) { SDL_Quit(); exit(rc); } void SDLCALL fillerup(void *unused, Uint8 * stream, int len) { Uint8 *waveptr; int waveleft; /*设置当前声音指针 声音指针+当前播放的位置 */ waveptr = wave.sound + wave.soundpos; //剩余声音数据 声音数据长度-当前播放的位置 waveleft = wave.soundlen - wave.soundpos; /* 如果剩余数据<需要的长度 */ while (waveleft <= len) { //拷贝剩余数据到音频缓冲区 SDL_memcpy(stream, waveptr, waveleft); //音频缓冲区stream指针后移 stream += waveleft; //len=len-waveleft len -= waveleft; //拷贝玩剩余数据 //waveptr指向 声音数据开头 waveptr = wave.sound; //长度等于len waveleft = wave.soundlen; //位置等于len wave.soundpos = 0; } //重新拷贝内存到 音频设备缓冲区 //也就是循环播放 SDL_memcpy(stream, waveptr, len); //当前播放的位置 +=len wave.soundpos += len; } static int done = 0; //退出信号 void poked(int sig) { done = 1; } int main(int argc, char *argv[]) { int i; char filename[4096]; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); /* 初始化SDL音频库 */ if (SDL_Init(SDL_INIT_AUDIO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return (1); } //拷贝文件名字 到 filename 缓冲区 if (argc >= 1) { SDL_strlcpy(filename, argv[1], sizeof(filename)); } else { SDL_strlcpy(filename, "D:\\vs2010_pro\\ffmpeg_test\\Output\\audio.aac", sizeof(filename)); } /* 加载声音文件到内存 */ if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], SDL_GetError()); quit(1); } //音频回调 在回调函数中填充音频缓冲区 需求的大小的数据 wave.spec.callback = fillerup; #if HAVE_SIGNAL_H /* Set the signals */ #ifdef SIGHUP signal(SIGHUP, poked); #endif signal(SIGINT, poked); #ifdef SIGQUIT signal(SIGQUIT, poked); #endif signal(SIGTERM, poked); #endif /* HAVE_SIGNAL_H */ /* Show the list of available drivers */ SDL_Log("Available audio drivers:"); //打印电脑上的所有音频驱动 for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); } /*初始化音频设备 并且打开 因为我们输出的wav有头部信息所有 我们不需要设置参数*/ if (SDL_OpenAudio(&wave.spec, NULL) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); SDL_FreeWAV(wave.sound); quit(2); } //打印当前音频设备 SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); /*开始播放声音 这个时候 SDL以异步线程的方式不停的回调 来取数据 */ SDL_PauseAudio(0); //如果当前正在播放 那么 主线程 Delay 1s //或者有退出信号 那么退出 while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) SDL_Delay(1000); /* 关闭音频 */ SDL_CloseAudio(); //释放分配的声音数据内存 SDL_FreeWAV(wave.sound); //退出程序 和SDL SDL_Quit(); return (0); }
SDL2.0例子代码分析---循环播放wav loopwav
原文地址:http://blog.csdn.net/yue7603835/article/details/42099671