Mercurial > sdl-ios-xcode
diff src/audio/symbian/streamplayer.cpp @ 3975:e85e65aec22f SDL-1.2
Added S60 port.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 24 Jun 2007 18:26:35 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/symbian/streamplayer.cpp Sun Jun 24 18:26:35 2007 +0000 @@ -0,0 +1,279 @@ +#include "streamplayer.h" +#include<mda/common/audio.h> + + + +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<TReal>(maxVol); + const TReal newvolume = (newVol * max) / newMax; + const TInt vol = static_cast<TReal>(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); + */ + + + + +