D:/Zythum/DinoKod/Sound/StreamTrackDS.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : StreamTrackDS.h
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 19/10/2002
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include "Common/Console.h"
00012 #include "Common/Error.h"
00013 #include "Common/Assert.h"
00014 #include "Common/Directory.h"
00015 #include "Wave/Wav.h"
00016 #include "Wave/Ogg.h"
00017 #include "Sound/SoundDS.h"
00018 
00019 #include "Sound/StreamTrackDS.h"
00020 
00021 //-------------------------------------------------------------------------------------------------------------------------
00022 KStreamTrack::KStreamTrack()
00023 {
00024         m_pWaveFile             = NULL;
00025         m_pDSBuffer             = NULL;
00026         m_pDSNotify             = NULL;
00027         m_hStopEvent1   = NULL;
00028         m_hStopEvent2   = NULL;
00029         m_Fade                  = KSTF_NONE;
00030         m_StartFade             = 0;
00031         m_EndFade               = 0;
00032 }
00033 
00034 //---------------------------------------------------------------------------------------------
00035 KStreamTrack::~KStreamTrack()
00036 {
00037 }
00038 
00039 //---------------------------------------------------------------------------------------------
00040 bool KStreamTrack::LoadTrack( KStreamTrackBank* pStreamTrackBank, KStr& sFileName )
00041 {
00042         KASSERT( !m_pWaveFile );
00043         KASSERT( !m_pDSBuffer );
00044         KASSERT( !m_pDSNotify );
00045         KASSERT( pStreamTrackBank );
00046         
00047         IDirectSound8*  pDS = pStreamTrackBank->GetSound()->GetDirectSound();
00048         HRESULT                 hr;
00049         
00050         // Determine le module de decompression à utiliser en fonction de l'extension
00051         char* pExtension = KFile::GetFileExtension( sFileName );
00052         if( !pExtension )
00053                 return false;
00054 
00055         if( !stricmp( pExtension, "wav" ) )
00056         {
00057                 // Wav
00058                 m_pWaveFile = new KWav();
00059         }
00060         else if( !stricmp( pExtension, "ogg" ) )
00061         {
00062                 // Ogg
00063                 m_pWaveFile = new KOgg();
00064         }
00065         else
00066                 return false;
00067 
00068         // Ouvre le Wave
00069         if( !m_pWaveFile->OpenWave( sFileName ) )
00070         {
00071                 Deletep( m_pWaveFile );
00072                 return false;
00073         }
00074 
00075         // Creation du Buffer Secondaire
00076         DSBUFFERDESC    dsdd;
00077 
00078         memset( &dsdd, 0, sizeof( dsdd ) );
00079         dsdd.dwSize                     = sizeof( dsdd );
00080         dsdd.dwFlags            = /*DSBCAPS_GLOBALFOCUS |*/ DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE;
00081         dsdd.dwBufferBytes      = m_pWaveFile->GetMaxBlockSize() * 2;
00082         dsdd.lpwfxFormat        = m_pWaveFile->GetWaveFormat();
00083 
00084         IDirectSoundBuffer*     pDSB;
00085         if( FAILED( hr = pDS->CreateSoundBuffer( &dsdd, &pDSB, NULL ) ) )
00086         {
00087                 KError::FatalError( NULL, "KStreamTrack::LoadTrack(...) %s.", DXGetErrorString9( hr ) );
00088                 return false;
00089         }
00090 
00091         if( FAILED( hr = pDSB->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*)&m_pDSBuffer ) ) )
00092         {
00093                 KError::FatalError( NULL, "KStreamTrack::LoadTrack(...) %s.", DXGetErrorString9( hr ) );
00094                 return false;
00095         }
00096 
00097         pDSB->Release();
00098 
00099         // Notify
00100         if( FAILED( hr = m_pDSBuffer->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&m_pDSNotify ) ) )
00101         {
00102                 KError::FatalError( NULL, "KStreamTrack::LoadTrack(...) %s.", DXGetErrorString9( hr ) );
00103                 return false;
00104         }
00105         
00106         // Preremplissage
00107         CopyNextBlock( 0 );
00108         CopyNextBlock( 1 );
00109         
00110         // Event
00111         m_hStopEvent1 = CreateEvent( NULL, FALSE, FALSE, NULL );
00112         if( !m_hStopEvent1 )
00113                 return false;
00114 
00115         m_hStopEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL );
00116         if( !m_hStopEvent2 )
00117                 return false;
00118 
00119         DSBPOSITIONNOTIFY       dspn[2];
00120 
00121         dspn[0].dwOffset                = m_pWaveFile->GetMaxBlockSize() - 1;
00122         dspn[0].hEventNotify    = m_hStopEvent1;
00123         dspn[1].dwOffset                = m_pWaveFile->GetMaxBlockSize() * 2 - 1;
00124         dspn[1].hEventNotify    = m_hStopEvent2;
00125         m_pDSNotify->SetNotificationPositions( 2, dspn );
00126         m_pDSNotify->Release();
00127         m_pDSNotify = NULL;
00128 
00129         m_sFileName = sFileName;
00130 
00131         return true;
00132 }
00133 
00134 //---------------------------------------------------------------------------------------------
00135 bool KStreamTrack::UnloadTrack()
00136 {
00137         if( m_hStopEvent1 )
00138         {
00139                 CloseHandle( m_hStopEvent1 );
00140                 m_hStopEvent1 = NULL;
00141         }
00142         
00143         if( m_hStopEvent2 )
00144         {
00145                 CloseHandle( m_hStopEvent2 );
00146                 m_hStopEvent2 = NULL;
00147         }
00148         
00149         if( m_pWaveFile )
00150         {
00151                 m_pWaveFile->CloseWave();
00152                 SafeDeletep( m_pWaveFile );
00153         }
00154 
00155         SafeRelease( m_pDSBuffer );
00156         SafeRelease( m_pDSNotify );
00157 
00158         return true;    
00159 }
00160 
00161 //-------------------------------------------------------------------------------------------------------------------------
00162 bool KStreamTrack::Lock( void** pData, u32* Size, u32 StartOffset, u32 SizeToLock )
00163 {
00164         HRESULT hr;
00165 
00166         if( FAILED( hr = m_pDSBuffer->Lock( StartOffset, SizeToLock, pData, Size, NULL, NULL, SizeToLock ? 0 : DSBLOCK_ENTIREBUFFER ) ) )
00167         {
00168                 KError::Error( NULL, "KStreamTrack::Lock(...) %s.", DXGetErrorString9( hr ) );
00169                 return false;
00170         }
00171 
00172         return true;
00173 }
00174 
00175 //-------------------------------------------------------------------------------------------------------------------------
00176 bool KStreamTrack::Unlock( void* pData, u32 Size )
00177 {
00178         HRESULT hr;
00179 
00180         if( FAILED( hr = m_pDSBuffer->Unlock( pData, Size, NULL, NULL ) ) )
00181         {
00182                 KError::Error( NULL, "KStreamTrack::Unlock(...) %s.", DXGetErrorString9( hr ) );
00183                 return false;
00184         }
00185 
00186         return true;
00187 }
00188 
00189 //-------------------------------------------------------------------------------------------------------------------------
00190 bool KStreamTrack::Play( bool bFadeIn, KTIME FadeTime )
00191 {
00192         KASSERT( m_pDSBuffer );
00193 
00194         HRESULT hr;
00195 
00196         if( bFadeIn )
00197         {
00198                 m_Fade          = KSTF_IN;
00199                 m_StartFade = g_Time.GetTime();
00200                 m_EndFade       = m_StartFade + FadeTime;
00201         }
00202         else
00203         {
00204                 m_Fade = KSTF_NONE;
00205                 m_pDSBuffer->SetVolume( DSBVOLUME_MAX );
00206         }
00207 
00208         if( FAILED( hr = m_pDSBuffer->Play( 0, 0, true ) ) )
00209         {
00210                 KError::Error( NULL, "KStreamTrack::Play(...) %s.", DXGetErrorString9( hr ) );
00211                 return false;
00212         }
00213 
00214         return true;
00215 }
00216 
00217 //-------------------------------------------------------------------------------------------------------------------------
00218 bool KStreamTrack::Stop( bool bFadeOut, KTIME FadeTime )
00219 {
00220         HRESULT hr;
00221 
00222         if( bFadeOut )
00223         {
00224                 m_Fade          = KSTF_OUT;
00225                 m_StartFade = g_Time.GetTime();
00226                 m_EndFade       = m_StartFade + FadeTime;
00227         }
00228         else
00229         {
00230                 m_Fade = KSTF_NONE;
00231                 m_pDSBuffer->SetVolume( DSBVOLUME_MAX );
00232                 
00233                 if( FAILED( hr = m_pDSBuffer->Stop() ) )
00234                 {
00235                         KError::Error( NULL, "KStreamTrack::Stop(...) %s.", DXGetErrorString9( hr ) );
00236                         return false;
00237                 }
00238         }
00239 
00240         return true;
00241 }
00242 
00243 
00244 //-------------------------------------------------------------------------------------------------------------------------
00245 void KStreamTrack::SetPlayPos( u32 Position )
00246 {
00247         KASSERT( m_pDSBuffer );
00248 
00249         m_pDSBuffer->SetCurrentPosition( Position );
00250 }
00251 
00252 //-------------------------------------------------------------------------------------------------------------------------
00253 bool KStreamTrack::IsPlaying()
00254 {
00255         KASSERT( m_pDSBuffer );
00256 
00257         DWORD   Status;
00258         
00259         m_pDSBuffer->GetStatus( &Status );
00260         
00261         if( Status & DSBSTATUS_PLAYING )
00262                 return true;
00263 
00264         return false;
00265 }
00266 
00267 //-------------------------------------------------------------------------------------------------------------------------
00268 bool KStreamTrack::CopyNextBlock( u32 BufferId )
00269 {
00270         u32             SizeRead;
00271         u32             StartOffset;
00272 
00273         StartOffset = BufferId * m_pWaveFile->GetMaxBlockSize();
00274         
00275         // Lit le bloc suivant
00276         if( !m_pWaveFile->ReadNextBlock( &SizeRead ) )
00277         {
00278                 return false;
00279 //              m_pWaveFile->CloseWave();
00280 //              Deletep( m_pWaveFile );
00281 //              m_pDSBuffer->Release();
00282 //              m_pDSBuffer = NULL;
00283         }
00284 
00285         // Fin du fichier wave?
00286         if( m_pWaveFile->IsEnd() )
00287         {
00288                 //Stop();
00289                 m_pWaveFile->Rewind();
00290 //              return false;
00291         }
00292 
00293         KASSERT( SizeRead <= m_pWaveFile->GetMaxBlockSize() );
00294 
00295         // Si le bloc n'est pas complet, on ajoute du vide a la fin
00296         if( SizeRead < m_pWaveFile->GetMaxBlockSize() )
00297         {
00298                 for( u32 i = SizeRead; i < m_pWaveFile->GetMaxBlockSize(); i ++ )
00299                 {
00300                         m_pWaveFile->GetBlock()[i] = 0;
00301                 }
00302                 SizeRead = m_pWaveFile->GetMaxBlockSize();
00303         }
00304 
00305         if( SizeRead == 0 )
00306                 return false;
00307 
00308         // Copie
00309         u8*             pBuffer = NULL;
00310         u32             Size = 0;
00311 
00312         Lock( (void**)&pBuffer, &Size, StartOffset, SizeRead );
00313         KASSERT( Size == SizeRead );
00314         memcpy( pBuffer, m_pWaveFile->GetBlock(), Size );       
00315         Unlock( (void*)pBuffer, Size );
00316 
00317         return true;
00318 }
00319 
00320 //-------------------------------------------------------------------------------------------------------------------------
00321 bool KStreamTrack::Manage()
00322 {
00323         KTIME   Time = g_Time.GetTime();
00324         float   delta = (float)( Time - m_StartFade ) / (float)( m_EndFade - m_StartFade );
00325 
00326         switch( m_Fade )
00327         {
00328         case KSTF_NONE:
00329                 break;
00330         case KSTF_IN:
00331                 {
00332                         if( delta > 1.0f )
00333                         {
00334                                 delta   = 1.0f;
00335                                 m_Fade  = KSTF_NONE;
00336                         }
00337 
00338                         LONG Volume = (LONG)( delta * (float)(DSBVOLUME_MAX - KDSBVOLUME_MIN)) + KDSBVOLUME_MIN;
00339                         m_pDSBuffer->SetVolume( Volume );
00340 //                      g_Console << "Volume : " << Volume << KENDL;
00341                 }
00342                 break;
00343         case KSTF_OUT:
00344                 {
00345                         if( delta > 1.0f )
00346                         {
00347                                 delta   = 1.0f;
00348                                 m_Fade  = KSTF_NONE;
00349 
00350                                 HRESULT hr;
00351                                 if( FAILED( hr = m_pDSBuffer->Stop() ) )
00352                                 {
00353                                         KError::Error( NULL, "KStreamTrack::Manage(...) Stop failed\n%s.", DXGetErrorString9( hr ) );
00354                                         return false;
00355                                 }
00356                         }
00357 
00358                         LONG Volume = (LONG)( (1.0f - delta) * (float)(DSBVOLUME_MAX - KDSBVOLUME_MIN)) + KDSBVOLUME_MIN;
00359                         m_pDSBuffer->SetVolume( Volume );
00360 //                      g_Console << "Volume : " << Volume << KENDL;
00361                 }
00362                 break;
00363         }
00364 
00365         return true;
00366 }
00367 
00368 //-------------------------------------------------------------------------------------------------------------------------
00369 //-------------------------------------------------------------------------------------------------------------------------
00370 //-------------------------------------------------------------------------------------------------------------------------
00371 KStreamTrackBank::KStreamTrackBank( KSound* pSound )
00372 {
00373         m_pSound                = pSound;
00374         m_nTracks               = 0;
00375 }
00376 
00377 //---------------------------------------------------------------------------------------------
00378 KStreamTrackBank::~KStreamTrackBank()
00379 {
00380         for(u32 i = 0;i < m_nTracks;i ++)
00381                 Deletep( m_pTrack[i] );
00382 
00383         m_pTrack.Clear();
00384 }
00385 
00386 //---------------------------------------------------------------------------------------------
00387 KStreamTrack* KStreamTrackBank::GetTrack( KSTREAMTRACK TrackId )
00388 {
00389         KASSERT( TrackId < m_nTracks );
00390 //      KASSERT( m_pTrack[TrackId] );
00391 
00392         return m_pTrack[TrackId];
00393 }
00394 
00395 //---------------------------------------------------------------------------------------------
00396 KSTREAMTRACK KStreamTrackBank::LoadTrack( KStr& sFileName )
00397 {
00398         KStr    sFullFileName;
00399 
00400         for( s32 Path = 0; Path < g_Directory.GetnPath(); Path ++ )
00401         {
00402                 sFullFileName = g_Directory.GetPath( KStr( "Sounds" ), Path );
00403                 sFullFileName += sFileName;
00404                 
00405                 KStreamTrack*   pTrack = NULL;
00406                 KSTREAMTRACK    TrackId = 0;
00407 
00408                 pTrack = new KStreamTrack();
00409                 if( !pTrack->LoadTrack( this, sFullFileName ) )
00410                 {
00411                         Deletep( pTrack );
00412                         continue;
00413                 }
00414 
00415                 TrackId = m_pTrack.Add( pTrack );
00416                 m_nTracks ++;
00417                 
00418                 g_Console << "Sound loaded : " << sFileName.GetpString() << KENDL;
00419 
00420                 return TrackId;
00421         }
00422 
00423         KError::Error( NULL, "KStreamTrackBank::LoadTrack(...) Cannot load sound %s.", sFileName.GetpString() );
00424         
00425         return KSTREAMTRACK_NO;
00426 }
00427 
00428 //---------------------------------------------------------------------------------------------
00429 bool KStreamTrackBank::UnloadTrack( KSTREAMTRACK& Track )
00430 {
00431         if( Track < 0 )
00432                 return false;
00433 
00434         if( Track >= m_pTrack.GetSize() )
00435         {
00436                 KError::Error( NULL, "KStreamTrackBank::UnloadTrack() : Invalid TrackId : %i", Track );
00437                 return false;
00438         }
00439 
00440         m_pTrack[Track]->UnloadTrack();
00441         SafeDeletep( m_pTrack[Track] );
00442 
00443         Track = KSTREAMTRACK_NO;
00444 
00445         return true;
00446 }

Generated on Sun Mar 25 20:02:16 2007 for Zythum Project by  doxygen 1.5.1-p1