e14743d1 |
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 | |