cwFlow*,cwPresetSel.cpp: Many changes to implement 'poly' networks.

cwFlowNet.h/cpp : Initial commit.
This commit is contained in:
kevin 2024-04-22 16:02:40 -04:00
parent 1c373f8d03
commit 1b649124a6
11 changed files with 3183 additions and 1917 deletions

View File

@ -34,8 +34,8 @@ libcwSRC += src/libcw/cwAudioFile.cpp src/libcw/cwMidiFile.cpp
libcwHDR += src/libcw/cwAudioFileOps.h src/libcw/cwAudioTransforms.h src/libcw/cwDspTransforms.h src/libcw/cwAudioFileProc.h src/libcw/cwPvAudioFileProc.h
libcwSRC += src/libcw/cwAudioFileOps.cpp src/libcw/cwAudioTransforms.cpp src/libcw/cwDspTransforms.cpp src/libcw/cwAudioFileProc.cpp src/libcw/cwPvAudioFileProc.cpp
libcwHDR += src/libcw/cwFlow.h src/libcw/cwFlowDecl.h src/libcw/cwFlowTypes.h src/libcw/cwFlowProc.h src/libcw/cwFlowCross.h
libcwSRC += src/libcw/cwFlow.cpp src/libcw/cwFlowTypes.cpp src/libcw/cwFlowProc.cpp src/libcw/cwFlowCross.cpp
libcwHDR += src/libcw/cwFlow.h src/libcw/cwFlowDecl.h src/libcw/cwFlowTypes.h src/libcw/cwFlowNet.h src/libcw/cwFlowProc.h src/libcw/cwFlowCross.h
libcwSRC += src/libcw/cwFlow.cpp src/libcw/cwFlowTypes.cpp src/libcw/cwFlowNet.cpp src/libcw/cwFlowProc.cpp src/libcw/cwFlowCross.cpp
if cwWEBSOCK
libcwHDR += src/libcw/cwWebSock.h src/libcw/cwWebSockSvr.h

1663
cwFlow.cpp

File diff suppressed because it is too large Load Diff

View File

@ -8,64 +8,6 @@ namespace cw
typedef handle<struct flow_str> handle_t;
enum
{
kAudioDevTypeId,
kMidiDevTypeId,
kSerialDevTypeId,
kSocketDevTypeId
};
enum
{
kInFl = 0x01,
kOutFl = 0x02
};
struct abuf_str;
typedef struct audio_dev_cfg_str
{
struct abuf_str* abuf; // Buffer to receive incoming or send outgoing audio for this device
// The audio_in/audio_out proc's locate and use these buffers.
} audio_dev_cfg_t;
struct external_device_str;
typedef rc_t (*send_midi_triple_func_t)( struct external_device_str* dev, uint8_t ch, uint8_t status, uint8_t d0, uint8_t d1 );
typedef struct midi_dev_cfg_str
{
// msgArray[] contains the current msgs for all devices NOT just the device that this record is embedded in.
// We do this so that the order of messages as they arrived is maintained. Otherwise, to achieve this ordering,
// the messages for all devices would need to be collected and sorted by time.
const midi::ch_msg_t* msgArray;
unsigned msgCnt;
unsigned maxMsgCnt; // max possible value of msgCnt
send_midi_triple_func_t sendTripleFunc;
} midi_dev_cfg_t;
// Generate external device record
typedef struct external_device_str
{
void* reserved;
const char* devLabel; // IO framework device label
const char* portLabel; // IO framework MIDI port label (only used by MIDI devices)
unsigned typeId; // see ???DevTypeId above
unsigned flags; // see ???Fl above
unsigned ioDevIdx; // IO framework device index
unsigned ioPortIdx; // IO framework MIDI port index (only used by MIDI devices)
union
{
audio_dev_cfg_t a; // audio devices use this record
midi_dev_cfg_t m; // MIDI " " " "
} u;
} external_device_t;
void print_abuf( const struct abuf_str* abuf );
@ -89,8 +31,8 @@ namespace cw
rc_t exec( handle_t h );
rc_t apply_preset( handle_t h, const char* presetLabel );
rc_t apply_preset( handle_t h, const multi_preset_selector_t& multi_preset_sel );
rc_t apply_dual_preset( handle_t h, const char* presetLabel_0, const char* presetLabel_1, double coeff );
rc_t apply_preset( handle_t h, const multi_preset_selector_t& multi_preset_sel );
rc_t set_variable_value( handle_t h, const char* inst_label, const char* var_label, unsigned chIdx, bool value );

View File

@ -5,6 +5,67 @@ namespace cw
{
namespace flow
{
enum
{
kAudioDevTypeId,
kMidiDevTypeId,
kSerialDevTypeId,
kSocketDevTypeId
};
enum
{
kInFl = 0x01,
kOutFl = 0x02
};
struct abuf_str;
typedef struct audio_dev_cfg_str
{
struct abuf_str* abuf; // Buffer to receive incoming or send outgoing audio for this device
// The audio_in/audio_out proc's locate and use these buffers.
} audio_dev_cfg_t;
struct external_device_str;
typedef rc_t (*send_midi_triple_func_t)( struct external_device_str* dev, uint8_t ch, uint8_t status, uint8_t d0, uint8_t d1 );
typedef struct midi_dev_cfg_str
{
// msgArray[] contains the current msgs for all devices NOT just the device that this record is embedded in.
// We do this so that the order of messages as they arrived is maintained. Otherwise, to achieve this ordering,
// the messages for all devices would need to be collected and sorted by time.
const midi::ch_msg_t* msgArray;
unsigned msgCnt;
unsigned maxMsgCnt; // max possible value of msgCnt
send_midi_triple_func_t sendTripleFunc;
} midi_dev_cfg_t;
// Generate external device record
typedef struct external_device_str
{
void* reserved;
const char* devLabel; // IO framework device label
const char* portLabel; // IO framework MIDI port label (only used by MIDI devices)
unsigned typeId; // see ???DevTypeId above
unsigned flags; // see ???Fl above
unsigned ioDevIdx; // IO framework device index
unsigned ioPortIdx; // IO framework MIDI port index (only used by MIDI devices)
union
{
audio_dev_cfg_t a; // audio devices use this record
midi_dev_cfg_t m; // MIDI " " " "
} u;
} external_device_t;
enum {
kPriPresetProbFl = 0x01,
kSecPresetProbFl = 0x02,

2279
cwFlowNet.cpp Normal file

File diff suppressed because it is too large Load Diff

82
cwFlowNet.h Normal file
View File

@ -0,0 +1,82 @@
#ifndef cwFlowNet_h
#define cwFlowNet_h
namespace cw
{
namespace flow
{
typedef enum {
kNetFirstPolyOrderId,
kProcFirstPolyOrderId
} network_order_id_t;
rc_t network_create( flow_t* p,
const object_t* networkCfg,
network_t& net, // Network object to be filled with new proc instances
unsigned polyCnt = 1, // Count of networks to create
network_order_id_t orderId = kNetFirstPolyOrderId // Set the network exec order.
);
rc_t network_destroy( network_t& net );
const object_t* find_network_preset( const network_t& net, const char* presetLabel );
rc_t exec_cycle( network_t& net );
rc_t get_variable( network_t& net, const char* inst_label, const char* var_label, unsigned chIdx, instance_t*& instPtrRef, variable_t*& varPtrRef );
template< typename T >
rc_t set_variable_value( network_t& net, const char* inst_label, const char* var_label, unsigned chIdx, T value )
{
rc_t rc = kOkRC;
instance_t* inst = nullptr;
variable_t* var = nullptr;
// get the variable
if((rc = get_variable(net,inst_label,var_label,chIdx,inst,var)) != kOkRC )
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;
}
template< typename T >
rc_t get_variable_value( network_t& net, const char* inst_label, const char* var_label, unsigned chIdx, T& valueRef )
{
rc_t rc = kOkRC;
instance_t* inst = nullptr;
variable_t* var = nullptr;
// get the variable
if((rc = get_variable(net,inst_label,var_label,chIdx,inst,var)) != kOkRC )
goto errLabel;
// get the variable value
if((rc = var_get( inst, var->vid, chIdx, valueRef )) != kOkRC )
{
rc = cwLogError(kOpFailRC,"The variable get failed on instance:'%s' variable:'%s'.",cwStringNullGuard(inst_label),cwStringNullGuard(var_label));
goto errLabel;
}
errLabel:
return rc;
}
rc_t network_apply_preset( network_t& net, const char* presetLabel );
rc_t network_apply_dual_preset( network_t& net, const char* presetLabel_0, const char* presetLabel_1, double coeff );
rc_t network_apply_preset( network_t& net, const multi_preset_selector_t& mps );
}
}
#endif

View File

@ -17,6 +17,7 @@
#include "cwFlowDecl.h"
#include "cwFlow.h"
#include "cwFlowTypes.h"
#include "cwFlowNet.h"
#include "cwFlowProc.h"
#include "cwFile.h"
@ -90,6 +91,119 @@ namespace cw
}
//------------------------------------------------------------------------------------------------------------------
//
// poly
//
namespace poly
{
enum
{
kCountPId,
kOrderPId,
};
typedef struct
{
unsigned count;
network_t net;
network_order_id_t orderId;
} inst_t;
rc_t create( instance_t* proc )
{
rc_t rc = kOkRC;
inst_t* inst = mem::allocZ<inst_t>();
const object_t* networkCfg = nullptr;
const char* order_label = nullptr;
proc->userPtr = inst;
if((rc = var_register_and_get( proc, kAnyChIdx,
kCountPId, "count", kBaseSfxId, inst->count,
kOrderPId, "order", kBaseSfxId, order_label )) != kOkRC )
goto errLabel;
if( inst->count == 0 )
{
cwLogWarning("The 'poly' %s:%i was given a count of 0.",proc->label,proc->label_sfx_id);
goto errLabel;
}
if((rc = proc->proc_cfg->getv("network",networkCfg)) != kOkRC )
{
rc = cwLogError(rc,"The 'network' cfg. was not found.");
goto errLabel;
}
// get the network exec. order type
if( textIsEqual(order_label,"net") )
inst->orderId = kNetFirstPolyOrderId;
else
{
if( textIsEqual(order_label,"proc") )
inst->orderId = kProcFirstPolyOrderId;
else
{
rc = cwLogError(kInvalidArgRC,"'%s' is not one of the valid order types (i.e. 'net','proc').",order_label);
goto errLabel;
}
}
if((rc = network_create(proc->ctx,networkCfg,inst->net,inst->count )) != kOkRC )
{
rc = cwLogError(rc,"Creation failed on the internal network.");
goto errLabel;
}
// Set the internal net pointer in the base proc instance
// so that network based utilities can scan it
proc->internal_net = &inst->net;
errLabel:
return rc;
}
rc_t destroy( instance_t* proc )
{
inst_t* p = (inst_t*)proc->userPtr;
network_destroy(p->net);
mem::release( proc->userPtr );
return kOkRC;
}
rc_t value( instance_t* ctx, variable_t* var )
{
return kOkRC;
}
rc_t exec( instance_t* ctx )
{
inst_t* p = (inst_t*)ctx->userPtr;
rc_t rc = kOkRC;
if((rc = exec_cycle(p->net)) != kOkRC )
{
rc = cwLogError(rc,"poly internal network exec failed.");
}
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
//------------------------------------------------------------------------------------------------------------------
//
// balance
@ -115,12 +229,12 @@ namespace cw
real_t in_value = 0.5;
ctx->userPtr = mem::allocZ<inst_t>();
if((rc = var_register_and_get( ctx, kAnyChIdx, kInPId, "in", in_value )) != kOkRC )
if((rc = var_register_and_get( ctx, kAnyChIdx, kInPId, "in", kBaseSfxId, in_value )) != kOkRC )
goto errLabel;
if((rc = var_register_and_set( ctx, kAnyChIdx,
kOutPId, "out", in_value,
kInvOutPId, "inv_out", (real_t)(1.0-in_value) )) != kOkRC )
kOutPId, "out", kBaseSfxId, in_value,
kInvOutPId, "inv_out", kBaseSfxId, (real_t)(1.0-in_value) )) != kOkRC )
{
goto errLabel;
}
@ -205,14 +319,14 @@ namespace cw
// Register variable and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx,
kDevLabelPId, "dev_label", dev_label,
kPortLabelPId, "port_label", port_label )) != kOkRC )
kDevLabelPId, "dev_label", kBaseSfxId, dev_label,
kPortLabelPId, "port_label", kBaseSfxId, port_label )) != kOkRC )
{
goto errLabel;
}
if((rc = var_register( ctx, kAnyChIdx,kOutPId, "out")) != kOkRC )
if((rc = var_register( ctx, kAnyChIdx, kOutPId, "out", kBaseSfxId)) != kOkRC )
{
goto errLabel;
}
@ -246,7 +360,7 @@ namespace cw
inst->buf = mem::allocZ<midi::ch_msg_t>( inst->bufN );
// create one output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, nullptr, 0 );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, nullptr, 0 );
errLabel:
@ -349,9 +463,9 @@ namespace cw
// Register variables and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx,
kDevLabelPId, "dev_label", dev_label,
kPortLabelPId,"port_label", port_label,
kInPId, "in", mbuf)) != kOkRC )
kDevLabelPId, "dev_label", kBaseSfxId, dev_label,
kPortLabelPId,"port_label", kBaseSfxId, port_label,
kInPId, "in", kBaseSfxId, mbuf)) != kOkRC )
{
goto errLabel;
}
@ -444,7 +558,7 @@ namespace cw
ctx->userPtr = inst;
// Register variable and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx, kDevLabelPId, "dev_label", inst->dev_label )) != kOkRC )
if((rc = var_register_and_get( ctx, kAnyChIdx, kDevLabelPId, "dev_label", kBaseSfxId, inst->dev_label )) != kOkRC )
{
goto errLabel;
}
@ -457,7 +571,7 @@ namespace cw
// create one output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, inst->ext_dev->u.a.abuf->srate, inst->ext_dev->u.a.abuf->chN, ctx->ctx->framesPerCycle );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, inst->ext_dev->u.a.abuf->srate, inst->ext_dev->u.a.abuf->chN, ctx->ctx->framesPerCycle );
errLabel:
return rc;
@ -542,8 +656,8 @@ namespace cw
// Register variables and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx,
kDevLabelPId, "dev_label", inst->dev_label,
kInPId, "in", src_abuf)) != kOkRC )
kDevLabelPId, "dev_label", kBaseSfxId, inst->dev_label,
kInPId, "in", kBaseSfxId, src_abuf)) != kOkRC )
{
goto errLabel;
}
@ -638,16 +752,16 @@ namespace cw
inst_t* inst = mem::allocZ<inst_t>();
ctx->userPtr = inst;
if((rc = var_register( ctx, kAnyChIdx, kOnOffFlPId, "on_off" )) != kOkRC )
if((rc = var_register( ctx, kAnyChIdx, kOnOffFlPId, "on_off", kBaseSfxId)) != kOkRC )
{
goto errLabel;
}
// Register variable and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx,
kFnamePId, "fname", inst->filename,
kSeekSecsPId, "seekSecs", seekSecs,
kEofFlPId, "eofFl", inst->eofFl )) != kOkRC )
kFnamePId, "fname", kBaseSfxId, inst->filename,
kSeekSecsPId, "seekSecs", kBaseSfxId, seekSecs,
kEofFlPId, "eofFl", kBaseSfxId, inst->eofFl )) != kOkRC )
{
goto errLabel;
}
@ -669,7 +783,7 @@ namespace cw
cwLogInfo("Audio '%s' srate:%f chs:%i frames:%i %f seconds.",inst->filename,info.srate,info.chCnt,info.frameCnt, info.frameCnt/info.srate );
// create one output audio buffer - with the same configuration as the source audio file
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, info.srate, info.chCnt, ctx->ctx->framesPerCycle );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, info.srate, info.chCnt, ctx->ctx->framesPerCycle );
errLabel:
return rc;
@ -795,9 +909,9 @@ namespace cw
// Register variables and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx,
kFnamePId, "fname", inst->filename,
kBitsPId, "bits", audioFileBits,
kInPId, "in", src_abuf )) != kOkRC )
kFnamePId, "fname", kBaseSfxId, inst->filename,
kBitsPId, "bits", kBaseSfxId, audioFileBits,
kInPId, "in", kBaseSfxId, src_abuf )) != kOkRC )
{
goto errLabel;
}
@ -902,16 +1016,16 @@ namespace cw
ctx->userPtr = mem::allocZ<inst_t>();
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,abuf )) != kOkRC )
goto errLabel;
// register the gain
for(unsigned i=0; i<abuf->chN; ++i)
if((rc = var_register( ctx, i, kGainPId, "gain" )) != kOkRC )
if((rc = var_register( ctx, i, kGainPId, "gain", kBaseSfxId )) != kOkRC )
goto errLabel;
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
errLabel:
@ -1021,7 +1135,7 @@ namespace cw
ctx->userPtr = inst;
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId, abuf )) != kOkRC )
goto errLabel;
if( abuf->chN )
@ -1030,20 +1144,20 @@ namespace cw
inst->chSelMap = mem::allocZ<bool>(abuf->chN);
if((rc = var_channel_count(ctx,"select",selChN)) != kOkRC )
if((rc = var_channel_count(ctx,"select",kBaseSfxId,selChN)) != kOkRC )
goto errLabel;
// register the gain
for(unsigned i=0; i<abuf->chN; ++i)
{
if( i < selChN )
if((rc = var_register_and_get( ctx, i, kSelectPId, "select", inst->chSelMap[i] )) != kOkRC )
if((rc = var_register_and_get( ctx, i, kSelectPId, "select", kBaseSfxId, inst->chSelMap[i] )) != kOkRC )
goto errLabel;
if( inst->chSelMap[i] )
{
// register an output gain control
if((rc = var_register( ctx, inst->outChN, kGainPId, "gain")) != kOkRC )
if((rc = var_register( ctx, inst->outChN, kGainPId, "gain", kBaseSfxId)) != kOkRC )
goto errLabel;
// count the number of selected channels to determine the count of output channels
@ -1055,7 +1169,7 @@ namespace cw
if( inst->outChN == 0 )
cwLogWarning("The audio split instance '%s' has no selected channels.",ctx->label);
else
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, inst->outChN, abuf->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf->srate, inst->outChN, abuf->frameN );
}
errLabel:
@ -1162,7 +1276,7 @@ namespace cw
ctx->userPtr = inst;
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,abuf )) != kOkRC )
goto errLabel;
if( abuf->chN )
@ -1172,13 +1286,13 @@ namespace cw
// register the gain
for(unsigned i=0; i<abuf->chN; ++i)
{
if((rc = var_register_and_get( ctx, i, kDuplicatePId, "duplicate", inst->chDuplMap[i] )) != kOkRC )
if((rc = var_register_and_get( ctx, i, kDuplicatePId, "duplicate", kBaseSfxId, inst->chDuplMap[i] )) != kOkRC )
goto errLabel;
if( inst->chDuplMap[i] )
{
// register an input gain control
if((rc = var_register( ctx, inst->outChN, kGainPId, "gain")) != kOkRC )
if((rc = var_register( ctx, inst->outChN, kGainPId, "gain", kBaseSfxId)) != kOkRC )
goto errLabel;
// count the number of selected channels to determine the count of output channels
@ -1190,7 +1304,7 @@ namespace cw
if( inst->outChN == 0 )
cwLogWarning("The audio split instance '%s' has no selected channels.",ctx->label);
else
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, inst->outChN, abuf->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf->srate, inst->outChN, abuf->frameN );
}
errLabel:
@ -1309,11 +1423,11 @@ namespace cw
// TODO: allow non-contiguous source labels
// the source labels must be contiguous
if( !var_has_value( ctx, label, kAnyChIdx ) )
if( !var_has_value( ctx, label, kBaseSfxId, kAnyChIdx ) )
break;
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInBasePId+i,label,abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInBasePId+i,label,kBaseSfxId, abuf )) != kOkRC )
{
goto errLabel;
}
@ -1337,11 +1451,11 @@ namespace cw
// register the gain
for(unsigned i=0; i<outChN; ++i)
if((rc = var_register( ctx, i, kGainPId, "gain" )) != kOkRC )
if((rc = var_register( ctx, i, kGainPId, "gain", kBaseSfxId )) != kOkRC )
goto errLabel;
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srate, outChN, frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srate, outChN, frameN );
errLabel:
return rc;
@ -1473,8 +1587,8 @@ namespace cw
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,
kIn0PId,"in0",abuf0,
kIn1PId,"in1",abuf1 )) != kOkRC )
kIn0PId,"in0",kBaseSfxId,abuf0,
kIn1PId,"in1",kBaseSfxId,abuf1 )) != kOkRC )
{
goto errLabel;
}
@ -1484,11 +1598,11 @@ namespace cw
outChN = std::max(abuf0->chN, abuf1->chN);
// register the gain
var_register_and_get( ctx, kAnyChIdx, kGain0PId, "gain0", dum );
var_register_and_get( ctx, kAnyChIdx, kGain1PId, "gain1", dum );
var_register_and_get( ctx, kAnyChIdx, kGain0PId, "gain0", kBaseSfxId, dum );
var_register_and_get( ctx, kAnyChIdx, kGain1PId, "gain1", kBaseSfxId, dum );
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
errLabel:
return rc;
@ -1601,7 +1715,7 @@ namespace cw
ctx->userPtr = inst;
// Register variables and get their current value
if((rc = var_register_and_get( ctx, kAnyChIdx, kChCntPid, "chCnt", chCnt)) != kOkRC )
if((rc = var_register_and_get( ctx, kAnyChIdx, kChCntPid, "chCnt", kBaseSfxId, chCnt)) != kOkRC )
{
goto errLabel;
}
@ -1609,15 +1723,15 @@ namespace cw
// register each oscillator variable
for(unsigned i=0; i<chCnt; ++i)
if((rc = var_register_and_get( ctx, i,
kSratePId, "srate", srate,
kFreqHzPId, "hz", hz,
kGainPId, "gain", gain)) != kOkRC )
kSratePId, "srate", kBaseSfxId, srate,
kFreqHzPId, "hz", kBaseSfxId, hz,
kGainPId, "gain", kBaseSfxId, gain)) != kOkRC )
{
goto errLabel;
}
// create one output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srate, chCnt, ctx->ctx->framesPerCycle );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srate, chCnt, ctx->ctx->framesPerCycle );
inst->phaseA = mem::allocZ<real_t>( chCnt );
@ -1719,7 +1833,7 @@ namespace cw
inst_t* inst = mem::allocZ<inst_t>();
ctx->userPtr = inst;
if((rc = var_register_and_get( ctx, kAnyChIdx,kInPId, "in", srcBuf )) != kOkRC )
if((rc = var_register_and_get( ctx, kAnyChIdx,kInPId, "in", kBaseSfxId, srcBuf )) != kOkRC )
{
cwLogError(kInvalidArgRC,"Unable to access the 'src' buffer.");
}
@ -1746,10 +1860,10 @@ namespace cw
bool hzFl = false;
if((rc = var_register_and_get( ctx, i,
kMaxWndSmpNPId, "maxWndSmpN", maxWndSmpN,
kWndSmpNPId, "wndSmpN", wndSmpN,
kHopSmpNPId, "hopSmpN", hopSmpN,
kHzFlPId, "hzFl", hzFl )) != kOkRC )
kMaxWndSmpNPId, "maxWndSmpN", kBaseSfxId, maxWndSmpN,
kWndSmpNPId, "wndSmpN", kBaseSfxId, wndSmpN,
kHopSmpNPId, "hopSmpN", kBaseSfxId, hopSmpN,
kHzFlPId, "hzFl", kBaseSfxId, hzFl )) != kOkRC )
{
goto errLabel;
}
@ -1771,7 +1885,7 @@ namespace cw
// create the fbuf 'out'
if((rc = var_register_and_set(ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, maxBinNV, binNV, hopNV, magV, phsV, hzV )) != kOkRC )
if((rc = var_register_and_set(ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, maxBinNV, binNV, hopNV, magV, phsV, hzV )) != kOkRC )
{
cwLogError(kOpFailRC,"The output freq. buffer could not be created.");
goto errLabel;
@ -1902,7 +2016,7 @@ namespace cw
inst_t* inst = mem::allocZ<inst_t>();
ctx->userPtr = inst;
if((rc = var_register_and_get( ctx, kAnyChIdx,kInPId, "in", srcBuf)) != kOkRC )
if((rc = var_register_and_get( ctx, kAnyChIdx,kInPId, "in", kBaseSfxId, srcBuf)) != kOkRC )
{
goto errLabel;
}
@ -1925,11 +2039,11 @@ namespace cw
}
}
if((rc = var_register( ctx, kAnyChIdx, kInPId, "in" )) != kOkRC )
if((rc = var_register( ctx, kAnyChIdx, kInPId, "in", kBaseSfxId)) != kOkRC )
goto errLabel;
// create the abuf 'out'
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, ctx->ctx->framesPerCycle );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, ctx->ctx->framesPerCycle );
}
errLabel:
@ -2035,7 +2149,7 @@ namespace cw
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
@ -2070,13 +2184,13 @@ namespace cw
spec_dist_t* sd = inst->sdA[i];
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", sd->bypassFl,
kCeilingPId, "ceiling", sd->ceiling,
kExpoPId, "expo", sd->expo,
kThreshPId, "thresh", sd->thresh,
kUprSlopePId, "upr", sd->uprSlope,
kLwrSlopePId, "lwr", sd->lwrSlope,
kMixPId, "mix", sd->mix )) != kOkRC )
kBypassPId, "bypass", kBaseSfxId, sd->bypassFl,
kCeilingPId, "ceiling", kBaseSfxId, sd->ceiling,
kExpoPId, "expo", kBaseSfxId, sd->expo,
kThreshPId, "thresh", kBaseSfxId, sd->thresh,
kUprSlopePId, "upr", kBaseSfxId, sd->uprSlope,
kLwrSlopePId, "lwr", kBaseSfxId, sd->lwrSlope,
kMixPId, "mix", kBaseSfxId, sd->mix )) != kOkRC )
{
goto errLabel;
}
@ -2084,7 +2198,7 @@ namespace cw
}
// create the output buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->maxBinN_V, srcBuf->binN_V, srcBuf->hopSmpN_V, magV, phsV, hzV )) != kOkRC )
if((rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->maxBinN_V, srcBuf->binN_V, srcBuf->hopSmpN_V, magV, phsV, hzV )) != kOkRC )
goto errLabel;
}
@ -2223,7 +2337,7 @@ namespace cw
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
@ -2243,15 +2357,15 @@ namespace cw
// get the compressor variable values
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", bypassFl,
kInGainPId, "igain", igain,
kThreshPId, "thresh", thresh,
kRatioPId, "ratio", ratio,
kAtkMsPId, "atk_ms", atk_ms,
kRlsMsPId, "rls_ms", rls_ms,
kWndMsPId, "wnd_ms", wnd_ms,
kMaxWndMsPId, "maxWnd_ms", maxWnd_ms,
kOutGainPId, "ogain", ogain )) != kOkRC )
kBypassPId, "bypass", kBaseSfxId, bypassFl,
kInGainPId, "igain", kBaseSfxId, igain,
kThreshPId, "thresh", kBaseSfxId, thresh,
kRatioPId, "ratio", kBaseSfxId, ratio,
kAtkMsPId, "atk_ms", kBaseSfxId, atk_ms,
kRlsMsPId, "rls_ms", kBaseSfxId, rls_ms,
kWndMsPId, "wnd_ms", kBaseSfxId, wnd_ms,
kMaxWndMsPId, "maxWnd_ms", kBaseSfxId, maxWnd_ms,
kOutGainPId, "ogain", kBaseSfxId, ogain )) != kOkRC )
{
goto errLabel;
}
@ -2266,7 +2380,7 @@ namespace cw
}
// create the output audio buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
if((rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
goto errLabel;
}
@ -2411,7 +2525,7 @@ namespace cw
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
@ -2431,10 +2545,10 @@ namespace cw
// get the limiter variable values
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", bypassFl,
kInGainPId, "igain", igain,
kThreshPId, "thresh", thresh,
kOutGainPId, "ogain", ogain )) != kOkRC )
kBypassPId, "bypass", kBaseSfxId, bypassFl,
kInGainPId, "igain", kBaseSfxId, igain,
kThreshPId, "thresh", kBaseSfxId, thresh,
kOutGainPId, "ogain", kBaseSfxId, ogain )) != kOkRC )
{
goto errLabel;
}
@ -2449,7 +2563,7 @@ namespace cw
}
// create the output audio buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
if((rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
goto errLabel;
}
@ -2585,7 +2699,7 @@ namespace cw
ctx->userPtr = inst;
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,abuf )) != kOkRC )
goto errLabel;
@ -2596,8 +2710,8 @@ namespace cw
for(unsigned i=0; i<abuf->chN; ++i)
{
if((rc = var_register_and_get( ctx, i,
kMaxDelayMsPId, "maxDelayMs", maxDelayMs,
kDelayMsPId, "delayMs", delayMs)) != kOkRC )
kMaxDelayMsPId, "maxDelayMs", kBaseSfxId, maxDelayMs,
kDelayMsPId, "delayMs", kBaseSfxId, delayMs)) != kOkRC )
{
goto errLabel;
}
@ -2617,7 +2731,7 @@ namespace cw
inst->delayBuf = abuf_create( abuf->srate, abuf->chN, inst->maxDelayFrameN );
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
errLabel:
@ -2775,7 +2889,7 @@ namespace cw
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
@ -2795,8 +2909,8 @@ namespace cw
// get the dc_filter variable values
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", bypassFl,
kGainPId, "gain", gain )) != kOkRC )
kBypassPId, "bypass", kBaseSfxId, bypassFl,
kGainPId, "gain", kBaseSfxId, gain )) != kOkRC )
{
goto errLabel;
}
@ -2811,7 +2925,7 @@ namespace cw
}
// create the output audio buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
if((rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
goto errLabel;
}
@ -2931,7 +3045,7 @@ namespace cw
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
@ -2950,18 +3064,18 @@ namespace cw
// get the audio_meter variable values
if((rc = var_register_and_get( ctx, i,
kDbFlPId, "dbFl", dbFl,
kWndMsPId, "wndMs", wndMs,
kPeakDbPId, "peakDb", peakThreshDb )) != kOkRC )
kDbFlPId, "dbFl", kBaseSfxId, dbFl,
kWndMsPId, "wndMs", kBaseSfxId, wndMs,
kPeakDbPId, "peakDb", kBaseSfxId, peakThreshDb )) != kOkRC )
{
goto errLabel;
}
// get the audio_meter variable values
if((rc = var_register( ctx, i,
kOutPId, "out",
kPeakFlPId, "peakFl",
kClipFlPId, "clipFl" )) != kOkRC )
kOutPId, "out", kBaseSfxId,
kPeakFlPId, "peakFl", kBaseSfxId,
kClipFlPId, "clipFl", kBaseSfxId )) != kOkRC )
{
goto errLabel;
}
@ -3075,15 +3189,15 @@ namespace cw
ctx->userPtr = mem::allocZ<inst_t>();
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",kBaseSfxId,abuf )) != kOkRC )
goto errLabel;
// register the marker input
if((rc = var_register_and_set( ctx, kAnyChIdx, kMarkPId, "mark", 0.0f )) != kOkRC )
if((rc = var_register_and_set( ctx, kAnyChIdx, kMarkPId, "mark", kBaseSfxId, 0.0f )) != kOkRC )
goto errLabel;
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf->srate, abuf->chN, abuf->frameN );
errLabel:
return rc;
@ -3148,6 +3262,307 @@ namespace cw
}
//------------------------------------------------------------------------------------------------------------------
//
// xfade_ctl
//
namespace xfade_ctl
{
enum {
kNetLabelPId,
kNetLabelSfxPId,
kSrateRefPId,
kDurMsPId,
kTriggerPId,
kGainPId,
};
typedef struct
{
unsigned xfadeDurMs; // crossfade duration in milliseconds
instance_t* net_proc; // source 'poly' network
network_t net; // internal proxy network
unsigned poly_ch_cnt; // set to 2 (one for 'cur' poly-ch., one for 'next' poly-ch.)
unsigned net_proc_cnt; // count of proc's in a single poly-channel (net_proc->proc_arrayN/poly_cnt)
unsigned cur_poly_ch_idx; //
unsigned next_poly_ch_idx; //
float* target_gainA; // target_gainA[net_proc->poly_cnt]
float* cur_gainA; // cur_gainA[net_proc->poly_cnt]
double srate;
} inst_t;
void _trigger_xfade( inst_t* p )
{
// begin fading out the cur channel
p->target_gainA[ p->cur_poly_ch_idx ] = 0;
// the next poly-ch become the cur poly-ch
p->cur_poly_ch_idx = p->next_poly_ch_idx;
// the next poly-ch advances
p->next_poly_ch_idx = p->next_poly_ch_idx+1 >= p->poly_ch_cnt ? 0 : p->next_poly_ch_idx+1;
// j selects a block of 'net_proc_cnt' slots in the proxy network which will become the 'next' channel
unsigned j = p->next_poly_ch_idx * p->net_proc_cnt;
// set the [j:j+poly_proc_cnt] pointers in the proxy net to the actual proc instances in the source net
for(unsigned i=0; i<p->net_proc->internal_net->proc_arrayN; ++i)
if( p->net_proc->internal_net->proc_array[i]->label_sfx_id == p->next_poly_ch_idx )
{
assert( p->next_poly_ch_idx * p->net_proc_cnt <= j
&& j < p->next_poly_ch_idx * p->net_proc_cnt + p->net_proc_cnt
&& j < p->net.proc_arrayN );
p->net.proc_array[j++] = p->net_proc->internal_net->proc_array[i];
}
// begin fading in the new cur channel
p->target_gainA[ p->cur_poly_ch_idx ] = 1;
// if the next channel is not already at 0 send it in that direction
p->target_gainA[ p->next_poly_ch_idx ] = 0;
}
rc_t create( instance_t* ctx )
{
rc_t rc = kOkRC;
const char* netLabel = nullptr;
unsigned netLabelSfxId = kBaseSfxId;
bool trigFl = false;
variable_t* gainVar = nullptr;
abuf_t* srateSrc = nullptr;
double dum;
inst_t* p = mem::allocZ<inst_t>();
ctx->userPtr = p;
p->poly_ch_cnt = 2;
if((rc = var_register_and_get(ctx,kAnyChIdx,
kNetLabelPId, "net", kBaseSfxId, netLabel,
kNetLabelSfxPId, "netSfxId", kBaseSfxId, netLabelSfxId,
kSrateRefPId, "srateSrc", kBaseSfxId, srateSrc,
kDurMsPId, "durMs", kBaseSfxId, p->xfadeDurMs,
kTriggerPId, "trigger", kBaseSfxId, trigFl,
kGainPId, "gain", kBaseSfxId, dum)) != kOkRC )
{
goto errLabel;
}
// locate the source poly-network for this xfad-ctl
if((rc = instance_find(*ctx->net,netLabel,netLabelSfxId,p->net_proc)) != kOkRC )
{
cwLogError(rc,"The xfade_ctl source network proc instance '%s:%i' was not found.",cwStringNullGuard(netLabel),netLabelSfxId);
goto errLabel;
}
if( p->net_proc->internal_net->poly_cnt < 3 )
{
cwLogError(rc,"The xfade_ctl source network must have at least 3 poly channels. %i < 3",p->net_proc->internal_net->poly_cnt);
goto errLabel;
}
// create the gain output variables - one output for each poly-channel
for(unsigned i=1; i<p->net_proc->internal_net->poly_cnt; ++i)
{
variable_t* dum;
if((rc = var_create(ctx, "gain", i, kGainPId+i, kAnyChIdx, nullptr, dum )) != kOkRC )
{
cwLogError(rc,"'gain:%i' create failed.",i);
goto errLabel;
}
}
// count of proc's in one poly-ch of the poly network
p->net_proc_cnt = p->net_proc->internal_net->proc_arrayN / p->net_proc->internal_net->poly_cnt;
// create the proxy network
p->net.proc_arrayAllocN = p->net_proc_cnt * p->poly_ch_cnt;
p->net.proc_arrayN = p->net.proc_arrayAllocN;
p->net.proc_array = mem::allocZ<instance_t*>(p->net.proc_arrayAllocN);
p->target_gainA = mem::allocZ<float>(p->net_proc->internal_net->poly_cnt);
p->cur_gainA = mem::allocZ<float>(p->net_proc->internal_net->poly_cnt);
p->srate = srateSrc->srate;
// make the proxy network public - xfad_ctl now looks like the source network
// because it has the same proc instances
ctx->internal_net = &p->net;
// setup the channels such that the first active channel after _trigger_xfade()
// will be channel 0
p->cur_poly_ch_idx = 1;
p->next_poly_ch_idx = 2;
_trigger_xfade(p); // cur=2 nxt=0 initialize inst ptrs in range: p->net[0:net_proc_cnt]
_trigger_xfade(p); // cur=0 nxt=1 initialize inst ptrs in range: p->net[net_proc_cnt:2*net_proc_cnt]
errLabel:
return rc;
}
rc_t destroy( instance_t* ctx )
{
inst_t* p = (inst_t*)ctx->userPtr;
mem::release(p->net.proc_array);
mem::release(p->target_gainA);
mem::release(p->cur_gainA);
mem::release(ctx->userPtr);
return kOkRC;
}
rc_t value( instance_t* ctx, variable_t* var )
{ return kOkRC; }
// return sign of expression as a float
float _signum( float v ) { return (0.0f < v) - (v < 0.0f); }
rc_t exec( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* p = (inst_t*)ctx->userPtr;
bool trigFl = false;
// check if a cross-fade has been triggered
if((rc = var_get(ctx,kTriggerPId,kAnyChIdx,trigFl)) == kOkRC )
{
_trigger_xfade(p);
var_set(ctx,kTriggerPId,kAnyChIdx,false);
}
// time in sample frames to complete a xfade
double xfade_dur_smp = p->xfadeDurMs * p->srate / 1000.0;
// fraction of a xfade which will be completed in on exec() cycle
float delta_gain_per_cycle = (float)(ctx->ctx->framesPerCycle / xfade_dur_smp);
// update the cross-fade gain outputs
for(unsigned i=0; i<p->net_proc->internal_net->poly_cnt; ++i)
{
p->cur_gainA[i] += _signum(p->target_gainA[i] - p->cur_gainA[i]) * delta_gain_per_cycle;
p->cur_gainA[i] = std::min(1.0f, std::max(0.0f, p->cur_gainA[i]));
var_set(ctx,kGainPId+i,kAnyChIdx,p->cur_gainA[i]);
}
errLabel:
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
//------------------------------------------------------------------------------------------------------------------
//
// poly_mixer
//
namespace poly_mixer
{
enum {
kOutGainPId,
kOutPId,
};
typedef struct
{
unsigned inBaseVId;
unsigned gainBaseVId;
} inst_t;
rc_t create( instance_t* ctx )
{
rc_t rc = kOkRC;
/*
const abuf_t* abuf0 = nullptr; //
const abuf_t* abuf1 = nullptr;
unsigned outChN = 0;
double dum;
// get the source audio buffer
if((rc = var_register_and_get(ctx, kAnyChIdx,
kIn0PId,"in0",kBaseSfxId,abuf0,
kIn1PId,"in1",kBaseSfxId,abuf1 )) != kOkRC )
{
goto errLabel;
}
assert( abuf0->frameN == abuf1->frameN );
outChN = std::max(abuf0->chN, abuf1->chN);
// register the gain
var_register_and_get( ctx, kAnyChIdx, kGain0PId, "gain0", kBaseSfxId, dum );
var_register_and_get( ctx, kAnyChIdx, kGain1PId, "gain1", kBaseSfxId, dum );
// create the output audio buffer
rc = var_register_and_set( ctx, "out", kBaseSfxId, kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
*/
errLabel:
return rc;
}
rc_t destroy( instance_t* ctx )
{ return kOkRC; }
rc_t value( instance_t* ctx, variable_t* var )
{ return kOkRC; }
rc_t exec( instance_t* ctx )
{
rc_t rc = kOkRC;
/*
abuf_t* obuf = nullptr;
//const abuf_t* ibuf0 = nullptr;
//const abuf_t* ibuf1 = nullptr;
if((rc = var_get(ctx,kOutPId, kAnyChIdx, obuf)) != kOkRC )
goto errLabel;
//if((rc = var_get(ctx,kIn0PId, kAnyChIdx, ibuf0 )) != kOkRC )
// goto errLabel;
//if((rc = var_get(ctx,kIn1PId, kAnyChIdx, ibuf1 )) != kOkRC )
// goto errLabel;
vop::zero(obuf->buf, obuf->frameN*obuf->chN );
_mix( ctx, kIn0PId, kGain0PId, obuf );
_mix( ctx, kIn1PId, kGain1PId, obuf );
*/
errLabel:
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = nullptr
};
}
} // flow
} // cw

View File

@ -2,6 +2,7 @@ namespace cw
{
namespace flow
{
namespace poly { extern class_members_t members; }
namespace midi_in { extern class_members_t members; }
namespace midi_out { extern class_members_t members; }
namespace audio_in { extern class_members_t members; }
@ -24,5 +25,7 @@ namespace cw
namespace balance { extern class_members_t members; }
namespace audio_meter { extern class_members_t members; }
namespace audio_marker { extern class_members_t members; }
namespace xfade_ctl { extern class_members_t members; }
namespace poly_mixer { extern class_members_t members; }
}
}

View File

@ -393,7 +393,7 @@ namespace cw
return cwLogError(kInvalidArgRC,"Cannnot get the value of a non-existent variable.");
if( var->value == nullptr )
return cwLogError(kInvalidStateRC,"No value has been assigned to the variable: %s.%s ch:%i.",cwStringNullGuard(var->inst->label),cwStringNullGuard(var->label),var->chIdx);
return cwLogError(kInvalidStateRC,"No value has been assigned to the variable: %s:%i.%s:%i ch:%i.",cwStringNullGuard(var->inst->label),var->inst->label_sfx_id,cwStringNullGuard(var->label),var->label_sfx_id,var->chIdx);
return _val_get(var->value,valRef);
}
@ -408,7 +408,7 @@ namespace cw
{
// validate the type of the variable against the description
if( !cwIsFlag(varRef->varDesc->type,typeFl ) )
rc = cwLogError(kTypeMismatchRC,"Type mismatch. Instance:%s variable:%s with type 0x%x does not match requested type:0x%x.",varRef->inst->label,varRef->label,varRef->varDesc->type,typeFl);
rc = cwLogError(kTypeMismatchRC,"Type mismatch. Instance:%s:%i variable:%s:%i with type 0x%x does not match requested type:0x%x.",varRef->inst->label,varRef->inst->label_sfx_id,varRef->label,varRef->label_sfx_id,varRef->varDesc->type,typeFl);
}
@ -430,16 +430,16 @@ namespace cw
return kOkRC;
}
}
return cwLogError(kInvalidIdRC,"The variable matching id:%i ch:%i on instance '%s' could not be found.", vid, chIdx, inst->label);
return cwLogError(kInvalidIdRC,"The variable matching id:%i ch:%i on instance '%s:%i' could not be found.", vid, chIdx, inst->label, inst->label_sfx_id);
}
// Variable lookup: Exact match on label and chIdx
variable_t* _var_find_on_label_and_ch( instance_t* inst, const char* var_label, unsigned chIdx )
variable_t* _var_find_on_label_and_ch( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx )
{
for(variable_t* var = inst->varL; var!=nullptr; var=var->var_link)
{
// the variable vid and chIdx should form a unique pair
if( textCompare(var->label,var_label)==0 && var->chIdx == chIdx )
if( var->label_sfx_id==sfx_id && textCompare(var->label,var_label)==0 && var->chIdx == chIdx )
return var;
}
@ -450,10 +450,10 @@ namespace cw
rc_t _validate_var_assignment( variable_t* var, unsigned typeFl )
{
if( cwIsFlag(var->varDesc->flags, kSrcVarFl ) )
return cwLogError(kInvalidStateRC, "The variable '%s' on instance '%s' cannot be set because it is a 'src' variable.", var->label, var->inst->label);
return cwLogError(kInvalidStateRC, "The variable '%s:%i' on instance '%s:%i' cannot be set because it is a 'src' variable.", var->label, var->label_sfx_id, var->inst->label,var->inst->label_sfx_id);
if( !cwIsFlag(var->varDesc->type, typeFl ) )
return cwLogError(kTypeMismatchRC, "The variable '%s' on instance '%s' is not a '%s'.", var->label, var->inst->label, _typeFlagToLabel( typeFl ));
return cwLogError(kTypeMismatchRC, "The variable '%s:%i' on instance '%s:%i' is not a '%s'.", var->label, var->label_sfx_id, var->inst->label, var->inst->label_sfx_id, _typeFlagToLabel( typeFl ));
return kOkRC;
}
@ -482,7 +482,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.b = val;
var->local_value[ local_value_idx ].flags = kBoolTFl;
cwLogMod("%s.%s ch:%i %i (bool).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %i (bool).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -490,7 +490,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.u = val;
var->local_value[ local_value_idx ].flags = kUIntTFl;
cwLogMod("%s.%s ch:%i %i (uint).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %i (uint).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -498,7 +498,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.i = val;
var->local_value[ local_value_idx ].flags = kIntTFl;
cwLogMod("%s.%s ch:%i %i (int).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %i (int).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -506,7 +506,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.f = val;
var->local_value[ local_value_idx ].flags = kFloatTFl;
cwLogMod("%s.%s ch:%i %f (float).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %f (float).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -514,7 +514,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.d = val;
var->local_value[ local_value_idx ].flags = kDoubleTFl;
cwLogMod("%s.%s ch:%i %f (double).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %f (double).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -522,7 +522,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.s = mem::duplStr(val);
var->local_value[ local_value_idx ].flags = kStringTFl;
cwLogMod("%s.%s ch:%i %s (string).",var->inst->label,var->label,var->chIdx,val);
cwLogMod("%s:%i.%s:%i ch:%i %s (string).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,val);
}
template<>
@ -530,7 +530,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.abuf = val;
var->local_value[ local_value_idx ].flags = kABufTFl;
cwLogMod("%s.%s ch:%i %s (abuf).",var->inst->label,var->label,var->chIdx,abuf==nullptr ? "null" : "valid");
cwLogMod("%s:%i.%s:%i ch:%i %s (abuf).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,abuf==nullptr ? "null" : "valid");
}
template<>
@ -538,7 +538,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.mbuf = val;
var->local_value[ local_value_idx ].flags = kMBufTFl;
cwLogMod("%s.%s ch:%i %s (abuf).",var->inst->label,var->label,var->chIdx,mbuf==nullptr ? "null" : "valid");
cwLogMod("%s:%i.%s:%i ch:%i %s (abuf).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,mbuf==nullptr ? "null" : "valid");
}
template<>
@ -546,7 +546,7 @@ namespace cw
{
var->local_value[ local_value_idx ].u.fbuf = val;
var->local_value[ local_value_idx ].flags = kFBufTFl;
cwLogMod("%s.%s ch:%i %s (fbuf).",var->inst->label,var->label,var->chIdx,fbuf==nullptr ? "null" : "valid");
cwLogMod("%s:%i.%s:%i ch:%i %s (fbuf).",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,var->chIdx,fbuf==nullptr ? "null" : "valid");
}
template< typename T >
@ -644,11 +644,11 @@ namespace cw
}
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, abuf_t* abuf )
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, abuf_t* abuf )
{
rc_t rc;
variable_t* var = nullptr;
if((rc = var_register_and_set( inst, var_label, vid, chIdx, var)) != kOkRC )
if((rc = var_register_and_set( inst, var_label, sfx_id, vid, chIdx, var)) != kOkRC )
return rc;
if( var != nullptr )
@ -657,11 +657,11 @@ namespace cw
return rc;
}
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, mbuf_t* mbuf )
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, mbuf_t* mbuf )
{
rc_t rc;
variable_t* var = nullptr;
if((rc = var_register_and_set( inst, var_label, vid, chIdx, var)) != kOkRC )
if((rc = var_register_and_set( inst, var_label, sfx_id, vid, chIdx, var)) != kOkRC )
return rc;
if( var != nullptr )
@ -670,11 +670,11 @@ namespace cw
return rc;
}
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, fbuf_t* fbuf )
rc_t _var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, fbuf_t* fbuf )
{
rc_t rc;
variable_t* var = nullptr;
if((rc = var_register_and_set( inst, var_label, vid, chIdx, var)) != kOkRC )
if((rc = var_register_and_set( inst, var_label, sfx_id, vid, chIdx, var)) != kOkRC )
return rc;
if( var != nullptr )
@ -746,7 +746,7 @@ namespace cw
errLabel:
if( rc != kOkRC )
rc = cwLogError(kSyntaxErrorRC,"The %s.%s could not extract a type:%s from a configuration value.",var->inst->label,var->label,_typeFlagToLabel(var->varDesc->type & kTypeMask));
rc = cwLogError(kSyntaxErrorRC,"The %s:%i.%s:%i could not extract a type:%s from a configuration value.",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id,_typeFlagToLabel(var->varDesc->type & kTypeMask));
return rc;
}
@ -757,20 +757,20 @@ namespace cw
// verify that the map idx is valid
if( idx >= inst->varMapN )
return cwLogError(kAssertFailRC,"The variable map positioning location %i is out of the range %i on instance '%s' vid:%i ch:%i.", idx, inst->varMapN, inst->label,vid,chIdx);
return cwLogError(kAssertFailRC,"The variable map positioning location %i is out of the range %i on instance '%s:%i' vid:%i ch:%i.", idx, inst->varMapN, inst->label,inst->label_sfx_id,vid,chIdx);
idxRef = idx;
return kOkRC;
}
rc_t _var_map_label_to_index( instance_t* inst, const char* var_label, unsigned chIdx, unsigned& idxRef )
rc_t _var_map_label_to_index( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, unsigned& idxRef )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
idxRef = kInvalidIdx;
if((rc = var_find(inst, var_label, chIdx, var )) == kOkRC)
if((rc = var_find(inst, var_label, sfx_id, chIdx, var )) == kOkRC)
rc = _var_map_id_to_index( inst, var->vid, chIdx, idxRef );
return rc;
@ -787,9 +787,9 @@ namespace cw
if( new_var->chIdx == kAnyChIdx )
return kOkRC;
if((base_var = _var_find_on_label_and_ch( inst, new_var->label, kAnyChIdx )) == nullptr )
if((base_var = _var_find_on_label_and_ch( inst, new_var->label, new_var->label_sfx_id, kAnyChIdx )) == nullptr )
{
rc = cwLogError(kInvalidStateRC,"The base channel variable does not exist for '%s.%s'. This is an illegal state.", inst->label, new_var->label );
rc = cwLogError(kInvalidStateRC,"The base channel variable does not exist for '%s:%i.%s:%i'. This is an illegal state.", inst->label, inst->label_sfx_id, new_var->label, new_var->label_sfx_id );
goto errLabel;
}
@ -815,7 +815,7 @@ namespace cw
// Create a variable and set it's value from 'value_cfg'.
// If 'value_cfg' is null then use the value from var->varDesc->val_cfg.
rc_t _var_create( instance_t* inst, const char* var_label, unsigned id, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
rc_t _var_create( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned id, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
@ -824,28 +824,29 @@ namespace cw
varRef = nullptr;
// if this var already exists - it can't be created again
if((var = _var_find_on_label_and_ch(inst,var_label,chIdx)) != nullptr )
if((var = _var_find_on_label_and_ch(inst,var_label, sfx_id, chIdx)) != nullptr )
{
rc = cwLogError(kInvalidStateRC,"The variable '%s' ch:%i has already been created on the instance: '%s'.",var_label,chIdx,inst->label);
rc = cwLogError(kInvalidStateRC,"The variable '%s:%i' ch:%i has already been created on the instance: '%s:%i'.",var_label,sfx_id,chIdx,inst->label,inst->label_sfx_id);
goto errLabel;
}
// locate the var desc
if((vd = var_desc_find( inst->class_desc, var_label)) == nullptr )
{
rc = cwLogError(kInvalidIdRC,"Unable to locate the variable '%s' in class '%s'.", var_label, inst->class_desc->label );
rc = cwLogError(kInvalidIdRC,"Unable to locate the variable '%s:%i' in class '%s'.", var_label, sfx_id, inst->class_desc->label );
goto errLabel;
}
// create the var
var = mem::allocZ<variable_t>();
var->varDesc = vd;
var->inst = inst;
var->label = mem::duplStr(var_label);
var->vid = id;
var->chIdx = chIdx;
var->value = nullptr;
var->varDesc = vd;
var->inst = inst;
var->label = mem::duplStr(var_label);
var->label_sfx_id = sfx_id;
var->vid = id;
var->chIdx = chIdx;
var->value = nullptr;
// if no value was given then set the value to the value given in the class
if( value_cfg == nullptr )
@ -868,12 +869,12 @@ namespace cw
if( rc != kOkRC )
{
_var_destroy(var);
cwLogError(kOpFailRC,"Variable creation failed on '%s.%s' ch:%i.", inst->label, var_label, chIdx );
cwLogError(kOpFailRC,"Variable creation failed on '%s:%i.%s:%i' ch:%i.", inst->label, inst->label_sfx_id, var_label, sfx_id, chIdx );
}
else
{
varRef = var;
cwLogMod("Created var: %s.%s ch:%i.", inst->label, var_label, chIdx );
cwLogMod("Created var: %s:%i.%s:%i ch:%i.", inst->label, inst->label_sfx_id, var_label, sfx_id, chIdx );
}
return rc;
@ -883,31 +884,34 @@ namespace cw
{
const char* conn_label = is_connected_to_external_proc(var) ? "extern" : " ";
printf(" %20s id:%4i ch:%3i : %s : ", var->label, var->vid, var->chIdx, conn_label );
printf(" %20s:%5i id:%4i ch:%3i : %s : ", var->label, var->label_sfx_id, var->vid, var->chIdx, conn_label );
if( var->value == nullptr )
_value_print( &var->local_value[0] );
else
_value_print( var->value );
if( var->src_var != nullptr )
printf(" src:%s:%i.%s:%i",var->src_var->inst->label,var->src_var->inst->label_sfx_id,var->src_var->label,var->src_var->label_sfx_id);
printf("\n");
}
rc_t _preset_set_var_value( instance_t* inst, const char* var_label, unsigned chIdx, const object_t* value )
rc_t _preset_set_var_value( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
// get the variable
if((rc = var_find( inst, var_label, chIdx, var )) != kOkRC )
if((rc = var_find( inst, var_label, sfx_id, chIdx, var )) != kOkRC )
goto errLabel;
rc = _set_var_value_from_cfg( var, value );
errLabel:
if( rc != kOkRC )
rc = cwLogError(rc,"The value of instance:%s variable:%s could not be set via a preset.", inst->label, var_label );
rc = cwLogError(rc,"The value of instance:%s:%i variable:%s:%i could not be set via a preset.", inst->label, inst->label_sfx_id, var_label, sfx_id );
return rc;
}
@ -1136,37 +1140,52 @@ void cw::flow::class_dict_print( flow_t* p )
for(; vd!=nullptr; vd=vd->link)
{
const char* srcFlStr = vd->flags & kSrcVarFl ? "src" : " ";
const char* srcOptFlStr = vd->flags & kSrcOptVarFl ? "srcOpt" : " ";
const char* srcFlStr = vd->flags & kSrcVarFl ? "src" : " ";
const char* srcOptFlStr = vd->flags & kSrcOptVarFl ? "srcOpt" : " ";
const char* plyMltFlStr = vd->flags & kMultVarFl ? "mult" : " ";
printf(" %10s 0x%08x %s %s %s\n", cwStringNullGuard(vd->label), vd->type, srcFlStr, srcOptFlStr, cwStringNullGuard(vd->docText) );
printf(" %10s 0x%08x %s %s %s %s\n", cwStringNullGuard(vd->label), vd->type, srcFlStr, srcOptFlStr, plyMltFlStr, cwStringNullGuard(vd->docText) );
}
}
}
void cw::flow::network_print( flow_t* p )
void cw::flow::network_print( const network_t& net )
{
for(instance_t* inst = p->network_head; inst!=nullptr; inst=inst->link)
// for each instance in the network
for(unsigned i=0; i<net.proc_arrayN; ++i)
{
instance_t* inst = net.proc_array[i];
instance_print(inst);
// if this instance has an internal network
if( inst->internal_net != nullptr )
{
printf("------- Begin Nested Network: %s -------\n",cwStringNullGuard(inst->label));
network_print(*(inst->internal_net));
printf("------- End Nested Network: %s -------\n",cwStringNullGuard(inst->label));
}
}
}
cw::flow::instance_t* cw::flow::instance_find( flow_t* p, const char* inst_label )
cw::flow::instance_t* cw::flow::instance_find( network_t& net, const char* inst_label, unsigned sfx_id )
{
for(instance_t* inst = p->network_head; inst!=nullptr; inst=inst->link )
if( textCompare(inst_label,inst->label) == 0 )
return inst;
for(unsigned i=0; i<net.proc_arrayN; ++i)
if( net.proc_array[i]->label_sfx_id==sfx_id && textIsEqual(inst_label,net.proc_array[i]->label) )
return net.proc_array[i];
return nullptr;
}
cw::rc_t cw::flow::instance_find( flow_t* p, const char* inst_label, instance_t*& instPtrRef )
cw::rc_t cw::flow::instance_find( network_t& net, const char* inst_label, unsigned sfx_id, instance_t*& instPtrRef )
{
rc_t rc = kOkRC;
if((instPtrRef = instance_find(p,inst_label)) != nullptr )
if((instPtrRef = instance_find(net,inst_label,sfx_id)) != nullptr )
return rc;
return cwLogError(kInvalidArgRC,"The instance '%s' was not found.", inst_label );
return cwLogError(kInvalidArgRC,"The instance '%s:%i' was not found.", inst_label, sfx_id );
}
cw::flow::external_device_t* cw::flow::external_device_find( flow_t* p, const char* device_label, unsigned typeId, unsigned inOrOutFl, const char* midiPortLabel )
@ -1185,7 +1204,7 @@ cw::flow::external_device_t* cw::flow::external_device_find( flow_t* p, const ch
void cw::flow::instance_print( instance_t* inst )
{
printf("%s\n", inst->label);
printf("%s:%i\n", inst->label,inst->label_sfx_id);
for(variable_t* var = inst->varL; var!=nullptr; var=var->var_link)
if( var->chIdx == kAnyChIdx )
for(variable_t* v0 = var; v0!=nullptr; v0=v0->ch_link)
@ -1209,31 +1228,31 @@ void cw::flow::_var_destroy( variable_t* var )
}
cw::rc_t cw::flow::var_create( instance_t* inst, const char* var_label, unsigned id, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
cw::rc_t cw::flow::var_create( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned id, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
{
rc_t rc = kOkRC;
rc = _var_create( inst, var_label, id, chIdx, value_cfg, varRef );
rc = _var_create( inst, var_label, sfx_id, id, chIdx, value_cfg, varRef );
return rc;
}
cw::rc_t cw::flow::var_channelize( instance_t* inst, const char* var_label, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef )
cw::rc_t cw::flow::var_channelize( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
variable_t* base_var = nullptr;
varRef = nullptr;
if((base_var = _var_find_on_label_and_ch( inst, var_label, kAnyChIdx)) == nullptr)
if((base_var = _var_find_on_label_and_ch( inst, var_label, sfx_id, kAnyChIdx)) == nullptr)
{
rc = cwLogError(kInvalidStateRC,"The base ('any') channel variable could not be located on '%s.%s'.",inst->label,var_label);
rc = cwLogError(kInvalidStateRC,"The base ('any') channel variable could not be located on '%s:%i.%s:%i'.",inst->label,inst->label_sfx_id,var_label,sfx_id);
goto errLabel;
}
// locate the variable with the stated chIdx
var = _var_find_on_label_and_ch( inst, var_label, chIdx );
var = _var_find_on_label_and_ch( inst, var_label, sfx_id, chIdx );
// 'src' variables cannot be channelized
@ -1247,7 +1266,7 @@ cw::rc_t cw::flow::var_channelize( instance_t* inst, const char* var_label, uns
if( var == nullptr && chIdx != kAnyChIdx )
{
// create the channelized var
if((rc = _var_create( inst, var_label, vid, chIdx, value_cfg, var )) != kOkRC )
if((rc = _var_create( inst, var_label, sfx_id, vid, chIdx, value_cfg, var )) != kOkRC )
goto errLabel;
// if no value was set then set the value from the 'any' channel
@ -1272,7 +1291,7 @@ cw::rc_t cw::flow::var_channelize( instance_t* inst, const char* var_label, uns
}
else
{
cwLogWarning("An existing var (%s.%s ch:%i) was specified for channelizing but no value was provided.", inst->label, var_label, chIdx );
cwLogWarning("An existing var (%s:i.%s:i ch:%i) was specified for channelizing but no value was provided.", inst->label, inst->label_sfx_id, var_label, sfx_id, chIdx );
}
}
@ -1281,20 +1300,20 @@ cw::rc_t cw::flow::var_channelize( instance_t* inst, const char* var_label, uns
errLabel:
if( rc != kOkRC )
rc = cwLogError(rc,"Channelize failed for variable '%s' on instance '%s' ch:%i.", var_label, inst->label, chIdx );
rc = cwLogError(rc,"Channelize failed for variable '%s:%i' on instance '%s:i' ch:%i.", var_label, sfx_id, inst->label, inst->label_sfx_id, chIdx );
return rc;
}
bool cw::flow::var_exists( instance_t* inst, const char* label, unsigned chIdx )
{ return _var_find_on_label_and_ch(inst,label,chIdx) != nullptr; }
bool cw::flow::var_exists( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx )
{ return _var_find_on_label_and_ch(inst,label,sfx_id,chIdx) != nullptr; }
bool cw::flow::var_has_value( instance_t* inst, const char* label, unsigned chIdx )
bool cw::flow::var_has_value( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx )
{
variable_t* varPtr = nullptr;
rc_t rc;
if((rc = var_find( inst, label, chIdx, varPtr )) != kOkRC )
if((rc = var_find( inst, label, sfx_id, chIdx, varPtr )) != kOkRC )
return false;
return varPtr->value != nullptr;
@ -1322,7 +1341,7 @@ cw::rc_t cw::flow::var_find( instance_t* inst, unsigned vid, unsigned chIdx, var
var = inst->varMapA[idx];
else
{
rc = cwLogError(kInvalidIdRC,"The index of variable vid:%i chIdx:%i on instance '%s' could not be calculated and the variable value could not be retrieved.", vid, chIdx, inst->label);
rc = cwLogError(kInvalidIdRC,"The index of variable vid:%i chIdx:%i on instance '%s:%i' could not be calculated and the variable value could not be retrieved.", vid, chIdx, inst->label,inst->label_sfx_id);
goto errLabel;
}
}
@ -1338,34 +1357,35 @@ cw::rc_t cw::flow::var_find( instance_t* inst, unsigned vid, unsigned chIdx, var
cw::rc_t cw::flow::var_find( instance_t* inst, const char* label, unsigned chIdx, variable_t*& vRef )
cw::rc_t cw::flow::var_find( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx, variable_t*& vRef )
{
variable_t* var;
vRef = nullptr;
if((var = _var_find_on_label_and_ch(inst,label,chIdx)) != nullptr )
if((var = _var_find_on_label_and_ch(inst,label,sfx_id,chIdx)) != nullptr )
{
vRef = var;
return kOkRC;
}
return cwLogError(kInvalidIdRC,"The instance '%s' does not have a variable named '%s'.", inst->label, label );
return cwLogError(kInvalidIdRC,"The instance '%s:%i' does not have a variable named '%s:%i'.", inst->label, inst->label_sfx_id, label, sfx_id );
}
cw::rc_t cw::flow::var_find( instance_t* inst, const char* label, unsigned chIdx, const variable_t*& vRef )
cw::rc_t cw::flow::var_find( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx, const variable_t*& vRef )
{
variable_t* v = nullptr;
rc_t rc = var_find(inst,label,chIdx,v);
rc_t rc = var_find(inst,label,sfx_id,chIdx,v);
vRef = v;
return rc;
}
cw::rc_t cw::flow::var_channel_count( instance_t* inst, const char* label, unsigned& chCntRef )
cw::rc_t cw::flow::var_channel_count( instance_t* inst, const char* label, unsigned sfx_id, unsigned& chCntRef )
{
rc_t rc = kOkRC;
const variable_t* var= nullptr;
if((rc = var_find(inst,label,kAnyChIdx,var)) != kOkRC )
return cwLogError(rc,"Channel count was not available because the variable '%s.%s' does not exist.",cwStringNullGuard(inst->label),cwStringNullGuard(label));
if((rc = var_find(inst,label,sfx_id,kAnyChIdx,var)) != kOkRC )
return cwLogError(rc,"Channel count was not available because the variable '%s:%i.%s:%i' does not exist.",cwStringNullGuard(inst->label),inst->label_sfx_id,cwStringNullGuard(label),sfx_id);
return var_channel_count(var,chCntRef);
}
@ -1377,9 +1397,9 @@ cw::rc_t cw::flow::var_channel_count( const variable_t* var, unsigned& chCntRef
chCntRef = 0;
if((rc = var_find( var->inst, var->label, kAnyChIdx, v )) != kOkRC )
if((rc = var_find( var->inst, var->label, var->label_sfx_id, kAnyChIdx, v )) != kOkRC )
{
rc = cwLogError(kInvalidStateRC,"The base channel variable instance could not be found for the variable '%s.%s'.",var->inst->label,var->label);
rc = cwLogError(kInvalidStateRC,"The base channel variable instance could not be found for the variable '%s:%i.%s:%i'.",var->inst->label,var->inst->label_sfx_id,var->label,var->label_sfx_id);
goto errLabel;
}
@ -1392,7 +1412,7 @@ cw::rc_t cw::flow::var_channel_count( const variable_t* var, unsigned& chCntRef
cw::rc_t cw::flow::var_register( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
cw::rc_t cw::flow::var_register( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef )
{
rc_t rc = kOkRC;
variable_t* var = nullptr;
@ -1403,7 +1423,7 @@ cw::rc_t cw::flow::var_register( instance_t* inst, const char* var_label, unsign
// The concatenation of 'vid' and 'chIdx' should be unique
// if an exact match to label/chIdx was found
if((var = _var_find_on_label_and_ch(inst,var_label,chIdx)) != nullptr )
if((var = _var_find_on_label_and_ch(inst,var_label,sfx_id,chIdx)) != nullptr )
{
// if a value was given - then update the value
if( value_cfg != nullptr )
@ -1412,74 +1432,74 @@ cw::rc_t cw::flow::var_register( instance_t* inst, const char* var_label, unsign
}
else // an exact match was not found - channelize the variable
{
if((rc = var_channelize(inst,var_label,chIdx,value_cfg,vid,var)) != kOkRC )
if((rc = var_channelize(inst,var_label,sfx_id,chIdx,value_cfg,vid,var)) != kOkRC )
goto errLabel;
}
var->vid = vid;
varRef = var;
if((var = _var_find_on_label_and_ch(inst,var_label,kAnyChIdx)) != nullptr )
if((var = _var_find_on_label_and_ch(inst,var_label,sfx_id,kAnyChIdx)) != nullptr )
var->vid = vid;
else
rc = cwLogError(kInvalidStateRC,"The variable '%s' instance '%s' has no base channel.", var_label, inst->label, chIdx);
rc = cwLogError(kInvalidStateRC,"The variable '%s:%i' instance '%s:%i' has no base channel.", var_label, sfx_id, inst->label, inst->label_sfx_id, chIdx);
errLabel:
if( rc != kOkRC )
rc = cwLogError(rc,"Registration failed on variable '%s' instance '%s' ch: %i.", var_label, inst->label, chIdx);
rc = cwLogError(rc,"Registration failed on variable '%s:%i' instance '%s:%i' ch: %i.", var_label, sfx_id, inst->label, inst->label_sfx_id, chIdx);
return rc;
}
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, variable_t*& varRef )
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, variable_t*& varRef )
{
return var_register( inst, var_label, vid, chIdx, nullptr, varRef );
return var_register( inst, var_label, sfx_id, vid, chIdx, nullptr, varRef );
}
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN )
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN )
{
rc_t rc = kOkRC;
abuf_t* abuf;
if((abuf = abuf_create( srate, chN, frameN )) == nullptr )
return cwLogError(kOpFailRC,"abuf create failed on instance:'%s' variable:'%s'.", inst->label, var_label);
return cwLogError(kOpFailRC,"abuf create failed on instance:'%s:%i' variable:'%s:%i'.", inst->label, inst->label_sfx_id, var_label,sfx_id);
if((rc = _var_register_and_set( inst, var_label, vid, chIdx, abuf )) != kOkRC )
if((rc = _var_register_and_set( inst, var_label, sfx_id, vid, chIdx, abuf )) != kOkRC )
abuf_destroy(abuf);
return rc;
}
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_real_t** magV, const fd_real_t** phsV, const fd_real_t** hzV )
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_real_t** magV, const fd_real_t** phsV, const fd_real_t** hzV )
{
rc_t rc = kOkRC;
fbuf_t* fbuf;
if((fbuf = fbuf_create( srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV )) == nullptr )
return cwLogError(kOpFailRC,"fbuf create failed on instance:'%s' variable:'%s'.", inst->label, var_label);
return cwLogError(kOpFailRC,"fbuf create failed on instance:'%s:%i' variable:'%s:%i'.", inst->label, inst->label_sfx_id, var_label,sfx_id);
if((rc = _var_register_and_set( inst, var_label, vid, chIdx, fbuf )) != kOkRC )
if((rc = _var_register_and_set( inst, var_label, sfx_id, vid, chIdx, fbuf )) != kOkRC )
fbuf_destroy(fbuf);
return rc;
}
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, midi::ch_msg_t* msgA, unsigned msgN )
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, midi::ch_msg_t* msgA, unsigned msgN )
{
rc_t rc = kOkRC;
mbuf_t* mbuf;
if((mbuf = mbuf_create(msgA,msgN)) == nullptr )
return cwLogError(kOpFailRC,"mbuf create failed on instance:'%s' variable:'%s'.", inst->label, var_label);
return cwLogError(kOpFailRC,"mbuf create failed on instance:'%s:%i' variable:'%s:%i'.", inst->label, inst->label_sfx_id, var_label, sfx_id);
if((rc = _var_register_and_set( inst, var_label, vid, chIdx, mbuf )) != kOkRC )
if((rc = _var_register_and_set( inst, var_label, sfx_id, vid, chIdx, mbuf )) != kOkRC )
mbuf_destroy(mbuf);
return rc;
}
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_real_t** magV, const fd_real_t** phsV, const fd_real_t** hzV )
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_real_t** magV, const fd_real_t** phsV, const fd_real_t** hzV )
{
unsigned maxBinN_V[ chN ];
unsigned binN_V[ chN ];
@ -1487,7 +1507,7 @@ cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label
vop::fill(maxBinN_V,chN,maxBinN);
vop::fill(binN_V,chN,binN);
vop::fill(hopSmpN_V,chN, hopSmpN );
return var_register_and_set(inst,var_label,vid,chIdx,srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV);
return var_register_and_set(inst,var_label,sfx_id,vid,chIdx,srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV);
}

View File

@ -15,6 +15,7 @@ namespace cw
typedef unsigned vid_t;
enum {
kBaseSfxId = 0,
kFbufVectN = 3, // count of signal vectors in fbuf (mag,phs,hz)
kAnyChIdx = kInvalidIdx,
kLocalValueN = 2
@ -127,8 +128,10 @@ namespace cw
enum
{
kNoVarFl = 0x00,
kSrcVarFl = 0x01,
kSrcOptVarFl = 0x02
kSrcOptVarFl = 0x02,
kMultVarFl = 0x04
};
typedef struct class_members_str
@ -165,6 +168,7 @@ namespace cw
var_desc_t* varDescL; // varDescA[varDescN] value description list
preset_t* presetL; // presetA[ presetN ]
class_members_t* members; // member functions for this class
unsigned polyLimitN; // max. poly copies of this class per network_t or 0 if no limit
} class_desc_t;
@ -174,6 +178,7 @@ namespace cw
{
struct instance_str* inst; // pointer to this variables instance
char* label; // this variables label
unsigned label_sfx_id; // the label suffix id of this variable or kInvalidIdx if this has no suffix
unsigned vid; // this variables numeric id ( cat(vid,chIdx) forms a unique variable identifier on this 'inst'
var_desc_t* varDesc; // the variable description for this variable
value_t local_value[ kLocalValueN ]; // the local value instance (actual value if this is not a 'src' variable)
@ -187,14 +192,32 @@ namespace cw
} variable_t;
struct instance_str;
typedef struct network_str
{
const object_t* procsCfg; // network proc list
const object_t* presetsCfg; // presets designed for this network
unsigned poly_cnt; // count of duplicated networks in the list
struct instance_str** proc_array;
unsigned proc_arrayAllocN;
unsigned proc_arrayN;
} network_t;
typedef struct instance_str
{
struct flow_str* ctx; // global system context
network_t* net; // network which owns this proc
class_desc_t* class_desc; //
const char* label; // instance label
const object_t* inst_cfg; // instance configuration
char* label; // instance label
unsigned label_sfx_id; // label suffix id (set to kBaseSfxId (0) unless poly is non-null)
const object_t* proc_cfg; // instance configuration
const char* arg_label; // optional args label
const object_t* arg_cfg; // optional args configuration
@ -208,16 +231,15 @@ namespace cw
unsigned varMapN; // varMapN = varMapIdN * varMapChN
variable_t** varMapA; // varMapA[ varMapN ] = allows fast lookup from ('vid','chIdx) to variable
struct instance_str* link;
} instance_t;
network_t* internal_net;
} instance_t;
typedef struct flow_str
{
const object_t* networkCfg; // complete cfg used to create this network
const object_t* flowCfg; // complete cfg used to create this flow
const object_t* presetCfg; // presets designed for this network
unsigned framesPerCycle; // sample frames per cycle (64)
bool multiPriPresetProbFl; // If set then probability is used to choose presets on multi-preset application
@ -232,8 +254,8 @@ namespace cw
external_device_t* deviceA; // deviceA[ deviceN ] external device description array
unsigned deviceN; //
struct instance_str* network_head; // first instance
struct instance_str* network_tail; // last insance
network_t net;
} flow_t;
//------------------------------------------------------------------------------------------------------------------------
@ -278,15 +300,16 @@ namespace cw
//
// Network
//
void network_print( flow_t* p );
void network_print(const network_t& net );
//------------------------------------------------------------------------------------------------------------------------
//
// Instance
//
instance_t* instance_find( flow_t* p, const char* inst_label );
rc_t instance_find( flow_t* p, const char* inst_label, instance_t*& instPtrRef );
instance_t* instance_find( network_t& net, const char* inst_label, unsigned sfx_id );
rc_t instance_find( network_t& net, const char* inst_label, unsigned sfx_id, instance_t*& instPtrRef );
external_device_t* external_device_find( flow_t* p, const char* device_label, unsigned typeId, unsigned inOrOutFl, const char* midiPortLabel=nullptr );
void instance_print( instance_t* inst );
@ -300,14 +323,14 @@ namespace cw
// Create a variable but do not assign it a value. Return a pointer to the new variable.
// Note: `value_cfg` is optional. Set it to NULL to ignore
rc_t var_create( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
rc_t var_create( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
// Channelizing creates a new var record with an explicit channel index to replace the
// automatically generated variable whose channel index is set to 'all'.
rc_t var_channelize( instance_t* inst, const char* var_label, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef );
rc_t var_channelize( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const object_t* value_cfg, unsigned vid, variable_t*& varRef );
// `value_cfg` is optional. Set it to NULL to ignore
rc_t var_register( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
rc_t var_register( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, const object_t* value_cfg, variable_t*& varRef );
// Returns true if this var is connected to an external proc variable
bool is_connected_to_external_proc( const variable_t* var );
@ -320,11 +343,11 @@ namespace cw
inline rc_t _var_reg(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
template< typename T0, typename T1, typename... ARGS >
rc_t _var_reg( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, ARGS&&... args )
rc_t _var_reg( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, ARGS&&... args )
{
rc_t rc;
variable_t* dummy = nullptr;
if((rc = var_register( inst, var_label, vid, chIdx, nullptr, dummy )) == kOkRC )
if((rc = var_register( inst, var_label, sfx_id, vid, chIdx, nullptr, dummy )) == kOkRC )
if((rc = _var_reg( inst, chIdx, std::forward<ARGS>(args)...)) != kOkRC )
return rc;
return rc;
@ -332,8 +355,8 @@ namespace cw
// Call var_register() on a list of variables.
template< typename... ARGS >
rc_t var_register( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
{ return _var_reg( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
rc_t var_register( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
{ return _var_reg( inst, chIdx, vid, var_label, sfx_id, std::forward<ARGS>(args)...); }
@ -345,11 +368,11 @@ namespace cw
inline rc_t _var_register_and_get(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
template< typename T>
rc_t var_register_and_get( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, T& valRef )
rc_t var_register_and_get( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, T& valRef )
{
rc_t rc;
variable_t* var;
if((rc = var_register(inst,var_label,vid,chIdx,nullptr,var)) == kOkRC )
if((rc = var_register(inst,var_label,sfx_id,vid,chIdx,nullptr,var)) == kOkRC )
rc = var_get(var,valRef);
return rc;
}
@ -358,11 +381,11 @@ namespace cw
inline rc_t _var_reg_and_get(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
template< typename T0, typename T1, typename T2, typename... ARGS >
rc_t _var_reg_and_get( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, T2& valRef, ARGS&&... args )
rc_t _var_reg_and_get( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, T2& valRef, ARGS&&... args )
{
rc_t rc;
if((rc = var_register_and_get( inst, var_label, vid, chIdx, valRef )) == kOkRC )
if((rc = var_register_and_get( inst, var_label, sfx_id, vid, chIdx, valRef )) == kOkRC )
if((rc = _var_reg_and_get( inst, chIdx, std::forward<ARGS>(args)...)) != kOkRC )
return rc;
@ -371,8 +394,8 @@ namespace cw
// Call var_register_and_get() on a list of variables.
template< typename... ARGS >
rc_t var_register_and_get( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
{ return _var_reg_and_get( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
rc_t var_register_and_get( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
{ return _var_reg_and_get( inst, chIdx, vid, var_label, sfx_id, std::forward<ARGS>(args)...); }
@ -384,22 +407,22 @@ namespace cw
// var_register_and_set(). If the variable has not yet been created then it is created and assigned a value.
// If the variable has already been created then 'vid' and the value are updated.
// (Note that abuf and fbuf values are not changed by this function only the 'vid' is updated.)
rc_t var_register_and_set( instance_t* inst, const char* label, unsigned vid, unsigned chIdx, variable_t*& varRef );
rc_t var_register_and_set( instance_t* inst, const char* label, unsigned sfx_id, unsigned vid, unsigned chIdx, variable_t*& varRef );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, midi::ch_msg_t* midiA, unsigned midiN );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_real_t** magV=nullptr, const fd_real_t** phsV=nullptr, const fd_real_t** hzV=nullptr );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_real_t** magV=nullptr, const fd_real_t** phsV=nullptr, const fd_real_t** hzV=nullptr );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, midi::ch_msg_t* midiA, unsigned midiN );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const fd_real_t** magV=nullptr, const fd_real_t** phsV=nullptr, const fd_real_t** hzV=nullptr );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const fd_real_t** magV=nullptr, const fd_real_t** phsV=nullptr, const fd_real_t** hzV=nullptr );
inline rc_t _var_register_and_set(cw::flow::instance_t*, unsigned int ) { return kOkRC; }
template< typename T0, typename T1, typename T2, typename... ARGS >
rc_t _var_register_and_set( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, T2 val, ARGS&&... args )
rc_t _var_register_and_set( instance_t* inst, unsigned chIdx, T0 vid, T1 var_label, unsigned sfx_id, T2 val, ARGS&&... args )
{
rc_t rc;
variable_t* var = nullptr;
if((rc = var_register_and_set( inst, var_label, vid, chIdx, var)) == kOkRC )
if((rc = var_register_and_set( inst, var_label, sfx_id, vid, chIdx, var)) == kOkRC )
{
var_set( inst, vid, chIdx, val );
@ -412,22 +435,23 @@ namespace cw
// Call var_register_and_set() on a list of variables.
template< typename... ARGS >
rc_t var_register_and_set( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, ARGS&&... args )
{ return _var_register_and_set( inst, chIdx, vid, var_label, std::forward<ARGS>(args)...); }
rc_t var_register_and_set( instance_t* inst, unsigned chIdx, unsigned vid, const char* var_label, unsigned sfx_id, ARGS&&... args )
{ return _var_register_and_set( inst, chIdx, vid, var_label, sfx_id, std::forward<ARGS>(args)...); }
void _var_destroy( variable_t* var );
bool var_exists( instance_t* inst, const char* label, unsigned chIdx );
bool var_has_value( instance_t* inst, const char* label, unsigned chIdx );
bool var_exists( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx );
bool var_has_value( instance_t* inst, const char* label, unsigned sfx_id, unsigned chIdx );
rc_t var_find( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, const variable_t*& varRef );
rc_t var_find( instance_t* inst, const char* var_label, unsigned sfx_id, unsigned chIdx, variable_t*& varRef );
rc_t var_find( instance_t* inst, unsigned vid, unsigned chIdx, variable_t*& varRef );
rc_t var_find( instance_t* inst, const char* var_label, unsigned chIdx, const variable_t*& varRef );
rc_t var_find( instance_t* inst, const char* var_label, unsigned chIdx, variable_t*& varRef );
rc_t var_find( instance_t* inst, unsigned vid, unsigned chIdx, variable_t*& varRef );
// Count of numbered channels - does not count the kAnyChIdx variable instance.
rc_t var_channel_count( instance_t* inst, const char* label, unsigned& chCntRef );
rc_t var_channel_count( instance_t* inst, const char* label, unsigned sfx_idx, unsigned& chCntRef );
rc_t var_channel_count( const variable_t* var, unsigned& chCntRef );

View File

@ -6,11 +6,12 @@
#include "cwObject.h"
#include "cwTime.h"
#include "cwVectOps.h"
#include "cwMidi.h"
#include "cwMidiDecls.h"
#include "cwFlowDecl.h"
#include "cwPresetSel.h"
#include "cwFile.h"
#include "cwMidi.h"
#include "cwDynRefTbl.h"
#include "cwScoreParse.h"
#include "cwSfScore.h"