1 #include "streamplayer.h" 2 #include<mda/common/audio.h> 3 4 5 6 const TInt KMaxVolume(256); 7 8 LOCAL_C TInt GetSampleRate(TInt aRate) 9 { 10 switch(aRate) 11 { 12 case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz; 13 case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz; 14 case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz; 15 case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz; 16 case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz; 17 case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz; 18 case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz; 19 case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz; 20 case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz; 21 case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz; 22 case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz; 23 } 24 return KErrNotFound; 25 } 26 27 LOCAL_C TInt GetChannels(TInt aChannels) 28 { 29 switch(aChannels) 30 { 31 case 1: return TMdaAudioDataSettings::EChannelsMono; 32 case 2: return TMdaAudioDataSettings::EChannelsStereo; 33 } 34 return KErrNotFound; 35 } 36 37 TInt CStreamPlayer::ClosestSupportedRate(TInt aRate) 38 { 39 if(aRate > 96000) 40 return 96000; 41 TInt rate = aRate; 42 while(GetSampleRate(rate) == KErrNotFound) 43 { 44 ++rate; 45 } 46 return rate; 47 } 48 49 CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) : 50 iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume) 51 { 52 } 53 54 CStreamPlayer::~CStreamPlayer() 55 { 56 iState |= EDied; 57 if(iState & EInited) 58 Close(); 59 User::After(100000); //wait buffer to be flushed 60 ASSERT(iPtr.Length() == 0); 61 delete iStream; 62 } 63 64 65 void CStreamPlayer::ConstructL() 66 { 67 iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax); 68 iSilence.SetMax(); 69 iSilence.FillZ(); 70 } 71 72 73 TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType) 74 { 75 Close(); 76 77 iType = aType; 78 79 iRate = GetSampleRate(aRate); 80 if(iRate == KErrNotFound) 81 return KErrNotSupported; 82 83 iChannels = GetChannels(aChannels); 84 if(iChannels == KErrNotFound) 85 return KErrNotSupported; 86 87 Open(); 88 89 return KErrNone; 90 } 91 92 93 TInt CStreamPlayer::MaxVolume() const 94 { 95 return KMaxVolume; 96 } 97 98 void CStreamPlayer::SetVolume(TInt aNew) 99 { 100 101 const TInt maxi = MaxVolume(); 102 if(aNew > maxi) 103 return; 104 if(aNew < 0) 105 return; 106 107 iVolume = aNew; 108 109 iState |= EVolumeChange; 110 } 111 112 TInt CStreamPlayer::Volume() const 113 { 114 return iVolume; 115 } 116 117 void CStreamPlayer::Open() 118 { 119 TMdaAudioDataSettings audioSettings; 120 audioSettings.Query(); 121 audioSettings.iCaps = TMdaAudioDataSettings::ERealTime | 122 TMdaAudioDataSettings::ESampleRateFixed; 123 audioSettings.iSampleRate = iRate; 124 audioSettings.iChannels = iChannels; 125 audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting; 126 audioSettings.iVolume = 0; 127 128 iState &= ~EStopped; 129 iStream->Open(&audioSettings); 130 } 131 132 void CStreamPlayer::Stop() 133 { 134 if(iState & (EStarted | EInited)) 135 { 136 Close(); 137 iState |= EStopped; 138 } 139 } 140 141 void CStreamPlayer::Start() 142 { 143 if(iPtr.Length() == 0) 144 { 145 iState |= EStarted; 146 if(iState & EInited) 147 { 148 Request(); 149 } 150 else if(iState & EStopped) 151 { 152 Open(); 153 } 154 } 155 } 156 157 void CStreamPlayer::Close() 158 { 159 iState &= ~EInited; 160 iStream->Stop(); 161 iState &= ~EStarted; 162 } 163 164 void CStreamPlayer::Request() 165 { 166 if(iState & EInited) 167 { 168 iPtr.Set(KNullDesC8); 169 170 if(iState & EVolumeChange) 171 { 172 const TReal newVol = iVolume; 173 const TReal newMax = MaxVolume(); 174 const TInt maxVol = iStream->MaxVolume(); 175 const TReal max = static_cast<TReal>(maxVol); 176 const TReal newvolume = (newVol * max) / newMax; 177 const TInt vol = static_cast<TReal>(newvolume); 178 iStream->SetVolume(vol); 179 iState &= ~EVolumeChange; 180 } 181 182 if(iState & EStarted) 183 { 184 iPtr.Set(iProvider.Data()); 185 } 186 if(iPtr.Length() == 0) 187 { 188 iPtr.Set(iSilence); 189 } 190 TRAPD(err, iStream->WriteL(iPtr)); 191 if(err != KErrNone) 192 { 193 iObs.Complete(MStreamObs::EWrite, err); 194 } 195 /* else 196 { 197 iProvider.Written(iPtr.Length()); 198 }*/ 199 } 200 } 201 202 203 void CStreamPlayer::SetCapsL() 204 { 205 iStream->SetDataTypeL(iType); 206 iStream->SetAudioPropertiesL(iRate, iChannels); 207 } 208 209 void CStreamPlayer::MaoscOpenComplete(TInt aError) 210 { 211 if(aError == KErrNone) 212 { 213 TRAPD(err, SetCapsL()); 214 if(err == KErrNone) 215 { 216 iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime); 217 iState |= EInited; 218 219 220 SetVolume(Volume()); 221 222 if(iState & EStarted) 223 { 224 Request(); 225 } 226 227 } 228 aError = err; 229 } 230 if(!(iState & EDied)) 231 iObs.Complete(MStreamObs::EInit, aError); 232 } 233 234 void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/) 235 { 236 iPtr.Set(KNullDesC8); 237 if(aError == KErrNone) 238 { 239 if(iState & EInited) 240 Request(); 241 else 242 iStream->Stop(); 243 } 244 else if(!(iState & EDied)) 245 iObs.Complete(MStreamObs::EPlay, aError); 246 } 247 248 void CStreamPlayer::MaoscPlayComplete(TInt aError) 249 { 250 iPtr.Set(KNullDesC8); 251 iState &= ~EStarted; 252 if(!(iState & EDied)) 253 iObs.Complete(MStreamObs::EClose, aError); 254 } 255 256 TBool CStreamPlayer::Playing() const 257 { 258 return (iState & EInited) && (iState & EStarted); 259 } 260 261 TBool CStreamPlayer::Closed() const 262 { 263 return !(iState & EInited) && !(iState & EDied); 264 } 265 266 /* 267 void CStreamPlayer::Request() 268 { 269 SetActive(); 270 TRequestStatus* s = &iStatus; 271 User::RequestComplete(s, KErrNone); 272 } 273 // iTimer.After(0); 274 */ 275 276 277 278 279 280