Discussion Board

Results 1 to 12 of 12
  1. #1
    Regular Contributor khurshed79's Avatar
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    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 Expert symbianyucca's Avatar
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    28,712
    you should use streaming instead. CMdaAudioPlayerUtility will have proablems with AMR in quite many target devices.

    yucca

  3. #3
    Regular Contributor khurshed79's Avatar
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    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 Expert symbianyucca's Avatar
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    28,712
    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 Expert symbianyucca's Avatar
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    28,712
    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 khurshed79's Avatar
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    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 Expert symbianyucca's Avatar
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    28,712
    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 khurshed79's Avatar
    Join Date
    Mar 2003
    Location
    Finland
    Posts
    224
    #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 Expert symbianyucca's Avatar
    Join Date
    Mar 2003
    Location
    Lempäälä/Finland
    Posts
    28,712
    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 khurshed79's Avatar
    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 khurshed79's Avatar
    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 rami75lu's Avatar
    Join Date
    May 2003
    Posts
    187
    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
  •  
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved