cwFlowPerrf.cpp : Initial score_follower_2 implementation.
'score_player' added 'max loc' output. 'vel_table' added 'score_vel' functionality to support output from score_follower. 'gutim_ps' added manual preset selection. Added 'per location' (see locA[]) and 'dry notes per chord' options.
This commit is contained in:
parent
637e9bfd28
commit
f1b7f1a263
@ -62,6 +62,7 @@ namespace cw
|
||||
{ "poly_voice_ctl", &poly_voice_ctl::members },
|
||||
{ "midi_voice", &midi_voice::members },
|
||||
{ "piano_voice", &piano_voice::members },
|
||||
{ "voice_detector", &voice_detector::members },
|
||||
{ "sample_hold", &sample_hold::members },
|
||||
{ "number", &number::members },
|
||||
{ "reg", ®::members },
|
||||
@ -82,6 +83,7 @@ namespace cw
|
||||
{ "preset_select", &preset_select::members },
|
||||
{ "gutim_ps", &gutim_ps::members },
|
||||
{ "score_follower", &score_follower::members },
|
||||
{ "score_follower_2",&score_follower_2::members },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
683
cwFlowPerf.cpp
683
cwFlowPerf.cpp
@ -32,6 +32,9 @@
|
||||
#include "cwScoreFollowerPerf.h"
|
||||
#include "cwScoreFollower.h"
|
||||
|
||||
#include "cwPianoScore.h"
|
||||
#include "cwScoreFollow2.h"
|
||||
|
||||
#include "cwPianoScore.h"
|
||||
|
||||
#include "cwPresetSel.h"
|
||||
@ -55,6 +58,7 @@ namespace cw
|
||||
kScoreFNamePId,
|
||||
kStoppingMsPId,
|
||||
kDoneFlPId,
|
||||
kMaxLocPId,
|
||||
kOutPId,
|
||||
kStartPId,
|
||||
kStopPId,
|
||||
@ -131,6 +135,8 @@ namespace cw
|
||||
unsigned stopping_ms; // max time in milliseconds to wait for all notes to end before sending all-note-off
|
||||
unsigned stopping_sample_idx; // 0 if not 'stopping', otherwise the max sample index after which the player will enter 'idle' state.
|
||||
|
||||
unsigned maxLocId;
|
||||
|
||||
} inst_t;
|
||||
|
||||
rc_t _load_score( proc_t* proc, inst_t* p, const char* score_fname )
|
||||
@ -178,6 +184,7 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
p->maxLocId = 0;
|
||||
p->msgA = mem::allocZ<msg_t>(p->msgAllocN);
|
||||
p->chMsgA = mem::allocZ<midi::ch_msg_t>(p->msgAllocN);
|
||||
|
||||
@ -185,11 +192,19 @@ namespace cw
|
||||
{
|
||||
if( score_evt->status != 0 )
|
||||
{
|
||||
bool note_on_fl = false;
|
||||
msg_t* m = p->msgA + p->msgN;
|
||||
midi::ch_msg_t* mm = p->chMsgA + p->msgN;
|
||||
|
||||
if( score_evt->loc != kInvalidId )
|
||||
{
|
||||
// verify that the score is in order by location
|
||||
assert( score_evt->loc >= last_loc );
|
||||
last_loc = score_evt->loc;
|
||||
}
|
||||
|
||||
if( last_loc > p->maxLocId )
|
||||
p->maxLocId = last_loc;
|
||||
|
||||
m->sample_idx = (unsigned)(proc->ctx->sample_rate * score_evt->sec);
|
||||
m->loc = last_loc;
|
||||
@ -206,9 +221,11 @@ namespace cw
|
||||
|
||||
time::fracSecondsToSpec( mm->timeStamp, score_evt->sec );
|
||||
|
||||
mm->devIdx = kInvalidIdx;
|
||||
mm->portIdx= kInvalidIdx;
|
||||
mm->uid = uuid++;
|
||||
note_on_fl = midi::isNoteOn(score_evt->status,score_evt->d1);
|
||||
|
||||
mm->devIdx = note_on_fl ? m->loc : kInvalidIdx; //BUG BUG BUG: hack to do per chord/note processing in gutim_ps
|
||||
mm->portIdx= note_on_fl ? score_evt->chord_note_idx : kInvalidIdx;
|
||||
mm->uid = note_on_fl ? score_evt->chord_note_cnt : kInvalidId;
|
||||
mm->ch = score_evt->status & 0x0f;
|
||||
mm->status = score_evt->status & 0xf0;
|
||||
mm->d0 = score_evt->d0;
|
||||
@ -216,6 +233,7 @@ namespace cw
|
||||
m->d1 = score_evt->d1; // track the initial d1 before vel. mapping is applied
|
||||
|
||||
|
||||
|
||||
if( midi::isSustainPedal( mm->status, mm->d0 ) )
|
||||
{
|
||||
bool down_fl = pedalStateFlags & kDampPedalDownFl;
|
||||
@ -417,7 +435,8 @@ namespace cw
|
||||
|
||||
|
||||
if((rc = var_register_and_set(proc,kAnyChIdx,
|
||||
kDoneFlPId,"done_fl", kBaseSfxId, false)) != kOkRC )
|
||||
kDoneFlPId,"done_fl", kBaseSfxId, false,
|
||||
kMaxLocPId,"loc_cnt", kBaseSfxId, p->maxLocId+1 )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
@ -670,6 +689,11 @@ namespace cw
|
||||
|
||||
bool note_on_fl = midi::isNoteOn(m->midi->status, m->midi->d1);
|
||||
|
||||
//if( note_on_fl )
|
||||
//{
|
||||
// printf("sc:%i %i %i %s\n",m->meas,m->loc,m->midi->d0,midi::midiToSciPitch(m->midi->d0));
|
||||
//}
|
||||
|
||||
// fill the output record with this msg but filter out note-on's when in stopping-state
|
||||
if( p->state == kPlayStateId || (p->state==kStoppingStateId && note_on_fl==false) )
|
||||
{
|
||||
@ -745,6 +769,7 @@ namespace cw
|
||||
vel_tbl_t* velTblL;
|
||||
vel_tbl_t* activeVelTbl;
|
||||
unsigned i_midi_fld_idx;
|
||||
unsigned i_score_vel_fld_idx;
|
||||
unsigned o_midi_fld_idx;
|
||||
|
||||
recd_array_t* recd_array; // output record array
|
||||
@ -954,6 +979,8 @@ namespace cw
|
||||
p->midiN = p->recd_array->allocRecdN;
|
||||
p->midiA = mem::allocZ<midi::ch_msg_t>(p->midiN);
|
||||
|
||||
// If the velocity table is being fed by the score follower then there may be a 'score_vel' field in the input record.
|
||||
p->i_score_vel_fld_idx = recd_type_field_index( rbuf->type, "score_vel");
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
@ -1029,15 +1056,46 @@ namespace cw
|
||||
// if this is a note on
|
||||
if( midi::isNoteOn(i_m->status,i_m->d1) )
|
||||
{
|
||||
// and the velocity is valid
|
||||
if( i_m->d1 >= p->activeVelTbl->tblN )
|
||||
|
||||
// if the 'score_vel' was not given
|
||||
if( p->i_score_vel_fld_idx == kInvalidIdx )
|
||||
{
|
||||
// and the velocity is valid
|
||||
if( i_m->d1 >= p->activeVelTbl->tblN )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The pre-mapped velocity value %i is outside of the range (%i) of the velocity table '%s'.",i_m->d1,p->activeVelTbl->tblN,cwStringNullGuard(p->activeVelTbl->label));
|
||||
goto errLabel;
|
||||
}
|
||||
}
|
||||
|
||||
// map the velocity through the active table
|
||||
o_m->d1 = p->activeVelTbl->tblA[ i_m->d1 ];
|
||||
// map the velocity through the active table
|
||||
o_m->d1 = p->activeVelTbl->tblA[ i_m->d1 ];
|
||||
}
|
||||
else // ... a 'score_vel' exists
|
||||
{
|
||||
unsigned score_vel = -1;
|
||||
|
||||
// get the score_vel
|
||||
if((rc = recd_get(i_rbuf->type,i_r,p->i_score_vel_fld_idx,score_vel)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(kOpFailRC,"'score_velocity access failed in velocity table.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// if the score_vel is valid (it won't be if this note was not tracked in the score)
|
||||
if( score_vel != (unsigned)-1 )
|
||||
{
|
||||
// verify that the 'score_vel' is inside the range of the table
|
||||
if(score_vel >= p->activeVelTbl->tblN )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The pre-mapped score velocity value %i is outside of the range (%i) of the velocity table '%s'.",score_vel,p->activeVelTbl->tblN,cwStringNullGuard(p->activeVelTbl->label));
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// apply the score_vel to the map
|
||||
o_m->d1 = p->activeVelTbl->tblA[ score_vel ];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//printf("%i %i %s\n",i_m->d1,o_m->d1,p->activeVelTbl->label);
|
||||
}
|
||||
@ -1261,10 +1319,15 @@ namespace cw
|
||||
kInitCfgPId,
|
||||
kPresetMapCfgPId,
|
||||
kFNamePId,
|
||||
kLocCntPId,
|
||||
kInPId,
|
||||
kLocPId,
|
||||
kResetPId,
|
||||
kPriManualSelPId,
|
||||
kSecManualSelPId,
|
||||
kPerNoteFlPId,
|
||||
kPerLocFlPId,
|
||||
kDryChordFlPId,
|
||||
|
||||
kPriProbFlPId,
|
||||
kPriUniformFlPId,
|
||||
@ -1310,6 +1373,15 @@ namespace cw
|
||||
kCoeffPresetValTId,
|
||||
} value_tid_t;
|
||||
|
||||
typedef struct loc_str
|
||||
{
|
||||
unsigned pri_preset_idx;
|
||||
unsigned sec_preset_idx;
|
||||
unsigned note_cnt;
|
||||
unsigned note_idx;
|
||||
unsigned rand;
|
||||
} loc_t;
|
||||
|
||||
typedef struct var_cfg_str
|
||||
{
|
||||
const char* var_label; // gutim_ps var label
|
||||
@ -1391,6 +1463,8 @@ namespace cw
|
||||
coeff_t cur_interp_dist;
|
||||
|
||||
bool per_note_fl;
|
||||
bool per_loc_fl;
|
||||
bool dry_chord_fl;
|
||||
bool pri_prob_fl;
|
||||
bool pri_uniform_fl;
|
||||
bool pri_dry_on_play_fl;
|
||||
@ -1406,9 +1480,31 @@ namespace cw
|
||||
bool interp_fl;
|
||||
bool interp_rand_fl;
|
||||
|
||||
list_t* manual_sel_list;
|
||||
unsigned cur_manual_pri_preset_idx;
|
||||
unsigned cur_manual_sec_preset_idx;
|
||||
|
||||
loc_t* locA;
|
||||
unsigned locN;
|
||||
unsigned dry_preset_idx;
|
||||
|
||||
} inst_t;
|
||||
|
||||
void _init_loc_array( inst_t* p )
|
||||
{
|
||||
if( p->locN > 0 && p->locA == nullptr )
|
||||
p->locA = mem::allocZ<loc_t>(p->locN);
|
||||
|
||||
for(unsigned i=0; i<p->locN; ++i)
|
||||
{
|
||||
p->locA[i].pri_preset_idx = kInvalidIdx;
|
||||
p->locA[i].sec_preset_idx = kInvalidIdx;
|
||||
p->locA[i].note_cnt = 0;
|
||||
p->locA[i].note_idx = kInvalidIdx;
|
||||
p->locA[i].rand = rand();
|
||||
}
|
||||
}
|
||||
|
||||
const char* _preset_index_to_label( inst_t* p, unsigned preset_idx )
|
||||
{
|
||||
const char* label = "<none>";
|
||||
@ -1419,6 +1515,46 @@ namespace cw
|
||||
return label;
|
||||
}
|
||||
|
||||
rc_t _create_manual_select_list( proc_t* proc, inst_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const char* var_labelA[] = { "pri_manual_sel", "sec_manual_sel" };
|
||||
const unsigned var_labelN = sizeof(var_labelA)/sizeof(var_labelA[0]);
|
||||
|
||||
p->cur_manual_pri_preset_idx = kInvalidIdx;
|
||||
p->cur_manual_sec_preset_idx = kInvalidIdx;
|
||||
|
||||
// create the list of values for the 'manual_sel' variable
|
||||
if((rc = list_create(p->manual_sel_list, p->presetN+1 )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = list_append(p->manual_sel_list,"auto",kInvalidIdx)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
for(unsigned i=0; i<p->presetN; ++i)
|
||||
if((rc = list_append( p->manual_sel_list, _preset_index_to_label(p,i), i)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
for(unsigned i=0; i<var_labelN; ++i)
|
||||
{
|
||||
variable_t* var = nullptr;
|
||||
|
||||
if((rc = var_find(proc, var_labelA[i], kBaseSfxId, kAnyChIdx, var )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The '%s' variable could not be found.",var_labelA[i]);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
var->value_list = p->manual_sel_list;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
if( rc != kOkRC )
|
||||
rc = cwLogError(rc,"The 'gutim_ps' manual selection list create failed.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
rc_t _read_class_preset_value( proc_t* proc, preset_t* preset, var_cfg_t* var_cfg, unsigned ch_idx, T& val_ref )
|
||||
{
|
||||
@ -1547,11 +1683,11 @@ namespace cw
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _apply_preset_no_interp(proc_t* proc, inst_t* p, unsigned voice_idx)
|
||||
rc_t _apply_preset_no_interp(proc_t* proc, inst_t* p, unsigned voice_idx, unsigned preset_idx)
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if( p->cur_pri_preset_idx == kInvalidIdx || p->cur_pri_preset_idx >= p->presetN )
|
||||
if( preset_idx == kInvalidIdx || preset_idx >= p->presetN )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The primary preset is invalid.");
|
||||
goto errLabel;
|
||||
@ -1561,11 +1697,11 @@ namespace cw
|
||||
{
|
||||
const var_cfg_t* var_cfg = _var_cfgA + var_idx;
|
||||
|
||||
assert( p->cur_pri_preset_idx < p->presetN );
|
||||
assert( preset_idx < p->presetN );
|
||||
|
||||
for(unsigned ch_idx=0; ch_idx<kMaxChN; ++ch_idx )
|
||||
{
|
||||
const preset_value_t* v = p->presetA[ p->cur_pri_preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
const preset_value_t* v = p->presetA[ preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
|
||||
variable_t* varb;
|
||||
var_find(proc, p->base[var_cfg->var_pid] + voice_idx,ch_idx, varb);
|
||||
@ -1600,17 +1736,17 @@ namespace cw
|
||||
}
|
||||
|
||||
|
||||
rc_t _apply_preset_with_interp(proc_t* proc, inst_t* p, unsigned voice_idx)
|
||||
rc_t _apply_preset_with_interp(proc_t* proc, inst_t* p, unsigned voice_idx, unsigned pri_preset_idx, unsigned sec_preset_idx)
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if( p->cur_pri_preset_idx == kInvalidIdx || p->cur_pri_preset_idx >= p->presetN )
|
||||
if( pri_preset_idx == kInvalidIdx || pri_preset_idx >= p->presetN )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The primary preset is invalid.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( p->cur_sec_preset_idx == kInvalidIdx || p->cur_sec_preset_idx >= p->presetN )
|
||||
if( sec_preset_idx == kInvalidIdx || sec_preset_idx >= p->presetN )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The secondary preset is invalid.");
|
||||
goto errLabel;
|
||||
@ -1620,13 +1756,13 @@ namespace cw
|
||||
{
|
||||
const var_cfg_t* var_cfg = _var_cfgA + var_idx;
|
||||
|
||||
assert( p->cur_pri_preset_idx < p->presetN );
|
||||
assert( pri_preset_idx < p->presetN );
|
||||
|
||||
for(unsigned ch_idx=0; ch_idx<kMaxChN; ++ch_idx )
|
||||
{
|
||||
|
||||
const preset_value_t* c0 = p->presetA[ p->cur_pri_preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
const preset_value_t* c1 = p->presetA[ p->cur_sec_preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
const preset_value_t* c0 = p->presetA[ pri_preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
const preset_value_t* c1 = p->presetA[ sec_preset_idx ].varA[ var_idx ].chA + ch_idx;
|
||||
|
||||
switch( var_cfg->tid )
|
||||
{
|
||||
@ -1697,23 +1833,26 @@ namespace cw
|
||||
_report_preset( proc, p, "Sec", p->cur_sec_preset_idx );
|
||||
}
|
||||
|
||||
rc_t _apply_preset( proc_t* proc, inst_t* p, const midi::ch_msg_t* m, unsigned voice_idx )
|
||||
// apply the preset assoc'd with p->cur_pri_preset_idx and p->cur_sec_preset_idx
|
||||
rc_t _apply_preset( proc_t* proc, inst_t* p, const midi::ch_msg_t* m, unsigned voice_idx, unsigned pri_preset_idx, unsigned sec_preset_idx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
pri_preset_idx = p->cur_manual_pri_preset_idx == kInvalidIdx ? pri_preset_idx : p->cur_manual_pri_preset_idx;
|
||||
sec_preset_idx = p->cur_manual_sec_preset_idx == kInvalidIdx ? sec_preset_idx : p->cur_manual_sec_preset_idx;
|
||||
|
||||
if( p->cur_frag == nullptr || p->cur_pri_preset_idx == kInvalidIdx )
|
||||
if( pri_preset_idx == kInvalidIdx )
|
||||
{
|
||||
rc = cwLogError(kInvalidStateRC,"No current preset has been selected.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( p->cur_sec_preset_idx == kInvalidIdx )
|
||||
if( !p->interp_fl || sec_preset_idx == kInvalidIdx )
|
||||
{
|
||||
rc = _apply_preset_no_interp(proc, p, voice_idx);
|
||||
rc = _apply_preset_no_interp(proc, p, voice_idx, pri_preset_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = _apply_preset_with_interp(proc, p, voice_idx);
|
||||
rc = _apply_preset_with_interp(proc, p, voice_idx, pri_preset_idx, sec_preset_idx);
|
||||
}
|
||||
|
||||
errLabel:
|
||||
@ -1795,13 +1934,20 @@ namespace cw
|
||||
const object_t* cfg = nullptr;
|
||||
bool resetFl = false;
|
||||
|
||||
p->dry_preset_idx = kInvalidIdx;
|
||||
|
||||
if((rc = var_register_and_get(proc,kAnyChIdx,
|
||||
kInitCfgPId, "cfg", kBaseSfxId, cfg, // TODO: clean up the contents of this CFG
|
||||
kInPId, "in", kBaseSfxId, rbuf,
|
||||
kFNamePId, "fname", kBaseSfxId, fname,
|
||||
kLocPId, "loc", kBaseSfxId, loc,
|
||||
kResetPId, "reset", kBaseSfxId, resetFl,
|
||||
kPerNoteFlPId, "per_note_fl",kBaseSfxId, p->per_note_fl,
|
||||
kInitCfgPId, "cfg", kBaseSfxId, cfg, // TODO: clean up the contents of this CFG
|
||||
kInPId, "in", kBaseSfxId, rbuf,
|
||||
kFNamePId, "fname", kBaseSfxId, fname,
|
||||
kLocCntPId, "loc_cnt", kBaseSfxId, p->locN,
|
||||
kLocPId, "loc", kBaseSfxId, loc,
|
||||
kResetPId, "reset", kBaseSfxId, resetFl,
|
||||
kPriManualSelPId, "pri_manual_sel", kBaseSfxId, p->cur_manual_pri_preset_idx,
|
||||
kSecManualSelPId, "sec_manual_sel", kBaseSfxId, p->cur_manual_sec_preset_idx,
|
||||
kPerNoteFlPId, "per_note_fl", kBaseSfxId, p->per_note_fl,
|
||||
kPerLocFlPId, "per_loc_fl", kBaseSfxId, p->per_loc_fl,
|
||||
kDryChordFlPId, "dry_chord_fl", kBaseSfxId, p->dry_chord_fl,
|
||||
|
||||
kPriProbFlPId, "pri_prob_fl", kBaseSfxId, p->pri_prob_fl,
|
||||
kPriUniformFlPId, "pri_uniform_fl", kBaseSfxId, p->pri_uniform_fl,
|
||||
@ -1841,6 +1987,8 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
p->dry_preset_idx = preset_sel::dry_preset_index(p->psH);
|
||||
|
||||
// read in the loc->preset map file
|
||||
if((rc = preset_sel::read(p->psH,exp_fname)) != kOkRC )
|
||||
{
|
||||
@ -1854,8 +2002,9 @@ namespace cw
|
||||
// The location is coming from a 'record', get the location field.
|
||||
if((p->loc_fld_idx = recd_type_field_index( rbuf->type, "loc")) == kInvalidIdx )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The 'in' record does not have a 'loc' field.");
|
||||
goto errLabel;
|
||||
cwLogWarning("The incoming record to the 'gutim_ps' object does not have a 'loc' field. Score tracking is disabled.");
|
||||
//rc = cwLogError(kInvalidArgRC,"The 'in' record does not have a 'loc' field.");
|
||||
//goto errLabel;
|
||||
}
|
||||
|
||||
|
||||
@ -1895,9 +2044,17 @@ namespace cw
|
||||
p->psPresetCnt = preset_count(p->psH); // get the count of preset class (~13)
|
||||
|
||||
// Get the values for all the presets required by the transform parameter variables
|
||||
rc = _create_and_fill_preset_array( proc, p );
|
||||
if((rc = _create_and_fill_preset_array( proc, p )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
// create the 'manual_sel' list based on the available preset labels
|
||||
if((rc = _create_manual_select_list(proc, p )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// initialize locA[]
|
||||
_init_loc_array(p);
|
||||
|
||||
errLabel:
|
||||
mem::release(exp_fname);
|
||||
return rc;
|
||||
@ -1907,24 +2064,88 @@ namespace cw
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
// Custom clean-up code goes here
|
||||
list_destroy(p->manual_sel_list);
|
||||
mem::release(p->locA);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _exec_note_on( proc_t* proc, inst_t* p, const midi::ch_msg_t* m, unsigned voice_idx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
bool per_note_fl = false;
|
||||
rc_t rc = kOkRC;
|
||||
bool per_note_fl = false;
|
||||
bool per_loc_fl = false;
|
||||
bool chord_dry_fl = false;
|
||||
bool apply_dry_fl = false;
|
||||
bool update_preset_fl = false;
|
||||
unsigned loc_idx = kInvalidIdx;
|
||||
unsigned pri_preset_idx = p->cur_pri_preset_idx;
|
||||
unsigned sec_preset_idx = p->cur_sec_preset_idx;
|
||||
|
||||
if( var_get(proc,kPerNoteFlPId,kAnyChIdx,per_note_fl) != kOkRC )
|
||||
if((rc = var_get(proc,kPerLocFlPId,kAnyChIdx,per_loc_fl)) != kOkRC)
|
||||
goto errLabel;
|
||||
|
||||
if( per_note_fl )
|
||||
if((rc = _update_cur_preset_idx( proc, p, p->cur_frag )) != kOkRC )
|
||||
goto errLabel;
|
||||
// if we are selecting a new preset per location
|
||||
if( per_loc_fl && p->locN > 0 )
|
||||
{
|
||||
|
||||
rc = _apply_preset( proc, p, m, voice_idx );
|
||||
unsigned loc = m->devIdx;
|
||||
unsigned note_idx = m->portIdx;
|
||||
unsigned note_cnt = m->uid;
|
||||
assert( loc < p->locN );
|
||||
|
||||
// if this is the first note received for this location
|
||||
if( p->locA[ loc ].note_cnt == 0 )
|
||||
{
|
||||
p->locA[ loc ].note_cnt = note_cnt;
|
||||
loc_idx = loc;
|
||||
update_preset_fl = true;
|
||||
}
|
||||
else // ... select the preset based on the preset previously picked for this location
|
||||
{
|
||||
pri_preset_idx = p->locA[ loc ].pri_preset_idx;
|
||||
sec_preset_idx = p->locA[ loc ].sec_preset_idx;
|
||||
}
|
||||
|
||||
p->locA[ loc ].note_idx += 1;
|
||||
|
||||
|
||||
var_get(proc,kDryChordFlPId,kAnyChIdx,chord_dry_fl);
|
||||
|
||||
apply_dry_fl = chord_dry_fl && (((note_idx % 2)==0) == (p->locA[ loc ].rand > RAND_MAX/2));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if((rc = var_get(proc,kPerNoteFlPId,kAnyChIdx,per_note_fl)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// if we are selecting presets per note
|
||||
if( per_note_fl )
|
||||
update_preset_fl = true;
|
||||
}
|
||||
|
||||
// if a new preset should be selected
|
||||
if( update_preset_fl )
|
||||
{
|
||||
if((rc = _update_cur_preset_idx( proc, p, p->cur_frag )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// if this is the first note for this 'loc' then cache the selected presets
|
||||
if( loc_idx != kInvalidIdx )
|
||||
{
|
||||
p->locA[ loc_idx ].pri_preset_idx = p->cur_pri_preset_idx;
|
||||
p->locA[ loc_idx ].sec_preset_idx = p->cur_sec_preset_idx;
|
||||
}
|
||||
}
|
||||
|
||||
if( apply_dry_fl )
|
||||
{
|
||||
pri_preset_idx = p->dry_preset_idx;
|
||||
sec_preset_idx = p->dry_preset_idx;
|
||||
}
|
||||
|
||||
rc = _apply_preset( proc, p, m, voice_idx, pri_preset_idx, sec_preset_idx );
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
@ -1956,15 +2177,16 @@ namespace cw
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _exec_on_new_location( proc_t* proc, inst_t* p )
|
||||
rc_t _exec_on_new_fragment( proc_t* proc, inst_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
bool per_note_fl = false;
|
||||
bool per_loc_fl = false;;
|
||||
var_get(proc,kPerNoteFlPId,kAnyChIdx,per_note_fl);
|
||||
var_get(proc,kPerLocFlPId,kAnyChIdx,per_loc_fl);
|
||||
|
||||
if( var_get(proc,kPerNoteFlPId,kAnyChIdx,per_note_fl) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if( !per_note_fl )
|
||||
// if we are not assigning presets per note - then select p->cur_pri/sec_preset_idx for all following notes
|
||||
if( per_note_fl == false && per_loc_fl == false )
|
||||
if((rc = _update_cur_preset_idx( proc, p, p->cur_frag )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
@ -1979,6 +2201,10 @@ namespace cw
|
||||
rbuf_t* in_rbuf = nullptr;
|
||||
unsigned loc = kInvalidIdx;
|
||||
|
||||
// if score tracking is disabled
|
||||
if( p->loc_fld_idx == kInvalidIdx )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = var_get(proc,kInPId,kAnyChIdx,in_rbuf)) != kOkRC)
|
||||
goto errLabel;
|
||||
|
||||
@ -2001,13 +2227,17 @@ namespace cw
|
||||
{
|
||||
const preset_sel::frag_t* frag = nullptr;
|
||||
|
||||
// lookup the fragment associated with the location
|
||||
// if this location is associated with a new set of preset selections ...
|
||||
if( preset_sel::track_loc( p->psH, loc, frag ) && frag != nullptr )
|
||||
{
|
||||
// p->cur_frag maintains a reference to the preset selections
|
||||
p->cur_frag = frag;
|
||||
|
||||
cwLogInfo("LOC:%i",loc);
|
||||
rc = _exec_on_new_location(proc,p);
|
||||
cwLogInfo("LOC:%i ",loc);
|
||||
//cwLogPrint("LOC:%i ",loc);
|
||||
//fragment_report( p->psH, frag );
|
||||
|
||||
rc = _exec_on_new_fragment(proc,p);
|
||||
}
|
||||
|
||||
}
|
||||
@ -2015,90 +2245,27 @@ namespace cw
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
bool _update( proc_t* proc, unsigned vid, bool& fl_ref, rc_t rc_ref)
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
bool fl_value = false;
|
||||
bool value_changed_fl = false;
|
||||
|
||||
if((rc = var_get(proc, vid, kAnyChIdx, fl_value)) != kOkRC )
|
||||
{
|
||||
rc_ref = rc;
|
||||
return false;
|
||||
}
|
||||
|
||||
value_changed_fl = (fl_value != fl_ref);
|
||||
|
||||
//if( vid == kPriProbFlPId )
|
||||
// printf("%i : %i %i %i\n",vid,fl_value,fl_ref,value_changed_fl);
|
||||
|
||||
fl_ref = fl_value;
|
||||
|
||||
return value_changed_fl;
|
||||
}
|
||||
|
||||
rc_t _exec_update_state( proc_t* proc, inst_t* p )
|
||||
rc_t _update_manual_preset_index( inst_t* p, variable_t* var, unsigned& preset_idx_ref )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned list_idx;
|
||||
|
||||
if( _update( proc, kPriProbFlPId, p->pri_prob_fl, rc) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kPriUniformFlPId, kAnyChIdx, p->pri_prob_fl );
|
||||
var_send_to_ui_enable(proc, kPriDryOnPlayFlPId, kAnyChIdx, p->pri_prob_fl );
|
||||
var_send_to_ui_enable(proc, kPriAllowAllFlPId, kAnyChIdx, p->pri_prob_fl );
|
||||
var_send_to_ui_enable(proc, kPriDryOnSelFlPId, kAnyChIdx, p->pri_prob_fl && p->pri_allow_all_fl );
|
||||
}
|
||||
if((rc = var_get(var,list_idx)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
|
||||
if( _update( proc, kPriAllowAllFlPId, p->pri_allow_all_fl, rc ) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kPriDryOnSelFlPId, kAnyChIdx, p->pri_allow_all_fl );
|
||||
}
|
||||
|
||||
_update( proc, kSecUniformFlPId, p->pri_uniform_fl, rc);
|
||||
_update( proc, kPriDryOnPlayFlPId, p->pri_dry_on_play_fl, rc);
|
||||
_update( proc, kPriDryOnSelFlPId, p->pri_dry_on_sel_fl, rc);
|
||||
if((rc = list_ele_value(p->manual_sel_list,list_idx,preset_idx_ref)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
if( _update( proc, kInterpFlPId, p->interp_fl, rc ) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kInterpRandFlPId, kAnyChIdx, p->interp_fl );
|
||||
var_send_to_ui_enable(proc, kInterpDistPId, kAnyChIdx, p->interp_fl & (!p->interp_rand_fl) );
|
||||
errLabel:
|
||||
if( rc != kOkRC )
|
||||
preset_idx_ref = kInvalidIdx;
|
||||
|
||||
var_send_to_ui_enable(proc, kSecProbFlPId, kAnyChIdx, p->interp_fl );
|
||||
var_send_to_ui_enable(proc, kSecUniformFlPId, kAnyChIdx, p->interp_fl );
|
||||
var_send_to_ui_enable(proc, kSecDryOnPlayFlPId, kAnyChIdx, p->interp_fl );
|
||||
var_send_to_ui_enable(proc, kSecAllowAllFlPId, kAnyChIdx, p->interp_fl );
|
||||
var_send_to_ui_enable(proc, kSecDryOnSelFlPId, kAnyChIdx, p->interp_fl && p->sec_allow_all_fl );
|
||||
}
|
||||
|
||||
if( _update( proc, kInterpRandFlPId, p->interp_rand_fl, rc ) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kInterpDistPId, kAnyChIdx, p->interp_fl & (!p->interp_rand_fl) );
|
||||
}
|
||||
|
||||
if( _update( proc, kSecProbFlPId, p->sec_prob_fl, rc) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kSecUniformFlPId, kAnyChIdx, p->sec_prob_fl );
|
||||
var_send_to_ui_enable(proc, kSecDryOnPlayFlPId, kAnyChIdx, p->sec_prob_fl );
|
||||
var_send_to_ui_enable(proc, kSecAllowAllFlPId, kAnyChIdx, p->sec_prob_fl );
|
||||
var_send_to_ui_enable(proc, kSecDryOnSelFlPId, kAnyChIdx, p->sec_prob_fl && p->sec_allow_all_fl );
|
||||
}
|
||||
|
||||
if( _update( proc, kSecAllowAllFlPId, p->sec_allow_all_fl, rc ) )
|
||||
{
|
||||
var_send_to_ui_enable(proc, kSecDryOnSelFlPId, kAnyChIdx, p->sec_allow_all_fl );
|
||||
}
|
||||
|
||||
_update( proc, kSecUniformFlPId, p->sec_uniform_fl, rc);
|
||||
_update( proc, kSecDryOnPlayFlPId, p->sec_dry_on_play_fl, rc);
|
||||
_update( proc, kSecDryOnSelFlPId, p->sec_dry_on_sel_fl, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
rc_t _update_ui_state( proc_t* proc, inst_t* p, variable_t* var )
|
||||
{
|
||||
@ -2110,6 +2277,16 @@ namespace cw
|
||||
|
||||
switch(var->vid)
|
||||
{
|
||||
case kPriManualSelPId:
|
||||
if((rc = _update_manual_preset_index(p,var,p->cur_manual_pri_preset_idx)) != kOkRC )
|
||||
rc = cwLogError(rc,"Manual primary selected preset index update failed.");
|
||||
break;
|
||||
|
||||
case kSecManualSelPId:
|
||||
if((rc = _update_manual_preset_index(p,var,p->cur_manual_sec_preset_idx)) != kOkRC )
|
||||
rc = cwLogError(rc,"Manual secondary selected preset index update failed.");
|
||||
break;
|
||||
|
||||
case kPriProbFlPId:
|
||||
var_get(var,p->pri_prob_fl);
|
||||
var_send_to_ui_enable(proc, kPriUniformFlPId, kAnyChIdx, p->pri_prob_fl );
|
||||
@ -2188,8 +2365,6 @@ namespace cw
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
//if((rc = _exec_update_state(proc, p )) != kOkRC )
|
||||
// goto errLabel;
|
||||
_update_ui_state( proc, p, var );
|
||||
|
||||
if( var->vid == kResetPId )
|
||||
@ -2197,6 +2372,7 @@ namespace cw
|
||||
if( p->psH.isValid() )
|
||||
track_loc_reset( p->psH);
|
||||
|
||||
_init_loc_array(p);
|
||||
}
|
||||
|
||||
//errLabel:
|
||||
@ -2431,6 +2607,265 @@ namespace cw
|
||||
} // score_follower
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Score Follower 2
|
||||
//
|
||||
namespace score_follower_2
|
||||
{
|
||||
|
||||
enum
|
||||
{
|
||||
kInPId,
|
||||
kFnamePId,
|
||||
kBegLocPId,
|
||||
kEndLocPId,
|
||||
kResetTrigPId,
|
||||
kPrintFlPId,
|
||||
kOutPId,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cw::perf_score::handle_t scoreH;
|
||||
cw::score_follow_2::handle_t sfH;
|
||||
unsigned i_midi_field_idx;
|
||||
unsigned o_midi_field_idx;
|
||||
unsigned loc_field_idx;
|
||||
unsigned vel_field_idx;
|
||||
recd_array_t* recd_array; // output record array
|
||||
|
||||
} inst_t;
|
||||
|
||||
|
||||
rc_t _alloc_recd_array( proc_t* proc, const char* var_label, unsigned sfx_id, unsigned chIdx, const recd_type_t* base, recd_array_t*& recd_array_ref )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
variable_t* var = nullptr;
|
||||
|
||||
// find the record variable
|
||||
if((rc = var_find( proc, var_label, sfx_id, chIdx, var )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The record variable '%s:%i' could was not found.",cwStringNullGuard(var_label),sfx_id);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// verify that the variable has a record format
|
||||
if( !var_has_recd_format(var) )
|
||||
{
|
||||
rc = cwLogError(kInvalidArgRC,"The variable does not have a valid record format.");
|
||||
goto errLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
recd_fmt_t* recd_fmt = var->varDesc->fmt.recd_fmt;
|
||||
|
||||
// create the recd_array
|
||||
if((rc = recd_array_create( recd_array_ref, recd_fmt->recd_type, base, recd_fmt->alloc_cnt )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
if( rc != kOkRC )
|
||||
rc = cwLogError(rc,"Record array create failed on the variable '%s:%i ch:%i.",cwStringNullGuard(var_label),sfx_id,chIdx);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
rc_t _create( proc_t* proc, inst_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
rbuf_t* in_rbuf = nullptr;
|
||||
const char* c_score_fname = nullptr;
|
||||
char* score_fname = nullptr;
|
||||
bool printParseWarningsFl = true;
|
||||
unsigned beg_loc_id = kInvalidId;
|
||||
unsigned end_loc_id = kInvalidId;
|
||||
bool reset_trig_fl = false;
|
||||
cw::score_follow_2::args_t sf_args = {
|
||||
.pre_affinity_sec = 1.0,
|
||||
.post_affinity_sec = 3.0,
|
||||
.pre_wnd_sec = 2.0,
|
||||
.post_wnd_sec = 5.0,
|
||||
.decay_coeff = 0.995,
|
||||
.d_sec_err_thresh_lo = 0.4,
|
||||
.d_loc_thresh_lo = 3,
|
||||
.d_sec_err_thresh_hi = 1.5,
|
||||
.d_loc_thresh_hi = 4,
|
||||
.d_loc_stats_thresh = 3,
|
||||
.rpt_fl = true
|
||||
};
|
||||
|
||||
if((rc = var_register_and_get(proc,kAnyChIdx,
|
||||
kInPId, "in", kBaseSfxId, in_rbuf,
|
||||
kFnamePId, "score_fname", kBaseSfxId, c_score_fname,
|
||||
kBegLocPId, "b_loc", kBaseSfxId, beg_loc_id,
|
||||
kEndLocPId, "e_loc", kBaseSfxId, end_loc_id,
|
||||
kResetTrigPId, "reset_trigger", kBaseSfxId, reset_trig_fl,
|
||||
kPrintFlPId, "print_fl", kBaseSfxId, sf_args.rpt_fl )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
if((score_fname = proc_expand_filename( proc, c_score_fname )) == nullptr )
|
||||
{
|
||||
rc = cwLogError(kOpFailRC,"Unable to expand the score filename '%s'.",cwStringNullGuard(c_score_fname));
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// create the SF score
|
||||
if((rc = create( p->scoreH, score_fname)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"SF Score create failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// create the score follower
|
||||
if((rc = create( p->sfH, sf_args, p->scoreH )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Score follower create failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = reset( p->sfH, beg_loc_id, end_loc_id )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Score follower reset failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// create the output recd_array using the 'in' record type as the base type
|
||||
if((rc = _alloc_recd_array( proc, "out", kBaseSfxId, kAnyChIdx, in_rbuf->type, p->recd_array )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// create one output record buffer
|
||||
rc = var_register_and_set( proc, "out", kBaseSfxId, kOutPId, kAnyChIdx, p->recd_array->type, nullptr, 0 );
|
||||
|
||||
p->i_midi_field_idx = recd_type_field_index( in_rbuf->type, "midi");
|
||||
p->o_midi_field_idx = recd_type_field_index( p->recd_array->type, "midi");
|
||||
p->loc_field_idx = recd_type_field_index( p->recd_array->type, "loc");
|
||||
p->vel_field_idx = recd_type_field_index( p->recd_array->type, "score_vel");
|
||||
|
||||
errLabel:
|
||||
mem::release(score_fname);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _destroy( proc_t* proc, inst_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
recd_array_destroy(p->recd_array);
|
||||
destroy(p->sfH);
|
||||
destroy(p->scoreH);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _notify( proc_t* proc, inst_t* p, variable_t* var )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
rc_t _set_output_record( inst_t* p, rbuf_t* rbuf, const recd_t* base, unsigned loc_id, unsigned vel )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
recd_t* r = p->recd_array->recdA + rbuf->recdN;
|
||||
|
||||
// if the output record array is full
|
||||
if( rbuf->recdN >= p->recd_array->allocRecdN )
|
||||
{
|
||||
rc = cwLogError(kBufTooSmallRC,"The internal record buffer overflowed. (buf recd count:%i).",p->recd_array->allocRecdN);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
recd_set( rbuf->type, base, r, p->loc_field_idx, loc_id );
|
||||
recd_set( rbuf->type, base, r, p->vel_field_idx, vel );
|
||||
rbuf->recdN += 1;
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _exec( proc_t* proc, inst_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
unsigned sample_idx = proc->ctx->cycleIndex * proc->ctx->framesPerCycle;
|
||||
double sec = ((double)sample_idx) / proc->ctx->sample_rate;
|
||||
const rbuf_t* i_rbuf = nullptr;
|
||||
rbuf_t* o_rbuf = nullptr;
|
||||
unsigned result_recd_idx = kInvalidIdx;
|
||||
|
||||
if((rc = var_get(proc,kInPId,kAnyChIdx,i_rbuf)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = var_get(proc,kOutPId,kAnyChIdx,o_rbuf)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
o_rbuf->recdA = p->recd_array->recdA;
|
||||
o_rbuf->recdN = 0;
|
||||
|
||||
// for each incoming record
|
||||
for(unsigned i=0; i<i_rbuf->recdN; ++i)
|
||||
{
|
||||
midi::ch_msg_t* m = nullptr;
|
||||
unsigned loc_id = kInvalidId;
|
||||
unsigned score_vel = -1;
|
||||
|
||||
if((rc = recd_get( i_rbuf->type, i_rbuf->recdA+i, p->i_midi_field_idx, m)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The 'midi' field read failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( midi::isNoteOn( m->status, m->d1 ) )
|
||||
{
|
||||
|
||||
if((rc = on_new_note( p->sfH, m->uid, sec, m->d0, m->d1, loc_id, score_vel )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Score follower note processing failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if( loc_id != kInvalidId )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
_set_output_record( p, o_rbuf, i_rbuf->recdA+i, loc_id, score_vel );
|
||||
|
||||
}
|
||||
|
||||
do_exec(p->sfH);
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _report( proc_t* proc, inst_t* p )
|
||||
{ return kOkRC; }
|
||||
|
||||
class_members_t members = {
|
||||
.create = std_create<inst_t>,
|
||||
.destroy = std_destroy<inst_t>,
|
||||
.notify = std_notify<inst_t>,
|
||||
.exec = std_exec<inst_t>,
|
||||
.report = std_report<inst_t>
|
||||
};
|
||||
|
||||
} // score_follower_2
|
||||
|
||||
|
||||
} // flow
|
||||
} //cw
|
||||
|
11
cwFlowPerf.h
11
cwFlowPerf.h
@ -2,11 +2,12 @@ namespace cw
|
||||
{
|
||||
namespace flow
|
||||
{
|
||||
namespace score_player { extern class_members_t members; }
|
||||
namespace vel_table { extern class_members_t members; }
|
||||
namespace preset_select { extern class_members_t members; }
|
||||
namespace gutim_ps { extern class_members_t members; }
|
||||
namespace score_follower { extern class_members_t members; }
|
||||
namespace score_player { extern class_members_t members; }
|
||||
namespace vel_table { extern class_members_t members; }
|
||||
namespace preset_select { extern class_members_t members; }
|
||||
namespace gutim_ps { extern class_members_t members; }
|
||||
namespace score_follower { extern class_members_t members; }
|
||||
namespace score_follower_2 { extern class_members_t members; }
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user