194 lines
3.9 KiB
C++
194 lines
3.9 KiB
C++
#include "Precompiled.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "RakiTests/Sounds/ADPCMDataProvider_Wii.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "RakiEngine/Data/Stream/SeekableStream.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace raki
|
|
{
|
|
|
|
|
|
|
|
typedef struct
|
|
{
|
|
// for header generation during decode
|
|
u32 num_samples; // total number of RAW samples
|
|
u32 num_adpcm_nibbles; // number of ADPCM nibbles (including frame headers)
|
|
u32 sample_rate; // Sample rate, in Hz
|
|
// DSP addressing and decode context
|
|
u16 loop_flag; // 1=LOOPED, 0=NOT LOOPED
|
|
u16 format; // Always 0x0000, for ADPCM
|
|
u32 sa; // Start offset address for looped samples (zero for non-looped)
|
|
u32 ea; // End offset address for looped samples
|
|
u32 ca; // always zero
|
|
u16 coef[16]; // decode coefficients (eight pairs of 16-bit words)
|
|
// DSP decoder initial state
|
|
u16 gain; // always zero for ADPCM
|
|
u16 ps; // predictor/scale
|
|
u16 yn1; // sample history
|
|
u16 yn2; // sample history
|
|
// DSP decoder loop context
|
|
u16 lps; // predictor/scale for loop context
|
|
u16 lyn1; // sample history (n-1) for loop context
|
|
u16 lyn2; // sample history (n-2) for loop context
|
|
u16 pad[11]; // reserved
|
|
} DSPADPCM;
|
|
|
|
|
|
|
|
ADPCMDataProvider::ADPCMDataProvider( SeekableStream * _stream, const void * _clientData, const u32 _nbChannels,
|
|
const void * _dspadpcmL, const void * _dspadpcmR )
|
|
: AdpcmSoundStreamDataProvider( _nbChannels )
|
|
, m_stream( _stream )
|
|
, m_nextStream( NULL )
|
|
, m_clientData( _clientData )
|
|
, m_nextClientData( NULL )
|
|
, m_sampleSize( 0 )
|
|
, m_dspadpcmL( _dspadpcmL )
|
|
, m_dspadpcmR( _dspadpcmR )
|
|
{
|
|
RAKI_ASSERT( m_stream );
|
|
RAKI_ASSERT( _dspadpcmL );
|
|
|
|
DSPADPCM * dspadpcm = (DSPADPCM*)_dspadpcmL;
|
|
m_sampleSize = (u64)dspadpcm->num_samples;
|
|
}
|
|
|
|
|
|
|
|
|
|
const u64 ADPCMDataProvider::pullData( void * const _buffer, const u64 _sizeToRead )
|
|
{
|
|
RAKI_ASSERT( m_stream );
|
|
|
|
return m_stream->stream( _buffer, _sizeToRead );
|
|
}
|
|
|
|
|
|
const u64 ADPCMDataProvider::getRemainingByteSize() const
|
|
{
|
|
if ( m_stream )
|
|
{
|
|
u64 size = m_stream->getSize();
|
|
u64 position = m_stream->getCurrentPos();
|
|
|
|
RAKI_ASSERT( position <= size );
|
|
|
|
return ( size - position );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void ADPCMDataProvider::prefetchNextStream()
|
|
{
|
|
}
|
|
|
|
|
|
void ADPCMDataProvider::setNextStreamNow()
|
|
{
|
|
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;
|
|
}
|
|
|
|
m_isFirstBuffer = true;
|
|
}
|
|
|
|
|
|
const u64 ADPCMDataProvider::getEntireSampleSize() const
|
|
{
|
|
return m_sampleSize;
|
|
}
|
|
|
|
|
|
const u64 ADPCMDataProvider::getEntireByteSize() const
|
|
{
|
|
return m_stream ? m_stream->getSize() : 0;
|
|
}
|
|
|
|
|
|
void ADPCMDataProvider::setNextStream( SeekableStream * _nextStream, void * _nextClientData )
|
|
{
|
|
m_nextStream = _nextStream;
|
|
m_nextClientData = _nextClientData;
|
|
}
|
|
|
|
|
|
|
|
const u64 ADPCMDataProvider::getCurrentSamplePosition() const
|
|
{
|
|
u64 position = m_stream ? m_stream->getCurrentPos() : 0;
|
|
|
|
return 14 * position / ( m_dspadpcmR ? 16 : 8 );
|
|
}
|
|
|
|
|
|
const void * ADPCMDataProvider::getClientData() const
|
|
{
|
|
return m_clientData;
|
|
}
|
|
|
|
|
|
const void * ADPCMDataProvider::getDspadpcm( const u32 _channel ) const
|
|
{
|
|
switch( _channel )
|
|
{
|
|
case 0:
|
|
return m_dspadpcmL;
|
|
|
|
case 1:
|
|
return m_dspadpcmR;
|
|
|
|
default:
|
|
RAKI_ASSERT_FALSE;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void ADPCMDataProvider::update( bool /*_launchNewReadRequests*/ )
|
|
{
|
|
|
|
}
|
|
|
|
|
|
u64 ADPCMDataProvider::getByteBlockPosition( const u64 _startSamplePosition ) const
|
|
{
|
|
// ADPCM is 14 samples per 8 byte block
|
|
|
|
u64 adpcmBlockNumber = 0;
|
|
adpcmBlockNumber = _startSamplePosition / 14;
|
|
|
|
u64 bytePosition = adpcmBlockNumber * 8 * getNbChannels();
|
|
|
|
return bytePosition;
|
|
}
|
|
|
|
|
|
} // namespace raki
|
|
|