JD2022-TU1/main/extern/Raki/Source/RakiTests/TestMTT/TestMTT.cpp

995 lines
No EOL
32 KiB
C++

#include "Precompiled.h"
#include "RakiEngine/Data/MemoryBlock/MemoryBlock.h"
#include "RakiEngine/Data/Serialization/Serializer.h"
#include "RakiEngine/Data/Serialization/SerializedObject.h"
#include "RakiEngine/Data/Stream/AsyncReadStreamer.h"
#include "RakiEngine/Data/Stream/MemoryStream/MemoryStream.h"
#include "RakiEngine/Data/Stream/SeekableStreamPart.h"
#include "RakiEngine/Data/Stream/Interleave/DeinterleaveStream.h"
#include "RakiEngine/Data/Stream/Interleave/Deinterleaver.h"
#include "RakiEngine/Data/Stream/Interleave/RegularTrackDeinterleaveStream.h"
#include "RakiEngine/Data/Stream/Interleave/RegularTrackDeinterleaver.h"
#include "RakiEngine/Data/Serialization/Serializer.h"
#include "RakiEngine/Data/WaveFile/DeinterleaveWaveData.h"
#include "RakiEngine/Data/WaveFile/RiffChunkManager.h"
#include "RakiEngine/Data/WaveFile/BinWaveData/BinWaveData.h"
#include "RakiEngine/Data/WaveFile/MTTConfigChunk.h"
#include "RakiEngine/Sounds/MTTSound.h"
#include "RakiEngine/Sounds/Sequencer/Sequencer.h"
#include "RakiEngine/Sounds/Sequencer/SineNoteMemBlock.h"
#include "RakiEngine/Sounds/StreamBufferInfo.h"
#include "RakiEngine/Sounds/SimpleStream/SimpleStreamSound.h"
#include "RakiEngine/System/Streaming/StreamingThread.h"
#include "RakiEngine/Utils/Calcs.h"
#include "RakiTests/Stream/ReadFileStream.h"
#include "RakiEngine/Utils/Calcs.h"
#include "RakiTests/Initializer/TestInitializer.h"
#include "RakiTests/Sounds/PCMDeinterleaveDataProvider.h"
#if defined ( RAKI_PLATFORM_WIN32 )
#include "RakiTests/_Win32/CoInitializeInitObject.h"
#endif // ( RAKI_PLATFORM_WIN32 )
#if defined ( RAKI_USING_XAUDIO2 )
#include "RakiEngine/Sounds/_XAudio2/BufferSoundNative.h"
#include "RakiEngine/Sounds/_XAudio2/PCMStreamSoundNative.h"
#elif defined ( RAKI_PLATFORM_PS3 )
#include <cell/mstream.h>
#include <sysutil/sysutil_common.h>
#include "RakiEngine/Sounds/_PS3/MP3StreamSoundNative_PS3.h"
#include "RakiTests/Sounds/MP3DataProvider.h"
#include "RakiTests/Sounds/MP3DeinterleaveDataProvider.h"
#elif defined ( RAKI_PLATFORM_WII )
#include <revolution/vi.h>
#include <revolution/pad.h>
#include "RakiEngine/Sounds/_Wii/BufferSoundNative_Wii.h"
#include <revolution/os.h>
#include <revolution/ax.h>
#include <revolution/mem.h>
#include <revolution/ai.h>
#include <revolution/dvd.h>
#include <revolution/vi.h>
#elif defined ( RAKI_PLATFORM_CAFE )
#include "RakiEngine/Sounds/_Cafe/ADPCMStreamSoundNative_Cafe.h"
#include "RakiTests/_Cafe/Memory/SimpleHeap_Cafe.h"
#include "RakiTests/Sounds/ADPCMDataProvider_Cafe.h"
#include "RakiTests/Sounds/ADPCMDeinterleaveDataProvider_Cafe.h"
#endif
#if defined ( RAKI_PLATFORM_XB360 )
#include "RakiEngine/Sounds/_XAudio2/XMA2StreamSoundNative_X360.h"
#include "RakiTests/Sounds/XMA2DataProvider.h"
#endif // defined ( RAKI_PLATFORM_XB360 )
#define TESTMTT_WITHOUT_PREFETCHBUFFER
#if defined ( RAKI_PLATFORM_XB360 )
#define BUFFER_PREFETCH_SIZE 0x10000
#elif defined ( RAKI_PLATFORM_WIN32 )
#define BUFFER_PREFETCH_SIZE ( 0x30000 )
#elif defined ( RAKI_PLATFORM_CAFE )
#define BUFFER_PREFETCH_SIZE ( 0x10000 )
#elif defined ( RAKI_PLATFORM_PS3 )
#define BUFFER_PREFETCH_SIZE ( 0x12000 )
#else // defined ( RAKI_PLATFORM_XB360 )
#define BUFFER_PREFETCH_SIZE 0x11800 // (0x8c) 140 and 128 aligned for ADPCM on Win32...
#endif // defined ( RAKI_PLATFORM_XB360 )
namespace raki
{
#if defined ( RAKI_PLATFORM_CAFE )
class ClientDeinterleaver : public RegularTrackDeinterleaver
{
public:
ClientDeinterleaver( SeekableStream * _seekabableStream, AsyncReadStreamer * _asyncReadStreamer, const u64 _interleaveBlockSize,
const u32 _nbChannels, const u32 _channelUsageFlags = 0xff )
: RegularTrackDeinterleaver( _asyncReadStreamer, _interleaveBlockSize, _nbChannels, _channelUsageFlags )
, m_seekabableStream( _seekabableStream )
, m_asyncReadStreamer( _asyncReadStreamer )
{
}
private:
virtual void clientPrefetchNextStream()
{
// looping test
m_seekabableStream->seekBeginning();
m_asyncReadStreamer->setStreamData( NULL, 0, m_seekabableStream, NULL );
}
virtual void clientSetNextStreamNow()
{
}
SeekableStream * m_seekabableStream;
AsyncReadStreamer * m_asyncReadStreamer;
};
#elif defined ( RAKI_PLATFORM_PS3 )
class ClientDeinterleaver : public RegularTrackDeinterleaver
{
public:
ClientDeinterleaver( SeekableStream * _seekabableStream, AsyncReadStreamer * _asyncReadStreamer, const u64 _interleaveBlockSize,
const u32 _nbTracks, const u32 _trackUsageFlags = 0xff )
: RegularTrackDeinterleaver( _asyncReadStreamer, _interleaveBlockSize, _nbTracks, _trackUsageFlags )
, m_seekabableStream( _seekabableStream )
, m_asyncReadStreamer( _asyncReadStreamer )
{
}
private:
virtual void clientPrefetchNextStream()
{
// looping test
m_seekabableStream->seekBeginning();
m_asyncReadStreamer->setStreamData( NULL, 0, m_seekabableStream, NULL );
}
virtual void clientSetNextStreamNow()
{
}
SeekableStream * m_seekabableStream;
AsyncReadStreamer * m_asyncReadStreamer;
};
#else // defined ( RAKI_PLATFORM_PS3 )
class ClientDeinterleaver : public Deinterleaver
{
public:
ClientDeinterleaver( SeekableStream * _seekabableStream, AsyncReadStreamer * _asyncReadStreamer, const u64 _interleaveBlockSize,
const char * _trackConfiguration, const u32 _trackUsageFlags = 0xff )
: Deinterleaver( _asyncReadStreamer, _interleaveBlockSize, _trackConfiguration, _trackUsageFlags )
, m_seekabableStream( _seekabableStream )
, m_asyncReadStreamer( _asyncReadStreamer )
{
}
private:
virtual void clientPrefetchNextStream()
{
// looping test
m_seekabableStream->seekBeginning();
m_asyncReadStreamer->setStreamData( NULL, 0, m_seekabableStream, NULL );
}
virtual void clientSetNextStreamNow()
{
}
SeekableStream * m_seekabableStream;
AsyncReadStreamer * m_asyncReadStreamer;
};
#endif // defined ( RAKI_PLATFORM_PS3 )
static bool TestMTT( const char * _path )
{
StreamingThread streamingThread;
streamingThread.start();
ReadFileStream fileStream;
RiffChunkManager::singleton().setShouldReadDataBlockForWaveData( false );
bool opened = fileStream.open( _path );
#if defined ( RAKI_PLATFORM_WIN32 )
#elif defined ( RAKI_PLATFORM_XB360 )
#elif defined ( RAKI_PLATFORM_PS3 )
#elif defined ( RAKI_PLATFORM_WII )
#endif
RAKI_ASSERT( opened );
BinWaveData binWaveData( MemoryBlock::ms_nativeMemoryType );
bool readOK = binWaveData.readOnlyHeader( &fileStream );
if ( !readOK )
return false;
AsyncReadStreamer asyncReadStreamer;
MTTSound * mttSound = NULL;
#if defined ( RAKI_PLATFORM_WIN32 )
SeekableStreamPart * seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, binWaveData.getDataOffset(), binWaveData.getDataSize() );
#elif defined ( RAKI_PLATFORM_XB360 )
SeekableStreamPart * seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, binWaveData.getDataOffset(), binWaveData.getDataSize() );
XMA2DataProvider * dataProvider = NULL;
#elif defined ( RAKI_PLATFORM_WII )
WiiAdpcmSoundStreamDataProvider * adpcmDataProvider = NULL;
ADPCMStreamSoundNative adpcmStreamSound( 2 );
adpcmStreamSound.getStreamBufferInfo()->setStreamUpdateClient( &testUpdateClient );
buffersAllocated = adpcmStreamSound.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
#elif defined ( RAKI_PLATFORM_PS3 )
SeekableStreamPart * seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, binWaveData.getDataOffset(), binWaveData.getDataSize() );
#elif defined ( RAKI_PLATFORM_CAFE )
SeekableStreamPart * seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, binWaveData.getDataOffset(), binWaveData.getDataSize() );
#endif
const bool isMusic = false;
const bool isLooping = true;
SoundParams soundParams( isMusic, isLooping );
WAVEFORMATEX * waveFormat = (WAVEFORMATEX*) binWaveData.getChunkData( RiffChunkManager::ms_riffTagFmt );
u32 waveFormatSize = binWaveData.getChunkSize( RiffChunkManager::ms_riffTagFmt );
RAKI_ASSERT( binWaveData.getChunkData( RiffChunkManager::ms_riffTagMTT ) );
MTTConfigChunk mttConfigChunk( binWaveData.getChunkData( RiffChunkManager::ms_riffTagMTT ), binWaveData.getChunkSize( RiffChunkManager::ms_riffTagMTT ) );
const u32 totalNbChannels = mttConfigChunk.getTotalNbChannels();
#if defined ( RAKI_PLATFORM_CAFE )
const u32 channelUsageFlags = 0xff;
#else
const u32 trackUsageFlags = 2;
const u32 totalNbTracks = mttConfigChunk.getNbTracks();
#endif // defined ( RAKI_PLATFORM_CAFE )
u16 formatTag = waveFormat->wFormatTag;
#if defined ( RAKI_PLATFORM_XB360 )
XMA2StreamSoundNative * xma2StreamSound = NULL;
#else
ClientDeinterleaver * deinterleaver = NULL;
#endif
switch ( formatTag )
{
#if defined ( RAKI_PLATFORM_WII )
case WAVE_FORMAT_ADPCM:
{
RAKI_ASSERT( waveFormat->nChannels <= 2 );
RAKI_ASSERT( waveFormat->wBitsPerSample <= 16 );
RAKI_ASSERT( waveFormat->nSamplesPerSec <= 50000 );
Format format( false );
#ifdef RAKI_PLATFORM_WII
format.setFormat( waveFormat );
#else // RAKI_PLATFORM_WII
format.setData( waveFormat, sizeof( WAVEFORMATEX ) );
#endif // RAKI_PLATFORM_WII
bool create = adpcmStreamSound.createVoice( &format );
RAKI_ASSERT( create );
seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, waveFile.getChunkOffsetInStream( dataChunck ),
waveFile.getChunkSize( dataChunck ) );
asyncReadStreamer->allocateBuffers( BUFFER_PREFETCH_SIZE );
u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer->setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer->setStreamData( dataBlock.getBuffer(), prefetchSize, seekableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer->setStreamingThread( &streamingThread );
const u32 nbChannels = waveFile.getChunkData( "dspR" ) ? 2 : 1;
adpcmDataProvider = RAKI_NEW( ADPCMDataProvider )( asyncReadStreamer, &clientData, nbChannels, waveFile.getChunkData( "dspL" ), waveFile.getChunkData( "dspR" ) );
// add second source
// dataProvider2 = RAKI_NEW( PCMDataProvider )( &dataStream2, &clientData2, (u64) pcmFormat.nBlockAlign );
// ( (PCMDataProvider*) dataProvider )->setNextStream( asyncReadStreamer, &clientData );
// ( (PCMDataProvider*) dataProvider2)->setNextStream( &dataStream2, &clientData2 );
adpcmStreamSound.prepare( adpcmDataProvider );
adpcmStreamSound.updateVolume( true );
adpcmStreamSound.start();
bool isPlaying = adpcmStreamSound.isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
#endif // RAKI_PLATFORM_WII
#if defined ( RAKI_PLATFORM_WIN32 )
case WAVE_FORMAT_PCM:
{
// hello bill...
WAVEFORMATEX pcmFormat = { 0 };
RAKI_ASSERT( waveFormatSize <= sizeof( WAVEFORMATEX ) );
memcpy( &pcmFormat, waveFormat, waveFormatSize );
pcmFormat.cbSize = 0;
RAKI_ASSERT( !( pcmFormat.nChannels % 2 ) );
RAKI_ASSERT( pcmFormat.wBitsPerSample <= 16 );
RAKI_ASSERT( pcmFormat.nSamplesPerSec <= 50000 );
RAKI_ASSERT( mttConfigChunk.getInterleaveBlockSize() );
RAKI_ASSERT( !( BUFFER_PREFETCH_SIZE % mttConfigChunk.getInterleaveBlockSize() ) );
RAKI_ASSERT( totalNbTracks > 1 );
deinterleaver = RAKI_NEW( ClientDeinterleaver )( seekableStreamPart, &asyncReadStreamer, mttConfigChunk.getInterleaveBlockSize(), mttConfigChunk.getMTTConfig(), trackUsageFlags );
mttSound = RAKI_NEW( MTTSound )( totalNbTracks );
for ( u32 track = 0 ; track < totalNbTracks ; ++track )
{
if ( ( 1 << track ) & trackUsageFlags )
{
DeinterleaveStream * deinterleaveStream = deinterleaver->getDeinterleaveStream( track );
const u32 nbChannelsForTrack = mttConfigChunk.getNbChannelsForTrack( track );
PCMStreamSoundNative * pcmStreamSound = RAKI_NEW( PCMStreamSoundNative );
pcmStreamSound->allocateBuffers( BUFFER_PREFETCH_SIZE * nbChannelsForTrack );
PCMDeinterleaveDataProvider * dataProvider = RAKI_NEW( PCMDeinterleaveDataProvider )( deinterleaver, deinterleaveStream, NULL, 2 * nbChannelsForTrack, nbChannelsForTrack, isLooping );
DeinterleaveWaveData * deinterleaveWaveData = RAKI_NEW( DeinterleaveWaveData )( &binWaveData, totalNbChannels, mttConfigChunk.getNbChannelsForTrack( track ) );
bool create = pcmStreamSound->createVoice( deinterleaveWaveData, soundParams );
RAKI_ASSERT( create );
pcmStreamSound->prepare( dataProvider );
mttSound->addTrack( pcmStreamSound, dataProvider );
}
}
RAKI_ASSERT( mttSound->getNbTracks() );
asyncReadStreamer.allocateBuffers( 2 * totalNbChannels * BUFFER_PREFETCH_SIZE ); // async read streamer buffers need to be able to read 2 times low level buffer sizes
// u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekabableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
mttSound->updateVolume( true );
mttSound->start();
bool isPlaying = mttSound->isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
/*
case WAVE_FORMAT_ADPCM:
{
RAKI_ASSERT( sizeof( ADPCMWAVEFORMAT ) <= binWaveData.getChunkSize( "fmt " ) );
ADPCMWAVEFORMAT * adpcmWaveFormat = (ADPCMWAVEFORMAT*)waveFormat;
RAKI_ASSERT( !( adpcmWaveFormat->wfx.nChannels % 2 ) );
RAKI_ASSERT( adpcmWaveFormat->wfx.wBitsPerSample <= 16 );
RAKI_ASSERT( adpcmWaveFormat->wfx.nSamplesPerSec <= 50000 );
RAKI_ASSERT( adpcmWaveFormat->wSamplesPerBlock );
RAKI_ASSERT( !( BUFFER_PREFETCH_SIZE % adpcmWaveFormat->wSamplesPerBlock ) );
const u32 nbTracks = waveFormat->nChannels / 2;
RAKI_ASSERT( nbTracks > 1 );
mttSound = RAKI_NEW( MTTSound )( nbTracks );
deinterleaver = RAKI_NEW( Deinterleaver )( &asyncReadStreamer, adpcmWaveFormat->wSamplesPerBlock, "22" );
for ( u32 track = 0 ; track < nbTracks ; ++track )
{
DeinterleaveStream * deinterleaveStream = deinterleaver->getDeinterleaveStream( track );
PCMStreamSoundNative * pcmStreamSound = RAKI_NEW( PCMStreamSoundNative );
pcmStreamSound->allocateBuffers( BUFFER_PREFETCH_SIZE );
PCMDeinterleaveDataProvider * dataProvider = RAKI_NEW( PCMDeinterleaveDataProvider )( deinterleaver, deinterleaveStream, NULL, 2, 2, isLooping );
DeinterleaveWaveData * deinterleaveWaveData = RAKI_NEW( DeinterleaveWaveData )( &binWaveData, totalNbChannels, mttConfigChunk.getNbChannelsForTrack( track ) );
bool create = pcmStreamSound->createVoice( deinterleaveWaveData, soundParams );
RAKI_ASSERT( create );
pcmStreamSound->prepare( dataProvider );
mttSound->addTrack( pcmStreamSound, dataProvider );
}
asyncReadStreamer.allocateBuffers( nbTracks * 2 * BUFFER_PREFETCH_SIZE );
// u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekabableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
mttSound->updateVolume( true );
mttSound->start();
bool isPlaying = mttSound->isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
*/
#endif // defined ( RAKI_PLATFORM_WIN32 )
#if defined ( RAKI_PLATFORM_XB360 )
case WAVE_FORMAT_XMA2:
{
RAKI_ASSERT( waveFormatSize >= sizeof( XMA2WAVEFORMATEX ) );
// MS HACK !!
XMA2WAVEFORMATEX * xma2waveFormat = (XMA2WAVEFORMATEX *)waveFormat;
xma2waveFormat->PlayBegin = xma2waveFormat->LoopBegin;
xma2waveFormat->PlayLength = xma2waveFormat->LoopLength;
xma2StreamSound = RAKI_NEW( XMA2StreamSoundNative );
xma2StreamSound->allocateBuffers( BUFFER_PREFETCH_SIZE - ( BUFFER_PREFETCH_SIZE % xma2waveFormat->BytesPerBlock ) );
bool create = xma2StreamSound->createVoice( &binWaveData, soundParams );
RAKI_ASSERT( create );
seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, binWaveData.getDataOffset(), binWaveData.getChunkSize( RiffChunkManager::ms_riffTagData ) );
asyncReadStreamer.allocateBuffers( 4 * 2 * BUFFER_PREFETCH_SIZE );
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
asyncReadStreamer->setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
u32 * seekTable = (u32*)binWaveData.getChunkData( RiffChunkManager::ms_riffTagSeek );
u32 seekTableSize = binWaveData.getChunkSize( RiffChunkManager::ms_riffTagSeek );
dataProvider = RAKI_NEW( XMA2DataProvider )( &asyncReadStreamer, xma2waveFormat, seekTable, seekTableSize, 0, 0, 0, xma2waveFormat->wfx.nChannels );
xma2StreamSound->prepare( dataProvider );
xma2StreamSound->updateVolume( true );
xma2StreamSound->start();
}
break;
#endif // ( RAKI_PLATFORM_XB360 )
#if defined ( RAKI_PLATFORM_PS3 )
case WAVE_FORMAT_MPEGLAYER3:
{
RAKI_ASSERT( !( BUFFER_PREFETCH_SIZE % mttConfigChunk.getInterleaveBlockSize() ) );
RAKI_ASSERT( totalNbTracks > 1 );
deinterleaver = RAKI_NEW( ClientDeinterleaver )( seekableStreamPart, &asyncReadStreamer, mttConfigChunk.getInterleaveBlockSize(), mttConfigChunk.getNbTracks(), trackUsageFlags );
mttSound = RAKI_NEW( MTTSound )( totalNbTracks );
for ( u32 track = 0 ; track < totalNbTracks ; ++track )
{
if ( ( 1 << track ) & trackUsageFlags )
{
RegularTrackDeinterleaveStream * deinterleaveStream = deinterleaver->getDeinterleaveStream( track );
const u32 nbChannelsForTrack = mttConfigChunk.getNbChannelsForTrack( track );
MP3StreamSoundNative * mp3StreamSound = RAKI_NEW( MP3StreamSoundNative );
mp3StreamSound->allocateBuffers( BUFFER_PREFETCH_SIZE ); // SAME BUFFER SIZE FOR MONO AND STEREO ON PS3/MP3 !!! * nbChannelsForTrack );
MP3DeinterleaveDataProvider * dataProvider = RAKI_NEW( MP3DeinterleaveDataProvider )( deinterleaver, deinterleaveStream, NULL, nbChannelsForTrack, isLooping );
DeinterleaveWaveData * deinterleaveWaveData = RAKI_NEW( DeinterleaveWaveData )( &binWaveData, totalNbChannels, mttConfigChunk.getNbChannelsForTrack( track ) );
bool create = mp3StreamSound->createVoice( deinterleaveWaveData, soundParams );
RAKI_ASSERT( create );
mp3StreamSound->prepare( dataProvider );
mttSound->addTrack( mp3StreamSound, dataProvider );
}
}
RAKI_ASSERT( mttSound->getNbTracks() );
asyncReadStreamer.allocateBuffers( 2 * totalNbTracks * BUFFER_PREFETCH_SIZE ); // async read streamer buffers need to be able to read 2 times low level buffer sizes
// u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekabableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
mttSound->updateVolume( true );
mttSound->start();
bool isPlaying = mttSound->isPlaying();
RAKI_ASSERT( isPlaying );
/*
RAKI_ASSERT( !( waveFormat->nChannels % 2 ) );
RAKI_ASSERT( waveFormat->wBitsPerSample <= 16 );
RAKI_ASSERT( waveFormat->nSamplesPerSec <= 50000 );
const u32 nbTracks = waveFormat->nChannels / 2;
RAKI_ASSERT( nbTracks > 1 );
mttSound = RAKI_NEW( MTTSound )( nbTracks );
u64 offset = 64 * nbTracks;
seekableStreamPart = RAKI_NEW( SeekableStreamPart )( &fileStream, offset + binWaveData.getDataOffset(), binWaveData.getDataSize() - offset );
deinterleaver = RAKI_NEW( ClientDeinterleaver )( 4 * BUFFER_PREFETCH_SIZE, 4, nbTracks, , &asyncReadStreamer, seekableStreamPart );
deinterleaver->setAsyncReadStreamer( &asyncReadStreamer );
for ( u32 track = 0 ; track < nbTracks ; ++track )
{
DeinterleaveStream * deinterleaveStream = deinterleaver->getDeinterleaveItem( track );
MP3StreamSoundNative * mp3StreamSound = RAKI_NEW( MP3StreamSoundNative );
mp3StreamSound->allocateBuffers( BUFFER_PREFETCH_SIZE );
MP3DeinterleaveDataProvider * dataProvider = RAKI_NEW( MP3DeinterleaveDataProvider )( deinterleaver, deinterleaveStream, NULL, 2, isLooping );
DeinterleaveWaveData * deinterleaveWaveData = RAKI_NEW( DeinterleaveWaveData )( &binWaveData );
bool create = mp3StreamSound->createVoice( deinterleaveWaveData, soundParams );
RAKI_ASSERT( create );
mp3StreamSound->prepare( dataProvider );
mttSound->addTrack( mp3StreamSound, dataProvider );
}
asyncReadStreamer.allocateBuffers( nbTracks * 2 * BUFFER_PREFETCH_SIZE );
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekabableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
mttSound->updateVolume( true );
mttSound->start();
bool isPlaying = mttSound->isPlaying();
RAKI_ASSERT( isPlaying );
*/
}
break;
#endif // ( RAKI_PLATFORM_PS3 )
#if defined ( RAKI_PLATFORM_CAFE )
case WAVE_FORMAT_ADPCM:
{
RAKI_ASSERT( !( BUFFER_PREFETCH_SIZE % mttConfigChunk.getInterleaveBlockSize() ) );
RAKI_ASSERT( mttConfigChunk.getTotalNbChannels() > 1 );
deinterleaver = RAKI_NEW( ClientDeinterleaver )( seekableStreamPart, &asyncReadStreamer, mttConfigChunk.getInterleaveBlockSize(), mttConfigChunk.getTotalNbChannels(), channelUsageFlags );
mttSound = RAKI_NEW( MTTSound )( mttConfigChunk.getTotalNbChannels() );
for ( u32 channel = 0 ; channel < mttConfigChunk.getTotalNbChannels() ; ++channel )
{
if ( ( 1 << channel ) & channelUsageFlags )
{
RegularTrackDeinterleaveStream * deinterleaveStream = deinterleaver->getDeinterleaveStream( channel );
ADPCMStreamSoundNative * streamSound = RAKI_NEW( ADPCMStreamSoundNative )( 1 );
streamSound->allocateBuffers( BUFFER_PREFETCH_SIZE );
AdpcmDeinterleaveDataProvider * dataProvider = RAKI_NEW( AdpcmDeinterleaveDataProvider )( deinterleaver, deinterleaveStream, NULL, 1, channel, isLooping,
(DSPADPCM*)binWaveData.getChunkData( RiffChunkManager::ms_riffTagDspM ) );
DeinterleaveWaveData * deinterleaveWaveData = RAKI_NEW( DeinterleaveWaveData )( &binWaveData, totalNbChannels, 1 );
bool create = streamSound->createVoice( deinterleaveWaveData, soundParams );
RAKI_ASSERT( create );
streamSound->prepare( dataProvider );
mttSound->addTrack( streamSound, dataProvider );
}
}
RAKI_ASSERT( mttSound->getNbTracks() );
asyncReadStreamer.allocateBuffers( 2 * totalNbChannels * BUFFER_PREFETCH_SIZE ); // async read streamer buffers need to be able to read 2 times low level buffer sizes
// u64 prefetchSize = dataBlock.getSize() > BUFFER_PREFETCH_SIZE ? BUFFER_PREFETCH_SIZE : dataBlock.getSize();
#ifdef TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( NULL, 0, seekableStreamPart, NULL );
#else // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamData( dataBlock.getBuffer(), BUFFER_PREFETCH_SIZE, seekabableStreamPart, NULL );
#endif // TESTMTT_WITHOUT_PREFETCHBUFFER
asyncReadStreamer.setStreamingThread( &streamingThread );
mttSound->updateVolume( true );
mttSound->start();
bool isPlaying = mttSound->isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
#endif // ( RAKI_PLATFORM_CAFE )
default:
RAKI_ASSERT_FALSE;
}
#define COUNT_LOOP 50
#define COUNT_STOP 20
#define COUNT_START 34
int count = 0;
#if defined ( RAKI_PLATFORM_XB360 )
//xma2StreamSound->setDecibelVolume( 0, -15.f );
xma2StreamSound->updateVolume();
#else // defined ( RAKI_PLATFORM_XB360 )
// guitar 0
// percussions 1
// violins 2
//mttSound->setDecibelVolume( 1, -15.f );
//mttSound->setDecibelVolume( 2, -15.f );
mttSound->updateVolume();
#endif // defined ( RAKI_PLATFORM_XB360 )
for ( ;; )
{
bool isPlaying = false;
#ifdef RAKI_PLATFORM_WII
VIWaitForRetrace();
#else // RAKI_PLATFORM_WII
Thread::sleep( 25 );
#endif // RAKI_PLATFORM_WII
#if defined ( RAKI_PLATFORM_XB360 )
xma2StreamSound->update();
dataProvider->update( true );
isPlaying |= xma2StreamSound->isPlaying();
#else // defined ( RAKI_PLATFORM_XB360 )
mttSound->update();
//deinterleaver->update();
isPlaying |= mttSound->isPlaying();
#endif // defined ( RAKI_PLATFORM_XB360 )
asyncReadStreamer.update( true );
++count;
if ( !isPlaying )
break;
}
#if defined ( RAKI_PLATFORM_XB360 )
xma2StreamSound->stop();
// XAudio2 doc: Stop is always asynchronous, even if called within a callback
Thread::sleep( 500 );
xma2StreamSound->destroyVoice();
Thread::sleep( 500 );
RAKI_DELETE( xma2StreamSound );
RAKI_DELETE( dataProvider );
#else // defined ( RAKI_PLATFORM_XB360 )
mttSound->stop();
Thread::sleep( 500 );
mttSound->destroyVoice();
Thread::sleep( 500 );
RAKI_DELETE( deinterleaver );
RAKI_DELETE( mttSound );
#endif // defined ( RAKI_PLATFORM_XB360 )
return true;
}
} // namespace raki
int rakimain()
{
#if defined ( RAKI_PLATFORM_WII )
DVDInit();
VIInit();
raki::SystemAllocator_Initialize();
#elif defined ( RAKI_PLATFORM_CAFE )
raki::SimpleHeap_Cafe::init();
#elif defined ( RAKI_PLATFORM_WIN32 )
raki::CoInitializeInitObject coInitializeInitObject;
#endif
raki::TestInitializer initializer;
#if defined ( RAKI_PLATFORM_WIN32 )
const char path[] = "../../../../TestData/MTTSineTest.wav.w32pcm";
#elif defined ( RAKI_PLATFORM_XB360 )
const char path[] = "game:\\MTT_6_short.wav.x360";
#elif defined ( RAKI_PLATFORM_PS3 )
const char path[] = "/app_home/E:/ITF/RO2/extern/Raki/TestData/MTTSineTest.wav.ps3";
#elif defined ( RAKI_PLATFORM_WII )
const char path_mono[] = "Sfx_ChangeCostume_01.wav.wii";
const char path_surroundTestL[] = "surroundTestL.wav.wii";
const char path_surroundTestR[] = "surroundTestR.wav.wii";
const char path_surroundTestBR[] = "surroundTestBR.wav.wii";
const char path_surroundTestBL[] = "surroundTestBL.wav.wii";
#elif defined ( RAKI_PLATFORM_CAFE )
//const char path[] = "MTTSineTest.wav.cafe";
const char path[] = "MTT_6.wav.cafe";
#endif
bool playedOK = raki::TestMTT( path );
if ( !playedOK )
return -1;
return 0;
}
#if defined ( RAKI_PLATFORM_CAFE )
int run_demo (int /*intArg*/, void */*ptrArg*/)
{
return rakimain();
}
u32 running_core;
u32 main_core;
u32 first_subcore;
u32 second_subcore;
u32 wait_main_core;
u32 wait_first_subcore;
u32 wait_second_subcore;
OSRendezvous rendezvous;
void
SetupCoreIds(void)
{
running_core = OSGetCoreId();
main_core = OSGetMainCoreId();
first_subcore = 0;
second_subcore = 2;
wait_main_core = OS_WAIT_CORE_MAIN;
wait_first_subcore = OS_WAIT_CORE_SUB1;
wait_second_subcore = OS_WAIT_CORE_SUB2;
if (main_core == 0)
{
first_subcore = 1;
second_subcore = 2;
wait_main_core = OS_WAIT_CORE_SUB1;
wait_first_subcore = OS_WAIT_CORE_MAIN;
wait_second_subcore = OS_WAIT_CORE_SUB2;
}
else
if (main_core == 2)
{
first_subcore = 0;
second_subcore = 1;
wait_main_core = OS_WAIT_CORE_SUB2;
wait_first_subcore = OS_WAIT_CORE_SUB1;
wait_second_subcore = OS_WAIT_CORE_MAIN;
}
}
int main( int /*argc*/, char * /*argv[]*/ )
{
u32 gx2InitAttribs[] =
{
GX2_INIT_ATTRIB_NULL // terminates the list
};
GX2Init(gx2InitAttribs);
// launch test on Core 0 if present
if (OSGetCoreCount() == 3)
{
OSThread* defaultThread0;
SetupCoreIds();
OSReport("Running Core == %d\n", running_core);
OSReport("OS Main Core == %d\n\n", main_core);
OSInitRendezvous(&rendezvous);
//
// Restart default thread on 1st subcore, core0
//
defaultThread0 = OSGetDefaultThread(first_subcore);
OSRunThread(defaultThread0,
run_demo,
0,
(void*) 0x23232323);
OSWaitRendezvous(&rendezvous, wait_first_subcore);
}
else
{
run_demo(0, NULL);
}
GX2Shutdown();
return 0;
}
#elif defined ( RAKI_USING_XAUDIO2 )
int _tmain(int /*argc*/, _TCHAR* /*argv[]*/)
{
rakimain();
return 0;
}
#else // RAKI_USING_XAUDIO2
int main( int /*argc*/, char * /*argv[]*/
{
rakimain();
return 0;
}
#endif // RAKI_USING_XAUDIO2