#include "streamplayer.h" #include const TInt KMaxVolume(256); LOCAL_C TInt GetSampleRate(TInt aRate) { switch(aRate) { case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz; case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz; case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz; case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz; case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz; case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz; case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz; case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz; case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz; case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz; case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz; } return KErrNotFound; } LOCAL_C TInt GetChannels(TInt aChannels) { switch(aChannels) { case 1: return TMdaAudioDataSettings::EChannelsMono; case 2: return TMdaAudioDataSettings::EChannelsStereo; } return KErrNotFound; } TInt CStreamPlayer::ClosestSupportedRate(TInt aRate) { if(aRate > 96000) return 96000; TInt rate = aRate; while(GetSampleRate(rate) == KErrNotFound) { ++rate; } return rate; } CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) : iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume) { } CStreamPlayer::~CStreamPlayer() { iState |= EDied; if(iState & EInited) Close(); User::After(100000); //wait buffer to be flushed ASSERT(iPtr.Length() == 0); delete iStream; } void CStreamPlayer::ConstructL() { iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax); iSilence.SetMax(); iSilence.FillZ(); } TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType) { Close(); iType = aType; iRate = GetSampleRate(aRate); if(iRate == KErrNotFound) return KErrNotSupported; iChannels = GetChannels(aChannels); if(iChannels == KErrNotFound) return KErrNotSupported; Open(); return KErrNone; } TInt CStreamPlayer::MaxVolume() const { return KMaxVolume; } void CStreamPlayer::SetVolume(TInt aNew) { const TInt maxi = MaxVolume(); if(aNew > maxi) return; if(aNew < 0) return; iVolume = aNew; iState |= EVolumeChange; } TInt CStreamPlayer::Volume() const { return iVolume; } void CStreamPlayer::Open() { TMdaAudioDataSettings audioSettings; audioSettings.Query(); audioSettings.iCaps = TMdaAudioDataSettings::ERealTime | TMdaAudioDataSettings::ESampleRateFixed; audioSettings.iSampleRate = iRate; audioSettings.iChannels = iChannels; audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting; audioSettings.iVolume = 0; iState &= ~EStopped; iStream->Open(&audioSettings); } void CStreamPlayer::Stop() { if(iState & (EStarted | EInited)) { Close(); iState |= EStopped; } } void CStreamPlayer::Start() { if(iPtr.Length() == 0) { iState |= EStarted; if(iState & EInited) { Request(); } else if(iState & EStopped) { Open(); } } } void CStreamPlayer::Close() { iState &= ~EInited; iStream->Stop(); iState &= ~EStarted; } void CStreamPlayer::Request() { if(iState & EInited) { iPtr.Set(KNullDesC8); if(iState & EVolumeChange) { const TReal newVol = iVolume; const TReal newMax = MaxVolume(); const TInt maxVol = iStream->MaxVolume(); const TReal max = static_cast(maxVol); const TReal newvolume = (newVol * max) / newMax; const TInt vol = static_cast(newvolume); iStream->SetVolume(vol); iState &= ~EVolumeChange; } if(iState & EStarted) { iPtr.Set(iProvider.Data()); } if(iPtr.Length() == 0) { iPtr.Set(iSilence); } TRAPD(err, iStream->WriteL(iPtr)); if(err != KErrNone) { iObs.Complete(MStreamObs::EWrite, err); } /* else { iProvider.Written(iPtr.Length()); }*/ } } void CStreamPlayer::SetCapsL() { iStream->SetDataTypeL(iType); iStream->SetAudioPropertiesL(iRate, iChannels); } void CStreamPlayer::MaoscOpenComplete(TInt aError) { if(aError == KErrNone) { TRAPD(err, SetCapsL()); if(err == KErrNone) { iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime); iState |= EInited; SetVolume(Volume()); if(iState & EStarted) { Request(); } } aError = err; } if(!(iState & EDied)) iObs.Complete(MStreamObs::EInit, aError); } void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/) { iPtr.Set(KNullDesC8); if(aError == KErrNone) { if(iState & EInited) Request(); else iStream->Stop(); } else if(!(iState & EDied)) iObs.Complete(MStreamObs::EPlay, aError); } void CStreamPlayer::MaoscPlayComplete(TInt aError) { iPtr.Set(KNullDesC8); iState &= ~EStarted; if(!(iState & EDied)) iObs.Complete(MStreamObs::EClose, aError); } TBool CStreamPlayer::Playing() const { return (iState & EInited) && (iState & EStarted); } TBool CStreamPlayer::Closed() const { return !(iState & EInited) && !(iState & EDied); } /* void CStreamPlayer::Request() { SetActive(); TRequestStatus* s = &iStatus; User::RequestComplete(s, KErrNone); } // iTimer.After(0); */