JD2022-TU1/main/extern/Soundwich/Solution/Samples/DirectSynth/Main.cpp

327 lines
8 KiB
C++

#include "Inc\Soundwich.h"
#if defined( SW_PLATFORM_PC )
#include <Windows.h>
#elif defined( SW_PLATFORM_PS4 )
#include <pthread.h>
#define Sleep( x ) sceKernelUsleep( 1000 * x );
#endif
#include <stdio.h>
#include "Components\External\Events\EventIn.h"
#include "Components\External\Events\EventOut.h"
#include "Components\Process\ControlGenerators\Timer.h"
#include "Components\External\Controls\ControlIn.h"
#include "Components\External\Controls\ControlOut.h"
#include "Components\Process\ControlProcessors\PiecewiseLinearFunction.h"
/*
This sample app creates 2 synths, one that delays an event and another that transforms a control value
In this case the synth is created directly in code with no data or scripts required
This is the most direct way to create a synth but care must be taken as less validation of the graph is performed.
The first synth has a module that delays an EventIn signal and fires an EventOut after the specified time (default is 2 seconds).
The second synth has a transform module which will transform a 0->1 value to a 1->0 value with a mid point mapping 0.5->0.75
The demo app runs 2 tests sequentially.
The first signals the EventIn and when the delayed EventOut is fired it retriggers the EventIn. this will loop for 10 seconds.
The second part will feed a ControlIn with a value incrementing from 0 to 1 over 20 seconds, and receive the transformed 1 to 0 ControlOut.
*/
using namespace Soundwich;
Engine* soundwich;
// A class to create and manage the event delay component graph, the class inherits from IEventOutCallback to receive EventOut callbacks
class EventDelay : public IEventOutCallback
{
public:
EventDelay( )
{
printf( "Testing EventDelay\n" );
// create a synth
_synth = new Synth( soundwich->GetImpl( ), "Demo" );
// create the components, they will add themselves to the module
_in = new EventIn( _synth, "Delay.EventIn", EventIn::Data( ) );
_out = new EventOut( _synth, "Delay.EventOut", EventOut::Data( ) );
// the delay is a non-looping timer with an interval of 2 seconds
Timer* delay = new Timer( _synth, "Delay.DelayTimer", Timer::Data( 0.0f, 1.0f, 2.0f, true ) );
// connect the components, the connections will add themselves to the module
new EventConnection( _synth, _in, EventIn::OutputEvents::OutEventOut, delay, Timer::InputEvents::ResetEventIn );
new EventConnection( _synth, _in, EventIn::OutputEvents::OutEventOut, delay, Timer::InputEvents::StartEventIn );
new EventConnection( _synth, delay, Timer::OutputEvents::ElapsedEventOut, _out, EventOut::InputEvents::InEventIn );
// register the event callback
SoundResult result = Ok;
if( result == Ok )
{
result = soundwich->RegisterEventOutCallback( this, _out );
}
if( result == Ok )
{
// activate the synth
result = soundwich->ActivateSynth( _synth );
}
if( result == Ok )
{
// signal the event in
printf( "Signalling event input\n" );
soundwich->SetEventIn( _in );
}
if( result != Ok )
{
// clean up
if( _synth )
{
delete _synth;
_synth = nullptr;
}
}
}
~EventDelay( )
{
if( _synth )
{
soundwich->UnregisterEventOutCallback( this, _out );
// deactivate the synth
soundwich->DeactivateSynth( _synth );
// destroy the synth
soundwich->DestroySynth( _synth );
}
}
void OnEventOut( const EventOut* eventOut )
{
if( eventOut == _out )
{
printf( "Delayed event output signalled, signalling event input again\n" );
soundwich->SetEventIn( _in );
}
}
private:
Synth* _synth;
Module* _module;
EventIn* _in;
EventOut* _out;
};
// A class to create and manage the control transform component graph, the class inherits from IControlOutCallback to receive ControlOut callbacks
class ControlTransform : public IControlOutCallback
{
public:
ControlTransform( )
: _value( 1.0f )
{
printf( "Testing ControlTransform\n" );
_value = 1.0f;
// create a synth
_synth = new Synth( soundwich->GetImpl( ), "Demo" );
// create the components, they will add themselves to the module
_in = new ControlIn( _synth, "Transform.ControlIn", ControlIn::Data( ) );
_out = new ControlOut( _synth, "Transform.ControlOut", ControlOut::Data( ) );
// the transform is a 3 point graph transforming 0->1, 0.5->0.75, 1->0
flt32 points[6] = { 0.0f, 1.0f, 0.5f, 0.75f, 1.0f, 0.0f };
PiecewiseLinearFunction* transform = new PiecewiseLinearFunction( _synth, "Transform.Transformer", PiecewiseLinearFunction::Data( 0.0f, Util::Flt32Array( points, 6 ) ) );
// connect the components, the connections will add themselves to the module
new ControlConnection( _synth, _in, ControlIn::OutputControls::OutControlOut, transform, PiecewiseLinearFunction::InputControls::InControlIn );
new ControlConnection( _synth, transform, PiecewiseLinearFunction::OutputControls::OutControlOut, _out, ControlOut::InputControls::InControlIn );
SoundResult result = Ok;
#if 0 // Quck hacky test: check for correct save and re-load
result = soundwich->SetDataPath( "c:" );
if( result == Ok )
{
result = soundwich->SaveSynthToXmlFile( _synth, "TestSynth" );
}
delete _synth;
_synth = nullptr;
if( result == Ok )
{
soundwich->CreateSynthFromXmlFile( "Demo2", &_synth, "TestSynth" );
}
#endif
if( result == Ok )
{
result = soundwich->GetControlInComponent( _synth, "Transform.ControlIn", &_in );
}
if( result == Ok )
{
result = soundwich->GetControlOutComponent( _synth, "Transform.ControlOut", &_out );
}
if( result == Ok )
{
// register the control callback
soundwich->RegisterControlOutCallback( this, _out );
}
if( result == Ok )
{
// activate the synth
soundwich->ActivateSynth( _synth );
}
if( result != Ok )
{
// clean up
if( _synth )
{
delete _synth;
_synth = nullptr;
}
}
}
~ControlTransform( )
{
if( _synth )
{
// deactivate the synth
soundwich->DeactivateSynth( _synth );
// destroy the synth
soundwich->DestroySynth( _synth );
}
// new line
printf( "\n" );
}
void SetValue( flt32 value )
{
printf( "Transforming control value from %.2f ", value );
soundwich->SetControlIn( _in, value );
}
void OnControlOut( const ControlOut* controlOut, flt32 value )
{
if( controlOut == _out )
{
if( _value != value )
{
_value = value;
printf( "to %.3f\n", value );
}
}
}
private:
Synth* _synth;
Module* _module;
ControlIn* _in;
ControlOut* _out;
flt32 _value;
};
void TestEventDelay( )
{
EventDelay synth;
int32 count = 100;
while( count-- )
{
soundwich->Tick( );
Sleep( 100 );
}
};
void TestControlTransform( )
{
ControlTransform synth;
int32 count = 100;
while( count-- )
{
if( count % 5 == 0 )
{
flt32 value = 1.0f - (flt32)count / 100.0f;
synth.SetValue( value );
}
soundwich->Tick( );
Sleep( 100 );
}
};
int main( int32 argc, char* argv[ ] )
{
Engine::Create( &soundwich );
TestEventDelay( );
TestControlTransform( );
Engine::Destroy( soundwich );
//system( "pause" );
}