From 5bbd3d0e0897f4a213b58a309bf6cd9d32388306 Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 3 Dec 2023 11:20:38 -0500 Subject: [PATCH] cwPresetSel, cwIoPresetSelApp : Added 'alt' functionality. --- cwIoPresetSelApp.cpp | 125 ++++++++++++++++-- cwPresetSel.cpp | 301 ++++++++++++++++++++++++++++++++++++++++--- cwPresetSel.h | 24 ++-- 3 files changed, 411 insertions(+), 39 deletions(-) diff --git a/cwIoPresetSelApp.cpp b/cwIoPresetSelApp.cpp index 22b574c..211437b 100644 --- a/cwIoPresetSelApp.cpp +++ b/cwIoPresetSelApp.cpp @@ -34,7 +34,6 @@ #include "cwSfTrack.h" #include "cwScoreFollower.h" - #define INVALID_LOC (0) namespace cw @@ -75,6 +74,7 @@ namespace cw kSaveBtnId, kLoadBtnId, kPerfSelId, + kAltSelId, kEnaRecordCheckId, kMidiSaveBtnId, @@ -120,6 +120,7 @@ namespace cw kFragPresetSelId, kFragPresetSeqSelId, kFragPresetOrderId, + kFragPresetAltId, kFragInGainId, kFragOutGainId, @@ -172,6 +173,7 @@ namespace cw { kPanelDivId, kSaveBtnId, "saveBtnId" }, { kPanelDivId, kLoadBtnId, "loadBtnId" }, { kPanelDivId, kPerfSelId, "perfSelId" }, + { kPanelDivId, kAltSelId, "altSelId" }, { kPanelDivId, kEnaRecordCheckId, "enaRecordCheckId" }, { kPanelDivId, kMidiSaveBtnId, "midiSaveBtnId" }, @@ -603,6 +605,38 @@ namespace cw return rc; } + + rc_t _load_alt_menu( app_t* app ) + { + rc_t rc = kOkRC; + unsigned uuid; + unsigned selectUuId = kInvalidId; + + // get the peformance menu UI uuid + if((selectUuId = io::uiFindElementUuId( app->ioH, kAltSelId )) == kInvalidId ) + { + rc = cwLogError(rc,"The 'alt' list base UI element does not exist."); + goto errLabel; + } + + for(unsigned altId=0; altIdpsH); ++altId) + { + const char* label = alt_label(app->psH,altId); + assert( label != nullptr ); + + // create an option entry in the selection ui + if((rc = uiCreateOption( app->ioH, uuid, selectUuId, nullptr, altId, kInvalidId, "optClass", label )) != kOkRC ) + { + rc = cwLogError(kSyntaxErrorRC,"The 'alt' menu create failed on %s.",cwStringNullGuard(label)); + goto errLabel; + } + } + + errLabel: + + return rc; + } + rc_t _parse_perf_recording_vel_tbl( app_t* app, const object_t* velTblCfg, vel_tbl_t*& velTblA_Ref, unsigned& velTblN_Ref ) { @@ -794,6 +828,7 @@ namespace cw goto errLabel; } + errLabel: if(rc != kOkRC ) @@ -1443,6 +1478,7 @@ namespace cw { bool bValue; unsigned uValue; + const char* sValue; unsigned fragPanelUuId; // The uiChan is the fragment endLoc @@ -1459,6 +1495,7 @@ namespace cw { _update_frag_ui( app, fragId, preset_sel::kPresetSelectVarId, preset_idx, fragPresetRowUuId, kFragPresetSelId, preset_idx, bValue ); _update_frag_ui( app, fragId, preset_sel::kPresetOrderVarId, preset_idx, fragPresetRowUuId, kFragPresetOrderId, preset_idx, uValue ); + _update_frag_ui( app, fragId, preset_sel::kPresetAltVarId, preset_idx, fragPresetRowUuId, kFragPresetAltId, preset_idx, sValue ); _update_frag_ui( app, fragId, preset_sel::kPresetSeqSelectVarId,preset_idx, fragPresetRowUuId, kFragPresetSeqSelId, preset_idx, bValue ); } @@ -1548,7 +1585,7 @@ namespace cw // _clear_status(app); //else if( !enableFl ) - _set_status(app,"Invalid fragment play range."); + _set_status(app,"Invalid fragment play range. beg:%i end:%i",begPlayLoc,endPlayLoc); } @@ -1587,6 +1624,10 @@ namespace cw _update_frag_select_flags( app, blob->fragId); break; + case preset_sel::kPresetAltVarId: + _update_frag_select_flags( app, blob->fragId); + break; + case preset_sel::kPresetSeqSelectVarId: _update_frag_select_flags( app, blob->fragId); break; @@ -1631,7 +1672,6 @@ namespace cw ui_blob_t blob = { .fragId = fragId, .varId=varId, .presetId=presetId }; return io::uiSetBlob( app->ioH, uuId, &blob, sizeof(blob) ); } - rc_t _create_frag_preset_ctl( app_t* app, unsigned fragId, unsigned fragPresetRowUuId, unsigned presetN, unsigned preset_idx ) { @@ -1657,6 +1697,25 @@ namespace cw // store a connection for the select control back to the fragment record _frag_set_ui_blob(app, uuId, fragId, preset_sel::kPresetSelectVarId, preset_idx ); + /* + // order/alt row container + if((rc = io::uiCreateDiv( app->ioH, rowUuId, colUuId, nullEleName, invalidAppId, chanId, "uiRow", nullptr )) != kOkRC ) + goto errLabel; + + // preset order number + if((rc = io::uiCreateNumb( app->ioH, uuId, rowUuId, nullEleName, kFragPresetOrderId, chanId, "uiNumber fragLittleNumb", nullptr, 0, presetN, 1, 0 )) != kOkRC ) + goto errLabel; + + // store a connection for the order control back to the fragment record + _frag_set_ui_blob(app, uuId, fragId, preset_sel::kPresetOrderVarId, preset_idx ); + + // preset alt letter + if((rc = io::uiCreateStr( app->ioH, uuId, rowUuId, nullEleName, kFragPresetAltId, chanId, "uiString fragLittleNumb", nullptr )) != kOkRC ) + goto errLabel; + + // store a connection for the order control back to the fragment record + _frag_set_ui_blob(app, uuId, fragId, preset_sel::kPresetAltVarId, preset_idx ); + */ // preset order number if((rc = io::uiCreateNumb( app->ioH, uuId, colUuId, nullEleName, kFragPresetOrderId, chanId, nullClass, nullptr, 0, presetN, 1, 0 )) != kOkRC ) @@ -1664,7 +1723,14 @@ namespace cw // store a connection for the order control back to the fragment record _frag_set_ui_blob(app, uuId, fragId, preset_sel::kPresetOrderVarId, preset_idx ); + + // preset alt letter + if((rc = io::uiCreateStr( app->ioH, uuId, colUuId, nullEleName, kFragPresetAltId, chanId, nullClass, nullptr )) != kOkRC ) + goto errLabel; + // store a connection for the order control back to the fragment record + _frag_set_ui_blob(app, uuId, fragId, preset_sel::kPresetAltVarId, preset_idx ); + // preset sequence select check if((rc = io::uiCreateCheck( app->ioH, uuId, colUuId, nullEleName, kFragPresetSeqSelId, chanId, nullClass, nullptr )) != kOkRC ) goto errLabel; @@ -1682,7 +1748,7 @@ namespace cw { rc_t rc = kOkRC; unsigned fragListUuId = io::uiFindElementUuId( app->ioH, kFragListId ); - unsigned fragChanId = fragId; //endLoc; // use the frag. endLoc as the channel id + unsigned fragChanId = fragId; //endLoc; // use the frag. endLoc as the channel id unsigned fragPanelUuId = kInvalidId; unsigned fragPresetRowUuId = kInvalidId; unsigned presetN = preset_sel::preset_count( app->psH ); @@ -1806,11 +1872,12 @@ namespace cw if( app->psNextFrag == nullptr ) { - // the fragments are loaded enable the 'load' menu + // the fragments are loaded enable the 'load' and 'alt' menu io::uiSetEnable( app->ioH, io::uiFindElementUuId( app->ioH, kPerfSelId ), true ); + io::uiSetEnable( app->ioH, io::uiFindElementUuId( app->ioH, kAltSelId ), true ); cwLogInfo("Fragment restore complete: elapsed secs:%f",time::elapsedSecs(app->psLoadT0)); - + io::uiRealTimeReport(app->ioH); } } @@ -2031,6 +2098,8 @@ namespace cw goto errLabel; } + cwLogInfo("Applied velocity table: %s to dev: %s.", cwStringNullGuard(vtA[i].name), cwStringNullGuard(vtA[i].device) ); + assignN += 1; } @@ -2147,6 +2216,8 @@ namespace cw goto errLabel; } + printf("Loading:%s %p %i\n",prp->fname,prp->vel_tblA, prp->vel_tblN); + // load the requested performance if((rc = _do_load(app,prp->fname,prp->vel_tblA, prp->vel_tblN)) != kOkRC ) { @@ -2157,7 +2228,28 @@ namespace cw errLabel: return rc; } - + + rc_t _on_alt_select(app_t* app, unsigned optionAppId ) + { + rc_t rc = kOkRC; + if( optionAppId == kInvalidId || optionAppId >= alt_count(app->psH)) + { + rc = cwLogError(kInvalidArgRC,"The selected 'alt' id (%i) is invalid.",optionAppId); + goto errLabel; + } + + if((rc = set_alternative( app->psH, optionAppId )) != kOkRC ) + { + rc = cwLogError(rc,"Alt selection failed."); + goto errLabel; + } + + cwLogInfo("Alt:%s selected.",alt_label(app->psH, optionAppId)); + + errLabel: + return rc; + } + rc_t _on_ui_start( app_t* app ) { @@ -2819,7 +2911,7 @@ namespace cw break; case kReportBtnId: - preset_sel::report( app->psH ); + //preset_sel::report( app->psH ); //io_flow::apply_preset( app->ioFlowH, 2000.0, app->tmp==0 ? "a" : "b"); //app->tmp = !app->tmp; //io_flow::print(app->ioFlowH); @@ -2841,6 +2933,10 @@ namespace cw case kPerfSelId: _on_perf_select(app,m.value->u.u); break; + + case kAltSelId: + _on_alt_select(app,m.value->u.u); + break; case kMidiThruCheckId: cwLogInfo("MIDI thru:%i",m.value->u.b); @@ -2994,7 +3090,11 @@ namespace cw case kFragPresetOrderId: _on_ui_frag_value( app, m.uuId, m.value->u.u ); break; - + + case kFragPresetAltId: + _on_ui_frag_value( app, m.uuId, m.value->u.s ); + break; + case kFragPresetSelId: _on_ui_frag_value( app, m.uuId, m.value->u.b ); break; @@ -3411,6 +3511,13 @@ cw::rc_t cw::preset_sel_app::main( const object_t* cfg, int argc, const char* ar rc = cwLogError(rc,"The performance list UI create failed."); goto errLabel; } + + // create the alt. selection menu + if((rc = _load_alt_menu(&app)) != kOkRC ) + { + rc = cwLogError(rc,"The 'alt' list UI create failed."); + goto errLabel; + } // create the IO Flow controller if(app.flow_cfg==nullptr || app.flow_proc_dict==nullptr || (rc = io_flow::create(app.ioFlowH,app.ioH,sysSampleRate,app.crossFadeCnt,*app.flow_proc_dict,*app.flow_cfg)) != kOkRC ) diff --git a/cwPresetSel.cpp b/cwPresetSel.cpp index 6f6bc91..a77f602 100644 --- a/cwPresetSel.cpp +++ b/cwPresetSel.cpp @@ -5,6 +5,7 @@ #include "cwText.h" #include "cwObject.h" #include "cwTime.h" +#include "cwVectOps.h" #include "cwPresetSel.h" #include "cwFile.h" #include "cwPianoScore.h" @@ -21,11 +22,20 @@ namespace cw { char* label; } preset_label_t; + + typedef struct alt_label_str + { + char* label; + } alt_label_t; + typedef struct preset_sel_str { preset_label_t* presetLabelA; unsigned presetLabelN; + + alt_label_t* altLabelA; + unsigned altLabelN; double defaultGain; double defaultWetDryGain; @@ -43,6 +53,8 @@ namespace cw double master_sync_delay_ms; unsigned sel_frag_id; // fragment id assoc'd with last selected frag. ui element + + unsigned cur_alt_idx; } preset_sel_t; @@ -62,6 +74,26 @@ namespace cw return kInvalidIdx; } + + const char* _alt_index_to_label( preset_sel_t* p, unsigned alt_idx ) + { + if( alt_idx >= p->altLabelN ) + return nullptr; + + return p->altLabelA[ alt_idx ].label; + } + + + unsigned _alt_char_to_index( preset_sel_t* p, char label ) + { + // Note that we start at 1 because 0 is the + for(unsigned i=1; ialtLabelN; ++i) + if( p->altLabelA[i].label[0] == std::toupper(label) ) + return i; + + return kInvalidIdx; + } + rc_t _delete_fragment( preset_sel_t* p, unsigned fragId ) { @@ -77,6 +109,9 @@ namespace cw else f0->link = f1->link; + for(unsigned i=0; ipresetN; ++i) + mem::release(f1->presetA[i].alt_str); + // release the fragment mem::release(f1->note); mem::release(f1->presetA); @@ -104,12 +139,121 @@ namespace cw for(unsigned i=0; ipresetLabelN; ++i) mem::release( p->presetLabelA[i].label ); mem::release( p->presetLabelA ); + + for(unsigned i=0; ialtLabelN; ++i) + mem::release( p->altLabelA[i].label ); + mem::release( p->altLabelA ); + p->presetLabelN = 0; mem::release(p); return kOkRC; } + void _print_preset_alts( preset_sel_t* p, const frag_t* f, const char* label ) + { + printf("%s : ",label); + for(unsigned i=0; ialtLabelN; ++i) + printf("%i ",f->altPresetIdxA[i]); + printf("\n"); + } + + void _clear_all_preset_alts( preset_sel_t* p, frag_t* f, unsigned preset_idx ) + { + // skip the 0th alt because it is controlled by the 'select' play flag + for(unsigned i=1; ialtLabelN; ++i) + if( f->altPresetIdxA[i] == preset_idx ) + f->altPresetIdxA[i] = kInvalidIdx; + } + + // clear preset of all alternative pointers + void _deselect_preset_as_alt( preset_sel_t* p, frag_t* f, unsigned preset_idx ) + { + assert( preset_idx < f->presetN); + + mem::release(f->presetA[ preset_idx ].alt_str); + + _clear_all_preset_alts(p,f,preset_idx); + + } + + void _remove_alt_char( frag_t* f, unsigned preset_idx, char c ) + { + assert( preset_idx < f->presetN ); + + if( f->presetA[preset_idx].alt_str != nullptr ) + { + char* s = f->presetA[preset_idx].alt_str; + bool fl = false; + for(unsigned i=0; s[i]; ++i) + { + if( s[i] == c ) + fl = true; + + if(fl) + s[i] = s[i+1]; + } + + if( textLength(f->presetA[preset_idx].alt_str) == 0) + mem::release(f->presetA[preset_idx].alt_str); + + } + } + + rc_t _set_alt( preset_sel_t* p, frag_t* f, unsigned preset_idx, char c ) + { + rc_t rc = kOkRC; + unsigned alt_idx; + + if((alt_idx = _alt_char_to_index(p,c)) == kInvalidIdx ) + { + if( !std::isspace(c) ) + cwLogWarning("The alternative '%c' is not valid.",c); + rc = kInvalidArgRC; + } + else + { + assert( alt_idx <= p->altLabelN ); + + if( f->altPresetIdxA[ alt_idx ] != kInvalidIdx ) + _remove_alt_char(f,f->altPresetIdxA[ alt_idx ],c); + + f->altPresetIdxA[ alt_idx ] = preset_idx; + } + + return rc; + } + + void _set_alt_str( preset_sel_t* p, frag_t* f, unsigned sel_preset_idx, const char* alt_str ) + { + if( alt_str == nullptr ) + { + _deselect_preset_as_alt(p,f,sel_preset_idx); + } + else + { + unsigned alt_strN = textLength(alt_str); + char alt_str_buf[ alt_strN+1 ] = {0}; + unsigned asi = 0; + + // clear the alt's pointing to the selected preset - because the 'alt_str' has changed + // and some previous alt's may have been removed. + _clear_all_preset_alts( p, f, sel_preset_idx ); + + // scan each char in the alt_str[] and update f->altPresetIdxA[] + for(unsigned i=0; alt_str[i]; ++i) + if( _set_alt(p, f, sel_preset_idx, alt_str[i] ) == kOkRC ) + { + // if this was a legal alt label then add it to alt_str_buf[] + assert( asi < alt_strN ); + alt_str_buf[ asi++ ] = alt_str[i]; + } + + // store the preset's new alt str. + f->presetA[ sel_preset_idx ].alt_str = mem::reallocStr(f->presetA[ sel_preset_idx ].alt_str, alt_str_buf); + } + } + frag_t* _find_frag( preset_sel_t* p, unsigned fragId ) { frag_t* f; @@ -207,10 +351,6 @@ namespace cw return nullptr; } - - - - bool _loc_is_in_frag( const frag_t* f, unsigned loc ) { // if f is the earliest fragment @@ -287,9 +427,10 @@ namespace cw f->guiUuId = value; break; - case kPresetSelectVarId: + case kPresetSelectVarId: for(unsigned i=0; ipresetN; ++i) - f->presetA[i].playFl = f->presetA[i].preset_idx == presetId ? value : false; + if((f->presetA[i].playFl = f->presetA[i].preset_idx == presetId ? value : false) == true) + f->altPresetIdxA[0] = i; break; case kPresetSeqSelectVarId: @@ -302,6 +443,10 @@ namespace cw f->presetA[ presetId ].order = value; break; + case kPresetAltVarId: + assert(0); + break; + case kInGainVarId: f->igain = value; break; @@ -406,6 +551,10 @@ namespace cw if((rc = _validate_preset_id(f, presetId )) == kOkRC ) valueRef = f->presetA[ presetId ].order; break; + + case kPresetAltVarId: + assert(0); + break; case kInGainVarId: valueRef = f->igain; @@ -675,7 +824,8 @@ cw::rc_t cw::preset_sel::create( handle_t& hRef, const object_t* cfg ) { rc_t rc = kOkRC; preset_sel_t* p = nullptr; - const object_t* labelL = nullptr; + const object_t* preset_labelL = nullptr; + const object_t* alt_labelL = nullptr; const char* default_preset_label = nullptr; if((rc = destroy(hRef)) != kOkRC ) @@ -684,7 +834,8 @@ cw::rc_t cw::preset_sel::create( handle_t& hRef, const object_t* cfg ) p = mem::allocZ(); // parse the cfg - if((rc = cfg->getv( "preset_labelL", labelL, + if((rc = cfg->getv( "preset_labelL", preset_labelL, + "alt_labelL", alt_labelL, "default_gain", p->defaultGain, "default_wet_dry_gain", p->defaultWetDryGain, "default_fade_ms", p->defaultFadeOutMs, @@ -699,14 +850,14 @@ cw::rc_t cw::preset_sel::create( handle_t& hRef, const object_t* cfg ) } // allocate the label array - p->presetLabelN = labelL->child_count(); + p->presetLabelN = preset_labelL->child_count(); p->presetLabelA = mem::allocZ(p->presetLabelN); // get the preset labels for(unsigned i=0; ipresetLabelN; ++i) { const char* label = nullptr; - const object_t* labelNode = labelL->child_ele(i); + const object_t* labelNode = preset_labelL->child_ele(i); if( labelNode!=nullptr ) rc = labelNode->value(label); @@ -720,6 +871,32 @@ cw::rc_t cw::preset_sel::create( handle_t& hRef, const object_t* cfg ) p->presetLabelA[i].label = mem::duplStr(label); } + + // allocate the label array + p->altLabelN = alt_labelL->child_count() + 1; + p->altLabelA = mem::allocZ(p->altLabelN); + + p->altLabelA[0].label = mem::duplStr("*"); + + // get the alt labels + for(unsigned i=1,j=0; ialtLabelN; ++i,++j) + { + const char* label = nullptr; + const object_t* labelNode = alt_labelL->child_ele(j); + + if( labelNode!=nullptr ) + rc = labelNode->value(label); + + if( rc != kOkRC || label == nullptr || textLength(label) == 0 ) + { + rc = cwLogError(kInvalidStateRC,"A empty alt label was encountered while reading the alt label list."); + goto errLabel; + } + + p->altLabelA[i].label = mem::duplStr(label); + } + + p->defaultPresetIdx = kInvalidIdx; if( default_preset_label != nullptr ) if((p->defaultPresetIdx = _preset_label_to_index(p,default_preset_label)) ==kInvalidIdx ) @@ -764,6 +941,17 @@ const char* cw::preset_sel::preset_label( handle_t h, unsigned preset_idx ) return _preset_label(p,preset_idx); } +unsigned cw::preset_sel::alt_count( handle_t h ) +{ + preset_sel_t* p = _handleToPtr(h); + return p->altLabelN; +} + +const char* cw::preset_sel::alt_label( handle_t h, unsigned alt_idx ) +{ + preset_sel_t* p = _handleToPtr(h); + return _alt_index_to_label(p,alt_idx); +} unsigned cw::preset_sel::fragment_count( handle_t h ) { @@ -841,10 +1029,14 @@ cw::rc_t cw::preset_sel::create_fragment( handle_t h, unsigned end_loc, time::sp f->fadeOutMs = p->defaultFadeOutMs; f->presetA = mem::allocZ(p->presetLabelN); f->presetN = p->presetLabelN; + f->altPresetIdxA = mem::allocZ(p->altLabelN); f->fragId = _generate_unique_frag_id(p); f->begPlayLoc = 0; f->endPlayLoc = end_loc; f->note = mem::duplStr(""); + + // set all but the first + vop::fill(f->altPresetIdxA+1,p->altLabelN-1,kInvalidIdx); // set the return value fragIdRef = f->fragId; @@ -949,7 +1141,21 @@ bool cw::preset_sel::is_fragment_end_loc( handle_t h, unsigned loc ) return _loc_to_frag(p,loc) != nullptr; } +cw::rc_t cw::preset_sel::set_alternative( handle_t h, unsigned alt_idx ) +{ + rc_t rc = kOkRC; + preset_sel_t* p = _handleToPtr(h); + + if( alt_idx >= p->altLabelN ) + { + rc = cwLogError(kInvalidArgRC,"The alternative index %i is invalid.",alt_idx); + goto errLabel; + } + p->cur_alt_idx = alt_idx; + errLabel: + return rc; +} unsigned cw::preset_sel::ui_select_fragment_id( handle_t h ) { @@ -961,7 +1167,6 @@ unsigned cw::preset_sel::ui_select_fragment_id( handle_t h ) return kInvalidId; } - void cw::preset_sel::ui_select_fragment( handle_t h, unsigned fragId, bool selectFl ) { preset_sel_t* p = _handleToPtr(h); @@ -998,6 +1203,16 @@ cw::rc_t cw::preset_sel::set_value( handle_t h, unsigned fragId, unsigned varId, if( value != nullptr ) f->note = mem::duplStr(value); break; + + case kPresetAltVarId: + if((rc = _validate_preset_id(f, presetId )) == kOkRC ) + { + _set_alt_str( p, f, presetId, value ); + + cwLogInfo("Set Preset Alt : %s",value); + } + break; + default: rc = cwLogError(kInvalidIdRC,"There is no preset variable of type 'string' with var id:%i.",varId); } @@ -1030,7 +1245,21 @@ cw::rc_t cw::preset_sel::get_value( handle_t h, unsigned fragId, unsigned varId, case kNoteVarId: valueRef = f->note; break; - + + case kPresetAltVarId: + if((rc = _validate_preset_id(f, presetId )) == kOkRC ) + { + + if( f->presetA[ presetId].alt_str == nullptr ) + f->presetA[ presetId].alt_str = mem::duplStr(""); + + valueRef = f->presetA[ presetId].alt_str; + + //cwLogInfo("Get Preset Alt Flags: 0x%x : %s",f->presetA[ presetId].altFlags,valueRef); + + } + break; + default: rc = cwLogError(kInvalidIdRC,"There is no preset variable of type 'string' with var id:%i.",varId); } @@ -1133,16 +1362,32 @@ bool cw::preset_sel::track_loc( handle_t h, unsigned loc, const cw::preset_sel:: return frag_changed_fl; } - - unsigned cw::preset_sel::fragment_play_preset_index( handle_t h, const frag_t* frag, unsigned preset_seq_idx ) { - unsigned n = 0; - preset_sel_t* p = _handleToPtr(h); + unsigned n = 0; + preset_sel_t* p = _handleToPtr(h); + + //cwLogInfo("preset_seq_idx:%i frag id:%i sel_frag_id:%i cur_alt_idx:%i ",preset_seq_idx,frag->fragId,p->sel_frag_id, p->cur_alt_idx); + + //_print_preset_alts( p, frag, "" ); + + if( preset_seq_idx==kInvalidIdx || frag->fragId != p->sel_frag_id ) + { + assert( p->cur_alt_idx < p->altLabelN ); + + unsigned preset_idx = frag->altPresetIdxA[ p->cur_alt_idx ]; + if( preset_idx == kInvalidIdx ) + preset_idx = frag->altPresetIdxA[0]; + + return preset_idx; + } + + // for each preset for(unsigned i=0; ipresetN; ++i) { + /* // if 'preset_seq_idx' is not valid ... if( preset_seq_idx==kInvalidIdx || frag->fragId != p->sel_frag_id ) { @@ -1152,6 +1397,7 @@ unsigned cw::preset_sel::fragment_play_preset_index( handle_t h, const frag_t* f } else { + */ // ... otherwise select the 'nth' preset whose 'seqFl' is set if( frag->presetA[i].seqFl || frag->seqAllFl ) { @@ -1159,7 +1405,7 @@ unsigned cw::preset_sel::fragment_play_preset_index( handle_t h, const frag_t* f return frag->presetA[i].preset_idx; ++n; } - } + //} } return kInvalidIdx; @@ -1222,6 +1468,7 @@ cw::rc_t cw::preset_sel::write( handle_t h, const char* fn ) object_t* presetD_obj = newDictObject( nullptr ); newPairObject("order", f->presetA[i].order, presetD_obj ); + newPairObject("alt_str", f->presetA[i].alt_str, presetD_obj ); newPairObject("preset_label", _preset_label(p, f->presetA[i].preset_idx ), presetD_obj ); newPairObject("play_fl", f->presetA[i].playFl, presetD_obj ); @@ -1353,6 +1600,7 @@ cw::rc_t cw::preset_sel::read( handle_t h, const char* fn ) { const object_t* r = presetL_obj->child_ele(i); unsigned order = 0; + const char* alt_str = nullptr; const char* preset_label = nullptr; unsigned preset_idx = kInvalidIdx; bool playFl = false; @@ -1366,6 +1614,12 @@ cw::rc_t cw::preset_sel::read( handle_t h, const char* fn ) goto errLabel; } + if((rc = r->getv_opt("alt_str", alt_str )) != kOkRC ) + { + rc = cwLogError(rc,"The fragment preset at index '%i' optional parse failed during restore.",i); + goto errLabel; + } + // locate the preset index associated with the preset label if((preset_idx = _preset_label_to_index(p,preset_label)) == kInvalidIdx ) { @@ -1373,8 +1627,15 @@ cw::rc_t cw::preset_sel::read( handle_t h, const char* fn ) goto errLabel; } - f->presetA[ preset_idx ].order = order; - f->presetA[ preset_idx ].playFl = playFl; + f->presetA[ preset_idx ].order = order; + f->presetA[ preset_idx ].alt_str = mem::duplStr(alt_str); + f->presetA[ preset_idx ].playFl = playFl; + + _set_alt_str( p, f, i, alt_str ); + + if( playFl ) + f->altPresetIdxA[0] = preset_idx; + } } @@ -1556,8 +1817,6 @@ cw::rc_t cw::preset_sel::translate_frags( const object_t* cfg ) //loc_to_pitch_context(pianoScoreH,tfragA[i].endLoc.preNote,tfragA[i].endLoc.postNote,kNoteN); - - tfragA[i].endLoc.loc = src_end_loc; tfragA[i].endLoc.opId = midi::isNoteOn(e->status,e->d1) ? score_parse::kNoteOnTId : score_parse::kBarTId; tfragA[i].endLoc.pitch = e->d0; diff --git a/cwPresetSel.h b/cwPresetSel.h index 74a5d67..2a0f034 100644 --- a/cwPresetSel.h +++ b/cwPresetSel.h @@ -14,6 +14,7 @@ namespace cw bool seqFl; // play this preset during sequencing. unsigned preset_idx; // preset index into preset_labelA[]. unsigned order; // + char* alt_str; } preset_t; typedef struct frag_str @@ -31,9 +32,11 @@ namespace cw unsigned endPlayLoc; char* note; - preset_t* presetA; + preset_t* presetA; // presetA[ presetN ] - status of each preset unsigned presetN; + unsigned* altPresetIdxA; // altPresetIdxA[ alt_count() ] selected preset idx for each alt. + bool uiSelectFl; bool seqAllFl; // Set if all preset.seqFl's should be treated as though they are set to true. @@ -41,7 +44,6 @@ namespace cw struct frag_str* prev; } frag_t; - enum { kGuiUuIdVarId, kBegLocVarId, @@ -57,12 +59,10 @@ namespace cw kPlaySeqAllBtnVarId, kNoteVarId, - kPresetOrderVarId, // preset order value - kPresetSelectVarId, // select a preset to play - kPresetSeqSelectVarId, // sequence preset selections to play - kPlayEnableVarId, // include in the segment to play - kDryFlVarId, // play this fragment dry - + kPresetOrderVarId, // preset order number + kPresetAltVarId, // preset alternative string + kPresetSelectVarId, // select a preset to play (play flag) + kPresetSeqSelectVarId, // sequence preset selections to play (seq flag) kBaseMasterVarId, // All 'master' variables have id's greater than kBaseMasterVarId kMasterWetInGainVarId, @@ -76,7 +76,11 @@ namespace cw unsigned preset_count( handle_t h ); const char* preset_label( handle_t h, unsigned preset_idx ); - + + // Count/label of alternatives (alt_idx==0 is 'no alternative selected) + unsigned alt_count( handle_t h ); + const char* alt_label( handle_t h, unsigned alt_idx ); + unsigned fragment_count( handle_t h ); const frag_t* get_fragment_base( handle_t h ); const frag_t* get_fragment( handle_t h, unsigned fragId ); @@ -90,6 +94,8 @@ namespace cw bool is_fragment_end_loc( handle_t h, unsigned loc ); + rc_t set_alternative( handle_t h, unsigned alt_idx ); + // Return the fragment id of the 'selected' fragment. unsigned ui_select_fragment_id( handle_t h );