BlackBerry 10:Qt中使用OpenAL播放wav声音文件

BlackBerry 10/PlayBook OS 2.0里面都内置OpenAL的类库,所以在程序中使用OpenAL类库播放声音是很方便的。


BlackBerry 10开发者网站上提供的例子程序Cowbell就包括了如何相应例子代码。

Basic sound handling
A cow, a bell, and Cascades are the only things that you need to build a simple instrument app. 

In this sample, a rotation animation is used to animate a bell hanging around the neck of a cow.


You will learn how to:

  • Handle rotation animations
  • Trigger C++ functions from QML
  • Use an AbsoluteLayout
  • Play a basic sound with OpenAL

好,

 a rotat

好,我们下载例子程序Cowbell的代码 cowbell.zip


BlackBerry 10 开发工具中导入项目:

选择菜单File -> Import ...

选择Existing Projects into Workspace

BlackBerry 10:Qt中使用OpenAL播放wav声音文件_第1张图片


选择select archive file,选择Browse按钮,在文件系统上找到cowbell.zip文件,选择Finish按钮,将导入项目cowbell。

BlackBerry 10:Qt中使用OpenAL播放wav声音文件_第2张图片

Build Project

Run Configurations...

运行结果如下图,注意在BlackBerry 10模拟器上是横屏显示的,按牛(cow)身上的铃铛(bell),铃铛会左右晃动,并发出铛铛(cowbell.wav)的声音;按牛身上其他地方,牛会发出牟(moo.wav)的声音。

BlackBerry 10:Qt中使用OpenAL播放wav声音文件_第3张图片


现在,我们把这个代码扣出来,看看Qt程序里面怎么用。


我们新建一个BlackBerry Cascades C++ Project。

从 cowbell项目中拷贝

程序文件:cowbellapp.cpp,  cowbellapp.h, soundmanager.cpp, soundmanager.h(其中红色的两个文件在cowbell.zip原始代码上稍作代码改动)

声音文件:cowbell.wav, moo.wav

最后的目录结构如下:

BlackBerry 10:Qt中使用OpenAL播放wav声音文件_第4张图片

因为我们是Qt程序,所以要修改一下bar-descriptor.xml文件,加入

  <env var="QT_QPA_FONTDIR" value="/usr/lib/qt4/lib/fonts" />


编辑项目根目录下面的pro文件,在CONFIG一行后面加入LIBS一行

CONFIG += qt warn_on debug_and_release cascades
LIBS   += -lOpenAL -lalut -lasound
注:如果没有这一行,项目编译出错,找不到OpenAL的类库。

我怀疑这个是开发工具的一个bug,按理说应该是在项目中,使用向导添加OpenAL的类库。具体做法如下:









好,现在我们来看看代码。

主程序main.cpp中,当你click按钮playButton后,将触发cowbell对象的playClicked方法发出bell声音。

#include <QApplication>
#include <QPushButton>
#include <QWidget>

#include <cowbellapp.h>

int main(int argc, char *argv[])
{
        QApplication app(argc, argv);

        QWidget window;
        window.resize(768, 1280);

        QPushButton playButton("Play sound(wav)", &window);
        playButton.setGeometry(100, 200, 280, 40);

        CowBellApp cowbell;

        QObject::connect(&playButton, SIGNAL(clicked()), &cowbell, SLOT(playClicked()));

        window.show();
        return app.exec();
}


下面我们看看CowBellApp.h 头文件。里面声明了 playClicked()方法供主程序main.cpp触发事件来调用。

#ifndef COWBELLAPP_H
#define COWBELLAPP_H

#include "soundmanager.h"

class CowBellApp: public QObject
{
Q_OBJECT

public:
    CowBellApp();
    ~CowBellApp();



public slots:
	void playSound(const QString &msg);
	void playClicked();

private:
    // The sound manager.
    SoundManager *mSoundManager;

};

#endif // ifndef COWBELLAPP_H


cowbellapp.cpp程序中

1)playClicked()方法中播放牛铃声音文件cowbell.wav 。

2)对sound manager做对象生命周期管理,退出时delete sound manager。

#include "cowbellapp.h"


CowBellApp::CowBellApp()
{
	//Sound manager, we initialize the sound manager with a directory that resides in the
   //assets directory and that directory only contains playable files.
	mSoundManager = new SoundManager("sounds/");
}

CowBellApp::~CowBellApp()
{
    // Destroy the sound manager.
    delete mSoundManager;
}

void CowBellApp::playSound(const QString &msg)
{
    mSoundManager->play(msg);
}

void CowBellApp:: playClicked() {
	mSoundManager->play("cowbell.wav");
	//mSoundManager->play("moo.wav");
}


最后,核心的sound manager程序,我们简单看一下soundmanager.h头文件吧,cpp程序就不看了。

我们看到头文件中首先入了OpenAL的三个头文件,然后引入Qt的头文件。这造成虽然OpenAL和Qt无关,但是这段Sound Manager这个例子代码只能运行在Qt/Cascades程序中,不能运行在非Qt程序中。

#ifndef _SOUNDMANAGER_H
#define _SOUNDMANAGER_H

#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alut.h>

#include <QtCore/qstring.h>
#include <qhash.h>

// The number of max number of sound sources.
#define SOUNDMANAGER_MAX_NBR_OF_SOURCES 32

/**
 * SoundManager
 *
 * A very basic sound manager class for playing sounds using OpenAL.
 */
class SoundManager
{
public:

    /**
     * Constructor, initializes the sound manager. This function sets up OpenAL
     * and loads all sounds from the specified directory. This directory  should
     * be a folder only containing valid sounds.
     *
     * @param soundDirectory directory where all sounds are kept (have to be located in the assets/ folder)
     */
    SoundManager(QString soundDirectory);

    /**
     * Destructor destroys all buffers and sources.
     */
    ~SoundManager();

    /**
     * Called by the constructor, loads all sounds from the specified directory.
     *
     * @param soundDirectory directory where all sounds are kept (have to be located in the assets/ folder)
     */
    bool init(QString soundDirectory);

    /**
     * Plays a sound.
     *
     * @param fileName the name of the file in the soundDirectory.
     */
    bool play(QString fileName);

    /**
     * Plays a sound, with modified pitch and gain.
     *
     * @param fileName the name of the file in the soundDirectory
     * @param pitch specifies the pitch to be applied to a sound Range: [0.5-2.0]
     * @param gain sound gain (volume amplification) Range: ]0.0-  ]
     */
    bool play(QString fileName, float pitch, float gain);

private:

    // Sound buffers.
    QHash<QString, ALuint> mSoundBuffers;

    // Sound sources.
    ALuint mSoundSources[SOUNDMANAGER_MAX_NBR_OF_SOURCES];
};

#endif //_SOUNDMANAGER_H



你可能感兴趣的:(manager,basic,qt,BlackBerry,Constructor,destructor)