SDL_mixer可从此处下载。
要安装SDL_mixer,请查看前面的扩展库安装教程。安装SDL_mixer的方法与安装SDL_image极其相似,你仅需将前面教程中的SDL_image替换为SDL_mixer。
本节课介绍了使用SDL_mixer播放音乐和声效的基本方法,并播放了我通过敲打我的显示器制作出来的声效和“音乐”。
//将要播放的音乐 Mix_Music *music = NULL; //将要使用的声效 Mix_Chunk *scratch = NULL; Mix_Chunk *high = NULL; Mix_Chunk *med = NULL; Mix_Chunk *low = NULL;
这里有新的数据类型,我们将与和它们打交道。
Mix_Music
是我们用于音乐的数据类型,Mix_Chunk
是用于声效的数据类型。bool init() { //初始化SDL的所有子系统 if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return false; } //设置窗口 screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); //如果设置窗口出错 if( screen == NULL ) { return false; } //初始化SDL_ttf if( TTF_Init() == -1 ) { return false; } //初始化SDL_mixer if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) { return false; } //设置窗口标题 SDL_WM_SetCaption( "Monitor Music", NULL ); //如果所有初始化成功 return true; }
在初始化函数中,我们调用
该函数的第一个参数是我们使用的声音频率,在本课中,它被设为22050,这也是推荐设置的值。第二个参数是声音格式,我们使用了默认的格式。第三个参数是我们计划使用的频道数量。我们将它设为2来获得立体声,如果设为1,将只有单声道声音。最后一个参数是样本大小,这里被设为4096。
对于那些使用OGG, MOD或者其他非WAV声音格式的人,请使用
Mix_OpenAudio()
来初始化SDL_mixer中的声音函数。该函数的第一个参数是我们使用的声音频率,在本课中,它被设为22050,这也是推荐设置的值。第二个参数是声音格式,我们使用了默认的格式。第三个参数是我们计划使用的频道数量。我们将它设为2来获得立体声,如果设为1,将只有单声道声音。最后一个参数是样本大小,这里被设为4096。
对于那些使用OGG, MOD或者其他非WAV声音格式的人,请使用
Mix_Init()
来初始化解码器,并使用Mix_Quit()
来关闭解码器。因为这里我们仅仅使用了WAV文件,所以我们不必为了用不到的东西来添加更多代码。bool load_files() { //加载背景图 background = load_image( "background.png" ); //打开字体 font = TTF_OpenFont( "lazy.ttf", 30 ); //如果加载背景出错 if( background == NULL ) { return false; } //如果加载字体出错 if( font == NULL ) { return false; } //加载音乐 music = Mix_LoadMUS( "beat.wav" ); //如果加载音乐出了问题 if( music == NULL ) { return false; } //加载声效 scratch = Mix_LoadWAV( "scratch.wav" ); high = Mix_LoadWAV( "high.wav" ); med = Mix_LoadWAV( "medium.wav" ); low = Mix_LoadWAV( "low.wav" ); //如果加载声效出了问题 if( ( scratch == NULL ) || ( high == NULL ) || ( med == NULL ) || ( low == NULL ) ) { return false; } //如果一切加载正常 return true; }
这是我们的文件加载函数。
要加载音乐,我们使用
要加载声效,我们使用
要加载音乐,我们使用
Mix_LoadMUS()
。这个函数接受一个音乐文件的文件名并返回其中的音乐数据。如果出错,它会返回NULL。要加载声效,我们使用
Mix_LoadWAV()
。它加载了传入的文件名所对应的声音文件,并返回了一个Mix_Chunk
,如果出错了,则返回NULL。void clean_up() { //释放表面 SDL_FreeSurface( background ); //释放声效 Mix_FreeChunk( scratch ); Mix_FreeChunk( high ); Mix_FreeChunk( med ); Mix_FreeChunk( low ); //释放音乐 Mix_FreeMusic( music ); //关闭字体 TTF_CloseFont( font ); //退出SDL_mixer Mix_CloseAudio(); //退出SDL_ttf TTF_Quit(); //退出SDL SDL_Quit(); }
在清理函数中,我们调用
然后,我们结束了SDL_mixer的使用,调用了
Mix_FreeChunk()
来清除声效,并用Mix_FreeMusic()
来释放音乐。然后,我们结束了SDL_mixer的使用,调用了
Mix_CloseAudio()
。//当用户还没退出 while( quit == false ) { //当有事件需要处理 while( SDL_PollEvent( &event ) ) { //如果一个按键被按下 if( event.type == SDL_KEYDOWN ) {
在main函数中,在初始化、文件加载、背景和信息的blit完成后,我们进入了主循环。然后我们开始处理事件,首先是按键事件。
//如果数字键“1”被按下 if( event.key.keysym.sym == SDLK_1 ) { //播放“挠”的声效 if( Mix_PlayChannel( -1, scratch, 0 ) == -1 ) { return 1; } } //如果数字键“2”被按下 else if( event.key.keysym.sym == SDLK_2 ) { //播放“重击”的声效 if( Mix_PlayChannel( -1, high, 0 ) == -1 ) { return 1; } } //如果数字键“3”被按下 else if( event.key.keysym.sym == SDLK_3 ) { //播放“中度击打”的声效 if( Mix_PlayChannel( -1, med, 0 ) == -1 ) { return 1; } } //如果数字键“4”被按下 else if( event.key.keysym.sym == SDLK_4 ) { //播放“轻击”的声效 if( Mix_PlayChannel( -1, low, 0 ) == -1 ) { return 1; } }
在检查按键按下的事件时,首先我们检查数字键1, 2, 3, 或 4是否被按下。这些是播放声效的按键。
如果这些键中的一个被按下,我们就调用
这个函数的第一个参数是我们将要播放声音的混音频道。由于它被设为了-1,这个函数会自动寻找第一个可用的频道,并播放声音。
第二个参数是将要播放的
当播放声音出了问题时,
如果这些键中的一个被按下,我们就调用
Mix_PlayChannel()
来播放与其关联的声效。这个函数的第一个参数是我们将要播放声音的混音频道。由于它被设为了-1,这个函数会自动寻找第一个可用的频道,并播放声音。
第二个参数是将要播放的
Mix_Chunk
。第三个参数是声效将要重复的次数。由于它被设为0,声效将只会播放一次。当播放声音出了问题时,
Mix_PlayChannel()
会返回 -1。
//如果数字键“9”被按下 else if( event.key.keysym.sym == SDLK_9 ) { //如果没有音乐在播放 if( Mix_PlayingMusic() == 0 ) { //播放音乐 if( Mix_PlayMusic( music, -1 ) == -1 ) { return 1; } }
接下来,我们处理数字键“9”被按下的事件,这里我们应该播放或暂停音乐。
首先,我们通过
函数
如果播放音乐出现问题,该函数会返回-1。
首先,我们通过
Mix_PlayingMusic()
检查是否有音乐正在播放。如果没有音乐在播放,我们调用Mix_PlayMusic()
来播放音乐。函数
Mix_PlayMusic()
的第一个参数是我们将要播放的音乐。第二个参数是音乐将要循环的次数。由于它被设为了-1,音乐将在手动停止前不停地循环下去。如果播放音乐出现问题,该函数会返回-1。
//如果音乐已进入播放状态 else { //如果音乐被暂停了 if( Mix_PausedMusic() == 1 ) { //恢复播放 Mix_ResumeMusic(); } //如果音乐正在播放 else { //暂停音乐 Mix_PauseMusic(); } } }
现在,如果当用户按下“9”时,音乐正在播放,我们则暂停或恢复音乐播放。
首先,我们使用
首先,我们使用
Mix_PausedMusic()
检查音乐是否已被暂停。如果是的,我们通过Mix_ResumeMusic()
来恢复播放。如果音乐没有被暂停,我们使用Mix_PauseMusic()
来将它暂停。//如果数字键“0”被按下 else if( event.key.keysym.sym == SDLK_0 ) { //停止音乐 Mix_HaltMusic(); } }