327 lines
8 KiB
C++
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" );
|
|
}
|