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
RFs iSession_mp3;
TBuf16
CMP3DecodeEngine *iMP3Decode;
TInt iDecodeCount;//记录解码次数
TInt iFileError;
CAudio3Engine* iEngine;
};
2、关键部分的代码的
void CSynchronousExampleStream::OpenFileL()
{
User::LeaveIfError(iSession_mp3.Connect());
字串4
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();
字串5
buf8_ptr = (TUint8* )iBuffer.Ptr();
for(i=0 ; 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()填充缓冲区。
![我要研发网[www.51dev.com]](/templets/images/toplogo.gif)
