`
totoxian
  • 浏览: 1074079 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

Symbian音频技术探究

阅读更多
Author:孙东风
Symbian SDK下有个sound的项目,这个例子囊括了Symbian下的音频播放技术。
下面有Symbian中的音频技术:
CMdaAudioToneUtility
Description
Generates tones on an audio capable device.
While this class is abstract, the static function constructs, initialises and returns a pointer to
an instance of a concrete class derived from this class. The concrete class is part of the MMF
implementation and is private.
从Class的Description中可以看出,这个类是用来播放tone的。
与其相对应的监听类为
MmdaAudioToneObserver
Description
An interface to a set of audio tone player callback functions.
The class is a mixin and is intended to be inherited by the client class which is observing the
audio tone playing operation. The functions encapsulated by this class are called when
specific events occur in the process of configuring the audio tone player utility and the
playing of a tone.
A reference to this object is passed as a parameter when constructing an audio tone player
utility, using the CMdaAudioToneUtility interface.
此监听类用来监视tone播放的操作,它封装了一些接口。在设置Player的属性和播放tone的过程中如果有特定的事件发生,就会去调用相应的接口。
在sound项目中对应的封装类如下所示:
先来看看类中声明了那些接口
#ifndef __CTONEADAPTER_H__
#define __CTONEADAPTER_H__
// INCLUDES
#include <e32std.h>
#include <MdaAudioTonePlayer.h>
#include "audioadapter.h"
// CONSTANTS
// Frequency and duration of the tone to be played
static const TInt KSoundFrequency = 3000; //声音的播放频率
static const TInt KSoundDuration = 5000000; //声音的播放时间
// FORWARD DECLARATIONS
class CSoundAppUi;
// CLASS DECLARATION
class CToneAdapter : public CBase,
public MAudioAdapter,
public MMdaAudioToneObserver
{
public:
static CToneAdapter* NewL( CSoundAppUi& aAppUi );
static CToneAdapter* NewLC( CSoundAppUi& aAppUi );
virtual ~CToneAdapter();
public: // from MAudioAdapter
/**
* PlayL
*Begin playback of the tone.
*/
void PlayL();
/**
* RecordL
* Do nothing. Recording is not supported.
*/
void RecordL();
/**
* StopL
* Stop playback or recording of the tone.
* Note that this implementation of the virtual function does not leave.
*/
void StopL();
/**
* UpdateMenuL
* Update the menu aMenuPane to reflect the
* current state of the audio tone utility.
* Note that this implementation of the virtual function does not leave.
* @param aMenuPane the menu pane to update
*/
void UpdateMenuL( CEikMenuPane* aMenuPane );
/**
* Identify
* Return an identifying string
* @return An identification string
*/
const TDesC& Identify();
public: // from MMdaAudioToneObserver
/**
* MatoPrepareComplete
* Handle the event when a tone utility initialisation
* operation has completed.
* @param aError indicates whether an error occurred.
*/
void MatoPrepareComplete( TInt aError );
/**
* MatoPlayComplete
* Handle the event when a tone playing operation has completed.
* @param aError indicates whether an error occurred.
*/
void MatoPlayComplete( TInt aError );
private: // Constructors and destructor
/**
* CToneAdapter.
* C++ default constructor.
* Perform the first phase of two phase construction
* @param aAppUi the Ui to use
*/
CToneAdapter( CSoundAppUi& aAppUi );
/**
* ConstructL
* 2nd phase constructor.
* @param aRect Frame rectangle for container.
*/
void ConstructL();
private:// Data
/**
* iMdaAudioToneUtility The audio tone utility object.
* owned by CToneAdapter object.
*/
CMdaAudioToneUtility* iMdaAudioToneUtility;
/** iAppUi Reference to the application's UI object. **/
CSoundAppUi& iAppUi;
/**
* itextResourceIdentifier. Textresource for identifier
* owned by CToneAdapter object.
*/
HBufC* itextResourceIdentifier;
};
#endif // __CTONEADAPTER_H__
从类声明的接口中我们可以看出,这个类封装了MAudioAdapterMMdaAudioToneObserver中的接口,MmdaAudioToneObserver没什么好说的,是Symbian音频框架提供的一个接口,用来监听音频播放中的各种事件。
而MaudioAdapter是项目中的另外一个接口,其声明如下
#ifndef __MAUDIOADAPTER_H__
#define __MAUDIOADAPTER_H__
#include <e32std.h>
class CEikMenuPane;
class MAudioAdapter
{
public: // New functions
/**
* PlayL
* Play the audio utility.
*/
virtual void PlayL() = 0;
/**
* StopL
* Stop the audio utility.
*/
virtual void StopL() = 0;
/**
* RecordL
* Record using the audio utility ( if supported ).
*/
virtual void RecordL() = 0;
/**
* UpdateMenuL
* Update the menu aMenuPane to reflect the current
* state of the audio utility.
* @param aMenuPane the menu pane to update
*/
virtual void UpdateMenuL( CEikMenuPane* aMenuPane ) = 0;
/**
* Identify
* Return an identifying string
* @return an identifier
*/
virtual const TDesC& Identify() = 0;
};
#endif // __MAUDIOADAPTER_H__
可以看出这是一个纯接口,抽象出了音频播放的一些共性的东西,然后“委托”给具体的播放类来实现。其中CtoneAdapter就是一个具体的实现。
下面来具体看看CtoneAdapter的实现
#include <eikmenup.h>
#include <sound.rsg>
#include "sound.pan"
#include "sound.hrh"
#include "toneadapter.h"
#include "soundappui.h"
// C++ default constructor can NOT contain any code, that might leave.
CToneAdapter::CToneAdapter( CSoundAppUi& aAppUi ) : iAppUi( aAppUi )
{
// No implementation required
}
// Two-phased constructor.
CToneAdapter* CToneAdapter::NewL( CSoundAppUi& aAppUi )
{
CToneAdapter* self = NewLC( aAppUi );
CleanupStack::Pop( self );
return self;
}
// Two-phased constructor.
CToneAdapter* CToneAdapter::NewLC( CSoundAppUi& aAppUi )
{
CToneAdapter* self = new( ELeave )CToneAdapter( aAppUi );
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
// Symbian 2nd phase constructor can leave.
void CToneAdapter::ConstructL()
{
// Load a string from the resource file.
// Identifying string for this audio utility.
itextResourceIdentifier = CCoeEnv::Static()->AllocReadResourceL(
R_SOUN_MODE_TONER );
iMdaAudioToneUtility = CMdaAudioToneUtility::NewL( *this );
// Configure the audio tone utility to play a single tone
// causes MMdaAudioToneObserver::MatoPrepareComplete to be called
iMdaAudioToneUtility->PrepareToPlayTone( KSoundFrequency,
TTimeIntervalMicroSeconds( KSoundDuration ) );
}
// Destructor.
CToneAdapter::~CToneAdapter()
{
delete iMdaAudioToneUtility;
iMdaAudioToneUtility = NULL;
// Delete private HBuf member for indetify
delete itextResourceIdentifier;
}
// Update Menu
void CToneAdapter::UpdateMenuL( CEikMenuPane* aMenuPane )
{
aMenuPane->SetItemDimmed( ESoundCmdPlay, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdRecord, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdStop, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdChange, ETrue );
switch ( iMdaAudioToneUtility->State() )
{
case EMdaAudioToneUtilityNotReady:
aMenuPane->SetItemDimmed( ESoundCmdChange, EFalse );
break;
case EMdaAudioToneUtilityPrepared:
aMenuPane->SetItemDimmed( ESoundCmdPlay, EFalse );
aMenuPane->SetItemDimmed( ESoundCmdChange, EFalse );
break;
case EMdaAudioToneUtilityPlaying:
aMenuPane->SetItemDimmed( ESoundCmdStop, EFalse );
break;
default:
User::Panic( KToneAdapter, KSoundPanicInvalidMdaState );
break;
}
}
// Play the tone
void CToneAdapter::PlayL()
{
iMdaAudioToneUtility->Play();
}
// CMdaAudioToneUtility is not able to record
void CToneAdapter::RecordL()
{
// No implementation required
}
// Stop the toneplay
void CToneAdapter::StopL()
{
iMdaAudioToneUtility->CancelPlay();
}
// Identify mode
const TDesC& CToneAdapter::Identify()
{
return *itextResourceIdentifier;
}
// Prepare to Complete
void CToneAdapter::MatoPrepareComplete( TInt /*aError*/ )
{
iMdaAudioToneUtility->SetVolume( iMdaAudioToneUtility->MaxVolume() );
}
// Play Complete
void CToneAdapter::MatoPlayComplete( TInt /*aError*/ )
{
// No implementation required
}
这个项目也体现了如何实现“动态菜单”,下面是和“动态菜单”相关的代码:
// This function is called by the EIKON framework just before it displays
// a menu pane. Its default implementation is empty, and by overriding it,
// the application can set the state of menu items dynamically according
// to the state of application data.
void CSoundAppUi::DynInitMenuPaneL( TInt aResourceId,
CEikMenuPane* aMenuPane)
{
if ( aResourceId == R_SOUND_MENU )
{
iAudioAdapter->UpdateMenuL( aMenuPane );
}
}
通过在AppUi中重写DynInitMenuPaneL()方法,然后在每次显示“菜单”之前,EIKON框架都会调用此方法,而此方法把“动态变化”的任务“委托”给各个播放类,从而实现了菜单的动态变化。
CmdaAudioPlayerUtility
Description
Plays sampled audio data.
The class offers a simple interface to open, play and obtain information from, sampled audio data. The audio data can supplied either in a file, a descriptor or a URL (since version 7.0s).
While this class is abstract, the four static functions construct, initialise and return pointers to instances of concrete classes derived from this abstract class. This concrete class is part of the MMF implementation and is private.
从类的Description中可以看出,这个类是用来播放audio data的。
Audio data可以是一个文件,也可以是一个描述符(Descriptor)或者是一个URL
但是URL只使用于7.0S以后的版本!
这个应该是我们在程序中用的最多的一个音频播放接口。
其对应的监听接口为MmdaAudioPlayerCallback,作用和其它监听接口一样。
class CPlayerAdapter : public CBase,
public MAudioAdapter,
public MmdaAudioPlayerCallback
可以看出CPlayerAdapter和CtoneAdapter一样,实现了MaudioAdapter和自己响应的监听接口。
下面是它的具体实现
#include <eikmenup.h>
#include <eikapp.h>
#include <sound.rsg>
#include "sound.pan"
#include "sound.hrh"
#include "playeradapter.h"
#include "soundappui.h"
CPlayerAdapter::CPlayerAdapter( CSoundAppUi& aAppUi )
: iState( ENotReady ), iAppUi( aAppUi )
{
// No implementation required
}
CPlayerAdapter* CPlayerAdapter::NewL( const TDesC& aFileName,
CSoundAppUi& aAppUi )
{
CPlayerAdapter* self = NewLC( aFileName, aAppUi );
CleanupStack::Pop( self );
return self;
}
CPlayerAdapter* CPlayerAdapter::NewLC( const TDesC& aFileName,
CSoundAppUi& aAppUi )
{
CPlayerAdapter* self = new ( ELeave ) CPlayerAdapter( aAppUi );
CleanupStack::PushL( self );
self->ConstructL( aFileName );
return self;
}
void CPlayerAdapter::ConstructL( const TDesC& aFileName )
{
// Load a string from the resource file.
// Identifying string for this audio utility.
itextResourceIdentifier = CCoeEnv::Static()->AllocReadResourceL(
R_SOUN_MODE_PLAYER );
#ifdef __WINS__
// on emulator, the sound files used by application are
// deployed onto c: drive
_LIT( tFullPath,"c:\\system\\apps\\sound\\" );
TParse parse;
#else
// on real phone, application can be installed to the memory
// card ( non-"C:" drive ),
// this part of code evaluates current application path:
// find the instance of EikonEnv
CEikonEnv& ee = *CEikonEnv::Static();
// derive the instance of EikonAppUi
CEikAppUi& ea = *( ee.EikAppUi() );
// fetch the application full filename
TFileName tAppFullName = ea.Application()->AppFullName();
TParse parse;
// form parse object containing full app name
parse.Set( tAppFullName, NULL, NULL );
// get application path with drive letter
TFileName tFullPath = parse.DriveAndPath();
#endif
// use tparse to get the full path to sound file
parse.Set( tFullPath, &aFileName,NULL );
TFileName tFullFileName = parse.FullName();
// Create an audio player utility instance for playing
// sample data from a file,
// causes MMdaAudioPlayerCallback::MapcInitComplete to be called
iMdaAudioPlayerUtility = CMdaAudioPlayerUtility::NewFilePlayerL( tFullFileName, *this );
}
CPlayerAdapter::~CPlayerAdapter()
{
delete iMdaAudioPlayerUtility;
// Delete private HBuf member for indetify
delete itextResourceIdentifier;
}
// Update Menu
void CPlayerAdapter::UpdateMenuL( CEikMenuPane* aMenuPane )
{
aMenuPane->SetItemDimmed( ESoundCmdPlay, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdRecord, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdStop, ETrue );
aMenuPane->SetItemDimmed( ESoundCmdChange, ETrue );
switch ( iState )
{
case ENotReady:
aMenuPane->SetItemDimmed( ESoundCmdChange, EFalse );
break;
case EReadyToPlay:
aMenuPane->SetItemDimmed( ESoundCmdPlay, EFalse );
aMenuPane->SetItemDimmed( ESoundCmdChange, EFalse );
break;
case EPlaying:
aMenuPane->SetItemDimmed( ESoundCmdStop, EFalse );
break;
default:
User::Panic( KPlayerAdapter, KSoundPanicInvalidMdaState );
break;
}
}
// Play the wav
void CPlayerAdapter::PlayL()
{
iMdaAudioPlayerUtility->Play();
iState = EPlaying;
}
// Record the wav, not available in Player mode.
void CPlayerAdapter::RecordL()
{
// No implementation required
}
// Stop the play
void CPlayerAdapter::StopL()
{
iMdaAudioPlayerUtility->Stop();
iState = EReadyToPlay;
}
// Identify mode
const TDesC& CPlayerAdapter::Identify()
{
return *itextResourceIdentifier;
}
// Mapc Init Complete
void CPlayerAdapter::MapcInitComplete( TInt aError,
const TTimeIntervalMicroSeconds& /*aDuration*/ )
{
iState = aError ? ENotReady : EReadyToPlay;
}
// Mapc Play Complete
void CPlayerAdapter::MapcPlayComplete( TInt aError )
{
iState = aError ? ENotReady : EReadyToPlay;
}
// End of File
CmdaAudioRecorderUtility
Description
Plays back, records and edits audio sample data.
The class offers an interface to play, record and edit audio sample data. This data can be supplied either in a file or as a descriptor. The functions that start and stop playback and recording are defined in the base class CMdaAudioClipUtility.
While this class is abstract, the static NewL() function constructs, initialises and returns a pointer to an instance of a concrete class derived from this abstract class. This concrete class is part of the MMF implementation and is private.
这个是关于“录音”的音频接口,其原理和上面两个也一样,略去!
分享到:
评论

相关推荐

    symbian下音频的播放

    在Symbian操作系统上开发音频播放程序是一项技术性较强的任务,尤其在早期的Symbian 2nd(第二代)平台上。Symbian系统以其高度优化的资源管理和强大的多任务能力而闻名,但它对开发者的要求也相对较高。下面将详细...

    symbian音频播放实现方法

    在Symbian操作系统中,音频播放的实现涉及多个关键步骤和技术。Symbian是一个历史悠久的移动操作系统,尤其在智能手机早期阶段广泛应用于诺基亚设备。本文将深入探讨如何在Symbian平台上实现音频播放功能,包括音频...

    移动平台音频流媒体播放软件塞班平台实现

    移动平台音频流媒体播放软件在塞班平台上的实现是一门技术含量较高的课题,涉及到多媒体处理、网络通信以及操作系统层面的编程。这篇本科毕业设计论文详细阐述了如何在塞班平台上开发一个能够播放在线音频流媒体和...

    symbian的mp3解码

    在Symbian操作系统上开发MP3解码与播放程序是一项技术性较强的工作,涉及到音频编解码、系统移植以及多媒体框架等多个方面的知识。Symbian是早期智能手机领域广泛使用的操作系统,其封闭式微内核设计使得它在资源...

    symbian_AudioPlayer.rar_Audio in symbian_symbian_symbian 播放器_sy

    本篇文章将深入探讨如何在Symbian平台上实现一个完整的音频播放器,通过分析提供的资源,我们可以了解到Symbian音频播放的核心技术。 一、Symbian音频框架基础 Symbian平台的多媒体支持基于其Audio Framework,这...

    21种音频格式文件(acc/ac3/ape/flac/m4r/ogg/wav等)

    11. **dts(Digital Theater Systems)**:DTS是一种多声道音频编码技术,与AC3类似,主要用于电影和家庭娱乐系统。 12. **pvf(Portable Voice Format)**:PVF是一种简单的声音文件格式,主要用于语音记录,主要...

    Symbian塞班操作系统

    综上所述,Symbian塞班操作系统作为智能移动终端领域的先驱,其发展历程不仅记录了技术进步的足迹,也映射出市场趋势的变化。尽管如今已不再是主流,但其在智能手机历史上的地位和贡献不容忽视,为后来的移动操作...

    Symbian中文技术周刊

    《Symbian中文技术周刊》是一系列专注于Symbian操作系统技术的资料集合,涵盖了内存管理、模拟器配置、socket编程以及DBMS等多个关键领域。在深入探讨这些主题之前,我们首先需要了解Symbian系统的基本架构和特性。 ...

    symbian中文技术期刊4合一

    《Symbian中文技术期刊4合一》是一份集成了四期技术期刊的压缩包,主要针对Symbian操作系统的一些高级技术问题进行了深入的探讨和解析。Symbian系统,作为曾经全球领先的智能手机操作系统,以其开源、高效和强大的...

    Symbian中文技术周刊1-4

    **Symbian中文技术周刊1-4** Symbian操作系统,作为早期智能手机平台的领军者,曾经在全球范围内占据了显著地位,特别是在2000年至2010年期间。这本"Symbian中文技术周刊1-4"是针对Symbian系统开发者的宝贵资源,...

    Symbian中文技术周刊1--4

    《Symbian中文技术周刊1--4》是一份宝贵的学习资料,主要涵盖了Symbian操作系统相关的技术知识。Symbian,作为一个历史悠久的移动操作系统,曾经在智能手机领域占据主导地位,尤其在诺基亚手机中广泛使用。这份周刊...

    Symbian中文技术周刊2

    Symbian中文技术周刊致力于推广Symbian技术在中国的应用和发展,每期刊物都会涵盖最新的技术动态、深入的技术分析等内容。通过这种方式,可以帮助更多的开发者了解和掌握Symbian平台的相关知识,促进技术交流和创新...

    电子信息技术在生活中的应用探究.pdf

    本文将从移动设备领域、计算机领域、汽车及交通领域、通讯领域四个方面具体探究电子信息技术在生活中的应用。 首先,移动设备领域的应用是电子信息技术发展最为迅速和普及的领域之一。移动设备,尤其是智能手机,...

    Symbian视频播放器源码

    Symbian的音频子系统(Audio Subsystem)提供了音频管道和音频驱动接口,用于实现音频播放。 6. **文件系统接口**:读取视频文件,可能需要处理各种文件系统和网络流,这涉及到Symbian的I/O子系统。 在压缩包中的...

    Symbian_2rd_Sourcecode

    通过深入研究这个Symbian 2nd Edition的音频播放器源代码,开发者不仅可以提升对Symbian操作系统的理解,还能学习到音频处理、文件解析、多线程编程等关键技术,这对于移动设备应用开发具有宝贵的参考价值。...

    Symbian资料技术PDF

    下面,我们将深入探讨Symbian操作系统的关键技术和特性。 1. **Symbian操作系统架构**: Symbian操作系统基于微内核设计,这意味着核心操作系统组件非常小,主要负责进程管理、内存管理和设备驱动。其余的服务和...

    Symbian中文技术周刊4

    从给定的文件信息来看,这期《Symbian中文技术周刊》主要聚焦于Symbian操作系统的开发,尤其深入探讨了任务管理器的开发、Metrowerks CodeWarrior的使用指南、Symbian可执行文件格式以及SyncML技术在Symbian中的应用...

    Symbian(塞班)智能手机应用技巧

    ### Symbian(塞班)智能手机应用技巧 #### 塞班智能手机概述 ...对于拥有塞班手机的用户而言,通过了解这些特点和技术背景,不仅可以更好地利用手中的设备,还能在未来选择新设备时做出更加明智的决定。

    Symbian 3版 音乐播放器

    在Symbian平台上,可以通过自定义的音频处理插件实现,将音频数据读取出来,反向后再送回音频输出。这个过程涉及到音频缓冲区的管理,以及对音频数据的位操作,以达到倒放的效果。 至于暂停功能,Symbian 3音乐...

Global site tag (gtag.js) - Google Analytics