#pragma once #include "Inc/Engine.h" #include "Core/AudioDevice.h" #include "Util/CommandQueue.h" #include "Util/Memory.h" #include "Util/PerformanceTimer.h" #include "Util/String.h" #include "Util/DynamicArray.h" #include "Util/Dictionary.h" #include "Util/MultiDictionary.h" #include "Util/Event.h" #include "Util/Thread.h" #include "Util/Mutex.h" #include "Util/OutputConsoleStream.h" #include "Util/OutputFileStream.h" #include "Util/TextWriter.h" #include "SynthFactory.h" class OutputConsoleFileStream : public Util::IOutputStream { public: OutputConsoleFileStream( ) { } OutputConsoleFileStream( const Util::String& fileName ) : _file( fileName ) { } inline void Open( const Util::String& fileName ) { _file.Open( fileName ); } inline void Close( ) { _file.Close( ); } inline sizeptr WriteBytes( void* addr, sizeptr size ) { _console.WriteBytes( addr, size ); return _file.WriteBytes( addr, size ); } inline sizeptr SeekToPosition( sizeptr position ) { _console.SeekToPosition( position ); return _file.SeekToPosition( position ); } inline sizeptr SeekToOffset( sizeptr offset ) { _console.SeekToOffset( offset ); return _file.SeekToOffset( offset ); } inline sizeptr GetPosition( ) { return _file.GetPosition( ); } private: Util::OutputConsoleStream _console; Util::OutputFileStream _file; }; typedef AudioDevice< AudioChannel< Soundwich::DefaultFrameSize, Soundwich::DefaultSampleRate >, 4 > DefaultAudioDevice; class Soundwich::Engine::Impl : public IRenderAudioCallback { friend class SynthFactory; friend class InternalShutdownCommand; friend class InternalDestroySynthCommand; friend class InternalActivateSynthCommand; friend class InternalDeactivateSynthCommand; friend class InternalSetEventInCommand; friend class InternalSetEventInWithIdCommand; friend class InternalSetControlInCommand; friend class InternalSetSwitchInCommand; friend class ExternalDestroySynthCommand; friend class ExternalSetEventOutCommand; friend class ExternalSetControlOutCommand; friend class ExternalSetSwitchOutCommand; friend class ExternalSetMonoOutCommand; private: typedef Util::DynamicArray< Synth* > SynthArray; typedef Util::StringDictionary< Synth* > SynthDictionary; private: // Factory methods static SoundResult Create( uint32 tickFPS, Engine** engine ); static SoundResult Destroy( Engine* engine ); public: inline void * operator new(size_t size) { return Util::Alloc( size ); } inline void operator delete(void* memory) { Util::Free( memory ); } Impl( ); virtual ~Impl( ); // Start the AudioDevice and Processing threads (if threaded) SoundResult Run( ); // IClientSystem static void SetClientSystem( IClientSystem* clientSystem ); static IClientSystem* GetClientSystem( ); // Data Path SoundResult SetDataPath( const Util::String& dataPath ); // // Immediate Methods // // Synths SoundResult CreateSynthFromXmlFile( const Util::String& name, Soundwich::Synth** synth, const Util::String& fileName ); SoundResult CreateSynthFromMemory( const Util::String& name, Soundwich::Synth** synth, void* data, uint32 size ); SoundResult CreateSynthFromXmlMemory( const Util::String& name, Soundwich::Synth** synth, const Util::String& xml ); SoundResult SaveSynthToFile( Soundwich::Synth* synth, const Util::String& fileName ); SoundResult SaveSynthToXmlFile( Soundwich::Synth* synth, const Util::String& fileName ); SoundResult DestroySynth( Synth* synth ); SoundResult ActivateSynth( Synth* synth ); SoundResult DeactivateSynth( Synth* synth ); // Accessors SoundResult GetSynth( const Util::String& name, Synth** synth ); SoundResult GetEventInComponent( Synth* synth, const Util::String& componentName, EventIn** eventIn ); SoundResult GetEventInWithIdComponent( Synth* synth, const Util::String& componentName, EventInWithId** eventIn ); SoundResult GetControlInComponent( Synth* synth, const Util::String& componentName, ControlIn** controlIn ); SoundResult GetSwitchInComponent( Synth* synth, const Util::String& componentName, SwitchIn** switchIn ); SoundResult GetEventOutComponent( Synth* synth, const Util::String& componentName, EventOut** eventOut ); SoundResult GetControlOutComponent( Synth* synth, const Util::String& componentName, ControlOut** controlOut ); SoundResult GetSwitchOutComponent( Synth* synth, const Util::String& componentName, SwitchOut** switchOut ); // Tick SoundResult Tick( ); // Interface Controls SoundResult SetEventIn( EventIn* eventIn ); SoundResult SetEventInWithId( EventInWithId* eventIn, int32 val ); SoundResult SetControlIn( ControlIn* controlIn, flt32 val ); SoundResult SetSwitchIn( SwitchIn* switchIn, int32 val ); // Debugging SoundResult GetComponent( Synth* synth, const Util::String& componentName, Component** component ); SoundResult SwitchTracking( Soundwich::Synth* synth, bool enable, const char* exportFilePath); SoundResult SetSynthDebugLogging( Synth* synth, bool enable ); SoundResult SetComponentDebugLogging( Component* component, bool enable ); SoundResult SetConnectionDebugLogging( Connection* connection, bool enable ); // Callbacks SoundResult RegisterEventOutCallback( IEventOutCallback* cb, EventOut* eventOut ); SoundResult RegisterControlOutCallback( IControlOutCallback* cb, ControlOut* controlOut ); SoundResult RegisterSwitchOutCallback( ISwitchOutCallback* cb, SwitchOut* switchOut ); SoundResult RegisterJustDancePlayMenuMusicCallback( IJustDancePlayMenuMusicCallback* cb ); SoundResult RegisterJustDanceStopMenuMusicCallback( IJustDanceStopMenuMusicCallback* cb ); SoundResult RegisterJustDanceSoundEffectCallback( IJustDanceSoundEffectCallback* cb ); SoundResult RegisterJustDanceSoundEffectOnTrackTransitionCallback( IJustDanceSoundEffectOnTrackTransitionCallback* cb ); SoundResult RegisterJustDanceRemoteSoundEffectCallback( IJustDanceRemoteSoundEffectCallback* cb ); SoundResult RegisterJustDancePlayEventBusMusicCallback( IJustDancePlayEventBusMusicCallback* cb ); SoundResult RegisterJustDanceStopEventBusMusicCallback( IJustDanceStopEventBusMusicCallback* cb ); SoundResult RegisterJustDanceStopAllEventBusMixesCallback(IJustDanceStopAllEventBusMixesCallback* cb); SoundResult RegisterJustDancePlayMusicMultiTrackCallback( IJustDancePlayMusicMultiTrackCallback* cb ); SoundResult RegisterSoundwichTrackingCallback(ISoundwichTracking* cb); SoundResult UnregisterEventOutCallback( IEventOutCallback* cb, EventOut* eventOut ); SoundResult UnregisterControlOutCallback( IControlOutCallback* cb, ControlOut* controlOut ); SoundResult UnregisterSwitchOutCallback( ISwitchOutCallback* cb, SwitchOut* switchOut ); SoundResult UnregisterJustDancePlayMenuMusicCallback( IJustDancePlayMenuMusicCallback* cb ); SoundResult UnregisterJustDanceStopMenuMusicCallback( IJustDanceStopMenuMusicCallback* cb ); SoundResult UnregisterJustDanceSoundEffectCallback( IJustDanceSoundEffectCallback* cb ); SoundResult UnregisterJustDanceSoundEffectOnTrackTransitionCallback( IJustDanceSoundEffectOnTrackTransitionCallback* cb ); SoundResult UnregisterJustDanceRemoteSoundEffectCallback( IJustDanceRemoteSoundEffectCallback* cb ); SoundResult UnregisterJustDancePlayEventBusMusicCallback( IJustDancePlayEventBusMusicCallback* cb ); SoundResult UnregisterJustDanceStopEventBusMusicCallback( IJustDanceStopEventBusMusicCallback* cb ); SoundResult UnregisterJustDanceStopAllEventBusMixesCallback(IJustDanceStopAllEventBusMixesCallback* cb); SoundResult UnregisterJustDancePlayMusicMultiTrackCallback( IJustDancePlayMusicMultiTrackCallback* cb ); SoundResult UnregisterSoundwichTrackingCallback(ISoundwichTracking* cb); // // Internal Methods // void SetEventOut( EventOut* eventOut ); void SetControlOut( ControlOut* controlOut, flt32 val ); void SetSwitchOut( SwitchOut* switchOut, int32 val ); private: // Processing Thread methods static void StartInternalProcessing( void* data ); void InternalProcessingLoop( ); void InternalShutdown( ); // Synths void InternalDestroySynth( Synth* synth ); void InternalActivateSynth( Synth* synth ); void InternalDeactivateSynth( Synth* synth ); // Tick the system void InternalTick( ); // Interface Controls void InternalSetEventIn( EventIn* eventIn ); void InternalSetEventInWithId( EventInWithId* eventIn, int32 val ); void InternalSetControlIn( ControlIn* controlIn, flt32 val ); void InternalSetSwitchIn( SwitchIn* switchIn, int32 val ); // // External Methods // // Synths void ExternalDestroySynth( Synth* synth ); // Interface Controls void ExternalSetEventOut( EventOut* eventOut ); void ExternalSetControlOut( ControlOut* controlOut, flt32 val ); void ExternalSetSwitchOut( SwitchOut* switchOut, int32 val ); // Rendering Thread private: void RenderAudio( ); public: Util::String& GetDataPath( ) { return _dataPath; } void GetStats( Engine::Stats& stats ); public: inline DefaultAudioDevice* GetAudioDevice( ) { return _audioDevice; } inline SynthFactory& GetFactory( ) { return *_synthFactory; } inline Util::TextWriter& GetLog( ) { return _logWriter; } private: DefaultAudioDevice* _audioDevice; #if defined( USE_PROCESSING_THREAD ) Util::Thread _processThread; volatile bool _processing; Util::Event _processThreadTickEvent; #endif Util::PerformanceTimer _systemTimer; Util::String _dataPath; SynthFactory* _synthFactory; #if defined( USE_DEFERRED_COMMANDS ) Util::CommandQueue _sendCommands; Util::CommandQueue _returnCommands; #endif SynthArray _ticking; #if defined( USE_NATIVE_AUDIO ) SynthArray _rendering; #if defined( USE_PROCESSING_THREAD ) Util::Mutex _renderLock; #endif #endif SynthDictionary _synths; #if defined( USE_PROCESSING_THREAD ) Util::Mutex _synthsLock; #endif OutputConsoleFileStream _logStream; Util::TextWriter _logWriter; static IClientSystem* _clientSystem; };