00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00017 #include "sidplayer.h"
00018
00019 enum
00020 {
00021 ERR_NOT_ENOUGH_MEMORY,
00022 ERR_SYNTAX,
00023 ERR_ENDIANESS
00024 };
00025 const TInt EXIT_ERROR_STATUS = (-1);
00026
00027
00028
00029
00030 GLREF_C bool sidEmuInitializeSong(emuEngine& thisEmuEngine,
00031 sidTune& thisTune,
00032 uword songNumber);
00033
00034
00035 TInt SidPlayerThread(TAny* aPlayer)
00039 {
00040 CSidPlayer* play = (CSidPlayer*)aPlayer;
00041
00042 if(play->IsPaused())
00043 return ETrue;
00044
00045 play->Thread();
00046 return ETrue;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055 CSidPlayer* CSidPlayer::NewL(const TDesC& aSong)
00056 {
00057 CSidPlayer* p = new (ELeave) CSidPlayer(aSong);
00058 CleanupStack::PushL(p);
00059 p->ConstructL();
00060 CleanupStack::Pop(p);
00061 return p;
00062 }
00063
00064
00065 CSidPlayer::~CSidPlayer()
00069 {
00070 DTOR(CSidPlayer);
00071
00072 delete iEmuEngine;
00073 delete iAudio;
00074 delete iTune;
00075 delete[] iBuffer;
00076
00077 if(iIdlePlay)
00078 delete iIdlePlay;
00079 }
00080
00081
00082 void CSidPlayer::ConstructL()
00086 {
00087 InitL();
00088 }
00089
00090
00091 CSidPlayer::CSidPlayer(const TDesC& aSong)
00095 :iIdlePlay(NULL)
00096 ,iIsReady(EFalse)
00097 {
00098 CTOR(CSidPlayer);
00099 iSongName.Copy(aSong);
00100 }
00101
00102
00103 void CSidPlayer::InitL()
00107 {
00108 ELOG1(_L8("CSidPlayer::InitL\n"));
00109 TInt ret;
00110
00111 if(iIsReady)
00112 {
00113 ELOG1(_L8("Hmm. already inited\n"));
00114 return;
00115 }
00116
00117
00118
00119
00120
00121 iEmuEngine = new (ELeave) emuEngine();
00122
00123
00124 if ( !iEmuEngine->verifyEndianess() )
00125 {
00126 User::Leave(ERR_ENDIANESS);
00127 }
00128
00129
00130 struct emuConfig myEmuConfig;
00131 iEmuEngine->getConfig(myEmuConfig);
00132
00133 uword selectedSong = 0;
00134
00135 #ifdef __ER6__
00136 myEmuConfig.frequency = SAMPLE_FREQ;
00137 myEmuConfig.channels = SIDEMU_MONO;
00138 myEmuConfig.bitsPerSample = SIDEMU_16BIT;
00139 #else
00140 myEmuConfig.frequency = KAlawSamplesPerSecond;
00141 myEmuConfig.channels = SIDEMU_MONO;
00142 myEmuConfig.bitsPerSample = SIDEMU_8BIT;
00143 #endif
00144 uword fragments = 16;
00145 uword fragSizeBase = 12;
00146 int forceBufSize = 0;
00147
00148
00149
00150
00151
00152 if ((myEmuConfig.autoPanning!=SIDEMU_NONE) && (myEmuConfig.channels==SIDEMU_MONO))
00153 {
00154 myEmuConfig.channels = SIDEMU_STEREO;
00155 }
00156 if ((myEmuConfig.autoPanning!=SIDEMU_NONE) && (myEmuConfig.volumeControl==SIDEMU_NONE))
00157 {
00158 myEmuConfig.volumeControl = SIDEMU_FULLPANNING;
00159 }
00160
00161
00162
00163
00164
00165
00166 TBuf8<256> buf8;
00167 buf8.Copy(iSongName);
00168 iTune = new (ELeave) sidTune( (const char*)buf8.PtrZ() );
00169 struct sidTuneInfo mySidInfo;
00170 iTune->getInfo( mySidInfo );
00171 if ( !iTune )
00172 {
00173 User::Leave(EXIT_ERROR_STATUS);
00174 }
00175
00176
00177
00178
00179
00180 #if defined (__WINS__)
00181 #define PDD_NAME _L("ESDRV")
00182 #define LDD_NAME _L("ESOUND")
00183
00184 ret = User::LoadPhysicalDevice(PDD_NAME);
00185 if (ret!=KErrNone && ret!=KErrAlreadyExists)
00186 User::LeaveIfError(ret);
00187
00188 ret = User::LoadLogicalDevice(LDD_NAME);
00189 if (ret!=KErrNone && ret!=KErrAlreadyExists)
00190 User::LeaveIfError(ret);
00191 #endif
00192
00193
00194
00195 iAudio = new (ELeave) audioDriver();
00196
00197 iAudio->ConstructL();
00198
00199 if ( !iAudio->IsThere() )
00200 {
00201 User::Leave(EXIT_ERROR_STATUS);
00202 }
00203
00204 if ( !iAudio->Open(myEmuConfig.frequency, myEmuConfig.bitsPerSample,
00205 myEmuConfig.channels, fragments, fragSizeBase))
00206 {
00207 ELOG1(_L8("Could not open audio\n"));
00208 User::Leave(KErrNotReady);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 myEmuConfig.frequency = (uword)iAudio->GetFrequency();
00218 myEmuConfig.bitsPerSample = iAudio->GetSamplePrecision();
00219 myEmuConfig.sampleFormat = iAudio->GetSampleEncoding();
00220 ret = iEmuEngine->setConfig( myEmuConfig );
00221 if(!ret)
00222 {
00223 ELOG1(_L8("Could not SetConfig on emu engine\n"));
00224 User::Leave(KErrNotReady);
00225 }
00226
00227
00228
00229
00230
00231 if ( !sidEmuInitializeSong(*iEmuEngine, *iTune, selectedSong) )
00232 {
00233 ELOG1(_L8("could not initialise emu engine\n"));
00234 User::Leave(KErrNotReady);
00235 }
00236
00237
00238
00239
00240
00241
00242 iBufSize = iAudio->GetBlockSize();
00243 if (forceBufSize != 0)
00244 {
00245 iBufSize = forceBufSize;
00246 }
00247
00248 if(iBufSize <= 0 )
00249 {
00250 User::Leave(EXIT_ERROR_STATUS);
00251 }
00252
00253 iBuffer = new (ELeave) ubyte[iBufSize];
00254
00255
00256
00257
00258 iIsReady = ETrue;
00259 }
00260
00261
00262 void CSidPlayer::Play()
00266 {
00267 ELOG1(_L8("CSidPlayer::Play\n"));
00268
00269 if(!iIsReady)
00270 {
00271 ELOG1(_L8("Oops. Not ready...\n"));
00272 return;
00273 }
00274
00275
00276 if(iIdlePlay)
00277 return;
00278
00279
00280 iIdlePlay = CIdle::NewL(CActive::EPriorityIdle);
00281 iIdlePlay->Start(TCallBack(SidPlayerThread, this));
00282 }
00283
00284
00285 void CSidPlayer::Stop()
00289 {
00290 ELOG1(_L8("CSidPlayer::Stop\n"));
00291
00292 if(iAudio)
00293 iAudio->StopStream();
00294
00295 if(iIdlePlay)
00296 {
00297 delete iIdlePlay;
00298 iIdlePlay = NULL;
00299 }
00300 sidEmuInitializeSong(*iEmuEngine, *iTune, 0);
00301 }
00302
00303
00304 void CSidPlayer::Pause()
00308 {
00309 ELOG1(_L8("CSidPlayer::Pause\n"));
00310
00311
00312
00313
00314 if(iIdlePlay)
00315 {
00316 delete iIdlePlay;
00317 iIdlePlay = NULL;
00318 }
00319 else
00320 Play();
00321 }
00322
00323
00324 TBool CSidPlayer::IsPaused()
00328 {
00329 return EFalse;
00330 }
00331
00332
00333 void CSidPlayer::Thread()
00338 {
00339 #if defined __ER6__ && !defined(__WINS__)
00340 if(!iAudio->iIsReady)
00341 return;
00342
00343 if(!iAudio->iPrefilled)
00344 {
00345 iEmuEngine->FillBuffer(*iTune, iBuffer, iBufSize);
00346 iAudio->iPrefilled = ETrue;
00347 }
00348
00349 if(iAudio->iPrefilled && iAudio->iBlocksInQueue == 0)
00350 {
00351 iAudio->Play((ubyte*)iBuffer, iBufSize);
00352 iAudio->iBlocksInQueue = 1;
00353 iAudio->iPrefilled = EFalse;
00354 }
00355 #else
00356 iEmuEngine->FillBuffer(*iTune, iBuffer, iBufSize);
00357 iAudio->Play(iBuffer, iBufSize);
00358 #endif
00359 }
00360
00361
00362 TInt CSidPlayer::VolumeDelta(TInt aDelta)
00366 {
00367 return iAudio->VolumeDelta(aDelta);
00368 }
00369
00370
00371 TInt CSidPlayer::SongDelta(TInt aDelta)
00375 {
00376 struct sidTuneInfo mySidInfo;
00377 iTune->getInfo( mySidInfo );
00378
00379 if(mySidInfo.songs == 1)
00380 return mySidInfo.currentSong;
00381
00382 if(iAudio)
00383 iAudio->StopStream();
00384
00385 TInt song = (mySidInfo.currentSong + aDelta) % mySidInfo.songs;
00386 if(song == 0)
00387 song = mySidInfo.songs;
00388
00389 if ( !sidEmuInitializeSong(*iEmuEngine, *iTune, (uword)song) )
00390 {
00391 ELOG1(_L8("could not initialise emu engine\n"));
00392 }
00393
00394 Play();
00395
00396 iTune->getInfo( mySidInfo );
00397 return mySidInfo.currentSong;
00398 }
00399
00400
00401 TInt CSidPlayer::SongSelect(TInt& aSong)
00405 {
00406 if(!sidEmuInitializeSong(*iEmuEngine, *iTune, (uword)aSong) )
00407 return KErrNotReady;
00408
00409 if(iAudio)
00410 iAudio->StopStream();
00411
00412 struct sidTuneInfo mySidInfo;
00413 iTune->getInfo( mySidInfo );
00414 aSong = mySidInfo.currentSong;
00415
00416 Play();
00417
00418 return KErrNone;
00419 }
00420
00421
00422 TInt CSidPlayer::NewTune(const TDesC& aTune)
00426 {
00427 delete iTune;
00428 iSongName.Copy(aTune);
00429
00430
00431 TBuf8<256> buf8;
00432 buf8.Copy(iSongName);
00433 iTune = new (ELeave) sidTune( (const char*)buf8.PtrZ() );
00434
00435 if(sidEmuInitializeSong(*iEmuEngine, *iTune, 0 ) )
00436 return KErrNone;
00437 else
00438 return KErrNotReady;
00439 }