📄 oggtremor_motorola.cpp
字号:
{
TTimeIntervalMicroSeconds currentPos;
iStream->Position( currentPos );
TInt idx;
idx = iLastFreqArrayIdx;
for (TInt i=0; i<KFreqArrayLength; i++)
{
if (iFreqArray[idx].iTime < currentPos)
{
break;
}
idx--;
if (idx < 0)
{
idx = KFreqArrayLength-1;
}
}
return iFreqArray[idx].iFreqCoefs;
}
#endif
// GetDataChunk
////////////////////////////////////////////////////////////////
#ifndef MDCT_FREQ_ANALYSER
const void* COggPlayback::GetDataChunk()
{
void *p = NULL;
p = (void*) iBuffer[iSentIdx]->Ptr();
return ( p );
}
#endif
// OnEvent
////////////////////////////////////////////////////////////////
void COggPlayback::OnEvent( TMAudioFBCallbackState aState, TInt aError )
{
#ifdef _DEBUG
RDebug::Print( _L("OnEvent:%d:%d"), aState, aError );
#endif
switch ( aState )
{
case EMAudioFBCallbackStateReady:
iState = EStopped;
iMaxVolume = iStream->GetMaxVolume();
if ( iPlayWhenOpened )
{
iPlayWhenOpened = EFalse;
iStream->SetPCMChannel( iApiStereo );
iStream->SetPCMSampleRate( (TMSampleRate) iApiRate );
Play();
}
break;
case EMAudioFBCallbackStateDecodeCompleteBufferListEmpty:
// Occurs mostly when all data has been played
// Check if all data has been played
if ( iEof )
{
TInt j;
for ( j = 0; j < KMotoBuffers; j++ )
{
if ( iBufferFlag[ j ] == EBufferInUse ) break;
}
if ( j >= KMotoBuffers )
{
// All data has been played, so stop
iStream->Stop();
iState = EStopped;
if (iFile)
{
iDecoder->Close();
iFile->Close();
delete iFile;
iFile = NULL;
delete iDecoder;
iDecoder = NULL;
}
ClearComments();
iTime = 0;
}
}
break;
case EMAudioFBCallbackStateDecodeCompleteStopped:
iDecoding = EFalse;
// Occurs after stop has been called
if ( iEof ) // Make sure this is a completed case not a user stop
{
if ( iObserverAO ) iObserverAO->NotifyPlayComplete();
iEof = EFalse;
}
break;
case EMAudioFBCallbackStateDecodeError:
switch( aError )
{
case EMAudioFBCallbackErrorPriorityRejection:
case EMAudioFBCallbackErrorResourceRejection:
case EMAudioFBCallbackErrorAlertModeRejection:
case EMAudioFBCallbackErrorBufferFull:
case EMAudioFBCallbackErrorForcedStop:
case EMAudioFBCallbackErrorForcedClose:
case EMAudioFBCallbackErrorUnknown:
// Setup the API to be deleted outside of the callback
iDelete = iStream;
iStream = NULL;
iState = EStopped;
if ( iObserverAO ) iObserverAO->NotifyPlayInterrupted();
break;
default:
break;
}
break;
default:
break;
}
}
// OnEvent
////////////////////////////////////////////////////////////////
void COggPlayback::OnEvent
( TMAudioFBCallbackState aState
, TInt aError
, TDes8* aBuffer
)
{
#ifdef _DEBUG
RDebug::Print( _L("OnEvent2:%d:%d"), aState, aError );
#endif
switch( aState )
{
case EMAudioFBCallbackStateDecodeBufferDecoded:
{
for (TInt i = 0; i < KMotoBuffers; i++)
{
if ( aBuffer == iBuffer[i] )
{
iBufferFlag[i] = EBufferFree;
if ( !iEof && (iState == EPlaying && !iPlayWhenOpened) )
{
TRAPD( err, SendBufferL( i ) );
}
break;
}
}
}
break;
default:
OnEvent( aState, aError );
break;
}
}
// GetNewSamples
////////////////////////////////////////////////////////////////
TInt COggPlayback::GetNewSamples( TDes8 &aBuffer, TBool aRequestFrequencyBins )
{
TInt cnt = 0;
if (!iEof)
{
TInt len = aBuffer.Length();
#ifdef MDCT_FREQ_ANALYSER
if (iTimeWithoutFreqCalculation > iTimeWithoutFreqCalculationLim )
{
iTimeWithoutFreqCalculation = 0;
iLastFreqArrayIdx++;
if (iLastFreqArrayIdx >= KFreqArrayLength)
{
iLastFreqArrayIdx = 0;
}
iDecoder->GetFrequencyBins(iFreqArray[iLastFreqArrayIdx].iFreqCoefs, KNumberOfFreqBins);
iFreqArray[iLastFreqArrayIdx].iTime = TInt64(iLatestPlayTime) ;
}
else
{
iDecoder->GetFrequencyBins(NULL,0);
}
#endif
cnt = iDecoder->Read( aBuffer, len );
if ( cnt > 0 )
{
aBuffer.SetLength( len + cnt );
#ifdef MDCT_FREQ_ANALYSER
iLatestPlayTime += ( cnt * iTimeBetweenTwoSamples );
iTimeWithoutFreqCalculation += cnt;
#endif
}
else
{
iEof = ETrue;
}
}
return ( cnt );
}
// Private methods
////////////////////////////////////////////////////////////////
// CreateStreamApi
////////////////////////////////////////////////////////////////
void COggPlayback::CreateStreamApi( void )
{
#ifdef _DEBUG
RDebug::Print( _L("COggPlayback::CreateStreamApi:%d"), iState );
#endif
if ( iDelete )
{
delete iDelete;
iDelete = NULL;
}
if ( !iStream )
{
TMAudioFBBufSettings settings;
settings.iPCMSettings.iSamplingFreq = EMAudioFBSampleRate8K;
settings.iPCMSettings.iStereo = EFalse;
iStream = CMAudioFB::NewL( EMAudioFBRequestTypeDecode
, EMAudioFBFormatPCM
, settings
, *this
, EMAudioPriorityPlaybackGeneric
);
}
}
// ResetStreamApi
////////////////////////////////////////////////////////////////
void COggPlayback::ResetStreamApi( void )
{
#ifdef _DEBUG
RDebug::Print( _L("ResetStreamApi:%d"), iState );
#endif
if ( iStream )
{
delete iStream;
iStream = NULL;
}
if ( iDelete )
{
delete iDelete;
iDelete = NULL;
}
iDecoding = EFalse;
iState = EStopped;
for (TInt i = 0; i < KMotoBuffers; i++)
{
iBufferFlag[i] = EBufferFree;
}
}
// SendBufferL
////////////////////////////////////////////////////////////////
void COggPlayback::SendBufferL( TInt aIndex )
{
#ifdef _DEBUG
RDebug::Print( _L("SendBufferL:%d"), aIndex );
#endif
if ( !iEof && (iState == EPlaying) && (!iPlayWhenOpened) && (iBufferFlag[aIndex] == EBufferFree) )
{
iBuffer[ aIndex ]->SetLength( 0 );
TInt cnt = iOggSampleRateConverter->FillBuffer( *iBuffer[ aIndex ] );
if (cnt > 0)
{
TRAPD( err, iStream->QueueBufferL( iBuffer[ aIndex ] ) );
if (err != KErrNone)
{
// This should never ever happen.
TBuf<256> cbuf, tbuf;
CEikonEnv::Static()->ReadResource( cbuf, R_OGG_ERROR_16 );
CEikonEnv::Static()->ReadResource( tbuf, R_OGG_ERROR_17 );
cbuf.AppendNum(err);
iEnv->OggErrorMsgL(tbuf,cbuf);
User::Leave(err);
}
iBufferFlag[ aIndex ] = EBufferInUse;
}
}
}
// SetAudioCaps
////////////////////////////////////////////////////////////////
TInt COggPlayback::SetAudioCaps(TInt aChannels, TInt aRate)
{
iApiStereo = ( aChannels > 1 ) ? ETrue : EFalse;
iStream->SetPCMChannel( iApiStereo );
iApiRate = 16000; // The default
switch( aRate )
{
case 8000:
case 11025:
case 12000:
case 16000:
case 22050:
case 24000:
case 32000:
case 44100:
case 48000:
iApiRate = aRate;
break;
default:
break;
};
iStream->SetPCMSampleRate( (TMSampleRate) iApiRate );
iOggSampleRateConverter->Init( this
, KMotoBuffers
, (TInt) (0.75 * KMotoBuffers)
, aRate
, iApiRate
, aChannels
, ( iApiStereo ) ? 2 : 1
);
return ( KErrNone );
}
// GetDecoderL
////////////////////////////////////////////////////////////////
MDecoder* COggPlayback::GetDecoderL(const TDesC& aFileName)
{
MDecoder* decoder = NULL;
TParsePtrC p( aFileName);
if( p.Ext().Compare( _L(".ogg"))==0 || p.Ext().Compare( _L(".OGG"))==0 )
{
decoder=new(ELeave) CTremorDecoder(iFs);
}
#if defined(MP3_SUPPORT)
else if( p.Ext().Compare( _L(".mp3"))==0 || p.Ext().Compare( _L(".MP3"))==0 )
{
decoder=new(ELeave)CMadDecoder;
}
#endif
else
{
_LIT(KPanic,"Panic:");
_LIT(KNotSupported,"File type not supported");
iEnv->OggErrorMsgL(KPanic,KNotSupported);
}
return decoder;
}
////////////////////////////////////////////////////////////////
//
// CObserverCallback
//
////////////////////////////////////////////////////////////////
COggPlayback::CObserverCallback::CObserverCallback( COggPlayback *aParent )
: CActive( EPriorityHigh ), iParent( aParent )
{
CActiveScheduler::Add(this);
for ( TInt i = 0; i < KMaxIndex; i++ ) iCBType[i] = ECBNone;
}
// NotifyPlayComplete
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::NotifyPlayComplete( void )
{
DoIt( ECBComplete );
}
// NotifyUpdate
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::NotifyUpdate( void )
{
DoIt( ECBUpdate );
}
// NotifyPlayInterrupted
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::NotifyPlayInterrupted( void )
{
DoIt( ECBInterrupted );
}
// DoIt - kick off the AO
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::DoIt( TInt aCBType )
{
for ( TInt i = 0; i < KMaxIndex; i++ )
{
if ( iCBType[i] == ECBNone )
{
iCBType[i] = aCBType;
if ( !IsActive() )
{
iStatus = KErrNone;
SetActive();
TRequestStatus *status = &iStatus;
User::RequestComplete( status, KErrNone );
}
break;
}
}
}
// RunL
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::RunL( void )
{
if ( iParent && iParent->iObserver )
{
TInt i = 0;
for ( ; i < KMaxIndex; i++ )
{
switch ( iCBType[i] )
{
case ECBComplete:
iParent->iObserver->NotifyPlayComplete();
break;
case ECBUpdate:
iParent->iObserver->NotifyUpdate();
break;
case ECBInterrupted:
iParent->iObserver->NotifyPlayInterrupted();
break;
default:
break;
}
iCBType[i] = ECBNone;
}
}
}
// DoCancel
////////////////////////////////////////////////////////////////
void COggPlayback::CObserverCallback::DoCancel( void )
{
}
#endif /* !PLUGIN_SYSTEM && MOTOROLA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -