aboutsummaryrefslogtreecommitdiffstats
path: root/distrib/sdl-1.2.15/src/audio/symbian
diff options
context:
space:
mode:
Diffstat (limited to 'distrib/sdl-1.2.15/src/audio/symbian')
-rw-r--r--distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.cpp614
-rw-r--r--distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.h37
-rw-r--r--distrib/sdl-1.2.15/src/audio/symbian/streamplayer.cpp279
-rw-r--r--distrib/sdl-1.2.15/src/audio/symbian/streamplayer.h89
4 files changed, 1019 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.cpp b/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.cpp
new file mode 100644
index 0000000..72a4eaf
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.cpp
@@ -0,0 +1,614 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@devolution.com
+*/
+
+/*
+ SDL_epocaudio.cpp
+ Epoc based SDL audio driver implementation
+
+ Markus Mertama
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_epocaudio.c,v 0.0.0.0 2001/06/19 17:19:56 hercules Exp $";
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include "epoc_sdl.h"
+
+#include <e32hal.h>
+
+
+extern "C" {
+#include "SDL_audio.h"
+#include "SDL_error.h"
+#include "SDL_audiomem.h"
+#include "SDL_audio_c.h"
+#include "SDL_timer.h"
+#include "SDL_audiodev_c.h"
+}
+
+#include "SDL_epocaudio.h"
+
+#include "streamplayer.h"
+
+
+//#define DEBUG_AUDIO
+
+
+/* Audio driver functions */
+
+static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec);
+static void EPOC_WaitAudio(SDL_AudioDevice *thisdevice);
+static void EPOC_PlayAudio(SDL_AudioDevice *thisdevice);
+static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice *thisdevice);
+static void EPOC_CloseAudio(SDL_AudioDevice *thisdevice);
+static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice);
+
+static int Audio_Available(void);
+static SDL_AudioDevice *Audio_CreateDevice(int devindex);
+static void Audio_DeleteDevice(SDL_AudioDevice *device);
+
+
+//void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len);
+
+#ifdef __WINS__
+#define DODUMP
+#endif
+
+#ifdef DODUMP
+NONSHARABLE_CLASS(TDump)
+ {
+ public:
+ TInt Open();
+ void Close();
+ void Dump(const TDesC8& aDes);
+ private:
+ RFile iFile;
+ RFs iFs;
+ };
+
+TInt TDump::Open()
+ {
+ TInt err = iFs.Connect();
+ if(err == KErrNone)
+ {
+#ifdef __WINS__
+_LIT(target, "C:\\sdlau.raw");
+#else
+_LIT(target, "E:\\sdlau.raw");
+#endif
+ err = iFile.Replace(iFs, target, EFileWrite);
+ }
+ return err;
+ }
+void TDump::Close()
+ {
+ iFile.Close();
+ iFs.Close();
+ }
+void TDump::Dump(const TDesC8& aDes)
+ {
+ iFile.Write(aDes);
+ }
+#endif
+
+
+NONSHARABLE_CLASS(CSimpleWait) : public CTimer
+ {
+ public:
+ void Wait(TTimeIntervalMicroSeconds32 aWait);
+ static CSimpleWait* NewL();
+ private:
+ CSimpleWait();
+ void RunL();
+ };
+
+
+CSimpleWait* CSimpleWait::NewL()
+ {
+ CSimpleWait* wait = new (ELeave) CSimpleWait();
+ CleanupStack::PushL(wait);
+ wait->ConstructL();
+ CleanupStack::Pop();
+ return wait;
+ }
+
+void CSimpleWait::Wait(TTimeIntervalMicroSeconds32 aWait)
+ {
+ After(aWait);
+ CActiveScheduler::Start();
+ }
+
+CSimpleWait::CSimpleWait() : CTimer(CActive::EPriorityStandard)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CSimpleWait::RunL()
+ {
+ CActiveScheduler::Stop();
+ }
+
+const TInt KAudioBuffers(2);
+
+
+NONSHARABLE_CLASS(CEpocAudio) : public CBase, public MStreamObs, public MStreamProvider
+ {
+ public:
+ static void* NewL(TInt BufferSize, TInt aFill);
+ inline static CEpocAudio& Current(SDL_AudioDevice* thisdevice);
+
+ static void Free(SDL_AudioDevice* thisdevice);
+
+ void Wait();
+ void Play();
+ // void SetBuffer(const TDesC8& aBuffer);
+ void ThreadInitL(TAny* aDevice);
+ void Open(TInt iRate, TInt iChannels, TUint32 aType, TInt aBytes);
+ ~CEpocAudio();
+ TUint8* Buffer();
+ TBool SetPause(TBool aPause);
+ #ifdef DODUMP
+ void Dump(const TDesC8& aBuf) {iDump.Dump(aBuf);}
+ #endif
+ private:
+ CEpocAudio(TInt aBufferSize);
+ void Complete(TInt aState, TInt aError);
+ TPtrC8 Data();
+ void ConstructL(TInt aFill);
+ private:
+ TInt iBufferSize;
+ CStreamPlayer* iPlayer;
+ TInt iBufferRate;
+ TInt iRate;
+ TInt iChannels;
+ TUint32 iType;
+ TInt iPosition;
+ TThreadId iTid;
+ TUint8* iAudioPtr;
+ TUint8* iBuffer;
+ // TTimeIntervalMicroSeconds iStart;
+ TTime iStart;
+ TInt iTune;
+ CSimpleWait* iWait;
+ #ifdef DODUMP
+ TDump iDump;
+ #endif
+ };
+
+inline CEpocAudio& CEpocAudio::Current(SDL_AudioDevice* thisdevice)
+ {
+ return *static_cast<CEpocAudio*>((void*)thisdevice->hidden);
+ }
+
+/*
+
+TBool EndSc(TAny*)
+ {
+ CActiveScheduler::Stop();
+ }
+
+LOCAL_C void CleanScL()
+ {
+ CIdle* d = CIdle::NewLC(CActive:::EPriorityIdle);
+ d->Start(TCallBack(EndSc));
+ CActiveScheduler::Start();
+
+ }
+*/
+
+void CEpocAudio::Free(SDL_AudioDevice* thisdevice)
+ {
+ CEpocAudio* ea = static_cast<CEpocAudio*>((void*)thisdevice->hidden);
+ if(ea)
+ {
+ ASSERT(ea->iTid == RThread().Id());
+ delete ea;
+ thisdevice->hidden = NULL;
+
+ CActiveScheduler* as = CActiveScheduler::Current();
+ ASSERT(as->StackDepth() == 0);
+ delete as;
+ CActiveScheduler::Install(NULL);
+ }
+ ASSERT(thisdevice->hidden == NULL);
+ }
+
+CEpocAudio::CEpocAudio(TInt aBufferSize) : iBufferSize(aBufferSize), iPosition(-1)
+ {
+ }
+
+void* CEpocAudio::NewL(TInt aBufferSize, TInt aFill)
+ {
+ CEpocAudio* eAudioLib = new (ELeave) CEpocAudio(aBufferSize);
+ CleanupStack::PushL(eAudioLib);
+ eAudioLib->ConstructL(aFill);
+ CleanupStack::Pop();
+ return eAudioLib;
+ }
+
+void CEpocAudio::ConstructL(TInt aFill)
+ {
+ iBuffer = (TUint8*) User::AllocL(KAudioBuffers * iBufferSize);
+ memset(iBuffer, aFill, KAudioBuffers * iBufferSize);
+ iAudioPtr = iBuffer;
+ }
+
+
+TBool CEpocAudio::SetPause(TBool aPause)
+ {
+ if(aPause && iPosition >= 0)
+ {
+ iPosition = -1;
+ if(iPlayer != NULL)
+ iPlayer->Stop();
+ }
+ if(!aPause && iPosition < 0)
+ {
+ iPosition = 0;
+ if(iPlayer != NULL)
+ iPlayer->Start();
+ }
+ return iPosition < 0;
+ }
+
+void CEpocAudio::ThreadInitL(TAny* aDevice)
+ {
+ iTid = RThread().Id();
+ CActiveScheduler* as = new (ELeave) CActiveScheduler();
+ CActiveScheduler::Install(as);
+
+ EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem((TSdlCleanupOperation)EPOC_CloseAudio, aDevice));
+
+ iWait = CSimpleWait::NewL();
+
+ iPlayer = new (ELeave) CStreamPlayer(*this, *this);
+ iPlayer->ConstructL();
+ iPlayer->OpenStream(iRate, iChannels, iType);
+
+ #ifdef DODUMP
+ User::LeaveIfError(iDump.Open());
+ #endif
+ }
+
+
+
+TUint8* CEpocAudio::Buffer()
+ {
+ iStart.UniversalTime();
+// iStart = iPlayer->Position();
+ return iAudioPtr;
+
+ }
+
+CEpocAudio::~CEpocAudio()
+ {
+ if(iWait != NULL)
+ iWait->Cancel();
+ delete iWait;
+ if(iPlayer != NULL)
+ iPlayer->Close();
+ delete iPlayer;
+ delete iBuffer;
+ }
+
+void CEpocAudio::Complete(TInt aState, TInt aError)
+ {
+ if(aState == MStreamObs::EClose)
+ {
+ }
+ if(iPlayer->Closed())
+ return;
+ switch(aError)
+ {
+ case KErrUnderflow:
+ case KErrInUse:
+ iPlayer->Start();
+ break;
+ case KErrAbort:
+ iPlayer->Open();
+ }
+ }
+
+
+void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len)
+ {
+#ifdef DODUMP
+ const TPtrC8 buf((TUint8*)data, len);
+ CEpocAudio::Current(thisdevice).Dump(buf);
+#endif
+ }
+
+const TInt KClip(256);
+
+TPtrC8 CEpocAudio::Data()
+ {
+ if(iPosition < 0)
+ return KNullDesC8();
+
+ TPtrC8 data(iAudioPtr + iPosition, KClip);
+
+#ifdef DODUMP
+ iDump.Dump(data);
+#endif
+
+ iPosition += KClip;
+ if(iPosition >= iBufferSize)
+ {
+
+/* if(iAudioPtr == iBuffer)
+ iAudioPtr = iBuffer + iBufferSize;
+ else
+ iAudioPtr = iBuffer;
+*/
+ iAudioPtr += iBufferSize;
+
+ if((iAudioPtr - iBuffer) >= KAudioBuffers * iBufferSize)
+ iAudioPtr = iBuffer;
+
+ iPosition = -1;
+ if(iWait->IsActive())
+ {
+ iWait->Cancel();
+ CActiveScheduler::Stop();
+ }
+ }
+ return data;
+ }
+
+
+
+
+void CEpocAudio::Play()
+ {
+ iPosition = 0;
+ }
+
+void CEpocAudio::Wait()
+ {
+ if(iPosition >= 0 /*&& iPlayer->Playing()*/)
+ {
+ const TInt64 bufMs = TInt64(iBufferSize - KClip) * TInt64(1000000);
+ const TInt64 specTime = bufMs / TInt64(iRate * iChannels * 2);
+ iWait->After(specTime);
+
+ CActiveScheduler::Start();
+ TTime end;
+ end.UniversalTime();
+ const TTimeIntervalMicroSeconds delta = end.MicroSecondsFrom(iStart);
+
+
+// const TTimeIntervalMicroSeconds end = iPlayer->Position();
+
+
+
+
+ const TInt diff = specTime - delta.Int64();
+
+ if(diff > 0 && diff < 200000)
+ {
+ User::After(diff);
+ }
+
+ }
+ else
+ {
+ User::After(10000);
+// iWait->Wait(10000); //just give some time...
+ }
+ }
+
+void CEpocAudio::Open(TInt aRate, TInt aChannels, TUint32 aType, TInt aBytes)
+ {
+ iRate = aRate;
+ iChannels = aChannels;
+ iType = aType;
+ iBufferRate = iRate * iChannels * aBytes; //1/x
+ }
+
+
+/* Audio driver bootstrap functions */
+
+AudioBootStrap EPOCAudio_bootstrap = {
+ "epoc\0\0\0",
+ "EPOC streaming audio\0\0\0",
+ Audio_Available,
+ Audio_CreateDevice
+};
+
+
+static SDL_AudioDevice *Audio_CreateDevice(int /*devindex*/)
+{
+ SDL_AudioDevice *thisdevice;
+
+ /* Initialize all variables that we clean on shutdown */
+ thisdevice = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
+ if ( thisdevice ) {
+ memset(thisdevice, 0, (sizeof *thisdevice));
+ thisdevice->hidden = NULL; /*(struct SDL_PrivateAudioData *)
+ malloc((sizeof thisdevice->hidden)); */
+ }
+ if ( (thisdevice == NULL) /*|| (thisdevice->hidden == NULL) */) {
+ SDL_OutOfMemory();
+ if ( thisdevice ) {
+ free(thisdevice);
+ }
+ return(0);
+ }
+// memset(thisdevice->hidden, 0, (sizeof *thisdevice->hidden));
+
+ /* Set the function pointers */
+ thisdevice->OpenAudio = EPOC_OpenAudio;
+ thisdevice->WaitAudio = EPOC_WaitAudio;
+ thisdevice->PlayAudio = EPOC_PlayAudio;
+ thisdevice->GetAudioBuf = EPOC_GetAudioBuf;
+ thisdevice->CloseAudio = EPOC_CloseAudio;
+ thisdevice->ThreadInit = EPOC_ThreadInit;
+ thisdevice->free = Audio_DeleteDevice;
+
+ return thisdevice;
+}
+
+
+static void Audio_DeleteDevice(SDL_AudioDevice *device)
+ {
+ //free(device->hidden);
+ free(device);
+ }
+
+static int Audio_Available(void)
+{
+ return(1); // Audio stream modules should be always there!
+}
+
+
+static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec)
+{
+ SDL_TRACE("SDL:EPOC_OpenAudio");
+
+
+ TUint32 type = KMMFFourCCCodePCM16;
+ TInt bytes = 2;
+
+ switch(spec->format)
+ {
+ case AUDIO_U16LSB:
+ type = KMMFFourCCCodePCMU16;
+ break;
+ case AUDIO_S16LSB:
+ type = KMMFFourCCCodePCM16;
+ break;
+ case AUDIO_U16MSB:
+ type = KMMFFourCCCodePCMU16B;
+ break;
+ case AUDIO_S16MSB:
+ type = KMMFFourCCCodePCM16B;
+ break;
+ //8 bit not supported!
+ case AUDIO_U8:
+ case AUDIO_S8:
+ default:
+ spec->format = AUDIO_S16LSB;
+ };
+
+
+
+ if(spec->channels > 2)
+ spec->channels = 2;
+
+ spec->freq = CStreamPlayer::ClosestSupportedRate(spec->freq);
+
+
+ /* Allocate mixing buffer */
+ const TInt buflen = spec->size;// * bytes * spec->channels;
+// audiobuf = NULL;
+
+ TRAPD(err, thisdevice->hidden = static_cast<SDL_PrivateAudioData*>(CEpocAudio::NewL(buflen, spec->silence)));
+ if(err != KErrNone)
+ return -1;
+
+ CEpocAudio::Current(thisdevice).Open(spec->freq, spec->channels, type, bytes);
+
+ CEpocAudio::Current(thisdevice).SetPause(ETrue);
+
+ // isSDLAudioPaused = 1;
+
+ thisdevice->enabled = 0; /* enable only after audio engine has been initialized!*/
+
+ /* We're ready to rock and roll. :-) */
+ return(0);
+}
+
+
+static void EPOC_CloseAudio(SDL_AudioDevice* thisdevice)
+ {
+#ifdef DEBUG_AUDIO
+ SDL_TRACE("Close audio\n");
+#endif
+
+ CEpocAudio::Free(thisdevice);
+ }
+
+
+static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice)
+ {
+ SDL_TRACE("SDL:EPOC_ThreadInit");
+ CEpocAudio::Current(thisdevice).ThreadInitL(thisdevice);
+ RThread().SetPriority(EPriorityMore);
+ thisdevice->enabled = 1;
+ }
+
+/* This function waits until it is possible to write a full sound buffer */
+static void EPOC_WaitAudio(SDL_AudioDevice* thisdevice)
+{
+#ifdef DEBUG_AUDIO
+ SDL_TRACE1("wait %d audio\n", CEpocAudio::AudioLib().StreamPlayer(KSfxChannel).SyncTime());
+ TInt tics = User::TickCount();
+#endif
+
+ CEpocAudio::Current(thisdevice).Wait();
+
+#ifdef DEBUG_AUDIO
+ TInt ntics = User::TickCount() - tics;
+ SDL_TRACE1("audio waited %d\n", ntics);
+ SDL_TRACE1("audio at %d\n", tics);
+#endif
+}
+
+
+
+static void EPOC_PlayAudio(SDL_AudioDevice* thisdevice)
+ {
+ if(CEpocAudio::Current(thisdevice).SetPause(SDL_GetAudioStatus() == SDL_AUDIO_PAUSED))
+ SDL_Delay(500); //hold on the busy loop
+ else
+ CEpocAudio::Current(thisdevice).Play();
+
+#ifdef DEBUG_AUDIO
+ SDL_TRACE("buffer has audio data\n");
+#endif
+
+
+#ifdef DEBUG_AUDIO
+ SDL_TRACE1("Wrote %d bytes of audio data\n", buflen);
+#endif
+}
+
+static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice* thisdevice)
+ {
+ return CEpocAudio::Current(thisdevice).Buffer();
+ }
+
+
+
diff --git a/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.h b/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.h
new file mode 100644
index 0000000..5c95c86
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/audio/symbian/SDL_epocaudio.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@devolution.com
+*/
+
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_epocaudio.h,v 1.1.2.2 2001/02/10 07:20:03 hercules Exp $";
+#endif
+
+#ifndef _SDL_EPOCAUDIO_H
+#define _SDL_EPOCAUDIO_H
+
+extern "C" {
+#include "SDL_sysaudio.h"
+}
+
+
+#endif /* _SDL_EPOCAUDIO_H */
diff --git a/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.cpp b/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.cpp
new file mode 100644
index 0000000..dd733a1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.cpp
@@ -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);
+ */
+
+
+
+
+
diff --git a/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.h b/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.h
new file mode 100644
index 0000000..8c6e74f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/audio/symbian/streamplayer.h
@@ -0,0 +1,89 @@
+#ifndef STREAMPLAYER_H
+#define STREAMPLAYER_H
+
+#include<MdaAudioOutputStream.h>
+
+const TInt KSilenceBuffer = 256;
+
+class MStreamObs
+ {
+ public:
+ enum
+ {
+ EInit,
+ EPlay,
+ EWrite,
+ EClose,
+ };
+ virtual void Complete(TInt aState, TInt aError) = 0;
+ };
+
+class MStreamProvider
+ {
+ public:
+ virtual TPtrC8 Data() = 0;
+ };
+
+NONSHARABLE_CLASS(CStreamPlayer) : public CBase, public MMdaAudioOutputStreamCallback
+ {
+ public:
+ CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs);
+ ~CStreamPlayer();
+ void ConstructL();
+
+ static TInt ClosestSupportedRate(TInt aRate);
+
+ TInt OpenStream(TInt aRate, TInt aChannels, TUint32 aType = KMMFFourCCCodePCM16);
+
+ void SetVolume(TInt aNew);
+ TInt Volume() const;
+ TInt MaxVolume() const;
+
+ void Stop();
+ void Start();
+ void Open();
+ void Close();
+
+ TBool Playing() const;
+ TBool Closed() const;
+
+ private:
+
+ void MaoscOpenComplete(TInt aError) ;
+ void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
+ void MaoscPlayComplete(TInt aError);
+
+ private:
+ void Request();
+ void SetCapsL();
+
+ private:
+ MStreamProvider& iProvider;
+ MStreamObs& iObs;
+ TInt iVolume;
+
+ CMdaAudioOutputStream* iStream;
+
+ TInt iRate;
+ TInt iChannels;
+ TUint32 iType;
+
+ enum
+ {
+ ENone = 0,
+ EInited = 0x1,
+ EStarted = 0x2,
+ EStopped = 0x4,
+ EVolumeChange = 0x8,
+ EDied = 0x10
+ };
+
+ TInt iState;
+ TBuf8<KSilenceBuffer> iSilence;
+ TPtrC8 iPtr;
+
+ };
+
+
+#endif
+