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

440 lines
11 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/Sources/SineSource.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/Specific/_XB360/Specific_X360.h"
#include "RakiTests/Sounds/XMA2DataProvider.h"
#include "RakiEngine/Mics/XMicManager_X360.h"
#elif defined ( RAKI_PLATFORM_PS3 )
#include "RakiEngine/Sounds/_PS3/PCMStreamSoundNative_PS3.h"
#include "RakiEngine/Mics/Mic_PS3.h"
#elif defined ( RAKI_PLATFORM_CAFE )
#include "RakiEngine/Mics/Mic_Cafe.h"
#include "RakiEngine/Sounds/_Cafe/PCMStreamSoundNative_Cafe.h"
#include "RakiTests/_Cafe/Memory/SimpleHeap_Cafe.h"
#elif defined ( RAKI_PLATFORM_ORBIS )
#include "RakiEngine/Mics/Mic_Orbis.h"
#endif
#if defined ( RAKI_PLATFORM_WIN32 )
#include "RakiTests/_Win32/CoInitializeInitObject.h"
#include "RakiEngine/Mics/MicWasapi.h"
#endif // ( RAKI_PLATFORM_WIN32 )
#include "RakiTests/Initializer/TestInitializer.h"
#define TESTSTREAMING_WITHOUT_PREFETCHBUFFER
namespace raki
{
class FakeMicWaveData : public WaveData
{
public:
FakeMicWaveData()
{
m_waveData.wFormatTag = WAVE_FORMAT_PCM;
m_waveData.nChannels = 1;
const u32 samplingRate = 16000; //RAKI_NATIVE_SAMPLING_RATE;
m_waveData.nSamplesPerSec = samplingRate;
m_waveData.nAvgBytesPerSec = m_waveData.nSamplesPerSec * 2;
m_waveData.nBlockAlign = 2;
m_waveData.wBitsPerSample = 16;
m_waveData.cbSize = 0;
}
virtual const void * getChunkData( const char * _name ) const
{
if ( RiffChunkManager::singleton().getTypeIdFromName( _name ) == RiffChunkManager::singleton().getTypeIdFromName( RiffChunkManager::ms_riffTagFmt ) )
return &m_waveData;
return NULL;
}
virtual u32 getChunkSize( const char * _name ) const
{
if ( RiffChunkManager::singleton().getTypeIdFromName( _name ) == RiffChunkManager::singleton().getTypeIdFromName( RiffChunkManager::ms_riffTagFmt ) )
return sizeof( m_waveData );
return 0;
}
virtual u32 getByteBlockPosForSamplePos( const u32 /*_samplePosition*/ ) const { RAKI_ASSERT_FALSE; return 0; }
virtual u32 getSamplePosForByteBlockPos( const u32 /*_byteBlockPosition*/ ) const { RAKI_ASSERT_FALSE; return 0; }
virtual u32 getSampleOffsetInBuffer( const u32 /*_byteBlockPosition*/, const u32 /*_samplePosition*/ ) const { RAKI_ASSERT_FALSE; return 0; }
private:
WAVEFORMATEX m_waveData;
};
class TestMicDataProvider : public SoundStreamDataProvider
{
public:
TestMicDataProvider( MicDataProvider * _micDataProvider, const u64 _sampleSize )
: m_micDataProvider( _micDataProvider )
, SoundStreamDataProvider( 1 ) // mono mic
, m_sineSource( 1 )
, m_sampleSize( _sampleSize )
, m_samplePos( 0 )
{
RAKI_ASSERT( _sampleSize > 0 )
}
virtual u64 pullData( void * _buffer, const u64 _sizeToRead ) //, bool /*_emergencyPull*/ )
{
u32 available = m_micDataProvider->getAvailableSampleSize(); // 16 kHz -> 48 kHz
if ( available > _sizeToRead / 2 )
{
u32 samplesRead = m_micDataProvider->pullSamples( _buffer, (u32)_sizeToRead / 2 );
RAKI_OUTPUT("MicDataProvider::pullData read %d samples", samplesRead);
}
else
{
// RAKI_OUTPUT("MicDataProvider::pullData unable to read any sample (available %d - size/2 %d)", available, _sizeToRead/2);
return 0;
}
return _sizeToRead;
// AudioBuffer buffer( AudioBuffer::pcm16, _buffer, _sizeToRead, 1 );
// return m_sineSource.pullSourceBuffer( buffer );
}
inline virtual u64 getRemainingByteSize() const { return ( m_sampleSize - m_samplePos ) * 2; }
inline virtual u64 getEntireByteSize() const { return m_sampleSize * 2; }
inline virtual u64 getEntireSampleSize() const { return m_sampleSize - m_samplePos; }
inline virtual u64 getCurrentSamplePosition() const { return m_samplePos; }
virtual const void * getClientData() const { return NULL; }
virtual bool isReadyToStart() const { return true; }
virtual u64 getByteBlockPosition( const u64 _startSamplePosition ) const { return _startSamplePosition * 2; }
virtual u64 getSampleOffsetInBuffer( const u64 /*_byteBlockPosition*/, const u64 /*_samplePosition*/ ) const { RAKI_ASSERT_FALSE; return 0; }
virtual bool isFirstBuffer( const u64 _samplePositionBeforeSubmit ) const { return _samplePositionBeforeSubmit == 0; }
virtual void prefetchNextStream(){}
virtual void setNextStreamNow(){}
virtual void update( bool /*_launchNewReadRequests*/ )
{
}
private:
MicDataProvider * m_micDataProvider;
SineSource m_sineSource;
u64 m_samplePos;
u64 m_sampleSize;
};
extern void SystemAllocator_Initialize();
#if defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE )
#define BUFFER_SIZE 55040
#else
#define BUFFER_SIZE 4608
#endif
static void TestSoundStreaming()
{
#if defined ( RAKI_PLATFORM_XB360 )
XMicManager mic;
#elif defined ( RAKI_PLATFORM_WIN32 )
MicWasapi mic( 16000 );
#elif defined ( RAKI_PLATFORM_CAFE )
MicCafe mic;
#elif defined ( RAKI_PLATFORM_PS3 )
MicPS3 mic( 16000 );
#endif
mic.init();
mic.startMicrophone();
TestMicDataProvider testMicDataProvider( &mic, 0x100000000 );
FakeMicWaveData fakeMicWaveData;
bool buffersAllocated = false;
#if defined ( RAKI_PLATFORM_WIN32 )
#if defined ( RAKI_USING_SOFTWARE_ENGINE )
StreamSoftwareSound sound;
#else
PCMStreamSoundNative sound;
#endif
// pcmStreamSound.getStreamBufferInfo()->setStreamUpdateClient( &testUpdateClient );
buffersAllocated = sound.allocateBuffers( BUFFER_SIZE );
RAKI_ASSERT( buffersAllocated );
#elif defined ( RAKI_PLATFORM_XB360 )
PCMStreamSoundNative sound;
// xma2StreamSound.getStreamBufferInfo()->setStreamUpdateClient( &testUpdateClient );
buffersAllocated = sound.allocateBuffers( BUFFER_SIZE );
RAKI_ASSERT( buffersAllocated );
#elif defined ( RAKI_PLATFORM_WII )
ADPCMStreamSoundNative adpcmStreamSound( 2 );
// adpcmStreamSound.getStreamBufferInfo()->setStreamUpdateClient( &testUpdateClient );
buffersAllocated = adpcmStreamSound.allocateBuffers( BUFFER_SIZE );
RAKI_ASSERT( buffersAllocated );
#elif defined ( RAKI_PLATFORM_CAFE )
PCMStreamSoundNative sound( 2 );
buffersAllocated = sound.allocateBuffers( BUFFER_SIZE );
RAKI_ASSERT( buffersAllocated );
#elif defined ( RAKI_PLATFORM_PS3 )
PCMStreamSoundNative sound;
buffersAllocated = sound.allocateBuffers( BUFFER_SIZE );
RAKI_ASSERT( buffersAllocated );
#endif
SoundParams soundParams;
bool create = sound.createVoice( &fakeMicWaveData, soundParams );
RAKI_ASSERT( create );
sound.prepare( &testMicDataProvider );
sound.updateRouting( true );
sound.start();
bool isPlaying = sound.isPlaying();
RAKI_ASSERT( isPlaying );
#define COUNT_LOOP 50
#define COUNT_STOP 20
#define COUNT_START 34
int count = 0;
const u32 bufferSampleSize = 2400;
void * tempBuffer = Memory::malloc( bufferSampleSize * 2, Memory::engine );
f32 timeBeginning = Time::getTime();
while ( Time::getTime() < 5000.f + timeBeginning )
{
bool isPlaying = false;
mic.update();
// if ( bufferSampleSize < micManager.getAvailableSampleSize() )
// micManager.pullSamples( tempBuffer, bufferSampleSize );
#ifdef RAKI_PLATFORM_WII
VIWaitForRetrace();
#else // RAKI_PLATFORM_WII
Thread::sleep( 15 );
#endif // RAKI_PLATFORM_WII
sound.update();
isPlaying |= sound.isPlaying();
testMicDataProvider.update( true );
++count;
// if ( !isPlaying )
// break;
}
sound.stop();
mic.stopMicrophone();
mic.uninit();
// XAudio2 doc: Stop is always asynchronous, even if called within a callback
Thread::sleep( 500 );
sound.destroyVoice();
Thread::sleep( 500 );
Memory::free( tempBuffer );
}
} // 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;
raki::TestSoundStreaming();
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 )
raki::TestInitializer initializer;
raki::TestSoundStreaming();
return 0;
#endif // !defined ( RAKI_PLATFORM_CAFE )
}