WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程Symbian程序开发使用libmad播放mp3文件

使用libmad播放mp3文件
作者:未知  来源:CSDN  发布时间:2005-12-21 3:53:36
我已经成功地播放出了声音!这里先说一下大概的思路:
1、定义类:
class CSynchronousExampleStream : public CBase, public MMdaAudioOutputStreamCallback
{
public:
//from MMdaAudioOutputStreamCallback
virtual void MaoscOpenComplete(TInt aError);
virtual void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
virtual void MaoscPlayComplete(TInt aError);

void ConstructL(CAudio3Engine* aEngine);
virtual ~CSynchronousExampleStream();
void StartPlayL();
void Stop();
private:
void OpenFileL();
void CloseFile();

void NextBuffer();
void PlayEnded(TInt aError);
TInt FillBuffer();
private:
CMdaAudioOutputStream* iStream;
RFs iSession;
TBuf8<KBufferSize*2> iBuffer;
RFs iSession_mp3;
TBuf16<KBufferSize> iBuffer16;
CMP3DecodeEngine *iMP3Decode;
TInt iDecodeCount;//记录解码次数
TInt iFileError;
CAudio3Engine* iEngine;
};
2、关键部分的代码的
void CSynchronousExampleStream::OpenFileL()
{
User::LeaveIfError(iSession_mp3.Connect());
iMP3Decode->OpenFile(iSession_mp3 , _L("c:\\play.mp3"));
iMP3Decode->SetResampleRate(16000);
iMP3Decode->DecodeStart();
}
void CSynchronousExampleStream::CloseFile()
{
iMP3Decode->DecodeStop();
iMP3Decode->CloseFile();
iSession_mp3.Close();
}
void CSynchronousExampleStream::ConstructL(CAudio3Engine* aEngine)
{
iDecodeCount = 0;
iMP3Decode = CMP3DecodeEngine::NewL();
iEngine=aEngine;
iStream=CMdaAudioOutputStream::NewL(*this);
iStream->Open(NULL);
}
void CSynchronousExampleStream::NextBuffer()
{
if (iFileError==KErrNone)
{
iMP3Decode->DecodeOneFrame(iBuffer16);//解码一个桢
if(iBuffer16.Length()!=0)
{
iFileError=KErrNone;
iDecodeCount++;//记录桢数
}
else
{
iFileError=KErrEof;
}
//复制到原来的数组中
//iBuffer.Copy(iBuffer16);//这样做不行,会丢掉16bit的高8位的,必须要转换
TInt i=0 ;//临时循环变量
TInt len ;
len = iBuffer16.Length()*2;
TUint8 *buf16_ptr;
TUint8 *buf8_ptr;
buf16_ptr = (TUint8* )iBuffer16.Ptr();
buf8_ptr = (TUint8* )iBuffer.Ptr();
for(i=0 ; i<len ; i++)
{
//双字节复制到单字节数组中,长度增加一倍
buf8_ptr[i] = (TUint8)buf16_ptr[i];
}
iBuffer.SetLength(len);
TRAPD(err,iStream->WriteL(iBuffer));
if (err!=KErrNone) Stop();
}
}
CSynchronousExampleStream::~CSynchronousExampleStream()
{
CloseFile();
delete iMP3Decode;
delete iStream;
}
void CSynchronousExampleStream::MaoscOpenComplete(TInt aError)
{
if (aError==KErrNone)
{
iStream->SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate16000Hz,TMdaAudioDataSettings::EChannelsMono);
iStream->SetVolume(iStream->MaxVolume());
iEngine->SetState(CAudio3Engine::EReadySynchronous);
}
}

大体上就是如此,思路上是:媒体文件流化后,每播放一个缓冲的内容后,会回调MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
在这个函数里面再调NextBuffer()填充缓冲区。
[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码