1#include "streamplayer.h"
2#include<mda/common/audio.h>
3
4
5
6const TInt KMaxVolume(256);
7
8LOCAL_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
27LOCAL_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
37TInt 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
49CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider,  MStreamObs& aObs) :
50 iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume)
51	{
52	}
53
54CStreamPlayer::~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
65void CStreamPlayer::ConstructL()
66	{
67	iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax);
68	iSilence.SetMax();
69	iSilence.FillZ();
70	}
71
72
73TInt 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
93TInt CStreamPlayer::MaxVolume() const
94	{
95	return KMaxVolume;
96	}
97
98void 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
117void 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
132void CStreamPlayer::Stop()
133	{
134	if(iState & (EStarted | EInited))
135		{
136		Close();
137		iState |= EStopped;
138		}
139	}
140
141void 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
157void CStreamPlayer::Close()
158	{
159	iState &= ~EInited;
160	iStream->Stop();
161	iState &= ~EStarted;
162	}
163
164void 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
203void CStreamPlayer::SetCapsL()
204	{
205	iStream->SetDataTypeL(iType);
206	iStream->SetAudioPropertiesL(iRate, iChannels);
207	}
208
209void 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
234void 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
248void CStreamPlayer::MaoscPlayComplete(TInt aError)
249	{
250	iPtr.Set(KNullDesC8);
251	iState &= ~EStarted;
252	if(!(iState & EDied))
253		iObs.Complete(MStreamObs::EClose, aError);
254	}
255
256TBool CStreamPlayer::Playing() const
257	{
258	return (iState & EInited) && (iState & EStarted);
259	}
260
261TBool CStreamPlayer::Closed() const
262	{
263	return !(iState & EInited) && !(iState & EDied);
264	}
265
266	/*
267void 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