首 页 | 新 闻 | Symbian | Android| Windows Mobile | J2ME | 下载中心 | 游戏策划招聘与求职 | 购书指南 | 视频教程
您现在的位置: 开发视界 >> Symbian英文资料 >> Multimedia >> 正文
Using Sound with Symbian
作者:佚名    文章来源:不详    更新时间:2006-5-7 11:15:59

As with many things in Symbian, the sound player is straightforward and powerful once mastered, but unintuitive and perplexing to those who have not yet dealt with it. The principles behind playing recorded sound, media files, and straightforward beeps are much the same as each other, so for today we shall deal only with simple notes on the tone player.

Part I: The Theory

If you’re using this tutorial to learn from scratch about the ins and outs of producing sound in Symbian, then read on. If you’re here because you’ve gotten stuck on a sound problem and need a nudge in the right direction from some sample code, it’s reasonably safe to skip to Part II.

The CMdaAudioToneUtility Object and its Observer

For each channel of sound that you want, there has to exist an object of type CMdaAudioToneUtility, and an object that invokes it and observes its operation. The idea of needing two objects to play a sound might seem unnecessary and confusing, but it is appropriate to the asynchronous nature of sound manipulation. (See the glossary in Part II for more on this.)

Your observer can be a new object that you’ve created especially for the task, which can be useful if you want to do your safety checks on a lower level in your program (you’ll see what this means in a bit), or it can be an existing object that does most of your program’s execution. Either way, you will need to derive your observer object from MMdaAudioToneObserver and define a few callback functions.

The MMdaAudioToneObserver class is an ’M type’ or mixin class (also known as an interface class), which means it does not define any methods of its own. It contains only a couple of pure virtual functions, MatoPrepareComplete() and MatoPlayComplete(), which you must define in your new class.

Here is part of our observer object, which will create a CMdaAudioToneUtility object for us and manipulate it. (Since the code in Part II is loosely based on the Sound Example in the Series 60 SDK, we shall use the same names for classes and variables.)

In the header file:

#include <MdaAudioTonePlayer.h>
class CToneAdapter : public CBase, public MMdaAudioToneObserver {
public: // inherited from MMdaAudioToneObserver
void MatoPrepareComplete(TInt aError);
void MatoPlayComplete(TInt aError);

private:
CMdaAudioToneUtility* iMdaAudioToneUtility; // The CMdaAudioToneUtility Object we plan to use
};

In our main .cpp file:

void CToneAdapter::MatoPrepareComplete(TInt aError)
{
/* code to execute when we're finished preparing the sound. Most likely it will set some kind of flag to let the program know it's safe to call Play(). */
}

void CToneAdapter::MatoPlayComplete(TInt aError)
{
/* code to execute when we're finished playing the sound. Most likely it will set some kind of flag to let the program know it's safe to call Prepare() or Play(). */
}

You may need to link your code against MediaClientAudio.lib by adding LIBRARY   mediaclientaudio.lib to your project’s .mmp file.

Preparing the Sound

You will by now have noticed the term ’Prepare’ appear more than once. To play a sound of a given pitch and duration, we must first call

iMdaAudioToneUtility->PrepareToPlayTone(iFrequency, TTimeIntervalMicroSeconds(iDuration));

to tell the iMdaAudioToneUtility object to prepare a note of that frequency and duration. Once it has indicated that it is ready by calling the MatoPrepareComplete() method we have defined, we then can call

iMdaAudioToneUtility->Play();

every time we want to play that kind of note. If we want to play a note of a different pitch or duration afterwards, we need to call PrepareToPlayTone() again. This detail is important to remember if you are designing a system that may only ever play two or three different notes - it may be worth your while creating two or three different CMdaAudioToneUtility objects and initializing each with a single PrepareToPlayTone instead of constantly changing over. This is especially true if the different notes are liable to be played at the same time.

Finally, it takes time to prepare a sound! It is by no means instantaneous, and you cannot assume that it is safe to send a Play() command immediately after a Prepare(). If the Prepare() has not completed your program will panic.

Using the Observer in Your Program

Chances are you’ll want the observer object to just handle sound. So, to use it in a bigger program, we need to add a few interface methods.

void CToneAdapter::PlayL()
{
        iMdaAudioToneUtility->Play();
}

void CToneAdapter::PrepareL()
{
iMdaAudioToneUtility->PrepareToPlayTone(iFrequency, TTimeIntervalMicroSeconds(iDuration));
}

Note that these example methods contain no checking for current state, and so run a high risk of causing a panic. So, our main program might (badly) use a sound player thus:

int main(void) {
...
CToneAdapter *iToneAdapter;
iToneAdapter = CToneAdapter::NewL(440,TTimeIntervalMicroSeconds(100000));
iToneAdapter->PrepareL();
iToneAdapter->PlayL();
...
}

We’ll fix the lack of decent synchronization in Part II.

Other Considerations

Do you need more than one channel? If, for example, there are two things in your program capable of generating a sound, you will have to ensure that they either take turns in a well-behaved manner or use separate channels - otherwise your program will panic. Can you prove by way of logic that your program will definitely not try to prepare or play anything on a channel before MatoPlayComplete has been called on the previous sound on the same channel?

Lastly, don’t forget to delete your object in your destructor!

Don’t worry if you’re still confused - it will all come together in Part II.

相关文章:
Emotionalize Your Mobile Games With Tuny Engine Lite
Overview of the Compilation system
GenBuild to Build Symbian Programs
How to setup a free Windows-based development environment for Symbian OS
Icons, .AIFs, and .SIS files in Series 60
Multichannel Sound using CMdaAudioOutputStream (v1.1)
Playing a WAV file
Using Command Line Arguments in Symbian
 

站点地图 | 加入收藏 | 联系站长 | 广告服务 |
QQ:280529124  Tel:0592-8271361 辽ICP备05021703号