123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- #include "Sound.h"
- #include "Player.h"
- using namespace GSL;
- #ifdef WIN32
- extern GSLPlayer *_player;
- void CALLBACK AudioOutProc( HWAVEOUT hOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
- #endif
- // Inhalt der Sound Klasse aus Sound.h
- // Konstruktor
- GSLSound::GSLSound( const SoundKopf &skpf )
- : Thread()
- {
- kpf = skpf;
- dat = new Datei();
- dat->setDatei( kpf.pfad );
- #ifdef WIN32
- status = 0;
- hAudioId = 0;
- uAudioDelay = 0;
- uAudioCount = 0;
- uAudioPlay = 16;
- hAudioEvent = 0;
- uAudioWrite = 0;
- uAudioStop = 0;
- lAudioDone = 0;
- uAudioWrOk = 0;
- iAudioThEnd = 0;
- linksV = 1;
- rechtsV = 1;
- #endif
- }
- // Destruktor
- GSLSound::~GSLSound()
- {
- #ifdef WIN32
- if( status )
- stopSound();
- #endif
- dat->release();
- }
- // privat
- int GSLSound::audioOpen()
- {
- #ifdef WIN32
- WAVEFORMATEX sAudioWm;
- sAudioWm.wFormatTag = WAVE_FORMAT_PCM;
- sAudioWm.nChannels = kpf.channels;
- sAudioWm.nSamplesPerSec = kpf.sampleRate;
- sAudioWm.nBlockAlign = ( ( 16 * kpf.channels ) + 7 ) >> 3;
- sAudioWm.nAvgBytesPerSec = kpf.sampleRate * sAudioWm.nBlockAlign;
- sAudioWm.wBitsPerSample = 16;
- sAudioWm.cbSize = 0;
- MMRESULT uRes = waveOutOpen( &hAudioId, WAVE_MAPPER, &sAudioWm, (DWORD_PTR)AudioOutProc, 0x00000000, CALLBACK_FUNCTION );
- if( uRes || !hAudioId )
- {
- memset( &sAudioWm, 0, sizeof( sAudioWm ) );
- return 1;
- }
- uAudioDelay = 0;
- uAudioWrite = 0;
- uAudioStop = 0;
- lAudioDone = 0;
- for( uAudioCount = 0; uAudioCount < 16; uAudioCount++ )
- {
- aAudioHdr[ uAudioCount ] = (LPWAVEHDR)GlobalAllocPtr( GMEM_MOVEABLE | GMEM_SHARE, sizeof( WAVEHDR ) + 0x4000 );
- if( !aAudioHdr[ uAudioCount ] )
- break;
- aAudioHdr[ uAudioCount ]->dwFlags = WHDR_DONE;
- aAudioHdr[ uAudioCount ]->lpData = (LPSTR)aAudioHdr[ uAudioCount ] + sizeof( WAVEHDR );
- aAudioHdr[ uAudioCount ]->dwBufferLength = 0x4000;
- aAudioHdr[ uAudioCount ]->dwUser = uAudioCount;
- aAudioHdr[ uAudioCount ]->dwBytesRecorded = 0;
- aAudioHdr[ uAudioCount ]->dwLoops = 1;
- aAudioHdr[ uAudioCount ]->lpNext = 0;
- aAudioPtr[ uAudioCount ] = (char *)( aAudioHdr[ uAudioCount ] ) + sizeof( WAVEHDR );
- if( !waveOutPrepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
- continue;
- GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] );
- break;
- }
- uAudioPlay = uAudioCount - 1;
- if( uAudioCount < 12 )
- {
- audioClose();
- return 2;
- }
- hAudioEvent = CreateEvent( 0, TRUE, TRUE, 0 );
- if( !hAudioEvent )
- {
- audioClose();
- return 3;
- }
- if( waveOutGetDevCaps( (UINT_PTR)hAudioId, (LPWAVEOUTCAPSA)&sAudioCaps, sizeof( WAVEOUTCAPS ) ) )
- memset( &sAudioCaps, 0, sizeof( sAudioCaps ) );
- waveOutReset( hAudioId );
- waveOutSetVolume( hAudioId, 0xFFFFFFFF );
- #endif
- dat->open( Datei::Style::lesen );
- #ifdef WIN32
- uAudioWrOk = 1;
- #endif
- return 0;
- }
- int GSLSound::audioClose()
- {
- int iErr = 0;
- #ifdef WIN32
- if( !hAudioId )
- return 1;
- audioStop();
- while( uAudioCount > 0 )
- {
- uAudioCount--;
- if( waveOutUnprepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
- iErr = 1;
- if( GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] ) )
- iErr = 1;
- aAudioHdr[ uAudioCount ] = 0;
- aAudioPtr[ uAudioCount ] = 0;
- }
- if( waveOutClose( hAudioId ) )
- iErr = 1;
- if( !CloseHandle( hAudioEvent ) )
- iErr = 1;
- hAudioId = 0;
- uAudioWrite = 0;
- uAudioDelay = 0;
- uAudioPlay = uAudioCount - 1;
- #endif
- dat->close();
- return iErr;
- }
- int GSLSound::audioStop()
- {
- #ifdef WIN32
- unsigned uPos;
- if( !hAudioId )
- return 1;
- uAudioStop = 1;
- uAudioWrOk = 0;
- warteAufThread( 5000 );
- SetEvent( hAudioEvent );
- waveOutReset( hAudioId );
- if( uAudioWrite != 0 && uAudioPlay != uAudioCount - 1 )
- {
- for( uPos = 0; uPos < uAudioCount; uPos++ ) // clears all buffers
- {
- memset( aAudioHdr[ uPos ]->lpData, 0, 0x4000 );
- break;
- }
- }
- uAudioPlay = uAudioCount - 1;
- uAudioWrite = 0;
- uAudioDelay = 0;
- SetEvent( hAudioEvent );
- uAudioWrOk = 1;
- if( isRunning() ) // close thread
- {
- warteAufThread( 1000 );
- if( !iAudioThEnd )
- {
- warteAufThread( 1000 );
- if( run )
- ende();
- Sleep( 100 );
- }
- }
- #endif
- return 0;
- }
- int GSLSound::audioSchreiben( unsigned int uCount )
- {
- #ifdef WIN32
- int iDelta, i, iPos;
- WAVEHDR *pHeader;
- if( !uAudioWrOk )
- return 4;
- if( uCount > 0x4000 )
- return 2;
- if( WaitForSingleObject( hAudioEvent, 2000 ) == WAIT_FAILED )
- return 1;
- if( uAudioDelay < 8 )
- {
- aAudioSize[ uAudioDelay ] = uCount;
- uAudioDelay++;
- hAudioCs.lock(); // increase write pos
- uAudioWrite++;
- if( uAudioWrite >= uAudioCount )
- uAudioWrite = 0;
- hAudioCs.unlock();
- return 0;
- }
- if( uAudioDelay == 8 )
- {
- uAudioDelay++;
- for( i = 8; i > 0; i-- )
- {
- iPos = uAudioWrite - i;
- if( iPos < 0 )iPos += uAudioCount;
- pHeader = aAudioHdr[ iPos ];
- pHeader->dwBufferLength = aAudioSize[ 8 - i ];
- if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
- return 3;
- }
- }
- pHeader = aAudioHdr[ uAudioWrite ];
- pHeader->dwBufferLength = uCount;
- if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
- return 3;
- hAudioCs.lock();
- uAudioWrite++;
- if( uAudioWrite >= uAudioCount )
- uAudioWrite = 0;
- iDelta = uAudioPlay - uAudioWrite;
- if( iDelta < 0 )
- iDelta += uAudioCount;
- if( iDelta < 2 )
- ResetEvent( hAudioEvent );
- hAudioCs.unlock();
- #endif
- return 0;
- }
- int GSLSound::audioLesen( char *buff, int len )
- {
- if( dat->getLPosition() < kpf.datPos )
- dat->setLPosition( kpf.datPos, 0 );
- if( dat->getLPosition() >= kpf.datEnd )
- return -1;
- if( dat->getLPosition() + len > kpf.datEnd )
- len = (int)( kpf.datEnd - dat->getLPosition() );
- if( len > 0 )
- dat->lese( buff, len );
- #ifdef WIN32
- for( int i = 0; i < len; i++, buff++ )
- {
- if( i % 4 >= 2 )
- *buff = (char)( *buff * rechtsV );
- else
- *buff = (char)( *buff * linksV );
- }
- #endif
- return len;
- }
- // nicht constant
- void GSLSound::playSound()
- {
- #ifdef WIN32
- if( !status )
- {
- if( _player->addSound( dynamic_cast<GSLSound *>( getThis() ) ) )
- status = 1;
- if( !audioOpen() )
- start();
- else
- {
- _player->removeSound( this );
- status = 0;
- }
- }
- setPause( 0 );
- #endif
- }
- void GSLSound::setPause( bool p )
- {
- #ifdef WIN32
- if( p )
- {
- if( !status )
- playSound();
- if( status == 1 )
- {
- waveOutPause( hAudioId );
- status = 2;
- }
- }
- else
- {
- if( status == 2 )
- {
- waveOutRestart( hAudioId );
- status = 1;
- }
- }
- #endif
- }
- void GSLSound::stopSound()
- {
- #ifdef WIN32
- setPause( 0 );
- if( status == 1 )
- {
- status = 0;
- _player->removeSound( this );
- audioClose();
- }
- #endif
- }
- void GSLSound::warteAufSound( int zeit )
- {
- warteAufThread( zeit );
- }
- void GSLSound::setVolume( unsigned int links, unsigned int rechts )
- {
- #ifdef WIN32
- linksV = (float)links / 0xFFFF;
- rechtsV = (float)rechts / 0xFFFF;
- #endif
- }
- #ifdef WIN32
- void GSLSound::msg( UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
- {
- WAVEHDR *pHeader;
- int iDelta;
- switch( uMsg )
- {
- case WOM_DONE:
- pHeader = (WAVEHDR *)dwParam1;
- hAudioCs.lock();
- InterlockedExchangeAdd( (unsigned __int64 *)& lAudioDone, (__int64)pHeader->dwBufferLength );
- iDelta = (int)( uAudioPlay - pHeader->dwUser );
- if( iDelta < 0 )
- iDelta += uAudioCount;
- if( iDelta > ( (int)uAudioCount >> 1 ) )
- {
- uAudioPlay = (unsigned int)pHeader->dwUser;
- if( uAudioPlay >= uAudioCount )
- uAudioPlay = 0;
- iDelta = uAudioPlay - uAudioWrite;
- if( iDelta < 0 )
- iDelta += uAudioCount;
- if( iDelta >= 2 )
- SetEvent( hAudioEvent );
- }
- hAudioCs.unlock();
- break;
- }
- }
- #endif
- void GSLSound::thread()
- {
- #ifdef WIN32
- iAudioThEnd = 0;
- uAudioStop = 0;
- if( !hAudioId )
- return;
- int iCount;
- while( !uAudioStop && hAudioId )
- {
- iCount = audioLesen( aAudioPtr[ uAudioWrite ], 0x4000 );
- if( iCount <= 0 )
- break;
- audioSchreiben( iCount );
- }
- iAudioThEnd = 1;
- stopSound();
- #endif
- run = 0;
- }
- // zum Speichern
- void GSLSound::open()
- {
- #ifdef WIN32
- if( !status )
- {
- dat->open( Datei::Style::lesen );
- status = 3;
- }
- #else
- dat->open( Datei::Style::lesen );
- #endif
- }
- int GSLSound::getDaten( char *buffer, int len )
- {
- #ifdef WIN32
- if( status != 3 )
- return -1;
- #endif
- return audioLesen( buffer, len );
- }
- void GSLSound::close()
- {
- #ifdef WIN32
- if( status == 3 )
- {
- dat->close();
- status = 0;
- }
- #else
- dat->close();
- #endif
- }
- bool GSLSound::istMono() const
- {
- return kpf.channels == 1;
- }
- int GSLSound::getSampleRate() const
- {
- return kpf.sampleRate;
- }
- __int64 GSLSound::getDatLength() const
- {
- return kpf.datEnd - kpf.datPos;
- }
- // constant
- #ifdef WIN32
- HWAVEOUT GSLSound::getHandle() const
- {
- return hAudioId;
- }
- #endif
- // Reference Counting
- Thread *GSLSound::getThis()
- {
- return Thread::getThis();
- }
- Thread *GSLSound::release()
- {
- return Thread::release();
- }
|