cwVelTableTuner.h/cpp : Add the 'defaultFl' parameter to determine which velocity table should be loaded by default for a given MIDI device.

This commit is contained in:
kevin 2023-03-20 08:55:23 -04:00
parent ecdec5aa60
commit 67361c928b
3 changed files with 59 additions and 23 deletions

View File

@ -23,6 +23,7 @@ namespace cw
{ kVtDeviceSelectId, kVtPianoDevId, "vtPianoDevId" }, { kVtDeviceSelectId, kVtPianoDevId, "vtPianoDevId" },
{ kVtDeviceSelectId, kVtSamplerDevId, "vtSamplerDevId" }, { kVtDeviceSelectId, kVtSamplerDevId, "vtSamplerDevId" },
{ kInvalidId, kVtTableSelectId, "vtTableSelectId" }, { kInvalidId, kVtTableSelectId, "vtTableSelectId" },
{ kInvalidId, kVtDefaultCheckId, "vtDefaultCheckId" },
{ kInvalidId, kVtPlayVelSeqBtnId, "vtPlayVelSeqBtnId" }, { kInvalidId, kVtPlayVelSeqBtnId, "vtPlayVelSeqBtnId" },
{ kInvalidId, kVtPitchId, "vtPitchId" }, { kInvalidId, kVtPitchId, "vtPitchId" },
{ kInvalidId, kVtPlayPitchSeqBtnId, "vtPlayPitchSeqBtnId" }, { kInvalidId, kVtPlayPitchSeqBtnId, "vtPlayPitchSeqBtnId" },
@ -66,12 +67,13 @@ namespace cw
typedef struct tbl_str typedef struct tbl_str
{ {
bool defaultFl;
bool enableFl; bool enableFl;
uint8_t* tableA; uint8_t* tableA;
unsigned tableN; unsigned tableN;
char* name; char* name;
unsigned mrpDevIdx; unsigned mrpDevIdx;
unsigned appId; // id associated with UI select option for this table unsigned appId; // id associated with UI select option for this table
struct tbl_str* link; struct tbl_str* link;
} tbl_t; } tbl_t;
@ -98,7 +100,7 @@ namespace cw
tbl_t* tableL; // array of tables tbl_t* tableL; // array of tables
unsigned nextTableAppId; unsigned nextTableAppId;
tbl_t curTable; // current table being edited tbl_t* curTable; // current table being edited
bool initUiFl; // True if the UI has been initialized (UI initialization happens once at startup) bool initUiFl; // True if the UI has been initialized (UI initialization happens once at startup)
bool waitForStopFl; // The player was requested to stop but is waiting for the current note cycle to end bool waitForStopFl; // The player was requested to stop but is waiting for the current note cycle to end
@ -190,9 +192,6 @@ namespace cw
mem::release(p->cfg_fname); mem::release(p->cfg_fname);
mem::release(p->cfg_backup_dir); mem::release(p->cfg_backup_dir);
mem::release(p->curTable.tableA);
mem::release(p->curTable.name);
mem::release(p->duplicateName); mem::release(p->duplicateName);
mem::release(p); mem::release(p);
@ -313,6 +312,7 @@ namespace cw
const char* tbl_name = nullptr; const char* tbl_name = nullptr;
const char* tbl_device = nullptr; const char* tbl_device = nullptr;
bool tbl_enableFl = false; bool tbl_enableFl = false;
bool tbl_defaultFl= false;
const object_t* tbl_node = nullptr; const object_t* tbl_node = nullptr;
const dev_map_t*devMap = nullptr; const dev_map_t*devMap = nullptr;
@ -327,6 +327,7 @@ namespace cw
if((rc = tbl_hdr->getv("name", tbl_name, if((rc = tbl_hdr->getv("name", tbl_name,
"device", tbl_device, "device", tbl_device,
"enableFl",tbl_enableFl, "enableFl",tbl_enableFl,
"defaultFl", tbl_defaultFl,
"table", tbl_node)) != kOkRC ) "table", tbl_node)) != kOkRC )
{ {
rc = cwLogError(rc,"Velocity table cfg. file parsing error."); rc = cwLogError(rc,"Velocity table cfg. file parsing error.");
@ -343,6 +344,7 @@ namespace cw
t->name = mem::duplStr(tbl_name); t->name = mem::duplStr(tbl_name);
t->mrpDevIdx= devMap->mrpDevIdx; t->mrpDevIdx= devMap->mrpDevIdx;
t->enableFl = tbl_enableFl; t->enableFl = tbl_enableFl;
t->defaultFl= tbl_defaultFl;
t->tableN = tbl_node->child_count(); t->tableN = tbl_node->child_count();
t->tableA = mem::allocZ<uint8_t>( t->tableN ); t->tableA = mem::allocZ<uint8_t>( t->tableN );
@ -489,14 +491,14 @@ namespace cw
rc_t rc = kOkRC; rc_t rc = kOkRC;
const dev_map_t* dm; const dev_map_t* dm;
if((dm = _dev_map_from_mrpDevIdx(p->curTable.mrpDevIdx)) == nullptr ) if((dm = _dev_map_from_mrpDevIdx(p->curTable->mrpDevIdx)) == nullptr )
{ {
rc = _set_status(p,kOpFailRC,"The current table has an invalid device index (%i).",p->curTable.mrpDevIdx ); rc = _set_status(p,kOpFailRC,"The current table has an invalid device index (%i).",p->curTable->mrpDevIdx );
goto errLabel; goto errLabel;
} }
if((rc = vel_table_set( p->mrpH, p->curTable.mrpDevIdx, p->curTable.tableA, p->curTable.tableN )) != kOkRC ) if((rc = vel_table_set( p->mrpH, p->curTable->mrpDevIdx, p->curTable->tableA, p->curTable->tableN )) != kOkRC )
rc = _set_status(p,rc,"Velocity table apply failed."); rc = _set_status(p,rc,"Velocity table apply failed.");
else else
_set_status(p,kOkRC,"Velocity table applied to '%s'.", cwStringNullGuard(dm->label)); _set_status(p,kOkRC,"Velocity table applied to '%s'.", cwStringNullGuard(dm->label));
@ -524,6 +526,8 @@ namespace cw
if( newTableName == nullptr ) if( newTableName == nullptr )
newTableName = t->name; newTableName = t->name;
dst_tbl.defaultFl = t->defaultFl;
dst_tbl.enableFl = t->enableFl;
dst_tbl.name = mem::reallocStr(dst_tbl.name,newTableName); dst_tbl.name = mem::reallocStr(dst_tbl.name,newTableName);
dst_tbl.mrpDevIdx = t->mrpDevIdx; dst_tbl.mrpDevIdx = t->mrpDevIdx;
dst_tbl.appId = t->appId; dst_tbl.appId = t->appId;
@ -607,7 +611,8 @@ namespace cw
} }
// duplicate the selected table into 'curTable' // duplicate the selected table into 'curTable'
_duplicateTable(p,p->curTable,t); //_duplicateTable(p,p->curTable,t);
p->curTable = t;
// update the UI with the new velocity table values // update the UI with the new velocity table values
for(unsigned i = 0; i<t->tableN; ++i) for(unsigned i = 0; i<t->tableN; ++i)
@ -615,14 +620,16 @@ namespace cw
// set the device menu // set the device menu
dm = _dev_map_from_mrpDevIdx(t->mrpDevIdx); dm = _dev_map_from_mrpDevIdx(t->mrpDevIdx);
// device labels were tested at parse time - so this function can't fail assert( dm != nullptr ); // device labels were tested at parse time - so dm must be non-null
assert( dm != nullptr );
uiSendValue( p->ioH, uiFindElementUuId( p->ioH, kVtDeviceSelectId), dm->appId ); uiSendValue( p->ioH, uiFindElementUuId( p->ioH, kVtDeviceSelectId), dm->appId );
// set the table menu // set the table menu
uiSendValue( p->ioH, io::uiFindElementUuId( p->ioH, kVtTableSelectId ), t->appId ); uiSendValue( p->ioH, io::uiFindElementUuId( p->ioH, kVtTableSelectId ), t->appId );
// set the 'default' check box
uiSendValue( p->ioH, io::uiFindElementUuId( p->ioH, kVtDefaultCheckId ), t->defaultFl );
// Set the 'duplicate name' based on the new table // Set the 'duplicate name' based on the new table
_set_duplicate_name(p,t->name); _set_duplicate_name(p,t->name);
@ -652,7 +659,8 @@ namespace cw
tbl_t* new_tbl = mem::allocZ<tbl_t>(); tbl_t* new_tbl = mem::allocZ<tbl_t>();
// duplicate 'curTable' into the new table // duplicate 'curTable' into the new table
_duplicateTable(p, *new_tbl, &p->curTable, p->duplicateName); //_duplicateTable(p, *new_tbl, &p->curTable, p->duplicateName);
p->curTable = new_tbl;
// link in the new table // link in the new table
_link_in_table(p, new_tbl ); _link_in_table(p, new_tbl );
@ -672,7 +680,24 @@ namespace cw
cwAssert( dm != nullptr ); cwAssert( dm != nullptr );
p->curTable.mrpDevIdx = dm->mrpDevIdx; p->curTable->mrpDevIdx = dm->mrpDevIdx;
return rc;
}
cw::rc_t _set_default_check( vtbl_t* p, unsigned defaultFl )
{
cw::rc_t rc = kOkRC;
if( defaultFl )
{
tbl_t* t;
for(t=p->tableL; t!=nullptr; t=t->link)
if( t->mrpDevIdx == p->curTable->mrpDevIdx )
t->defaultFl = false;
}
p->curTable->defaultFl = defaultFl;
return rc; return rc;
} }
@ -756,7 +781,7 @@ namespace cw
cw::rc_t _set_table_entry( vtbl_t* p, unsigned table_idx, unsigned value ) cw::rc_t _set_table_entry( vtbl_t* p, unsigned table_idx, unsigned value )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
if( table_idx >= p->curTable.tableN ) if( table_idx >= p->curTable->tableN )
{ {
rc = _set_status(p,kInvalidArgRC,"The table index %i is not valid.",table_idx); rc = _set_status(p,kInvalidArgRC,"The table index %i is not valid.",table_idx);
} }
@ -764,7 +789,7 @@ namespace cw
{ {
if((rc = _validate_midi_value(p,value)) == kOkRC ) if((rc = _validate_midi_value(p,value)) == kOkRC )
{ {
p->curTable.tableA[ table_idx ] = value; p->curTable->tableA[ table_idx ] = value;
_set_status(p,kOkRC,"The table index '%i' was set to the value '%i'.",table_idx,value); _set_status(p,kOkRC,"The table index '%i' was set to the value '%i'.",table_idx,value);
} }
} }
@ -864,6 +889,10 @@ cw::rc_t cw::vtbl::on_ui_value( handle_t h, const io::ui_msg_t& m )
case kVtDeviceSelectId: case kVtDeviceSelectId:
rc = vtbl::_set_device(p, m.value->u.u ); rc = vtbl::_set_device(p, m.value->u.u );
break; break;
case kVtDefaultCheckId:
rc = vtbl::_set_default_check(p, m.value->u.b );
break;
case kVtPianoDevId: case kVtPianoDevId:
rc = vtbl::_set_device(p,midi_record_play::kPiano_MRP_DevIdx ); rc = vtbl::_set_device(p,midi_record_play::kPiano_MRP_DevIdx );
@ -954,10 +983,14 @@ cw::rc_t cw::vtbl::on_ui_echo( handle_t h, const io::ui_msg_t& m )
p->initUiFl = true; p->initUiFl = true;
} }
break; break;
case kVtDefaultCheckId:
rc = io::uiSendValue(p->ioH, m.uuId, p->curTable->defaultFl );
break;
case kVtPitchId: case kVtPitchId:
rc = io::uiSendValue(p->ioH, m.uuId, p->vseqPitch ); rc = io::uiSendValue(p->ioH, m.uuId, p->vseqPitch );
break; break;
case kVtVelocityId: case kVtVelocityId:
rc = io::uiSendValue(p->ioH, m.uuId, p->pseqVelocity ); rc = io::uiSendValue(p->ioH, m.uuId, p->pseqVelocity );
break; break;
@ -1002,8 +1035,8 @@ cw::rc_t cw::vtbl::exec( handle_t h )
{ {
case kVelSeqModeId: case kVelSeqModeId:
pitch = p->vseqPitch; pitch = p->vseqPitch;
cwAssert( p->nextVelIdx < p->curTable.tableN ); cwAssert( p->nextVelIdx < p->curTable->tableN );
vel = p->curTable.tableA[ p->nextVelIdx ]; vel = p->curTable->tableA[ p->nextVelIdx ];
break; break;
case kPitchSeqModeId: case kPitchSeqModeId:
@ -1030,7 +1063,7 @@ cw::rc_t cw::vtbl::exec( handle_t h )
{ {
pitch = p->vseqPitch; pitch = p->vseqPitch;
if( p->nextVelIdx + 1 >= p->curTable.tableN || p->waitForStopFl ) if( p->nextVelIdx + 1 >= p->curTable->tableN || p->waitForStopFl )
p->state = kStoppedStateId; p->state = kStoppedStateId;
else else
p->nextVelIdx += 1; p->nextVelIdx += 1;
@ -1061,12 +1094,12 @@ cw::rc_t cw::vtbl::exec( handle_t h )
_set_status(p,kOkRC,"state:%i mode:%i wfs_fl:%i : dev:%i : pitch:%i vel:%i : nxt %i %i", _set_status(p,kOkRC,"state:%i mode:%i wfs_fl:%i : dev:%i : pitch:%i vel:%i : nxt %i %i",
p->state,p->mode,p->waitForStopFl, p->state,p->mode,p->waitForStopFl,
p->curTable.mrpDevIdx, p->curTable->mrpDevIdx,
pitch,vel, pitch,vel,
p->nextPitch,p->nextVelIdx); p->nextPitch,p->nextVelIdx);
send_midi_msg( p->mrpH, send_midi_msg( p->mrpH,
p->curTable.mrpDevIdx, p->curTable->mrpDevIdx,
0, 0,
midi::kNoteOnMdId, midi::kNoteOnMdId,
_cast_int_to_8bits(p,pitch), _cast_int_to_8bits(p,pitch),

View File

@ -10,6 +10,7 @@ namespace cw
kVtPianoDevId, kVtPianoDevId,
kVtSamplerDevId, kVtSamplerDevId,
kVtTableSelectId, kVtTableSelectId,
kVtDefaultCheckId,
kVtPlayVelSeqBtnId, kVtPlayVelSeqBtnId,
kVtPitchId, kVtPitchId,
kVtPlayPitchSeqBtnId, kVtPlayPitchSeqBtnId,

View File

@ -118,6 +118,8 @@
option: { name: vtSamplerDevId, title: "Sampler" } option: { name: vtSamplerDevId, title: "Sampler" }
} }
} }
check: { name: vtDefaultCheckId, title:"Default" },
} }