1 #include "streamplayer.h"
2 #include<mda/common/audio.h>
3
4
5
6 const TInt KMaxVolume(256);
7
GetSampleRate(TInt aRate)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
GetChannels(TInt aChannels)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
ClosestSupportedRate(TInt aRate)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
CStreamPlayer(MStreamProvider & aProvider,MStreamObs & aObs)49 CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) :
50 iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume)
51 {
52 }
53
~CStreamPlayer()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
ConstructL()65 void CStreamPlayer::ConstructL()
66 {
67 iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax);
68 iSilence.SetMax();
69 iSilence.FillZ();
70 }
71
72
OpenStream(TInt aRate,TInt aChannels,TUint32 aType)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
MaxVolume() const93 TInt CStreamPlayer::MaxVolume() const
94 {
95 return KMaxVolume;
96 }
97
SetVolume(TInt aNew)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
Volume() const112 TInt CStreamPlayer::Volume() const
113 {
114 return iVolume;
115 }
116
Open()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
Stop()132 void CStreamPlayer::Stop()
133 {
134 if(iState & (EStarted | EInited))
135 {
136 Close();
137 iState |= EStopped;
138 }
139 }
140
Start()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
Close()157 void CStreamPlayer::Close()
158 {
159 iState &= ~EInited;
160 iStream->Stop();
161 iState &= ~EStarted;
162 }
163
Request()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
SetCapsL()203 void CStreamPlayer::SetCapsL()
204 {
205 iStream->SetDataTypeL(iType);
206 iStream->SetAudioPropertiesL(iRate, iChannels);
207 }
208
MaoscOpenComplete(TInt aError)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
MaoscBufferCopied(TInt aError,const TDesC8 &)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
MaoscPlayComplete(TInt aError)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
Playing() const256 TBool CStreamPlayer::Playing() const
257 {
258 return (iState & EInited) && (iState & EStarted);
259 }
260
Closed() const261 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