cwFlowProc.cpp : 'midi_out' now has both a 'midi' and a 'record' input variable.
Added 'print_fl' to 'midi_voice' and 'midi_out' Added 'preset_sfx_id' and 'preset_label' variables to implement _apply_preset() in 'poly'.
This commit is contained in:
parent
db3e96cdf6
commit
1bde870d3a
209
cwFlowProc.cpp
209
cwFlowProc.cpp
@ -129,7 +129,7 @@ namespace cw
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((rc = network_create(proc->ctx,&networkCfg,1,proc->varL,1,nullptr,p->net)) != kOkRC )
|
if((rc = network_create(proc->ctx,&networkCfg,1,proc->varL,proc,1,p->net)) != kOkRC )
|
||||||
{
|
{
|
||||||
rc = cwLogError(rc,"Creation failed on the subnet internal network.");
|
rc = cwLogError(rc,"Creation failed on the subnet internal network.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -192,6 +192,8 @@ namespace cw
|
|||||||
{
|
{
|
||||||
kParallelFlPId,
|
kParallelFlPId,
|
||||||
kCountPId,
|
kCountPId,
|
||||||
|
kPresetSfxIdPId,
|
||||||
|
kPresetLabelPId
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct voice_str
|
typedef struct voice_str
|
||||||
@ -201,14 +203,13 @@ namespace cw
|
|||||||
} voice_t;
|
} voice_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned count; // count of subnets in 'net'
|
unsigned count; // count of subnets in 'net'
|
||||||
//network_t* net; // internal network containing 'count' duplicate sub-nets
|
|
||||||
bool parallel_fl; // true if the subnets should be executed in parallel
|
bool parallel_fl; // true if the subnets should be executed in parallel
|
||||||
thread_tasks::handle_t threadTasksH; //
|
thread_tasks::handle_t threadTasksH; //
|
||||||
thread_tasks::task_t* taskA; // taskA[ count ]
|
thread_tasks::task_t* taskA; // taskA[ count ]
|
||||||
voice_t* voiceA; // voiceA[ count ]
|
voice_t* voiceA; // voiceA[ count ]
|
||||||
|
unsigned preset_sfx_id;
|
||||||
} inst_t;
|
} inst_t;
|
||||||
|
|
||||||
rc_t _poly_thread_func( void* arg )
|
rc_t _poly_thread_func( void* arg )
|
||||||
@ -226,6 +227,31 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc_t _apply_preset(proc_t* proc,unsigned preset_sfx_id,const char* preset_label)
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
network_t* net = proc->internal_net;
|
||||||
|
for(; net!=nullptr; net=net->poly_link)
|
||||||
|
if( net->poly_idx == preset_sfx_id )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( net == nullptr )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kEleNotFoundRC,"The preset application poly voice '%i' was not found.",preset_sfx_id);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = network_apply_preset(*net,preset_label,preset_sfx_id)) != kOkRC )
|
||||||
|
{
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rc_t create( proc_t* proc )
|
rc_t create( proc_t* proc )
|
||||||
{
|
{
|
||||||
@ -236,6 +262,8 @@ namespace cw
|
|||||||
const object_t** networkCfgA = nullptr;
|
const object_t** networkCfgA = nullptr;
|
||||||
unsigned networkCfgN = 1;
|
unsigned networkCfgN = 1;
|
||||||
network_t* internal_net = nullptr;
|
network_t* internal_net = nullptr;
|
||||||
|
unsigned preset_sfx_id = kInvalidId;
|
||||||
|
const char* preset_label = nullptr;
|
||||||
|
|
||||||
proc->userPtr = inst;
|
proc->userPtr = inst;
|
||||||
|
|
||||||
@ -247,7 +275,10 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the 'parallel flag'
|
// get the 'parallel flag'
|
||||||
if((rc = var_register_and_get( proc, kAnyChIdx,kParallelFlPId, "parallel_fl", kBaseSfxId, inst->parallel_fl )) != kOkRC )
|
if((rc = var_register_and_get( proc, kAnyChIdx,
|
||||||
|
kPresetSfxIdPId,"preset_sfx_id", kBaseSfxId, preset_sfx_id,
|
||||||
|
kPresetLabelPId,"preset_label", kBaseSfxId, preset_label,
|
||||||
|
kParallelFlPId, "parallel_fl", kBaseSfxId, inst->parallel_fl )) != kOkRC )
|
||||||
{
|
{
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
@ -299,12 +330,18 @@ namespace cw
|
|||||||
|
|
||||||
// create the network object - which will hold 'count' subnets - each a duplicate of the
|
// create the network object - which will hold 'count' subnets - each a duplicate of the
|
||||||
// network described by 'networkCfg'.
|
// network described by 'networkCfg'.
|
||||||
if((rc = network_create(proc->ctx,networkCfgA,networkCfgN,proxyVarL,inst->count,nullptr,internal_net)) != kOkRC )
|
if((rc = network_create(proc->ctx,networkCfgA,networkCfgN,proxyVarL,proc,inst->count,internal_net)) != kOkRC )
|
||||||
{
|
{
|
||||||
rc = cwLogError(rc,"Creation failed on the internal network.");
|
rc = cwLogError(rc,"Creation failed on the internal network.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( preset_sfx_id != kInvalidId && textLength(preset_label) > 0 )
|
||||||
|
{
|
||||||
|
if((rc = _apply_preset(proc,preset_sfx_id,preset_label)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
if( inst->parallel_fl )
|
if( inst->parallel_fl )
|
||||||
{
|
{
|
||||||
network_t* net = internal_net;
|
network_t* net = internal_net;
|
||||||
@ -369,6 +406,28 @@ namespace cw
|
|||||||
{
|
{
|
||||||
inst_t* p = (inst_t*)proc->userPtr;
|
inst_t* p = (inst_t*)proc->userPtr;
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
unsigned preset_sfx_id = kInvalidId;
|
||||||
|
|
||||||
|
if((rc = var_get(proc,kPresetSfxIdPId,kAnyChIdx,preset_sfx_id)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
// if a new preset value has arrived
|
||||||
|
if( preset_sfx_id != kInvalidId && preset_sfx_id != p->preset_sfx_id )
|
||||||
|
{
|
||||||
|
const char* preset_label;
|
||||||
|
|
||||||
|
p->preset_sfx_id = preset_sfx_id;
|
||||||
|
|
||||||
|
// get the preset label
|
||||||
|
if((rc = var_get(proc,kPresetLabelPId,kAnyChIdx,preset_label)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
// and apply the preset
|
||||||
|
if( textLength(preset_label) > 0 )
|
||||||
|
if((rc = _apply_preset(proc,preset_sfx_id,preset_label)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( p->parallel_fl )
|
if( p->parallel_fl )
|
||||||
{
|
{
|
||||||
@ -389,6 +448,7 @@ namespace cw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,52 +703,88 @@ namespace cw
|
|||||||
kPortLabelPId,
|
kPortLabelPId,
|
||||||
kBufMsgCntPId,
|
kBufMsgCntPId,
|
||||||
kInPId,
|
kInPId,
|
||||||
|
kRInPId,
|
||||||
|
kPrintFlPId
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
external_device_t* ext_dev;
|
external_device_t* ext_dev;
|
||||||
|
bool rin_exists_fl;
|
||||||
unsigned inVarN;
|
bool in_exists_fl;
|
||||||
|
|
||||||
unsigned msgN;
|
unsigned msgN;
|
||||||
midi::ch_msg_t* msgA;
|
midi::ch_msg_t* msgA;
|
||||||
unsigned msg_idx;
|
unsigned msg_idx;
|
||||||
|
|
||||||
|
unsigned midi_fld_idx;
|
||||||
|
recd_type_t null_recd_type{ .fieldL=nullptr, .fieldN=0, .base=nullptr };
|
||||||
} inst_t;
|
} inst_t;
|
||||||
|
|
||||||
rc_t _create( proc_t* proc, inst_t* p )
|
rc_t _create( proc_t* proc, inst_t* p )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC; //
|
rc_t rc = kOkRC; //h
|
||||||
const char* dev_label = nullptr;
|
const char* dev_label = nullptr;
|
||||||
const char* port_label = nullptr;
|
const char* port_label = nullptr;
|
||||||
unsigned inVarN = var_mult_count(proc,"in");
|
rbuf_t* rbuf = nullptr;
|
||||||
mbuf_t* mbuf = nullptr;
|
bool printFl = false;
|
||||||
unsigned sfxIdA[ inVarN ];
|
|
||||||
|
|
||||||
// get the the sfx_id's of the input audio variables
|
|
||||||
if((rc = var_mult_sfx_id_array(proc, "in", sfxIdA, inVarN, p->inVarN )) != kOkRC )
|
|
||||||
goto errLabel;
|
|
||||||
|
|
||||||
std::sort(sfxIdA, sfxIdA + p->inVarN, [](unsigned& a,unsigned& b){ return a<b; } );
|
|
||||||
|
|
||||||
|
|
||||||
// Register variables and get their current value
|
// Register variables and get their current value
|
||||||
if((rc = var_register_and_get( proc, kAnyChIdx,
|
if((rc = var_register_and_get( proc, kAnyChIdx,
|
||||||
kDevLabelPId, "dev_label", kBaseSfxId, dev_label,
|
kDevLabelPId, "dev_label", kBaseSfxId, dev_label,
|
||||||
kPortLabelPId,"port_label", kBaseSfxId, port_label,
|
kPortLabelPId,"port_label", kBaseSfxId, port_label,
|
||||||
kInPId, "in", kBaseSfxId, mbuf,
|
kPrintFlPId, "print_fl", kBaseSfxId, printFl,
|
||||||
kBufMsgCntPId,"buf_cnt", kBaseSfxId, p->msgN )) != kOkRC )
|
kBufMsgCntPId,"buf_cnt", kBaseSfxId, p->msgN )) != kOkRC )
|
||||||
{
|
{
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the MIDI 'in' variable has a value then it exists and is connected ...
|
||||||
|
if((p->in_exists_fl = var_has_value(proc, "in", kBaseSfxId, kAnyChIdx )) == true )
|
||||||
|
{
|
||||||
|
// ... register it
|
||||||
|
if((rc = var_register( proc, kAnyChIdx,kInPId, "in", kBaseSfxId )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ... otherwise setup it up with an empty mbuf to get it by the post proc create variable value checker
|
||||||
|
if((rc = var_register_and_set( proc, "in", kBaseSfxId, kInPId, kAnyChIdx, nullptr, 0 )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the 'record' input variable has a value then it exists and is connected ...
|
||||||
|
if((p->rin_exists_fl = var_has_value(proc, "rin", kBaseSfxId, kAnyChIdx )) == true )
|
||||||
|
{
|
||||||
|
// ... register it and get a pointer to the incoming record buffer to use below
|
||||||
|
if((rc = var_register_and_get( proc, kAnyChIdx,kRInPId, "rin", kBaseSfxId, rbuf )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ... otherwise give it an empty record buf to get by the post proc create variable value checker
|
||||||
|
if((rc = var_register_and_set( proc, "rin", kBaseSfxId, kRInPId, kAnyChIdx, &p->null_recd_type, nullptr, 0 )) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
if((p->ext_dev = external_device_find( proc->ctx, dev_label, kMidiDevTypeId, kOutFl, port_label )) == nullptr )
|
if((p->ext_dev = external_device_find( proc->ctx, dev_label, kMidiDevTypeId, kOutFl, port_label )) == nullptr )
|
||||||
{
|
{
|
||||||
rc = cwLogError(kOpFailRC,"The audio output device description '%s' could not be found.", cwStringNullGuard(dev_label));
|
rc = cwLogError(kOpFailRC,"The audio output device description '%s' could not be found.", cwStringNullGuard(dev_label));
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( rbuf == nullptr )
|
||||||
|
p->midi_fld_idx = kInvalidIdx;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((p->midi_fld_idx = recd_type_field_index( rbuf->type, "midi")) == kInvalidIdx )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kInvalidArgRC,"The 'rin' record does not have a 'midi' field.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p->msgA = mem::allocZ<midi::ch_msg_t>(p->msgN);
|
p->msgA = mem::allocZ<midi::ch_msg_t>(p->msgN);
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
@ -705,23 +801,63 @@ namespace cw
|
|||||||
{
|
{
|
||||||
return kOkRC;
|
return kOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _send_msg( inst_t* p, bool print_fl, const midi::ch_msg_t* m )
|
||||||
|
{
|
||||||
|
p->ext_dev->u.m.sendTripleFunc( p->ext_dev, m->ch, m->status, m->d0, m->d1 );
|
||||||
|
if( print_fl )
|
||||||
|
{
|
||||||
|
cwLogPrint("%2i 0x%2x %3i %3i : %s %s\n",m->ch, m->status, m->d0, m->d1, cwStringNullGuard(p->ext_dev->devLabel),cwStringNullGuard(p->ext_dev->portLabel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc_t _exec( proc_t* proc, inst_t* p )
|
rc_t _exec( proc_t* proc, inst_t* p )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
const rbuf_t* rbuf = nullptr;
|
||||||
|
bool print_fl = false;
|
||||||
const mbuf_t* src_mbuf = nullptr;
|
const mbuf_t* src_mbuf = nullptr;
|
||||||
|
|
||||||
if((rc = var_get(proc,kInPId,kAnyChIdx,src_mbuf)) != kOkRC )
|
var_get(proc,kPrintFlPId,kAnyChIdx,print_fl);
|
||||||
rc = cwLogError(kInvalidStateRC,"The MIDI output instance '%s' does not have a valid input connection.",proc->label);
|
|
||||||
else
|
if( p->rin_exists_fl )
|
||||||
{
|
{
|
||||||
for(unsigned i=0; i<src_mbuf->msgN; ++i)
|
if((rc = var_get(proc,kRInPId,kAnyChIdx,rbuf)) != kOkRC )
|
||||||
{
|
rc = cwLogError(kInvalidStateRC,"The the record input connection is not valid.");
|
||||||
const midi::ch_msg_t* m = src_mbuf->msgA + i;
|
else
|
||||||
p->ext_dev->u.m.sendTripleFunc( p->ext_dev, m->ch, m->status, m->d0, m->d1 );
|
{
|
||||||
|
for(unsigned i=0; i<rbuf->recdN; ++i)
|
||||||
|
{
|
||||||
|
const recd_t* r = rbuf->recdA + i;
|
||||||
|
const midi::ch_msg_t* m = nullptr;
|
||||||
|
|
||||||
|
if((rc = recd_get(rbuf->type,r,p->midi_fld_idx,m)) == kOkRC )
|
||||||
|
_send_msg(p,print_fl,m);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Record 'midi' field read failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( p->in_exists_fl )
|
||||||
|
{
|
||||||
|
if((rc = var_get(proc,kInPId,kAnyChIdx,src_mbuf)) != kOkRC )
|
||||||
|
rc = cwLogError(kInvalidStateRC,"The MIDI output instance '%s' does not have a valid input connection.",proc->label);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(unsigned i=0; i<src_mbuf->msgN; ++i)
|
||||||
|
{
|
||||||
|
_send_msg(p,print_fl,src_mbuf->msgA + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4190,7 +4326,8 @@ namespace cw
|
|||||||
if( p->voiceA[i].age > p->voiceA[ max_age_idx].age )
|
if( p->voiceA[i].age > p->voiceA[ max_age_idx].age )
|
||||||
max_age_idx = i;
|
max_age_idx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cwLogWarning("Stealing:%i",p->voiceA[max_age_idx].pitch );
|
||||||
return max_age_idx;
|
return max_age_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4414,6 +4551,7 @@ namespace cw
|
|||||||
kGainPId,
|
kGainPId,
|
||||||
kChCntPId,
|
kChCntPId,
|
||||||
kOutPId,
|
kOutPId,
|
||||||
|
kPrintFlPId,
|
||||||
kDoneFlPId
|
kDoneFlPId
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4455,12 +4593,14 @@ namespace cw
|
|||||||
mbuf_t* mbuf = nullptr;
|
mbuf_t* mbuf = nullptr;
|
||||||
srate_t srate = proc->ctx->sample_rate;
|
srate_t srate = proc->ctx->sample_rate;
|
||||||
bool done_fl = false;
|
bool done_fl = false;
|
||||||
|
bool print_fl= false;
|
||||||
|
|
||||||
// get the MIDI input variable
|
// get the MIDI input variable
|
||||||
if((rc = var_register_and_get( proc, kAnyChIdx,
|
if((rc = var_register_and_get( proc, kAnyChIdx,
|
||||||
kInPId, "in", kBaseSfxId, mbuf,
|
kInPId, "in", kBaseSfxId, mbuf,
|
||||||
kGainPId, "gain", kBaseSfxId, p->fixed_gain,
|
kGainPId, "gain", kBaseSfxId, p->fixed_gain,
|
||||||
kChCntPId, "chCnt", kBaseSfxId, p->chN,
|
kChCntPId, "chCnt", kBaseSfxId, p->chN,
|
||||||
|
kPrintFlPId,"print_fl",kBaseSfxId, print_fl,
|
||||||
kDoneFlPId, "done_fl", kBaseSfxId, done_fl)) != kOkRC )
|
kDoneFlPId, "done_fl", kBaseSfxId, done_fl)) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
@ -4528,6 +4668,7 @@ namespace cw
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
abuf_t* abuf = nullptr;
|
abuf_t* abuf = nullptr;
|
||||||
mbuf_t* mbuf = nullptr;
|
mbuf_t* mbuf = nullptr;
|
||||||
|
bool print_fl = false;
|
||||||
|
|
||||||
// get the input MIDI buffer
|
// get the input MIDI buffer
|
||||||
if((rc = var_get(proc,kInPId,kAnyChIdx,mbuf)) != kOkRC )
|
if((rc = var_get(proc,kInPId,kAnyChIdx,mbuf)) != kOkRC )
|
||||||
@ -4537,10 +4678,16 @@ namespace cw
|
|||||||
if((rc = var_get(proc,kOutPId,kAnyChIdx,abuf)) != kOkRC )
|
if((rc = var_get(proc,kOutPId,kAnyChIdx,abuf)) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
|
var_get(proc,kPrintFlPId,kAnyChIdx,print_fl);
|
||||||
|
|
||||||
// if there are MIDI messages - update cur_hz and cur_vel
|
// if there are MIDI messages - update cur_hz and cur_vel
|
||||||
for(unsigned i=0; i<mbuf->msgN; ++i)
|
for(unsigned i=0; i<mbuf->msgN; ++i)
|
||||||
{
|
{
|
||||||
const midi::ch_msg_t* m = mbuf->msgA + i;
|
const midi::ch_msg_t* m = mbuf->msgA + i;
|
||||||
|
|
||||||
|
if( print_fl )
|
||||||
|
cwLogPrint("%2i 0x%2x %3i %3i : %s:%i\n",m->ch, m->status, m->d0, m->d1, cwStringNullGuard(proc->label),proc->label_sfx_id);
|
||||||
|
|
||||||
switch( m->status )
|
switch( m->status )
|
||||||
{
|
{
|
||||||
case midi::kNoteOnMdId:
|
case midi::kNoteOnMdId:
|
||||||
|
Loading…
Reference in New Issue
Block a user