Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

sidplayer.cpp

Go to the documentation of this file.
00001 // sidplayer.cpp
00002 //
00003 // Copyright (c) 2001-2002 Alfred E. Heggestad
00004 //
00005 //    This program is free software; you can redistribute it and/or modify
00006 //    it under the terms of the GNU General Public License as published by
00007 //    the Free Software Foundation; either version 2 of the License, or
00008 //    (at your option) any later version.
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 // forward declarations
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 // implementation of CSidPlayer
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         // INITIALIZE THE EMULATOR ENGINE
00119         // ======================================================================
00120 
00121         iEmuEngine = new (ELeave) emuEngine();
00122 
00123         // Initialize the SID-Emulator Engine to defaults.
00124         if ( !iEmuEngine->verifyEndianess() )
00125                 {
00126                 User::Leave(ERR_ENDIANESS);
00127                 }
00128 
00129         // Get the default configuration.
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;  // get it from argument line
00147 
00148         // ======================================================================
00149         // VALIDATE SID EMULATOR SETTINGS
00150         // ======================================================================
00151 
00152         if ((myEmuConfig.autoPanning!=SIDEMU_NONE) && (myEmuConfig.channels==SIDEMU_MONO))
00153                 {
00154                 myEmuConfig.channels = SIDEMU_STEREO;  // sane
00155                 }
00156         if ((myEmuConfig.autoPanning!=SIDEMU_NONE) && (myEmuConfig.volumeControl==SIDEMU_NONE))
00157                 {
00158                 myEmuConfig.volumeControl = SIDEMU_FULLPANNING;  // working
00159                 }
00160 
00161         // ======================================================================
00162         // INSTANTIATE A SIDTUNE OBJECT
00163         // ======================================================================
00164 
00165         // warning! 16-bit descriptor truncated to 8-bit
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         // CONFIGURE THE AUDIO DRIVER
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         // Instantiate the audio driver. The capabilities of the audio driver
00194         // can override the settings of the SID emulator.
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         // CONFIGURE THE EMULATOR ENGINE
00214         // ======================================================================
00215 
00216         // Configure the SID emulator according to the audio driver settings.
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         // INITIALIZE THE EMULATOR ENGINE TO PREPARE PLAYING A SIDTUNE
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         // KEEP UP A CONTINUOUS OUTPUT SAMPLE STREAM
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         // OK - everything is now ready for ::Play();
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         // if already playing, just return
00276         if(iIdlePlay)
00277                 return;
00278 
00279         // create a new CIdle object and start it
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 //      if(iAudio)
00312 //              iAudio->StopStream(); ?
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         // warning! 16-bit descriptor truncated to 8-bit
00431         TBuf8<256> buf8;
00432         buf8.Copy(iSongName);
00433         iTune = new (ELeave) sidTune( (const char*)buf8.PtrZ() );
00434 
00435         if(sidEmuInitializeSong(*iEmuEngine, *iTune, 0 /* default song */ ) )
00436                 return KErrNone;
00437         else
00438                 return KErrNotReady;
00439         }

Generated on Tue Feb 8 04:14:15 2005 for Esidplay by doxygen 1.3.3