1068 lines
23 KiB
C++
1068 lines
23 KiB
C++
#include "EngineImpl.h"
|
|
#include "Synth.h"
|
|
#include "Components/External/Events/EventIn.h"
|
|
#include "Components/External/Events/EventInWithId.h"
|
|
#include "Components/External/Events/EventOut.h"
|
|
#include "Components/External/Controls/ControlIn.h"
|
|
#include "Components/External/Controls/ControlOut.h"
|
|
#include "Components/External/Switches/SwitchIn.h"
|
|
#include "Components/External/Switches/SwitchOut.h"
|
|
#include "Components/JustDance/PlayMenuMusic.h"
|
|
#include "Components/JustDance/StopMenuMusic.h"
|
|
#include "Components/JustDance/JDSound.h"
|
|
#include "Components/JustDance/JDSoundSyncOnTransition.h"
|
|
#include "Components/JustDance/JDRemoteSound.h"
|
|
#include "Components/JustDance/PlayEventBusMusic.h"
|
|
#include "Components/JustDance/StopEventBusMusic.h"
|
|
#include "Components/JustDance/StopAllEventBusMixes.h"
|
|
#include "Components/JustDance/PlayMusicMultiTrack.h"
|
|
#include "Commands.h"
|
|
#include "Inc/Defs.h"
|
|
#include "Util/Logger.h"
|
|
#include "Util/Directory.h"
|
|
#include "Util/StringHash.h"
|
|
|
|
|
|
Soundwich::IClientSystem* Soundwich::Engine::Impl::_clientSystem = nullptr;
|
|
|
|
Soundwich::Engine::Impl::Impl( )
|
|
: _audioDevice( nullptr )
|
|
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
, _processing( false )
|
|
#endif
|
|
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
, _sendCommands( 256 )
|
|
, _returnCommands( 64 )
|
|
#endif
|
|
|
|
, _logWriter( _logStream )
|
|
{
|
|
_synthFactory = new SynthFactory( this );
|
|
|
|
_logStream.Open( Util::Directory::GetCurrent( ) + "log.txt" );
|
|
|
|
LOG_INFO( GetLog( ), "Initialize Soundwich engine" );
|
|
}
|
|
|
|
Soundwich::Engine::Impl::~Impl( )
|
|
{
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
// signal process thread to finish
|
|
|
|
_processing = false;
|
|
|
|
// wake it up if it is asleep waiting for a tick
|
|
|
|
_processThreadTickEvent.Signal( );
|
|
|
|
// wait for it to finish
|
|
|
|
_processThread.Join( );
|
|
|
|
#endif
|
|
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
// discard pending return commands
|
|
|
|
_returnCommands.Clear( );
|
|
|
|
#endif
|
|
|
|
// release the audio device (ensures rendering has stopped)
|
|
|
|
DefaultAudioDevice::Release( _audioDevice );
|
|
|
|
// destroy synths
|
|
|
|
for( SynthDictionary::Iterator it = _synths.Begin( ); it != _synths.End( ); )
|
|
{
|
|
Synth* synth = it->second;
|
|
|
|
_synths.Erase( it++ );
|
|
|
|
delete synth;
|
|
}
|
|
|
|
delete _synthFactory;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::Run( )
|
|
{
|
|
#if defined( USE_NATIVE_AUDIO )
|
|
|
|
// create the audio device
|
|
|
|
SoundResult result = DefaultAudioDevice::Create( &_audioDevice, this ) ? Ok : Error;
|
|
|
|
#else
|
|
|
|
SoundResult result = Ok;
|
|
|
|
#endif
|
|
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
if( result == Ok )
|
|
{
|
|
// start the processing thread
|
|
|
|
_processThread.Start( Engine::Impl::StartInternalProcessing, this );
|
|
}
|
|
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::SetClientSystem( Soundwich::IClientSystem* clientSystem )
|
|
{
|
|
_clientSystem = clientSystem;
|
|
}
|
|
|
|
Soundwich::IClientSystem* Soundwich::Engine::Impl::GetClientSystem( )
|
|
{
|
|
AssertMessage( _clientSystem, "Client system is null" );
|
|
|
|
return _clientSystem;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetDataPath( const Util::String& dataPath )
|
|
{
|
|
_dataPath = dataPath;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::CreateSynthFromXmlFile( const Util::String& name, Soundwich::Synth** synth, const Util::String& fileName )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
*synth = new Synth( this, name );
|
|
|
|
result = (*synth)->LoadFromXmlFile( ( _dataPath + "\\" + fileName + ".xws" ).Chars( ) );
|
|
|
|
if( result == Ok )
|
|
{
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
Util::AutoLock lock ( _synthsLock );
|
|
|
|
#endif
|
|
|
|
_synths.Add( name, *synth );
|
|
}
|
|
else
|
|
{
|
|
delete *synth;
|
|
|
|
*synth = nullptr;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::CreateSynthFromMemory( const Util::String& name, Soundwich::Synth** synth, void* data, uint32 size )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
*synth = new Synth( this, name );
|
|
|
|
result = (*synth)->LoadFromMemory( data, size );
|
|
|
|
if( result == Ok )
|
|
{
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
Util::AutoLock lock ( _synthsLock );
|
|
|
|
#endif
|
|
|
|
_synths.Add( name, *synth );
|
|
}
|
|
else
|
|
{
|
|
delete *synth;
|
|
|
|
*synth = nullptr;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::CreateSynthFromXmlMemory( const Util::String& name, Soundwich::Synth** synth, const Util::String& xml )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
*synth = new Synth( this, name );
|
|
|
|
result = (*synth)->LoadFromXmlMemory( xml );
|
|
|
|
if( result == Ok )
|
|
{
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
Util::AutoLock lock ( _synthsLock );
|
|
|
|
#endif
|
|
|
|
_synths.Add( name, *synth );
|
|
}
|
|
else
|
|
{
|
|
delete *synth;
|
|
|
|
*synth = nullptr;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SaveSynthToFile( Soundwich::Synth* synth, const Util::String& fileName )
|
|
{
|
|
AssertMessage( synth, "Synth is null" );
|
|
|
|
return synth->SaveToFile( ( _dataPath + "\\" + fileName + ".bws" ).Chars( ) );
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SaveSynthToXmlFile( Soundwich::Synth* synth, const Util::String& fileName )
|
|
{
|
|
AssertMessage( synth, "Synth is null" );
|
|
|
|
return synth->SaveToXmlFile( ( _dataPath + "\\" + fileName + ".xws" ).Chars( ) );
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::DestroySynth( Synth* synth )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
if( !_synths.ContainsValue( synth ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalDestroySynthCommand( synth ) );
|
|
|
|
#else
|
|
|
|
InternalDestroySynth( synth );
|
|
|
|
#endif
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::ActivateSynth( Synth* synth )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalActivateSynthCommand( synth ) );
|
|
|
|
#else
|
|
|
|
InternalActivateSynth( synth );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::DeactivateSynth( Synth* synth )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalDeactivateSynthCommand( synth ) );
|
|
|
|
#else
|
|
|
|
InternalDeactivateSynth( synth );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetSynth( const Util::String& name, Synth** synth )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
if( !_synths.TryGetValue( name, *synth ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetEventInComponent( Synth* synth, const Util::String& componentName, EventIn** eventIn )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != EventIn::GetType( ) )
|
|
{
|
|
*eventIn = nullptr;
|
|
|
|
result = ComponentNotEventIn;
|
|
}
|
|
else
|
|
{
|
|
*eventIn = (EventIn*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetEventInWithIdComponent( Synth* synth, const Util::String& componentName, EventInWithId** eventIn )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != EventInWithId::GetType( ) )
|
|
{
|
|
*eventIn = nullptr;
|
|
|
|
result = ComponentNotEventIn;
|
|
}
|
|
else
|
|
{
|
|
*eventIn = (EventInWithId*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetControlInComponent( Synth* synth, const Util::String& componentName, ControlIn** controlIn )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != ControlIn::GetType( ) )
|
|
{
|
|
*controlIn = nullptr;
|
|
|
|
result = ComponentNotControlIn;
|
|
}
|
|
else
|
|
{
|
|
*controlIn = (ControlIn*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetSwitchInComponent( Synth* synth, const Util::String& componentName, SwitchIn** switchIn )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != SwitchIn::GetType( ) )
|
|
{
|
|
*switchIn = nullptr;
|
|
|
|
result = Error;
|
|
}
|
|
else
|
|
{
|
|
*switchIn = (SwitchIn*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetEventOutComponent( Synth* synth, const Util::String& componentName, EventOut** eventOut )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != EventOut::GetType( ) )
|
|
{
|
|
*eventOut = nullptr;
|
|
|
|
result = Error;
|
|
}
|
|
else
|
|
{
|
|
*eventOut = (EventOut*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetControlOutComponent( Synth* synth, const Util::String& componentName, ControlOut** controlOut )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != ControlOut::GetType( ) )
|
|
{
|
|
*controlOut = nullptr;
|
|
|
|
result = Error;
|
|
}
|
|
else
|
|
{
|
|
*controlOut = (ControlOut*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetSwitchOutComponent( Synth* synth, const Util::String& componentName, SwitchOut** switchOut )
|
|
{
|
|
SoundResult result = Ok;
|
|
|
|
Component* component;
|
|
|
|
if( !synth->GetComponents( ).TryGetValue( componentName, component ) )
|
|
{
|
|
result = UnknownSynth;
|
|
}
|
|
else
|
|
{
|
|
if( component->GetDerivedType( ) != SwitchOut::GetType( ) )
|
|
{
|
|
*switchOut = nullptr;
|
|
|
|
result = Error;
|
|
}
|
|
else
|
|
{
|
|
*switchOut = (SwitchOut*)component;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::Tick( )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
// process all external commands returned from the engine
|
|
|
|
while( _returnCommands.Receive( ) );
|
|
|
|
_returnCommands.Clean( );
|
|
|
|
#endif
|
|
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
// signal the engine to process all internal commands if threaded
|
|
|
|
_processThreadTickEvent.Signal( );
|
|
|
|
#else
|
|
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
// process all commands and tick the engine
|
|
|
|
while( _sendCommands.Receive( ) );
|
|
|
|
_sendCommands.Clean( );
|
|
|
|
#endif
|
|
|
|
InternalTick( );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetEventIn( EventIn* eventIn )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalSetEventInCommand( eventIn ) );
|
|
|
|
#else
|
|
|
|
InternalSetEventIn( eventIn );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetEventInWithId( EventInWithId* eventIn, int32 val )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalSetEventInWithIdCommand( eventIn, val ) );
|
|
|
|
#else
|
|
|
|
InternalSetEventInWithId( eventIn, val );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetControlIn( ControlIn* controlIn, flt32 val )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalSetControlInCommand( controlIn, val ) );
|
|
|
|
#else
|
|
|
|
InternalSetControlIn( controlIn, val );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetSwitchIn( SwitchIn* switchIn, int32 val )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_sendCommands.Send( new InternalSetSwitchInCommand( switchIn, val ) );
|
|
|
|
#else
|
|
|
|
InternalSetSwitchIn( switchIn, val );
|
|
|
|
#endif
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::GetComponent( Synth* synth, const Util::String& componentName, Component** component )
|
|
{
|
|
return synth->GetComponents( ).TryGetValue( componentName, *component ) ? Ok : Error;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SwitchTracking( Soundwich::Synth* synth, bool enable, const char* exportFilePath)
|
|
{
|
|
synth->SwitchTracking(enable, exportFilePath);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetSynthDebugLogging( Synth* synth, bool enable )
|
|
{
|
|
synth->SetDebugLogging( enable );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetComponentDebugLogging( Component* component, bool enable )
|
|
{
|
|
component->SetDebugLogging( enable );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::SetConnectionDebugLogging( Connection* connection, bool enable )
|
|
{
|
|
connection->SetDebugLogging( enable );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterEventOutCallback( IEventOutCallback* cb, EventOut* eventOut )
|
|
{
|
|
eventOut->RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterControlOutCallback( IControlOutCallback* cb, ControlOut* controlOut )
|
|
{
|
|
controlOut->RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterSwitchOutCallback( ISwitchOutCallback* cb, SwitchOut* switchOut )
|
|
{
|
|
switchOut->RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDancePlayMenuMusicCallback( IJustDancePlayMenuMusicCallback* cb )
|
|
{
|
|
PlayMenuMusic::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceStopMenuMusicCallback( IJustDanceStopMenuMusicCallback* cb )
|
|
{
|
|
StopMenuMusic::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceSoundEffectCallback( IJustDanceSoundEffectCallback* cb )
|
|
{
|
|
JDSound::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceSoundEffectOnTrackTransitionCallback( IJustDanceSoundEffectOnTrackTransitionCallback* cb )
|
|
{
|
|
JDSoundSyncOnTransition::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceRemoteSoundEffectCallback( IJustDanceRemoteSoundEffectCallback* cb )
|
|
{
|
|
JDRemoteSound::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDancePlayEventBusMusicCallback( IJustDancePlayEventBusMusicCallback* cb )
|
|
{
|
|
PlayEventBusMusic::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceStopEventBusMusicCallback( IJustDanceStopEventBusMusicCallback* cb )
|
|
{
|
|
StopEventBusMusic::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDanceStopAllEventBusMixesCallback(IJustDanceStopAllEventBusMixesCallback* cb)
|
|
{
|
|
StopAllEventBusMixes::RegisterCallback(cb);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterJustDancePlayMusicMultiTrackCallback( IJustDancePlayMusicMultiTrackCallback* cb )
|
|
{
|
|
PlayMusicMultiTrack::RegisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::RegisterSoundwichTrackingCallback(ISoundwichTracking* cb)
|
|
{
|
|
for (SynthDictionary::Iterator item = _synths.begin(); item != _synths.end(); ++item)
|
|
{
|
|
Synth* synth = item->second;
|
|
if (synth != nullptr)
|
|
{
|
|
synth->RegisterTracker(cb);
|
|
}
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterEventOutCallback( IEventOutCallback* cb, EventOut* eventOut )
|
|
{
|
|
eventOut->UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterControlOutCallback( IControlOutCallback* cb, ControlOut* controlOut )
|
|
{
|
|
controlOut->UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterSwitchOutCallback( ISwitchOutCallback* cb, SwitchOut* switchOut )
|
|
{
|
|
switchOut->UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDancePlayMenuMusicCallback( IJustDancePlayMenuMusicCallback* cb )
|
|
{
|
|
PlayMenuMusic::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceStopMenuMusicCallback( IJustDanceStopMenuMusicCallback* cb )
|
|
{
|
|
StopMenuMusic::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceSoundEffectCallback( IJustDanceSoundEffectCallback* cb )
|
|
{
|
|
JDSound::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceSoundEffectOnTrackTransitionCallback( IJustDanceSoundEffectOnTrackTransitionCallback* cb )
|
|
{
|
|
JDSoundSyncOnTransition::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceRemoteSoundEffectCallback( IJustDanceRemoteSoundEffectCallback* cb )
|
|
{
|
|
JDRemoteSound::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDancePlayEventBusMusicCallback( IJustDancePlayEventBusMusicCallback* cb )
|
|
{
|
|
PlayEventBusMusic::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceStopEventBusMusicCallback( IJustDanceStopEventBusMusicCallback* cb )
|
|
{
|
|
StopEventBusMusic::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDanceStopAllEventBusMixesCallback(IJustDanceStopAllEventBusMixesCallback* cb)
|
|
{
|
|
StopAllEventBusMixes::UnregisterCallback(cb);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterJustDancePlayMusicMultiTrackCallback( IJustDancePlayMusicMultiTrackCallback* cb )
|
|
{
|
|
PlayMusicMultiTrack::UnregisterCallback( cb );
|
|
|
|
return Ok;
|
|
}
|
|
|
|
SoundResult Soundwich::Engine::Impl::UnregisterSoundwichTrackingCallback(ISoundwichTracking* cb)
|
|
{
|
|
for (SynthDictionary::Iterator item = _synths.begin(); item != _synths.end(); ++item)
|
|
{
|
|
Synth* synth = item->second;
|
|
if (synth != nullptr)
|
|
{
|
|
synth->UnregisterTracker(cb);
|
|
}
|
|
}
|
|
return Ok;
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::SetEventOut( EventOut* eventOut )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_returnCommands.Send( new ExternalSetEventOutCommand( eventOut ) );
|
|
|
|
#else
|
|
|
|
ExternalSetEventOut( eventOut );
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::SetControlOut( ControlOut* controlOut, flt32 val )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_returnCommands.Send( new ExternalSetControlOutCommand( controlOut, val ) );
|
|
|
|
#else
|
|
|
|
ExternalSetControlOut( controlOut, val );
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::SetSwitchOut( SwitchOut* switchOut, int32 val )
|
|
{
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
_returnCommands.Send( new ExternalSetSwitchOutCommand( switchOut, val ) );
|
|
|
|
#else
|
|
|
|
ExternalSetSwitchOut( switchOut, val );
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::StartInternalProcessing( void* data )
|
|
{
|
|
Engine::Impl* engine = (Engine::Impl*)data;
|
|
|
|
// run the process loop
|
|
|
|
engine->InternalProcessingLoop( );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalProcessingLoop( )
|
|
{
|
|
#if defined( USE_PROCESSING_THREAD )
|
|
|
|
_processing = true;
|
|
|
|
while( _processing )
|
|
{
|
|
// wait on main thread Tick( )
|
|
|
|
_processThreadTickEvent.Wait( );
|
|
|
|
// process commands from main thread
|
|
|
|
while( _sendCommands.Receive( ) );
|
|
|
|
_sendCommands.Clean( );
|
|
|
|
InternalTick( );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalShutdown( )
|
|
{
|
|
for( SynthArray::Iterator it = _ticking.Begin( ); it != _ticking.End( ); ++it )
|
|
{
|
|
Synth* synth = *it;
|
|
|
|
_ticking.Remove( synth );
|
|
|
|
#if defined( USE_NATIVE_AUDIO )
|
|
|
|
if( _rendering.Contains( synth ) )
|
|
{
|
|
_renderLock.Lock( );
|
|
|
|
_rendering.Remove( synth );
|
|
|
|
_renderLock.Unlock( );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalDestroySynth( Synth* synth )
|
|
{
|
|
// ensure we are not currently active, deactivate if so
|
|
|
|
InternalDeactivateSynth( synth );
|
|
|
|
#if defined( USE_DEFERRED_COMMANDS )
|
|
|
|
// signal the main thread to destroy the synth next Tick( )
|
|
|
|
_returnCommands.Send( new ExternalDestroySynthCommand( synth ) );
|
|
|
|
#else
|
|
|
|
ExternalDestroySynth( synth );
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalActivateSynth( Synth* synth )
|
|
{
|
|
if( !_ticking.Contains( synth ) )
|
|
{
|
|
_ticking.PushBack( synth );
|
|
|
|
// give it a first tick to initialize values
|
|
|
|
synth->Tick( 0.0f );
|
|
}
|
|
|
|
#if defined( USE_NATIVE_AUDIO )
|
|
|
|
if( !_rendering.Contains( synth ) )
|
|
{
|
|
_renderLock.Lock( );
|
|
|
|
_rendering.PushBack( synth );
|
|
|
|
_renderLock.Unlock( );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalDeactivateSynth( Synth* synth )
|
|
{
|
|
if( _ticking.Contains( synth ) )
|
|
{
|
|
_ticking.Remove( synth );
|
|
}
|
|
|
|
#if defined( USE_NATIVE_AUDIO )
|
|
|
|
if( _rendering.Contains( synth ) )
|
|
{
|
|
_renderLock.Lock( );
|
|
|
|
_rendering.Remove( synth );
|
|
|
|
_renderLock.Unlock( );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalTick( )
|
|
{
|
|
// round to nearest millisec, in seconds
|
|
|
|
flt32 interval = 0.001f * Util::Maths::Round( (flt32)_systemTimer.GetTime( true ) * 0.001f );
|
|
|
|
for ( SynthArray::Iterator item = _ticking.begin() ; item != _ticking.end() ; ++item )
|
|
{
|
|
(*item)->Tick( interval );
|
|
}
|
|
|
|
#if defined( ENABLE_STATISTICS )
|
|
|
|
Stats stats;
|
|
for ( SynthArray::Iterator item = _ticking.begin() ; item != _ticking.end() ; ++item )
|
|
{
|
|
(*item)->GetStats( stats );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalSetEventIn( EventIn* eventIn )
|
|
{
|
|
eventIn->Set( );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalSetEventInWithId( EventInWithId* eventIn, int32 val )
|
|
{
|
|
eventIn->Set( val );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalSetControlIn( ControlIn* controlIn, flt32 val )
|
|
{
|
|
controlIn->SetValue( val );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::InternalSetSwitchIn( SwitchIn* switchIn, int32 val )
|
|
{
|
|
switchIn->SetValue( val );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::ExternalDestroySynth( Synth* synth )
|
|
{
|
|
_synths.Remove( synth->GetName( ) );
|
|
|
|
delete synth;
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::ExternalSetEventOut( EventOut* eventOut )
|
|
{
|
|
eventOut->ExecuteCallbacks( );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::ExternalSetControlOut( ControlOut* controlOut, flt32 val )
|
|
{
|
|
controlOut->ExecuteCallbacks( val );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::ExternalSetSwitchOut( SwitchOut* switchOut, int32 val )
|
|
{
|
|
switchOut->ExecuteCallbacks( val );
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::RenderAudio( )
|
|
{
|
|
#if defined( USE_NATIVE_AUDIO )
|
|
|
|
_renderLock.Lock( );
|
|
|
|
SynthArray rendering = _rendering;
|
|
|
|
_renderLock.Unlock( );
|
|
|
|
for( auto item : rendering )
|
|
{
|
|
item->Render( );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Soundwich::Engine::Impl::GetStats( Engine::Stats& stats )
|
|
{
|
|
for ( SynthDictionary::Iterator item = _synths.begin() ; item != _synths.end() ; ++item )
|
|
{
|
|
Synth* synth = item->second;
|
|
|
|
synth->GetStats( stats );
|
|
}
|
|
}
|