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();
}
}