#include "audio_mediaserver.h"\r
#include "debug.h"\r
\r
+//#define DEBUG_UNDERFLOWS\r
//#undef DEBUGPRINT\r
//#define DEBUGPRINT(x...)\r
\r
*\r
*******************************************/\r
\r
-CGameAudioMS::CGameAudioMS(TInt aRate, TBool aStereo, TInt aWritesPerSec)\r
-: iRate(aRate), iStereo(aStereo), iWritesPerSec(aWritesPerSec)\r
+CGameAudioMS::CGameAudioMS(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume)\r
+: iRate(aRate), iStereo(aStereo), iWritesPerSec(aWritesPerSec), iVolume(aVolume)\r
{\r
}\r
\r
\r
-CGameAudioMS* CGameAudioMS::NewL(TInt aRate, TBool aStereo, TInt aWritesPerSec)\r
+CGameAudioMS* CGameAudioMS::NewL(TInt aRate, TBool aStereo, TInt aWritesPerSec, TInt aVolume)\r
{\r
- DEBUGPRINT(_L("CGameAudioMS::NewL(%i, %i, %i)"), aRate, aStereo, aWritesPerSec);\r
- CGameAudioMS* self = new(ELeave) CGameAudioMS(aRate, aStereo, aWritesPerSec);\r
+ DEBUGPRINT(_L("CGameAudioMS::NewL(%i, %i, %i, %i)"), aRate, aStereo, aWritesPerSec, aVolume);\r
+ CGameAudioMS* self = new(ELeave) CGameAudioMS(aRate, aStereo, aWritesPerSec, aVolume);\r
CleanupStack::PushL(self);\r
self->ConstructL();\r
CleanupStack::Pop(); // self\r
iMdaAudioDataSettings.iCaps = TMdaAudioDataSettings::ESampleRateFixed | iMdaAudioDataSettings.iSampleRate;\r
iMdaAudioDataSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;\r
\r
- int pcmFrames = iRate / iWritesPerSec;\r
- pcmFrames += iRate - (iRate / iWritesPerSec) * iWritesPerSec; // add division remainder too for our buffer size\r
- iBufferedFrames = iWritesPerSec / KUpdatesPerSec;\r
+ iMaxWriteSamples = iRate / iWritesPerSec;\r
+ if (iRate % iWritesPerSec)\r
+ iMaxWriteSamples++;\r
+ int bufferedFrames = iWritesPerSec / KUpdatesPerSec;\r
\r
- TInt bytesPerFrame = pcmFrames << (iStereo?2:1);\r
+ iBufferSize = iMaxWriteSamples * (iStereo ? 4 : 2);\r
+ iBufferSize *= bufferedFrames;\r
for (TInt i=0 ; i<KSoundBuffers ; i++)\r
{\r
- iSoundBuffers[i] = HBufC8::NewL(bytesPerFrame * iBufferedFrames);\r
- iSoundBuffers[i]->Des().FillZ (bytesPerFrame * iBufferedFrames);\r
+ iSoundBuffers[i] = HBufC8::NewL(iBufferSize);\r
+ iSoundBuffers[i]->Des().FillZ (iBufferSize);\r
}\r
\r
iCurrentBuffer = 0;\r
iCurrentBufferSize = 0;\r
\r
+ DEBUGPRINT(_L("sound: iMaxWriteSamples: %i, iBufferSize: %i"), iMaxWriteSamples, iBufferSize);\r
+\r
// here we actually test if we can create and open CMdaAudioOutputStream at all, but really create and use it later.\r
iMdaAudioOutputStream = CMdaAudioOutputStream::NewL(iListener, iServer);\r
- if(iMdaAudioOutputStream) {\r
- iVolume = iMdaAudioOutputStream->MaxVolume();\r
- DEBUGPRINT(_L("MaxVolume: %i"), iVolume);\r
+ if (iMdaAudioOutputStream) {\r
+ if (iVolume < 0 || iVolume > iMdaAudioOutputStream->MaxVolume())\r
+ iVolume = iMdaAudioOutputStream->MaxVolume();\r
delete iMdaAudioOutputStream;\r
iMdaAudioOutputStream = 0;\r
}\r
// to be used when iSoundBuffers are used directly\r
TInt16 *CGameAudioMS::NextFrameL(TInt aPcmFrames)\r
{\r
- iCurrentPosition += aPcmFrames << (iStereo?1:0);\r
- iCurrentBufferSize += aPcmFrames << (iStereo?2:1);\r
+ TInt mul = iStereo ? 4 : 2;\r
+ TInt bytes = aPcmFrames * mul;\r
+ iCurrentPosition += bytes / 2;\r
+ iCurrentBufferSize += bytes;\r
\r
- if (++iFrameCount == iBufferedFrames)\r
+ if (aPcmFrames > iMaxWriteSamples) {\r
+ DEBUGPRINT(_L("too many samples: %i > %i"), aPcmFrames, iMaxWriteSamples);\r
+ }\r
+\r
+ if (iCurrentBufferSize + iMaxWriteSamples * mul > iBufferSize)\r
{\r
+ //DEBUGPRINT(_L("write on iCurrentBufferSize %i"), iCurrentBufferSize);\r
WriteBlockL();\r
}\r
\r
}\r
}\r
\r
- iFrameCount = 0;\r
if (++iCurrentBuffer == KSoundBuffers)\r
iCurrentBuffer = 0;\r
+ iSoundBuffers[iCurrentBuffer]->Des().SetMax();\r
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();\r
iCurrentBufferSize = 0;\r
}\r
iListener.iIsOpen = ETrue;\r
iListener.iUnderflowed = 1;\r
iListener.iLastError = 0;\r
- iFrameCount = 0;\r
iCurrentBufferSize = 0;\r
iCurrentPosition = (TInt16*) iSoundBuffers[iCurrentBuffer]->Ptr();\r
return iCurrentPosition;\r
// handles underflow condition\r
void CGameAudioMS::UnderflowedL()\r
{\r
+#ifdef DEBUG_UNDERFLOWS\r
DEBUGPRINT(_L("UnderflowedL()"));\r
+#endif\r
\r
if (iListener.iLastError != KErrUnderflow)\r
{\r
User::LeaveIfError(KErrNotSupported);\r
}\r
\r
-void CGameAudioMS::ChangeVolume(TInt aUp)\r
+TInt CGameAudioMS::ChangeVolume(TInt aUp)\r
{\r
//DEBUGPRINT(_L("CGameAudioMS::ChangeVolume(%i)"), aUp);\r
\r
if (iMdaAudioOutputStream) {\r
if (aUp) {\r
- if (iVolume < iMdaAudioOutputStream->MaxVolume()) iVolume+=5;\r
+ iVolume += 5;\r
+ if (iVolume > iMdaAudioOutputStream->MaxVolume())\r
+ iVolume = iMdaAudioOutputStream->MaxVolume();\r
} else {\r
- if (iVolume > 0) iVolume-=5;\r
+ iVolume -= 5;\r
+ if (iVolume < 0) iVolume = 0;\r
}\r
iMdaAudioOutputStream->SetVolume(iVolume);\r
}\r
+\r
+ return iVolume;\r
}\r
\r
void TGameAudioEventListener::MaoscOpenComplete(TInt aError)\r
{\r
+#ifdef DEBUG_UNDERFLOWS\r
DEBUGPRINT(_L("CGameAudioMS::MaoscOpenComplete, error=%d"), aError);\r
+#endif\r
\r
iIsOpen = ETrue;\r
if(aError) {\r
\r
void TGameAudioEventListener::MaoscPlayComplete(TInt aError)\r
{\r
+#ifdef DEBUG_UNDERFLOWS\r
DEBUGPRINT(_L("CGameAudioMS::MaoscPlayComplete: %i"), aError);\r
+#endif\r
if(aError) {\r
iLastError = aError;\r
iUnderflowed++; // never happened to me while testing, but just in case\r