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

832 lines
30 KiB
C++

#include "Precompiled.h"
#include "RakiEngine/Data/MemoryBlock/MemoryBlock.h"
#include "RakiEngine/Data/Stream/MemoryStream/MemoryStream.h"
#include "RakiEngine/Data/Stream/SeekableStreamPart.h"
#include "RakiEngine/Data/Stream/AsyncReadStreamer.h"
#include "RakiEngine/Data/WaveFile/BinWaveData/BinWaveData.h"
#include "RakiEngine/Data/WaveFile/RiffChunkManager.h"
#include "RakiEngine/Sounds/Sequencer/Sequencer.h"
#include "RakiEngine/Sounds/Sequencer/SineNoteMemBlock.h"
#include "RakiEngine/Sounds/StreamBufferInfo.h"
#include "RakiEngine/Sounds/SoftwareEngine/StreamSoftwareSound.h"
#include "RakiEngine/System/Streaming/StreamingThread.h"
#include "RakiEngine/Utils/Calcs.h"
#include "RakiTests/Sounds/PCMDataProvider.h"
#include "RakiTests/Stream/ReadFileStream.h"
#include "RakiEngine/Utils/Calcs.h"
#if defined ( RAKI_USING_XAUDIO2 )
#include "RakiEngine/Sounds/_XAudio2/BufferSoundNative.h"
#include "RakiEngine/Sounds/_XAudio2/PCMStreamSoundNative.h"
#include "RakiEngine/Sounds/_XAudio2/XMA2StreamSoundNative_X360.h"
#include "RakiEngine/Specific/_XB360/Specific_X360.h"
#include "RakiTests/Sounds/XMA2DataProvider.h"
#elif defined ( RAKI_PLATFORM_PS3 )
#include <cell/mstream.h>
#include "RakiEngine/Sounds/_PS3/BufferSoundNative_PS3.h"
#include "RakiEngine/Sounds/_PS3/MP3StreamSoundNative_PS3.h"
#include "RakiTests/Sounds/MP3DataProvider.h"
#elif defined ( RAKI_PLATFORM_WII )
#include <revolution/vi.h>
#include "RakiTests/Sounds/ADPCMDataProvider_Wii.h"
#include "RakiEngine/Sounds/_Wii/BufferSoundNative_Wii.h"
#include "RakiEngine/Sounds/_Wii/ADPCMStreamSoundNative_Wii.h"
#include "RakiEngine/Sounds/_Wii/PCMStreamSoundNative_Wii.h"
#elif defined ( RAKI_PLATFORM_CAFE )
#include "RakiTests/Sounds/ADPCMDataProvider_Cafe.h"
#include "RakiEngine/Sounds/_Cafe/ADPCMStreamSoundNative_Cafe.h"
#include "RakiTests/_Cafe/Memory/SimpleHeap_Cafe.h"
#endif
#if defined ( RAKI_PLATFORM_WIN32 )
#include "RakiTests/_Win32/CoInitializeInitObject.h"
#endif // ( RAKI_PLATFORM_WIN32 )
#include "RakiTests/Initializer/TestInitializer.h"
namespace raki
{
extern void SystemAllocator_Initialize();
#if defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
#define BUFFER_PREFETCH_SIZE 55040
#else
#define BUFFER_PREFETCH_SIZE ( 2 * 0x10000 )
//#define BUFFER_PREFETCH_SIZE ( 2 * 0x1000 )
#endif
class SynchroStarter : public StreamBufferInfo::AudioCallbackStreamUpdateClient
{
public:
SynchroStarter()
: m_soundToStart( NULL ), m_sampleToStart( 0 )
{
}
void setData( Sound * _soundToStart, u64 _sampleToStart )
{
m_soundToStart = _soundToStart;
m_sampleToStart = _sampleToStart;
}
virtual void audioCallbackUpdateStreamPosition( const void * /*_clientData*/, const u64 _samplePosition )
{
#if defined ( RAKI_USING_SOFTWARE_ENGINE )
if ( m_soundToStart && ( _samplePosition + 1024 ) >= m_sampleToStart )
#elif defined ( RAKI_USING_XAUDIO2 ) // hum hum order :)
if ( m_soundToStart && ( _samplePosition + 1024 ) >= m_sampleToStart )
#elif defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
if ( m_soundToStart && ( _samplePosition + 96 ) >= m_sampleToStart )
#elif defined ( RAKI_PLATFORM_PS3 )
if ( m_soundToStart && ( _samplePosition + 512 ) >= m_sampleToStart )
#else
if ( m_soundToStart && _samplePosition >= m_sampleToStart )
#endif
{
RAKI_OUTPUT("audioCallbackUpdateStreamPosition calling m_soundToStart->startFromAudioCallback");
m_soundToStart->startFromAudioCallback();
m_soundToStart = NULL;
}
}
private:
Sound * m_soundToStart;
u64 m_sampleToStart;
};
void TestSynchroStreams( const char * _path1, const char * _path2, const u64 _sampleOffset );
void TestSynchroStreams( const char * _path1, const char * _path2, const u64 _sampleOffset )
{
StreamingThread streamingThread;
streamingThread.start();
ReadFileStream fileStream1, fileStream2;
bool opened = fileStream1.open( _path1 );
RAKI_ASSERT_WITH_MESSAGE( opened, "Invalid path1" );
BinWaveData binWaveData1( MemoryBlock::ms_nativeMemoryType );
bool readOK = binWaveData1.readOnlyHeader( &fileStream1 );
RAKI_ASSERT( readOK );
opened = fileStream2.open( _path2 );
RAKI_ASSERT_WITH_MESSAGE( opened, "Invalid path2" );
BinWaveData binWaveData2( MemoryBlock::ms_nativeMemoryType );
readOK = binWaveData2.readOnlyHeader( &fileStream2 );
RAKI_ASSERT( readOK );
SoundStreamDataProvider * dataProvider1 = NULL;
SoundStreamDataProvider * dataProvider2 = NULL;
SeekableStreamPart * seekableStreamPart1 = NULL;
SeekableStreamPart * seekableStreamPart2 = NULL;
AsyncReadStreamer * asyncReader1 = RAKI_NEW( AsyncReadStreamer );
AsyncReadStreamer * asyncReader2 = RAKI_NEW( AsyncReadStreamer );
SynchroStarter synchroStarter;
bool buffersAllocated = false;
#if defined ( RAKI_PLATFORM_WIN32 )
#if defined ( RAKI_USING_SOFTWARE_ENGINE )
StreamSoftwareSound pcmStreamSound1;
StreamSoftwareSound pcmStreamSound2;
#else
PCMStreamSoundNative pcmStreamSound1;
PCMStreamSoundNative pcmStreamSound2;
#endif
buffersAllocated = pcmStreamSound1.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
buffersAllocated = pcmStreamSound2.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
pcmStreamSound1.getStreamBufferInfo()->setAudioCallbackStreamUpdateClient( &synchroStarter );
synchroStarter.setData( &pcmStreamSound2, _sampleOffset );
#elif defined ( RAKI_PLATFORM_XB360 )
XMA2StreamSoundNative xma2StreamSound1, xma2StreamSound2;
buffersAllocated = xma2StreamSound1.allocateBuffers( 0x20000 );
RAKI_ASSERT( buffersAllocated );
buffersAllocated = xma2StreamSound2.allocateBuffers( 0x20000 );
RAKI_ASSERT( buffersAllocated );
xma2StreamSound1.getStreamBufferInfo()->setAudioCallbackStreamUpdateClient( &synchroStarter );
synchroStarter.setData( &xma2StreamSound2, _sampleOffset );
#elif defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
ADPCMDataProvider * adpcmDataProvider1 = NULL;
ADPCMDataProvider * adpcmDataProvider2 = NULL;
ADPCMStreamSoundNative adpcmStreamSound1( 2 );
ADPCMStreamSoundNative adpcmStreamSound2( 2 );
buffersAllocated = adpcmStreamSound1.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
buffersAllocated = adpcmStreamSound2.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
adpcmStreamSound1.getStreamBufferInfo()->setAudioCallbackStreamUpdateClient( &synchroStarter );
synchroStarter.setData( &adpcmStreamSound2, _sampleOffset );
#elif defined ( RAKI_PLATFORM_PS3 )
MP3StreamSoundNative mp3StreamSound1;
buffersAllocated = mp3StreamSound1.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
MP3StreamSoundNative mp3StreamSound2;
buffersAllocated = mp3StreamSound2.allocateBuffers( BUFFER_PREFETCH_SIZE );
RAKI_ASSERT( buffersAllocated );
mp3StreamSound1.getStreamBufferInfo()->setAudioCallbackStreamUpdateClient( &synchroStarter );
synchroStarter.setData( &mp3StreamSound2, _sampleOffset );
#endif
const bool isMusic = false;
const bool isLooping = false;
SoundParams soundParams( isMusic, isLooping );
WAVEFORMATEX * waveFormat = (WAVEFORMATEX*) binWaveData1.getChunkData( RiffChunkManager::ms_riffTagFmt );
u32 waveFormatSize = binWaveData1.getChunkSize( RiffChunkManager::ms_riffTagFmt );
RAKI_ASSERT( binWaveData1.isStreamed() );
u16 formatTag = waveFormat->wFormatTag;
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 <= 48000 );
bool create = adpcmStreamSound1.createVoice( &binWaveData1, soundParams );
RAKI_ASSERT( create );
seekableStreamPart1 = RAKI_NEW( SeekableStreamPart )( &fileStream1, binWaveData1.getDataOffset(), binWaveData1.getDataSize() );
asyncReader1->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader1->setStreamData( NULL, 0, seekableStreamPart1, NULL );
asyncReader1->setStreamingThread( &streamingThread );
u32 nbChannels = binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspR ) ? 2 : 1;
adpcmDataProvider1 = RAKI_NEW( ADPCMDataProvider )( asyncReader1, NULL, nbChannels, binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspL ), binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspR ) );
/*
const u64 seekSamplePosition1 = _sampleOffset;
const u64 seekBytePosition1 = adpcmDataProvider1->getByteBlockPosition( seekSamplePosition1 );
asyncReader1->seek( seekBytePosition1, SeekableStream::fromBeginning );
*/
adpcmStreamSound1.prepare( adpcmDataProvider1 );
adpcmStreamSound1.updateRouting( true );
create = adpcmStreamSound2.createVoice( &binWaveData2, soundParams );
RAKI_ASSERT( create );
seekableStreamPart2 = RAKI_NEW( SeekableStreamPart )( &fileStream2, binWaveData2.getDataOffset(), binWaveData2.getDataSize() );
asyncReader2->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader2->setStreamData( NULL, 0, seekableStreamPart2, NULL );
asyncReader2->setStreamingThread( &streamingThread );
nbChannels = binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspR ) ? 2 : 1;
adpcmDataProvider2 = RAKI_NEW( ADPCMDataProvider )( asyncReader2, NULL, nbChannels, binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspL ), binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspR ) );
const u64 seekSamplePosition2 = _sampleOffset;
const u64 seekBytePosition2 = adpcmDataProvider2->getByteBlockPosition( seekSamplePosition2 );
asyncReader2->seek( seekBytePosition2, SeekableStream::fromBeginning );
adpcmStreamSound2.prepare( adpcmDataProvider2 );
adpcmStreamSound2.updateRouting( true );
adpcmStreamSound2.pause();
adpcmStreamSound1.start();
bool isPlaying = adpcmStreamSound1.isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
#endif // RAKI_PLATFORM_WII
#if defined ( RAKI_PLATFORM_CAFE )
case WAVE_FORMAT_ADPCM:
{
RAKI_ASSERT( waveFormat->nChannels <= 2 );
RAKI_ASSERT( waveFormat->wBitsPerSample <= 16 );
RAKI_ASSERT( waveFormat->nSamplesPerSec <= 48000 );
bool create = adpcmStreamSound1.createVoice( &binWaveData1, soundParams );
RAKI_ASSERT( create );
seekableStreamPart1 = RAKI_NEW( SeekableStreamPart )( &fileStream1, binWaveData1.getDataOffset(), binWaveData1.getDataSize() );
asyncReader1->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader1->setStreamData( NULL, 0, seekableStreamPart1, NULL );
asyncReader1->setStreamingThread( &streamingThread );
const u32 nbChannels1 = binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspR ) ? 2 : 1;
RAKI_ASSERT( nbChannels1 == 2 ); // ADPCMStreamSoundNative adpcmStreamSound( 2 );
adpcmDataProvider1 = RAKI_NEW( ADPCMDataProvider )( asyncReader1, (void*)1, nbChannels1, true, binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspL ), binWaveData1.getChunkData( RiffChunkManager::ms_riffTagDspR ) );
const u64 seekSamplePosition1 = 0;
const u64 seekBytePosition1 = adpcmDataProvider1->getByteBlockPosition( seekSamplePosition1 );
asyncReader1->seek( seekBytePosition1, SeekableStream::fromBeginning );
adpcmStreamSound1.prepare( adpcmDataProvider1 );
adpcmStreamSound1.updateRouting( true );
create = adpcmStreamSound2.createVoice( &binWaveData2, soundParams );
RAKI_ASSERT( create );
seekableStreamPart2 = RAKI_NEW( SeekableStreamPart )( &fileStream2, binWaveData2.getDataOffset(), binWaveData2.getDataSize() );
asyncReader2->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader2->setStreamData( NULL, 0, seekableStreamPart2, NULL );
asyncReader2->setStreamingThread( &streamingThread );
const u32 nbChannels2 = binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspR ) ? 2 : 1;
RAKI_ASSERT( nbChannels2 == 2 ); // ADPCMStreamSoundNative adpcmStreamSound( 2 );
adpcmDataProvider2 = RAKI_NEW( ADPCMDataProvider )( asyncReader2, (void*)2, nbChannels2, true, binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspL ), binWaveData2.getChunkData( RiffChunkManager::ms_riffTagDspR ) );
const u64 seekSamplePosition2 = _sampleOffset;
const u64 seekBytePosition2 = adpcmDataProvider2->getByteBlockPosition( seekSamplePosition2 );
asyncReader2->seek( seekBytePosition2, SeekableStream::fromBeginning );
adpcmStreamSound2.prepare( adpcmDataProvider2 );
adpcmStreamSound2.updateRouting( true );
adpcmStreamSound2.pause();
adpcmStreamSound1.start();
bool isPlaying = adpcmStreamSound1.isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
#endif // RAKI_PLATFORM_CAFE
#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 <= 48000 );
bool create = pcmStreamSound1.createVoice( &binWaveData1, soundParams );
RAKI_ASSERT( create );
seekableStreamPart1 = RAKI_NEW( SeekableStreamPart )( &fileStream1, binWaveData1.getDataOffset(), binWaveData1.getDataSize() );
asyncReader1->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader1->setStreamData( NULL, 0, seekableStreamPart1, NULL );
dataProvider1 = RAKI_NEW( PCMDataProvider )( asyncReader1, (void*)1, (u64) pcmFormat.nBlockAlign, pcmFormat.nChannels, true );
asyncReader1->setStreamingThread( &streamingThread );
pcmStreamSound1.prepare( dataProvider1 );
pcmStreamSound1.updateRouting( true );
create = pcmStreamSound2.createVoice( &binWaveData2, soundParams );
RAKI_ASSERT( create );
seekableStreamPart2 = RAKI_NEW( SeekableStreamPart )( &fileStream2, binWaveData2.getDataOffset(), binWaveData2.getDataSize() );
asyncReader2->allocateBuffers( BUFFER_PREFETCH_SIZE );
asyncReader2->setStreamData( NULL, 0, seekableStreamPart2, NULL );
dataProvider2 = RAKI_NEW( PCMDataProvider )( asyncReader2, (void*)2, (u64) pcmFormat.nBlockAlign, pcmFormat.nChannels, true );
const u64 seekBytePosition2 = dataProvider2->getByteBlockPosition( _sampleOffset );
asyncReader2->seek( seekBytePosition2 , SeekableStream::fromBeginning );
asyncReader2->setStreamingThread( &streamingThread );
pcmStreamSound2.prepare( dataProvider2 );
pcmStreamSound2.updateRouting( true );
pcmStreamSound1.start();
bool isPlaying = pcmStreamSound1.isPlaying();
RAKI_ASSERT( isPlaying );
}
break;
#endif // defined ( RAKI_PLATFORM_WIN32 )
#if defined ( RAKI_PLATFORM_XB360 )
case WAVE_FORMAT_XMA2:
{
RAKI_ASSERT( waveFormatSize >= sizeof( XMA2WAVEFORMATEX ) );
bool create = xma2StreamSound1.createVoice( &binWaveData1, soundParams );
RAKI_ASSERT( create );
seekableStreamPart1 = RAKI_NEW( SeekableStreamPart )( &fileStream1, binWaveData1.getDataOffset(), binWaveData1.getDataSize() );
asyncReader1->allocateBuffers( BUFFER_PREFETCH_SIZE / 2 );
asyncReader1->setStreamData( NULL, 0, seekableStreamPart1, NULL );
u32 * seekTable1 = (u32*)binWaveData1.getChunkData( RiffChunkManager::ms_riffTagSeek );
u32 seekTableSize1 = binWaveData1.getChunkSize( RiffChunkManager::ms_riffTagSeek );
XMA2WAVEFORMATEX * xma2waveFormat = (XMA2WAVEFORMATEX *)waveFormat;
const u64 seekSamplePosition1 = 0;
dataProvider1 = RAKI_NEW( XMA2DataProvider )( asyncReader1, xma2waveFormat, seekTable1, seekTableSize1, 0, 0, 0, xma2waveFormat->wfx.nChannels, seekSamplePosition1 );
const u64 seekBytePosition1 = dataProvider1->getByteBlockPosition( seekSamplePosition1 );
const u64 playStartSamplePositionInBuffer1 = dataProvider1->getSampleOffsetInBuffer( seekBytePosition1, seekSamplePosition1 );
asyncReader1->seek( seekBytePosition1, SeekableStream::fromBeginning );
asyncReader1->setStreamingThread( &streamingThread );
xma2StreamSound1.prepare( dataProvider1, playStartSamplePositionInBuffer1 );
xma2StreamSound1.setDecibelVolume( 0.f );
xma2StreamSound1.updateRouting( true );
create = xma2StreamSound2.createVoice( &binWaveData2, soundParams );
RAKI_ASSERT( create );
seekableStreamPart2 = RAKI_NEW( SeekableStreamPart )( &fileStream2, binWaveData2.getDataOffset(), binWaveData2.getDataSize() );
asyncReader2->allocateBuffers( BUFFER_PREFETCH_SIZE / 2 );
asyncReader2->setStreamData( NULL, 0, seekableStreamPart2, NULL );
u32 * seekTable2 = (u32*)binWaveData2.getChunkData( RiffChunkManager::ms_riffTagSeek );
u32 seekTableSize2 = binWaveData2.getChunkSize( RiffChunkManager::ms_riffTagSeek );
const u64 seekSamplePosition2 = _sampleOffset;
dataProvider2 = RAKI_NEW( XMA2DataProvider )( asyncReader2, xma2waveFormat, seekTable2, seekTableSize2, 0, 0, 0, xma2waveFormat->wfx.nChannels, seekSamplePosition2 );
const u64 seekBytePosition2 = dataProvider2->getByteBlockPosition( seekSamplePosition2 );
const u64 playStartSamplePositionInBuffer2 = dataProvider2->getSampleOffsetInBuffer( seekBytePosition2, seekSamplePosition2 );
asyncReader2->seek( seekBytePosition2, SeekableStream::fromBeginning );
asyncReader2->setStreamingThread( &streamingThread );
xma2StreamSound2.prepare( dataProvider2, playStartSamplePositionInBuffer2 );
xma2StreamSound2.setDecibelVolume( 0.f );
xma2StreamSound2.updateRouting( true );
xma2StreamSound1.start();
}
break;
#endif // ( RAKI_PLATFORM_XB360 )
#if defined ( RAKI_PLATFORM_PS3 )
case WAVE_FORMAT_MPEGLAYER3:
{
/* void * mp3Data = waveFile.getChunkData( dataChunck );
unsigned int tSize = 0;
unsigned int offset = 0;
float tTime = 0.f;
while(1)
{
CellMSMP3FrameHeader header;
int ret = cellMSMP3GetFrameInfo( mp3Data, &header );
if ( ret == -1 )
{
printf("Invalid MP3 header\n");
printf("Offset=0x%x\n",offset);
break;
}
tSize += header.PacketSize; // Update total file size
if ((header.ID3==0)&&(header.Tag==0))
tTime+=header.PacketTime; // Update total playing time (in seconds)
mp3Data = (void*)( header.PacketSize + (u32)mp3Data ); // Move forward to next packet
offset+=header.PacketSize;
// ** Display packet information **
// Using the packet size and packet time information, it is possible to build "Seek Tables".
// Then, by knowing approximately what time (in seconds) you require to playback from,
// you can start playback from the closest data packet by searching for the closest record in the table.
if (header.ID3!=0)
{
printf("Found ID3 Info\n");
printf("Version: %x.%x\n",header.ID3>>8, header.ID3&255);
}
else if (header.Tag!=0)
{
printf("Found Tag info\n");
}
else
{
printf("Sync: 0x%x\n",header.Sync);
printf("ID: 0x%x\n",header.ID);
printf("Layer: 0x%x\n",header.Layer);
printf("ProtBit: 0x%x\n",header.ProtBit);
printf("BitRate: %d\n",header.BitRate);
printf("Frequency: %d\n",header.Frequency);
printf("PadBit: 0x%x\n",header.PadBit);
printf("PrivBit: 0x%x\n",header.PrivBit);
printf("Mode: 0x%x\n",header.Mode);
printf("Copy: 0x%x\n",header.Copy);
printf("Home: 0x%x\n",header.Home);
printf("Emphasis: 0x%x\n",header.Emphesis);
printf("Packet Time (secs): %f\n",header.PacketTime);
}
printf("Packet Size (bytes): 0x%x\n",header.PacketSize);
if ( tSize == waveFile.getChunkSize( dataChunck ) )
{
printf("MP3 File is valid.\n");
printf("Total Playback Time at %d Hz = (secs): %f\n",header.Frequency,tTime);
break;
}
else if (tSize > waveFile.getChunkSize( dataChunck ) )
{
break;
}
}
*/
bool create = mp3StreamSound1.createVoice( &binWaveData1, soundParams );
RAKI_ASSERT( create );
seekableStreamPart1 = RAKI_NEW( SeekableStreamPart )( &fileStream1, binWaveData1.getDataOffset(), binWaveData1.getDataSize() );
asyncReader1->allocateBuffers( BUFFER_PREFETCH_SIZE / 2 );
asyncReader1->setStreamData( NULL, 0, seekableStreamPart1, NULL );
asyncReader1->setStreamingThread( &streamingThread );
dataProvider1 = RAKI_NEW( MP3DataProvider )( asyncReader1, NULL, waveFormat->nChannels );
mp3StreamSound1.prepare( dataProvider1 );
mp3StreamSound1.updateRouting( true );
create = mp3StreamSound2.createVoice( &binWaveData2, soundParams );
RAKI_ASSERT( create );
seekableStreamPart2 = RAKI_NEW( SeekableStreamPart )( &fileStream2, binWaveData2.getDataOffset(), binWaveData2.getDataSize() );
asyncReader2->allocateBuffers( BUFFER_PREFETCH_SIZE / 2 );
asyncReader2->setStreamData( NULL, 0, seekableStreamPart2, NULL );
asyncReader2->setStreamingThread( &streamingThread );
dataProvider2 = RAKI_NEW( MP3DataProvider )( asyncReader2, NULL, waveFormat->nChannels );
const u64 seekSamplePosition2 = _sampleOffset;
const u64 seekBytePosition2 = dataProvider2->getByteBlockPosition( seekSamplePosition2 );
asyncReader2->seek( seekBytePosition2, SeekableStream::fromBeginning );
mp3StreamSound2.prepare( dataProvider2 );
mp3StreamSound2.updateRouting( true );
mp3StreamSound2.pause();
mp3StreamSound1.start();
}
break;
#endif // ( RAKI_PLATFORM_PS3 )
default:
RAKI_ASSERT_FALSE;
}
// #define COUNT_LOOP 50
// #define COUNT_STOP 20
// #define COUNT_START 34
int count = 0;
for ( ;; )
{
bool isPlaying = false;
#ifdef RAKI_PLATFORM_WII
VIWaitForRetrace();
#else // RAKI_PLATFORM_WII
Thread::sleep( 25 );
#endif // RAKI_PLATFORM_WII
#if defined ( RAKI_PLATFORM_WIN32 )
pcmStreamSound1.update();
pcmStreamSound2.update();
isPlaying |= pcmStreamSound1.isPlaying();
isPlaying |= pcmStreamSound2.isPlaying();
#elif defined ( RAKI_PLATFORM_XB360 )
xma2StreamSound1.update();
isPlaying |= xma2StreamSound1.isPlaying();
xma2StreamSound2.update();
isPlaying |= xma2StreamSound2.isPlaying();
#elif defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
adpcmStreamSound1.update();
isPlaying |= adpcmStreamSound1.isPlaying();
adpcmStreamSound2.update();
isPlaying |= adpcmStreamSound2.isPlaying();
#elif defined ( RAKI_PLATFORM_PS3 )
mp3StreamSound1.update();
isPlaying |= mp3StreamSound1.isPlaying();
mp3StreamSound2.update();
isPlaying |= mp3StreamSound2.isPlaying();
#endif
asyncReader1->update( true );
asyncReader2->update( true );
/*
if ( ( count % COUNT_LOOP ) == COUNT_STOP )
xma2StreamSound.stop();
if ( ( count % COUNT_LOOP ) == COUNT_START )
xma2StreamSound.play();
*/
++count;
if ( !isPlaying )
break;
}
#if defined ( RAKI_PLATFORM_WIN32 )
pcmStreamSound1.stop();
#elif defined ( RAKI_PLATFORM_XB360 )
xma2StreamSound1.stop();
xma2StreamSound2.stop();
#elif defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
adpcmStreamSound1.stop();
adpcmStreamSound2.stop();
#elif defined ( RAKI_PLATFORM_PS3 )
mp3StreamSound1.stop();
mp3StreamSound2.stop();
#endif
// XAudio2 doc: Stop is always asynchronous, even if called within a callback
Thread::sleep( 5000 );
#if defined ( RAKI_PLATFORM_WIN32 )
pcmStreamSound1.destroyVoice();
pcmStreamSound2.destroyVoice();
#elif defined ( RAKI_PLATFORM_XB360 )
xma2StreamSound1.destroyVoice();
xma2StreamSound2.destroyVoice();
#elif defined ( RAKI_PLATFORM_WII )
adpcmStreamSound1.destroyVoice();
adpcmStreamSound2.destroyVoice();
#elif defined ( RAKI_PLATFORM_PS3 )
mp3StreamSound1.destroyVoice();
mp3StreamSound2.destroyVoice();
#endif
Thread::sleep( 500 );
if ( asyncReader1 ) RAKI_DELETE( asyncReader1 );
asyncReader2 = NULL;
if ( asyncReader2 ) RAKI_DELETE( asyncReader2 );
asyncReader2 = NULL;
if ( seekableStreamPart1 ) RAKI_DELETE( seekableStreamPart1 );
seekableStreamPart1 = NULL;
if ( seekableStreamPart2 ) RAKI_DELETE( seekableStreamPart2 );
seekableStreamPart2 = NULL;
if ( dataProvider1 ) RAKI_DELETE( dataProvider1 );
dataProvider1 = NULL;
if ( dataProvider2 ) RAKI_DELETE( dataProvider2 );
dataProvider2 = NULL;
streamingThread.stop();
Thread::sleep( 500 );
}
} // namespace raki
#if defined ( RAKI_PLATFORM_CAFE )
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 run_demo (int intArg, void *ptrArg)
{
raki::SimpleHeap_Cafe::init();
raki::TestInitializer initializer;
const char path1[] = "/vol/content/_raki_/BeatsOnLeft.wav.cafe";
const char path2[] = "/vol/content/_raki_/BeatsOnRight.wav.cafe";
const raki::u64 sampleOffset = 123456;
raki::TestSynchroStreams( path1, path2, sampleOffset );
return 0;
}
#endif
#if defined ( RAKI_USING_XAUDIO2 )
int _tmain( int /*argc*/, _TCHAR* /*argv[]*/ )
#else // RAKI_USING_XAUDIO2
int main( int /*argc*/, char * /*argv[]*/ )
#endif // RAKI_USING_XAUDIO2
{
#if defined ( RAKI_PLATFORM_WII )
DVDInit();
VIInit();
raki::SystemAllocator_Initialize();
#elif defined ( RAKI_PLATFORM_WIN32 )
raki::CoInitializeInitObject coInitializeInitObject;
#elif defined ( RAKI_PLATFORM_CAFE )
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;
#endif
#if !defined ( RAKI_PLATFORM_CAFE )
const raki::u64 sampleOffset = 123456;
#if defined ( RAKI_PLATFORM_WIN32 )
const char path1[] = "Y:/JD5/JD/main/extern/Raki/TestData/BeatsOnLeft.wav.w32pcm";
const char path2[] = "Y:/JD5/JD/main/extern/Raki/TestData/BeatsOnRight.wav.w32pcm";
#elif defined ( RAKI_PLATFORM_XB360 )
const char path1[] = "game:\\BeatsOnLeft.wav.x360";
const char path2[] = "game:\\BeatsOnRight.wav.x360";
#elif defined ( RAKI_PLATFORM_PS3 )
const char path1[] = "/app_home/Y:/JD5/JD/main/extern/Raki/TestData/BeatsOnLeft.wav.ps3";
const char path2[] = "/app_home/Y:/JD5/JD/main/extern/Raki/TestData/BeatsOnRight.wav.ps3";
#elif defined ( RAKI_PLATFORM_WII )
const char path1[] = "_raki_/BeatsOnLeft.wav.wii";
const char path2[] = "_raki_/BeatsOnRight.wav.wii";
#endif
raki::TestInitializer initializer;
raki::TestSynchroStreams( path1, path2, sampleOffset );
return 0;
#endif // !defined ( RAKI_PLATFORM_CAFE )
}