×

Discussion Board

Results 1 to 12 of 12
  1. #1
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224

    Plyaing AMR file using MMF framework.

    Hi all,

    I tried to play amr using CMdaAudioPlayerUtility class, which works only in Emulator.

    I am downloading the AMR data from the server which is put to the descriptor array. Then I want to play this from the descriptor.

    I really appreciate any help regarding this.

    Regards,

    shagor

  2. #2
    Nokia Developer Moderator
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,167
    you should use streaming instead. CMdaAudioPlayerUtility will have proablems with AMR in quite many target devices.

    yucca

  3. #3
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224

    Thanks yucca.

    Could you please provide me some example code. I have been trying to solve this problem for long time. Hope you would send some code for streaming technique for playing amr .

  4. #4
    Nokia Developer Moderator
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,167
    here's a sample code for playing buffers with streaming:

    // CStreamPlayEngine class
    //
    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    CStreamPlayEngine::CStreamPlayEngine(MRectPlayCallBack* aCallBack)
    :iCallBack(aCallBack),iVolume(10),iReadSize(0)
    ,iPlayError(KErrNone),iStatus(EEngineReady),iPlayBuffer(NULL)
    {
    }


    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    CStreamPlayEngine::~CStreamPlayEngine()
    {
    Stop();

    delete iStream;
    iStream = NULL;
    delete iOCodec;
    iOCodec = NULL;
    delete iPcm16Buffer;
    iPcm16Buffer = NULL;
    delete iAmrBuffer;
    iAmrBuffer = NULL;
    delete iTmpBuffer;
    iTmpBuffer = NULL;
    delete iPlayBuffer;
    iPlayBuffer = NULL;

    iBuffer.ResetAndDestroy();
    }

    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    CStreamPlayEngine* CStreamPlayEngine::NewL(MRectPlayCallBack* aCallBack)
    {
    CStreamPlayEngine* self = new (ELeave) CStreamPlayEngine(aCallBack);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(); // self
    return self;
    }

    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    const TInt KAdvancedUidCodecAMRToPCM16 = 0x101FAF67;

    void CStreamPlayEngine::ConstructL()
    {
    iEnv = CEikonEnv::Static();
    }

    /*
    -------------------------------------------------------------------------------
    implement any callbacks in here..
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::SetengineState(TInt aNewState)
    {
    if(iPlayBuffer && iCallBack)
    {
    TPoint AudioLength(iReadSize,iPlayBuffer->Des().Length());
    TPoint PlayState(iStatus,aNewState);
    iStatus = aNewState;

    iCallBack->StateChange(PlayState,iPlayError,AudioLength,this);
    }
    }

    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::ReStartL()
    {
    Stop();

    delete iStream;
    iStream = NULL;
    delete iTmpBuffer;
    iTmpBuffer = NULL;
    iTmpBuffer = HBufC8::NewL(KPcmBufferSize);

    delete iOCodec;
    iOCodec = NULL;
    iOCodec = CMMFCodec::NewL(TUid::Uid(KAdvancedUidCodecAMRToPCM16));

    delete iPcm16Buffer;
    iPcm16Buffer = NULL;
    iPcm16Buffer = CMMFDescriptorBuffer::NewL(KPcmBufferSize);

    delete iAmrBuffer;
    iAmrBuffer = NULL;
    iAmrBuffer = CMMFDescriptorBuffer::NewL(KAmrBufferSize);

    iPlayError = KErrNone;
    SetengineState(EEngineReady);

    LoadFileL();

    iStream = CMdaAudioOutputStream::NewL(*this);
    iStream->Open(&iSettings);
    }
    /*
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::MaoscOpenComplete(TInt aError)
    {
    iPlayError = aError;

    if (aError==KErrNone && iStream)
    {
    iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
    iSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
    // iSettings.iVolume = ((iStream->MaxVolume() * iVolume) / 10);

    iStream->SetAudioPropertiesL(iSettings.iSampleRate,iSettings.iChannels);
    SetVolume(iVolume);
    iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceNone);

    SetengineState(EEnginePlaying);
    iStream->WriteL(*iBuffer[0]);//iPlayBuffer->Des());//
    }
    else
    {
    SetengineState(iStatus);// keep the state
    }
    }


    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
    {
    iPlayError = aError;

    if(aError == KErrNone && iStream)
    {
    if (&aBuffer == iBuffer[0])
    {
    iCurrIndex = 0;
    SetengineState(EEnginePlaying);
    if((*iBuffer[1]).Length())
    {
    iStream->WriteL(*iBuffer[1]);
    ReadFromFromL(0);
    }
    else
    {
    SetengineState(EEngineReady);
    }
    }
    else// if (&aBuffer == iBuffer[1])
    {
    iCurrIndex = 1;
    SetengineState(EEnginePlaying);
    if((*iBuffer[0]).Length())
    {
    iStream->WriteL(*iBuffer[0]);
    ReadFromFromL(1);
    }
    else
    {
    SetengineState(EEngineReady);
    }
    }
    }
    else
    {
    SetengineState(EEngineReady);
    }
    }

    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::MaoscPlayComplete(TInt aError)
    {
    iPlayError = aError;

    if (aError == KErrUnderflow)
    {
    if(iPlayBuffer->Des().Length() > iReadSize)
    {
    iCurrIndex = 0;
    for (TInt index = 0; index < iBuffer.Count(); index++)
    {
    ReadFromFromL(index);
    }

    iStream->WriteL(*iBuffer[0]);
    }
    else
    {
    SetengineState(EEngineReady);
    }
    }
    else if(aError == KErrCancel)
    {
    SetengineState(EEngineReady);
    }
    else
    {
    SetengineState(EEngineReady);
    }
    }
    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::PlayL(const TDesC8& aPlayBuffer)
    {
    iReadSize = 0;
    delete iPlayBuffer;
    iPlayBuffer = NULL;
    iPlayBuffer = HBufC8::NewL(aPlayBuffer.Length());
    iPlayBuffer->Des().Copy(aPlayBuffer);

    ReStartL();
    }
    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::Stop()
    {
    if(iStatus == EEnginePlaying)
    {
    if(iStream)
    iStream->Stop();

    }


    iPlayError = KErrNone;
    SetengineState(EEngineReady);
    }
    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::SetVolume(TInt aVol)
    {
    iVolume = aVol;

    if(iVolume < 0)
    iVolume = 0;
    else if(iVolume > 10)
    iVolume = 10;

    if(iStream)
    {
    iStream->SetVolume(((iStream->MaxVolume() * iVolume) / 10));
    }
    }

    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::ReadFromFromL(TInt aBufferIndex)
    {
    if(aBufferIndex ==0 || aBufferIndex == 1 && iPlayBuffer)
    {
    (*iBuffer[aBufferIndex]).FillZ();
    (*iBuffer[aBufferIndex]).Zero();

    if((iPlayBuffer->Des().Length() > iReadSize) && iTmpBuffer)
    {
    TInt ReadFor(KAmrBufferSize);
    if(iPlayBuffer->Des().Length() < (iReadSize + ReadFor))
    {
    ReadFor = iPlayBuffer->Des().Length() - iReadSize;
    }

    /* if(iReadSize < 6)
    {
    iReadSize = 6;
    }
    */
    iTmpBuffer->Des().Copy(iPlayBuffer->Des().Mid(iReadSize,ReadFor));
    iReadSize = iReadSize + ReadFor;

    ConvertAmr2PcmL(iTmpBuffer->Des(),(*iBuffer[aBufferIndex]));
    }
    }
    }
    /*
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    */
    void CStreamPlayEngine::LoadFileL()
    {
    iBuffer.ResetAndDestroy();

    TDes8* buffer = new(ELeave) TBuf8<KPcmBufferSize>;
    buffer->SetMax();
    CleanupStack::PushL(buffer);
    User::LeaveIfError(iBuffer.Append(buffer));
    CleanupStack::Pop(buffer);

    buffer = new(ELeave) TBuf8<KPcmBufferSize>;
    buffer->SetMax();
    CleanupStack::PushL(buffer);
    User::LeaveIfError(iBuffer.Append(buffer));
    CleanupStack::Pop(buffer);

    iReadSize = 0;
    iCurrIndex = 0;
    for (TInt index = 0; index < iBuffer.Count(); index++)
    {
    ReadFromFromL(index);
    }
    }

    /*
    -----------------------------------------------------------------------------
    -----------------------------------------------------------------------------
    */
    void CStreamPlayEngine::ConvertAmr2PcmL(const TDesC8& aAmrData,TDes8& aDestBuffer)
    {
    iAmrBuffer->Data().Copy(aAmrData);

    TBool OkMai(EFalse);
    TCodecProcessResult result = iOCodec->ProcessL(*iAmrBuffer,*iPcm16Buffer);

    if((result.iStatus == TCodecProcessResult::EProcessComplete))
    {
    OkMai = ETrue;
    aDestBuffer.Copy(iPcm16Buffer->Data());
    }
    else
    {
    // should we report error.
    }
    }

  5. #5
    Nokia Developer Moderator
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,167
    and here's the header:

    class CStreamPlayEngine : public CBase, public MMdaAudioOutputStreamCallback
    {
    public:
    static CStreamPlayEngine* NewL(MRectPlayCallBack* aCallBack);
    ~CStreamPlayEngine();
    void PlayL(const TDesC8& aPlayBuffer);
    void Stop();

    // from MMdaAudioOutputStreamCallback
    virtual void MaoscOpenComplete(TInt aError);
    virtual void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
    virtual void MaoscPlayComplete(TInt aError);
    // inline gets and sets
    inline TInt Volume();
    inline TBool StreamReady();
    void SetVolume(TInt aVol);
    protected:
    void SetengineState(TInt aNewState);
    void ConvertAmr2PcmL(const TDesC8& aAmrData,TDes8& aDestBuffer);
    void ReStartL();
    TInt GetSampltRate();
    CStreamPlayEngine(MRectPlayCallBack* aCallBack);
    void ConstructL();
    void LoadFileL();
    void ReadFromFromL(TInt aBufferIndex);
    private:
    MRectPlayCallBack* iCallBack;
    TInt iVolume; // volume
    TInt iReadSize,iCurrIndex,iPlayError; // size of the pcm sound file (and buffer)
    TInt iStatus; // engine status

    RPointerArray<TDes8> iBuffer;

    CMdaAudioOutputStream* iStream;
    TMdaAudioDataSettings iSettings;

    CEikonEnv* iEnv;
    CMMFCodec* iOCodec;
    CMMFDescriptorBuffer* iPcm16Buffer;
    CMMFDescriptorBuffer* iAmrBuffer;
    HBufC8* iTmpBuffer;
    HBufC8* iPlayBuffer;
    };

    // INLINES

    inline TInt CStreamPlayEngine::Volume() { return iVolume; }
    inline TBool CStreamPlayEngine::StreamReady() { return (iStatus == EEngineReady)?ETrue:EFalse; }

    yucca

  6. #6
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224

    I don't know how to thank you.

    Hello yucca,

    I really appreciate for your kindness. However I tried to put your code in my application. I have been facing some problem. I have got few questions:

    In this method, ConvertAmr2PcmL(const TDesC8& aAmrData,TDes8& aDestBuffer)

    I get : result.iStatus EDstNotFilled

    TCodecProcessResult result = iOCodec->ProcessL(*iAmrBuffer,*iPcm16Buffer);;

    So it's not playing amr file.

    If you want I can send you the whole application. I guess it would be easier for you to point out the problem.

    Hope to hearing from you.

    Regards,

    shagor

  7. #7
    Nokia Developer Moderator
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,167
    you are propably having the aMR mode wrong. There is quite nice post in NewLC about the different modes & stuff with AMR, so maybe you should search it for more information.

    Basically, make the AMR file in CMR 0 and mode AMR 4.75, and then you will have AMR frame size of 13 bytes, which is just right for this code. You could also try figuring out the frame size from the AMR header, and then reading right size frames from the file.

    yucca

  8. #8
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224

    Thanks for your prompt reply.

    #include <amrcodec.h>

    TAmrEncParams params;
    params.iMode = 0;
    iOCodec->ConfigureL(TUid::Uid(0x101FAF67),(const TDesC8&)params );
    TCodecProcessResult result = iOCodec->ProcessL(*iAmrBuffer,*iPcm16Buffer);

    I used the above technique for Configuring. I get error "Feature not supported(-5). It gets this error as soon as it calls ConfigureL(..).

    I don't know what to do.

    I put the whole application including one test.amr file in the following location:
    http://users.evtek.fi/~muhammki/AudioStreamExample.zip

    It would be so kind of you to take a look the application.

    I used: Symbian OS: 7.0s
    SDK 2.0

  9. #9
    Nokia Developer Moderator
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    29,167
    what does the ConfigureL function do ? I can see using it in the sample code, so do you really need to use it ?

    yucca

  10. #10
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    I guess, ConfigureL has something to do with amr mode stuff. You can leave that thing.

    Have you got the application working? Please inform me.

    Regards,
    shagor

  11. #11
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    The main thing of playing AMR using streaming is to cut the 6-Bytes header from the begining of AMR file.

    Regards,
    shagor

  12. #12
    Registered User
    Join Date
    May 2003
    Posts
    187

    Re: Plyaing AMR file using MMF framework.

    Hi ,

    If I want to play AMR from a Descriptor , should I remove the 6 byte as well?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×