SDL 声音库 (SoundBank)

本系列教程来自Dev Hub。

英文原文地址: http://www.sdltutorials.com/sdl-soundbank/

在这附加的教程里,我们将会增加一个声音库用于加载我们所有的声音。并且,我们通过ID来播放这些文件,不管我们什么时候想要。这个教程只会涉及到声音,没有音乐,对于你来说这是一个非常基本的教程,仅仅让这声音处理的事情完成了。有很多东西可以被加到这个类里,通道,组等等,但是在这里我们只处理基本事情。我们这个教程将会基于我先前的SDL Events 教程。所以,使用这些项目文件如果你想要下面的例子正常工作的话。

第一件你要去做的事情是从 SDL website下载SDL mixer。那里也有我主页上提供的SDL库。确保include文件和SDL的inlcude文件在同一个目录下。lib目录和SDL的lib文件在同一目录下,使得事情变得简单。

通过打开你的项目来开始吧,然后进入到linker设置。吧SDL_mixer加在SDLmain以后,就像:

mingw32
SDLmain
SDL_mixer
SDL

如果你不记得在哪里去找这些设置,你可以去看看第一个教程,温习一下链接设置。如果你有一个.lib的文件,而不是.a的文件,通过browse按钮去找到库文件。

仅仅在一个小方注意一下声音。SDL_mixer把任何在内存里声音都当成是数据块(chunk)。数据块(chunk)包含了频率数据。SDL_mixer的好处是,由来它处理这些数据,并把它发送到音频输出,那意味着SDL_mixer做了所有这些困难的工作。所以所有我们要做的事情只需要加载我们的数据。比如从一个WAV文件里,然后将它发送到SDL_mixer去播放。

首先,创建两个新文件,CSoundBank.h和CSoundBank.cpp。先打开头文件:

#ifndef _CSOUNDBANK_H_
    #define _CSOUNDBANK_H_

#include <SDL.h>
#include <SDL_mixer.h>
#include <vector>

class CSoundBank {
    public:
        static CSoundBank           SoundControl;

std::vector<Mix_Chunk*>     SoundList;

public:
        CSoundBank();

int OnLoad(char* File);

void OnCleanup();

public:
        void Play(int ID);
};

#endif

我们先有了一个静态的控制对象,这让我们能在程序的任何位置增加声音和播放声音。想象一下这个东西就像是增加/播放声音的主控件。然后我们有了我们的SoundList,这是一个SDL_mixer声音的列表。现在,一个Mix_Chunk的对象包含了需要去播放一个声音的信息。我们接下来要做的事情是加载一个wav文件到Mix_Chunk对象里。想象一下,声音就像SDL_Surface。那么,我们有了一些加载,清除,和播放声音的的基本功能了。很简单吧。

接下来,打开CSoundBank.cpp:

#include "CSoundBank.h"

CSoundBank CSoundBank::SoundControl;

CSoundBank::CSoundBank() {
}

int CSoundBank::OnLoad(char* File) {
    Mix_Chunk* TempSound = NULL;

if((TempSound = Mix_LoadWAV(File)) == NULL) {
        return -1;
    }

SoundList.push_back(TempSound);

return (SoundList.size() - 1);
}

void CSoundBank::OnCleanup() {
    for(int i = 0;i < SoundList.size();i++) {
        Mix_FreeChunk(SoundList[i]);
    }

SoundList.clear();
}

void CSoundBank::Play(int ID) {
    if(ID < 0 || ID >= SoundList.size()) return;
    if(SoundList[ID] == NULL) return;

Mix_PlayChannel(-1, SoundList[ID], 0);
}

这些东西也是非常直观的。我们有一个静态控件,我们空的构造函数,并且还有我们的加载函数。我们基本上能够让声音文件被加载,并且尝试通过Mix_LoadWAV加载到Mix_Chunk对象里。 注意,我先是创建一个临时对象,然后把它扔到列表里。在快接近函数结束的地方,我返回最后被插入声音的ID。因此,例如,我加载了SoundA和SoundB:

int SoundA = CSoundBank::SoundControl.OnLoad("sounda.wav");
int SoundB = CSoundBank::SoundControl.OnLoad("soundb.wav");

用来播放这个声音的ID会被OnLoad函数返回。

OK,接下来我们有cleanup函数,它遍历这个列表并且释放声音数据块。就像SDL_FreeSurface一样简单吧。

最后,我们有了真正播放声音的Play函数。我们先传一个ID(从Load函数得到的返回值)给Play函数。我们做一小点边界测试,确保ID是有效的。然后,试着去播放声音。Mix_PlayChannel有三个参数:

第一个参数指定要播放的通道,-1代表使用第一个可用的通道。

第二个参数指定要播放的数据块。

最后一个参数指定要播放多长的时间。-1代表无限。

我们这个类里没有做大量的关于通道的工作,但是这个类很容被修改,增加功能。基本的,通道允许你修改特定声音的设定。例如,你可以设置音量和偏移在第一个通道上,因此任何在那个通道上播放的声音都有同样的效果。

现在那么让我们做一点小小的测试。打开CApp.h,并且加上头文件,然后加上一些变量和函数到CApp类里:

#include "CSoundBank.h"

//…

class CApp {
    public:
        int SoundA;
        int SoundB;

//… other code

public:
        void OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode);
};

现在,打开CApp_Init.cpp,要是我们能够加载一些声音:

if((SoundA = CSoundBank::SoundControl.OnLoad("sounda.wav")) == -1) {
    return false;
}

if((SoundB = CSoundBank::SoundControl.OnLoad("soundb.wav")) == -1) {
    return false;
}

现在,为了能让我们按下一个按键是发出声音,打开CApp_OnEvent.cpp,然后增加下面的函数:

void CApp::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) {
    if(sym == SDLK_1) {
        CSoundBank::SoundControl.Play(SoundA);
    }

if(sym == SDLK_2) {
        CSoundBank::SoundControl.Play(SoundB);
    }
}

我们还没有完成,我们必须做一点点事情去启动SDL_mixer。这就像是启动SDL一样,但是我们需要的是去启动SDL_mixer去访问声音。打开CApp_Init.cpp并且加入下面的代码,在SDL_Init下面一点的地方。

if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0) {
    return false;
}

Mix_OpenAudio简单的初始话SDL_Mixer。 这个函数接受4个参数。第一个参数用来指定频率,44100通常是一个比较好的频率。但是你依据的WAV文件,你也许要变更频率。另一个通用的频率是22050。我不想谈论过的关于频率的细节,让它在那里,除非你真的需要改变它。下一个参数是格式(format),最好是不要管它除非你有很多关于声音的知识(基本上是采样的大小,8位或16位)。再下一个参数是通道数,1 代表单声道,2代表立体声。注意,这里的通道和以前我在其地方谈的通道是不一样的。这里的通道,其实是声音的输出数目。想象一下,他就像是你有的音箱数目。两个音箱,两个通道。最后一个参数是用来设置声音的大小。除非你真的知道怎么做,最好不要去管它。

为了让代码整洁,当我们完成时我们需要确保我们停止了SDL_mixer的服务,就像是释放任何我们加载的声音。

所以打开CApp_OnCleanup.cpp,然后加入下面的代码:

CSoundBank::SoundControl.OnCleanup();

Mix_CloseAudio();

我们完成了!试着去编译,并且按下1 和 2 键去听一些声音。如果你需要一些WAV文件,下载下面的项目文件去获取它们。

SDL 声音库 (SoundBank) - 课程文件:
Win32: Zip, Rar
Linux: Tar (Thanks Gaten)

转载于:https://www.cnblogs.com/Henrya2/archive/2009/03/22/1418535.html

SDL 声音库 (SoundBank)相关推荐

  1. SDL教程4——在VS2010中设置SDL扩展库

    前几节我们了解到,SDL基本库只能加载普通的BMP图像,如果我们还想加载其它格式的图片,我们就需要用到SDL的扩展库,它可以帮助我们加载BMP, PNM, XPM, LBM, PCX, GIF, JP ...

  2. 小程序---声音库播放

    一:运行预览 二:解决方案截图 三:主要代码 程序入口:App.xaml using System; using System.Diagnostics; using System.Resources; ...

  3. SDL及扩展库在ARM-Linux 完整移植

    SDL的正确运行需要大量的支持库 1.编译安装支持库 在ARM-LINUX编译SDL之前.需要编译如下安装库. 常见的库的iconv,zlib,freetype等都要 SDL支持库的移植参见.我的博客 ...

  4. SDL库及SDL_draw库的安装、SDL库的使用

    SDL库及SDL_draw库的安装.SDL库的使用 (1)SDL基本库的安装 在Ubuntu下使用apt-get安装,由于我在安装过程中出现的错误,要注意一定要在联网的情况下进行安装.分别安装libs ...

  5. 你必须尝试的20个 Python 库

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达推荐阅读 42个pycharm使用技巧,瞬间从黑铁变王者Google ...

  6. FFmpeg再学习 -- SDL 环境搭建和视频显示

    继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作 一.SDL 简介 参看:WIKI -- Simple DirectMedia Layer 参看:最简单的视音频播放示例9:SD ...

  7. freebasic 编译linux,FreeBasic库文件入门 [SJ ZERO原创,沧海冷心翻译]

    FreeBasic库文件入门 [SJ ZERO原创,沧海冷心翻译] http://www.freebasic.cn FreeBasic最大的优势就是可以与标准C的类库无缝结合.在FREEBASIC拥有 ...

  8. ffmpeg(5):SDL相关学习

    转自:http://blog.csdn.net/oldmtn/article/details/20853117 SDL学习资料1 SDL在Wiki上的介绍:http://zh.wikipedia.or ...

  9. FFmpeg+SDL,如何用少于1000行代码编写视频播放器

    此文档翻译国外dranger教程: An ffmpeg and SDL Tutorial or How to Write a Video Player in Less Than 1000 Lines ...

最新文章

  1. 鲁棒图的三元素:抽象对象,实体对象和控制对象
  2. 有一种爱,永远也无法逾越
  3. pear Auth的使用
  4. MySQL主从原理,基于快速学习一门技术的3种方式!
  5. RocketMQ核心架构和概
  6. Set集合以及HashSet、LinkedHashSet、TreeSet等讲解
  7. React 重温之 组件生命周期
  8. mysql测试数据图表_mysql测试数据表
  9. [OI学习笔记]最小生成树之Prim算法
  10. 使用Geolocation校正GDAL不支持的数据
  11. Silverlight 游戏开发小技巧:昼夜交替动画
  12. 测试一个链表是否为空表 C语言,【链表测试面试题】面试问题:C语言单链表的… - 看准网...
  13. (十二)JAVA springboot微服务b2b2c电子商务系统:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪...
  14. python执行命令不阻塞_通过python 执行 nohup 不生效的解决
  15. 英伟达控制面板打不开的解决办法
  16. 调用DllRegisterServer进行COM组件的注册
  17. 【yum】yum 源的配置与使用
  18. 【python】二进制与十进制的转换
  19. 达达O2O后台架构演进实践:从0到4000高并发请求背后的努力
  20. 宁波市第一医院附近的房屋调研

热门文章

  1. 阿里云实名认证常见问题分析
  2. (转载)摄影集.西湖边的一棵树
  3. VBA:单元格实例(格式化工资条),拾取的颜色求平均
  4. VC2010使用过程常见问题
  5. 哪个pc服务器稳定,稳定就等于效率 低端塔式服务器精选!
  6. 乔吉拉德——250定律
  7. 国培 计算机远程培训心得,国培网络研修心得体会(通用4篇)
  8. Leetcode_454_4Sum II
  9. 【Window】线程同步方式1——临界区(关键代码段)
  10. App渠道统计工具openinstall测评报告总结