#include "Precompiled.h" #include "RakiTests/Sounds/MP3DataProvider.h" #include "RakiEngine/Data/Stream/AsyncReadStreamer.h" #include "RakiEngine/Data/Stream/SeekableStream.h" namespace raki { MP3DataProvider::MP3DataProvider( AsyncReadStreamer * _asyncReadStreamer, const void * _clientData, const u32 _nbChannels ) : SoundStreamDataProvider( _nbChannels ) , m_asyncReadStreamer( _asyncReadStreamer ) , m_nextStream( NULL ) , m_clientData( _clientData ) , m_nextClientData( NULL ) { RAKI_ASSERT( m_asyncReadStreamer ); } u64 MP3DataProvider::pullData( void * const _buffer, const u64 _sizeToRead ) { RAKI_ASSERT( m_asyncReadStreamer ); return m_asyncReadStreamer->stream( _buffer, _sizeToRead ); } u64 MP3DataProvider::getRemainingByteSize() const { if ( m_asyncReadStreamer ) { u64 size = m_asyncReadStreamer->getSize(); u64 position = m_asyncReadStreamer->getCurrentPos(); RAKI_ASSERT( position <= size ); return ( size - position ); } return 0; } void MP3DataProvider::update( bool /*_launchNewReadRequests*/ ) { } void MP3DataProvider::prefetchNextStream() { if ( m_asyncReadStreamer && m_nextStream ) { if ( m_nextStream ) m_nextStream->seek( 0, SeekableStream::fromBeginning ); m_asyncReadStreamer->setStreamData( NULL, 0, m_nextStream, m_nextClientData ); } } void MP3DataProvider::setNextStreamNow() { m_asyncReadStreamer->seekBeginning(); /* if ( m_nextStream ) { m_nextStream->seekBeginning(); m_stream = m_nextStream; m_clientData = m_nextClientData; m_nextStream = NULL; m_nextClientData = NULL; } else { m_stream = NULL; m_clientData = NULL; }*/ } u64 MP3DataProvider::getEntireSampleSize() const { u64 byteSize = getEntireByteSize(); u64 nbBlocks = byteSize / 576; return nbBlocks * 1152; } u64 MP3DataProvider::getEntireByteSize() const { return m_asyncReadStreamer ? m_asyncReadStreamer->getSize() : 0; } void MP3DataProvider::setNextStream( SeekableStream * _nextStream, const void * _nextClientData ) { m_nextStream = _nextStream; m_nextClientData = _nextClientData; } u64 MP3DataProvider::getCurrentSamplePosition() const { u64 position = m_asyncReadStreamer ? m_asyncReadStreamer->getCurrentPos() : 0; u64 nbBlocks = position / 576; return nbBlocks * 1152; } const void * MP3DataProvider::getClientData() const { return m_clientData; } u64 MP3DataProvider::getByteBlockPosition( const u64 _startSamplePosition ) const { // Fixed size MP3 is 1152 samples per 576 byte block u64 blockNumber = _startSamplePosition / 1152; u64 bytePosition = blockNumber * 576; return bytePosition; } u64 MP3DataProvider::getSampleOffsetInBuffer( const u64 _byteBlockPosition, const u64 _samplePosition ) const { if ( !_byteBlockPosition ) return _samplePosition; const u64 blockSize = 576; RAKI_ASSERT( !( _byteBlockPosition % blockSize ) ); const u64 block = _byteBlockPosition / blockSize; const u64 blockSamplePosition = block * 1152; RAKI_ASSERT( block ); RAKI_ASSERT( _samplePosition >= blockSamplePosition ); return _samplePosition - blockSamplePosition; } } // namespace raki