diff --git a/cwFlow.cpp b/cwFlow.cpp index b2a8fa5..ace5954 100644 --- a/cwFlow.cpp +++ b/cwFlow.cpp @@ -27,11 +27,15 @@ namespace cw { "audio_out", &audio_out::members }, { "audioFileIn", &audioFileIn::members }, { "audioFileOut", &audioFileOut::members }, + { "gain", &gain::members }, + { "audio_split", &audio_split::members }, + { "audio_merge", &audio_merge::members }, { "sine_tone", &sine_tone::members }, { "pv_analysis", &pv_analysis::members }, { "pv_synthesis", &pv_synthesis::members }, { "spec_dist", &spec_dist::members }, { "compressor", &compressor::members }, + { "audio_delay", &audio_delay::members }, { nullptr, nullptr } }; @@ -759,6 +763,40 @@ namespace cw return rc; } + + template< typename T > + rc_t _set_variable_value( flow_t* p, const char* inst_label, const char* var_label, unsigned chIdx, T value ) + { + rc_t rc = kOkRC; + instance_t* inst = nullptr; + variable_t* var = nullptr; + + // locate the proc instance + if((inst = instance_find(p,inst_label)) != nullptr ) + { + rc = cwLogError(kInvalidIdRC,"Unknown proc instance label '%s'.", cwStringNullGuard(inst_label)); + goto errLabel; + } + + // locate the variable + if((rc = var_find( inst, var_label, chIdx, var)) != kOkRC ) + { + rc = cwLogError(kInvalidArgRC,"The variable '%s' could not be found on the proc instance '%s'.",cwStringNullGuard(var_label),cwStringNullGuard(inst_label)); + goto errLabel; + } + + // set the variable value + if((rc = var_set( inst, var->vid, chIdx, value )) != kOkRC ) + { + rc = cwLogError(kOpFailRC,"The variable set failed on instance:'%s' variable:'%s'.",cwStringNullGuard(inst_label),cwStringNullGuard(var_label)); + goto errLabel; + } + + errLabel: + return rc; + } + + } } @@ -870,6 +908,35 @@ cw::rc_t cw::flow::destroy( handle_t& hRef ) return rc; } + +cw::rc_t cw::flow::exec_cycle( handle_t h ) +{ + return _exec_cycle(_handleToPtr(h)); +} + +cw::rc_t cw::flow::exec( handle_t h ) +{ + rc_t rc = kOkRC; + flow_t* p = _handleToPtr(h); + + while( true ) + { + rc = _exec_cycle(p); + + if( rc == kEofRC ) + { + rc = kOkRC; + break; + } + + p->cycleIndex += 1; + if( p->maxCycleCount > 0 && p->cycleIndex >= p->maxCycleCount ) + break; + } + + return rc; +} + cw::rc_t cw::flow::apply_preset( handle_t h, const char* presetLabel ) { rc_t rc = kOkRC; @@ -911,6 +978,7 @@ cw::rc_t cw::flow::apply_preset( handle_t h, const char* presetLabel ) if( preset_value_cfg->is_dict() ) { printf("Not implemented.\n"); + assert(0); } else { @@ -930,33 +998,21 @@ cw::rc_t cw::flow::apply_preset( handle_t h, const char* presetLabel ) return rc; } -cw::rc_t cw::flow::exec_cycle( handle_t h ) -{ - return _exec_cycle(_handleToPtr(h)); -} +cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool value ) +{ return _set_variable_value( _handleToPtr(h), inst_label, var_label, chIdx, value ); } -cw::rc_t cw::flow::exec( handle_t h ) -{ - rc_t rc = kOkRC; - flow_t* p = _handleToPtr(h); +cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, int value ) +{ return _set_variable_value( _handleToPtr(h), inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ) +{ return _set_variable_value( _handleToPtr(h), inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, float value ) +{ return _set_variable_value( _handleToPtr(h), inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::flow::set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, double value ) +{ return _set_variable_value( _handleToPtr(h), inst_label, var_label, chIdx, value ); } - while( true ) - { - rc = _exec_cycle(p); - - if( rc == kEofRC ) - { - rc = kOkRC; - break; - } - - p->cycleIndex += 1; - if( p->maxCycleCount > 0 && p->cycleIndex >= p->maxCycleCount ) - break; - } - - return rc; -} void cw::flow::print_class_list( handle_t h ) { diff --git a/cwFlow.h b/cwFlow.h index e6d31bc..13f23bf 100644 --- a/cwFlow.h +++ b/cwFlow.h @@ -59,15 +59,20 @@ namespace cw rc_t destroy( handle_t& hRef ); - rc_t apply_preset( handle_t h, const char* presetLabel ); - // Run one cycle of the network. rc_t exec_cycle( handle_t h ); // Run the network to completion. rc_t exec( handle_t h ); - + rc_t apply_preset( handle_t h, const char* presetLabel ); + + rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool value ); + rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, int value ); + rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ); + rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, float value ); + rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, double value ); + void print_class_list( handle_t h ); void print_network( handle_t h ); diff --git a/cwFlowCross.cpp b/cwFlowCross.cpp index a531471..ca17263 100644 --- a/cwFlowCross.cpp +++ b/cwFlowCross.cpp @@ -123,11 +123,13 @@ namespace cw dsp::recorder::create( net->recorder, srate, 10.0, 1 ); net->deviceA = _clone_external_device_array( deviceA, deviceN ); - net->deviceN = deviceN; + net->deviceN = 0; net->stateId = net_idx == 0 ? kActiveStateId : kInactiveStateId; net->net_idx = net_idx; - if((rc = flow::create( net->flowH, classCfg, networkCfg, net->deviceA, net->deviceN )) != kOkRC ) + if((rc = flow::create( net->flowH, classCfg, networkCfg, net->deviceA, deviceN )) == kOkRC ) + net->deviceN += 1; + else { cwLogError(rc,"Flow cross index %i network created failed.",net_idx); goto errLabel; @@ -226,6 +228,33 @@ namespace cw _fade_audio( src, dst, net ); } + + unsigned _get_flow_index( flow_cross_t* p, destId_t destId ) + { + unsigned flow_idx = kInvalidIdx; + + switch( destId ) + { + case kCurDestId: flow_idx = p->cur_idx; break; + case kNextDestId: flow_idx = (p->cur_idx + 1) % p->netN; + default: + assert(0); + + } + return flow_idx; + } + + template< typename T > + rc_t _set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, const T& value ) + { + //rc_t rc = kOkRC; + flow_cross_t* p = _handleToPtr(h); + unsigned flow_idx = _get_flow_index(p, destId ); + return set_variable_value( p->netA[ flow_idx ].flowH, inst_label, var_label, chIdx, value ); + + } + + } } @@ -250,13 +279,15 @@ cw::rc_t cw::flow_cross::create( handle_t& hRef, flow_cross_t* p = mem::allocZ(); p->netA = mem::allocZ( crossN ); - p->netN = crossN; + p->netN = 0; p->srate = srate; p->deviceA = deviceA; p->deviceN = deviceN; for(unsigned i=0; inetN += 1; + else { rc = cwLogError(rc,"Sub-network index '%i' create failed.",i); goto errLabel; @@ -339,35 +370,52 @@ cw::rc_t cw::flow_cross::exec_cycle( handle_t h ) } */ -cw::rc_t cw::flow_cross::apply_preset( handle_t h, unsigned crossFadeMs, const char* presetLabel ) + + +cw::rc_t cw::flow_cross::apply_preset( handle_t h, destId_t destId, const char* presetLabel ) +{ + rc_t rc = kOkRC; + flow_cross_t* p = _handleToPtr(h); + unsigned flow_idx = _get_flow_index(p, destId ); + + if((rc = flow::apply_preset( p->netA[flow_idx].flowH, presetLabel )) != kOkRC ) + rc = cwLogError(rc,"Preset application '%s' failed.",cwStringNullGuard(presetLabel)); + + return rc; +} + +cw::rc_t cw::flow_cross::set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, bool value ) +{ return _set_variable_value(h,destId,inst_label,var_label,chIdx,value); } + +cw::rc_t cw::flow_cross::set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, int value ) +{ return _set_variable_value(h,destId,inst_label,var_label,chIdx,value); } + +cw::rc_t cw::flow_cross::set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ) +{ return _set_variable_value(h,destId,inst_label,var_label,chIdx,value); } + +cw::rc_t cw::flow_cross::set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, float value ) +{ return _set_variable_value(h,destId,inst_label,var_label,chIdx,value); } + +cw::rc_t cw::flow_cross::set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, double value ) +{ return _set_variable_value(h,destId,inst_label,var_label,chIdx,value); } + +cw::rc_t cw::flow_cross::begin_cross_fade( handle_t h, unsigned crossFadeMs ) { rc_t rc = kOkRC; flow_cross_t* p = _handleToPtr(h); - - unsigned next_idx = (p->cur_idx + 1) % p->netN; - - // TODO: verify that this network is inactive - - if((rc = flow::apply_preset( p->netA[next_idx].flowH, presetLabel )) != kOkRC ) - { - cwLogError(rc,"Preset application '%s' failed.",cwStringNullGuard(presetLabel)); - goto errLabel; - } - + p->netA[ p->cur_idx ].stateId = kFadeOutStateId; - p->cur_idx = next_idx; + p->cur_idx = _get_flow_index( p, kNextDestId ); + p->netA[ p->cur_idx ].stateId = kFadeInStateId; p->netA[ p->cur_idx ].fadeSmpN = (unsigned)(p->srate * crossFadeMs / 1000.0); - cwLogInfo("Apply preset:%s.",presetLabel); - - errLabel: - return rc; } + void cw::flow_cross::print( handle_t h ) { flow_cross_t* p = _handleToPtr(h); diff --git a/cwFlowCross.h b/cwFlowCross.h index 17b703d..5b5e949 100644 --- a/cwFlowCross.h +++ b/cwFlowCross.h @@ -8,6 +8,12 @@ namespace cw typedef handle handle_t; + typedef enum + { + kCurDestId, // Apply value to the current flow network + kNextDestId, // Apply value to the next flow network (i.e. network which will be current following the next cross-fade) + } destId_t; + rc_t create( handle_t& hRef, const object_t& classCfg, const object_t& networkCfg, @@ -21,8 +27,16 @@ namespace cw // Run one cycle of the network. rc_t exec_cycle( handle_t h ); - rc_t apply_preset( handle_t h, unsigned crossFadeMs, const char* presetLabel ); + rc_t apply_preset( handle_t h, destId_t destId, const char* presetLabel ); + rc_t set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, bool value ); + rc_t set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, int value ); + rc_t set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ); + rc_t set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, float value ); + rc_t set_variable_value( handle_t h, destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, double value ); + + rc_t begin_cross_fade( handle_t h, unsigned crossFadeMs ); + void print( handle_t h ); } diff --git a/cwIoFlow.cpp b/cwIoFlow.cpp index d1790e9..895f126 100644 --- a/cwIoFlow.cpp +++ b/cwIoFlow.cpp @@ -406,13 +406,23 @@ cw::rc_t cw::io_flow::exec( handle_t h, const io::msg_t& msg ) } -cw::rc_t cw::io_flow::apply_preset( handle_t h, double crossFadeMs, const char* presetLabel ) -{ - cw::rc_t rc = kOkRC; +cw::rc_t cw::io_flow::apply_preset( handle_t h, flow_cross::destId_t destId, const char* presetLabel ) +{ return apply_preset( _handleToPtr(h)->crossFlowH, destId, presetLabel ); } - io_flow_t* p = _handleToPtr(h); +cw::rc_t cw::io_flow::set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, bool value ) +{ return flow_cross::set_variable_value( _handleToPtr(h)->crossFlowH, destId, inst_label, var_label, chIdx, value ); } - rc = apply_preset( p->crossFlowH, crossFadeMs, presetLabel ); - - return rc; -} +cw::rc_t cw::io_flow::set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, int value ) +{ return flow_cross::set_variable_value( _handleToPtr(h)->crossFlowH, destId, inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::io_flow::set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ) +{ return flow_cross::set_variable_value( _handleToPtr(h)->crossFlowH, destId, inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::io_flow::set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, float value ) +{ return flow_cross::set_variable_value( _handleToPtr(h)->crossFlowH, destId, inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::io_flow::set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, double value ) +{ return flow_cross::set_variable_value( _handleToPtr(h)->crossFlowH, destId, inst_label, var_label, chIdx, value ); } + +cw::rc_t cw::io_flow::begin_cross_fade( handle_t h, unsigned crossFadeMs ) +{ return flow_cross::begin_cross_fade( _handleToPtr(h)->crossFlowH, crossFadeMs ); } diff --git a/cwIoFlow.h b/cwIoFlow.h index 54720d7..fe4da0d 100644 --- a/cwIoFlow.h +++ b/cwIoFlow.h @@ -12,7 +12,16 @@ namespace cw rc_t exec( handle_t h, const io::msg_t& msg ); - rc_t apply_preset( handle_t h, double crossFadeMs, const char* presetLabel ); + + rc_t apply_preset( handle_t h, flow_cross::destId_t destId, const char* presetLabel ); + + rc_t set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, bool value ); + rc_t set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, int value ); + rc_t set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, unsigned value ); + rc_t set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, float value ); + rc_t set_variable_value( handle_t h, flow_cross::destId_t destId, const char* inst_label, const char* var_label, unsigned chIdx, double value ); + + rc_t begin_cross_fade( handle_t h, unsigned crossFadeMs ); }