2021-11-01 14:28:44 +00:00
# include "cwCommon.h"
# include "cwLog.h"
# include "cwCommonImpl.h"
# include "cwMem.h"
# include "cwObject.h"
# include "cwText.h"
# include "cwFileSys.h"
# include "cwFile.h"
# include "cwTime.h"
# include "cwMidiDecls.h"
# include "cwMidi.h"
# include "cwUiDecls.h"
# include "cwIo.h"
# include "cwIoMidiRecordPlay.h"
# include "cwIoPresetSelApp.h"
# include "cwPianoScore.h"
2021-12-28 01:32:56 +00:00
# include "cwVectOps.h"
# include "cwMath.h"
# include "cwDspTypes.h"
# include "cwMtx.h"
# include "cwFlow.h"
# include "cwFlowTypes.h"
# include "cwFlowCross.h"
2021-12-11 20:21:03 +00:00
# include "cwIoFlow.h"
2021-11-06 02:28:38 +00:00
# include "cwPresetSel.h"
2021-11-01 14:28:44 +00:00
namespace cw
{
namespace preset_sel_app
{
// Application Id's for UI elements
enum
{
// Resource Based elements
kPanelDivId = 1000 ,
kQuitBtnId ,
kIoReportBtnId ,
2022-01-22 14:55:17 +00:00
kNetPrintBtnId ,
2021-11-01 14:28:44 +00:00
kReportBtnId ,
kStartBtnId ,
kStopBtnId ,
2022-01-22 14:55:17 +00:00
kPrintMidiCheckId ,
kPianoMidiCheckId ,
kSamplerMidiCheckId ,
kSyncDelayMsId ,
kWetInGainId ,
kWetOutGainId ,
kDryGainId ,
2021-11-01 14:28:44 +00:00
kMidiThruCheckId ,
kCurMidiEvtCntId ,
kTotalMidiEvtCntId ,
kCurAudioSecsId ,
kTotalAudioSecsId ,
kSaveBtnId ,
kLoadBtnId ,
2021-11-14 18:11:11 +00:00
kBegPlayLocNumbId ,
kEndPlayLocNumbId ,
2021-11-06 02:28:38 +00:00
kInsertLocId ,
kInsertBtnId ,
kDeleteBtnId ,
2021-12-28 01:32:56 +00:00
kStatusId ,
2021-12-30 02:57:04 +00:00
kLogId ,
2021-11-06 02:28:38 +00:00
kFragListId ,
kFragPanelId ,
2021-12-28 01:32:56 +00:00
kFragBegLocId ,
2021-11-06 02:28:38 +00:00
kFragEndLocId ,
kFragPresetRowId ,
kFragPresetSelId ,
kFragPresetOrderId ,
2021-12-28 01:32:56 +00:00
kFragInGainId ,
kFragOutGainId ,
2021-11-06 02:28:38 +00:00
kFragWetDryGainId ,
2021-12-28 01:32:56 +00:00
kFragFadeOutMsId ,
kFragBegPlayLocId ,
kFragEndPlayLocId ,
kFragPlayBtnId ,
kFragNoteId
2021-11-01 14:28:44 +00:00
} ;
2022-01-22 14:55:17 +00:00
enum
{
kPiano_MRP_DevIdx = 0 ,
kSampler_MRP_DevIdx = 1
} ;
2021-11-01 14:28:44 +00:00
enum
{
kAmMidiTimerId
} ;
// Application Id's for the resource based UI elements.
ui : : appIdMap_t mapA [ ] =
{
{ ui : : kRootAppId , kPanelDivId , " panelDivId " } ,
{ kPanelDivId , kQuitBtnId , " quitBtnId " } ,
{ kPanelDivId , kIoReportBtnId , " ioReportBtnId " } ,
2022-01-22 14:55:17 +00:00
{ kPanelDivId , kNetPrintBtnId , " netPrintBtnId " } ,
2021-11-01 14:28:44 +00:00
{ kPanelDivId , kReportBtnId , " reportBtnId " } ,
{ kPanelDivId , kStartBtnId , " startBtnId " } ,
{ kPanelDivId , kStopBtnId , " stopBtnId " } ,
2022-01-22 14:55:17 +00:00
{ kPanelDivId , kPrintMidiCheckId , " printMidiCheckId " } ,
{ kPanelDivId , kPianoMidiCheckId , " pianoMidiCheckId " } ,
{ kPanelDivId , kSamplerMidiCheckId , " samplerMidiCheckId " } ,
{ kPanelDivId , kSyncDelayMsId , " syncDelayMsId " } ,
{ kPanelDivId , kWetInGainId , " wetInGainId " } ,
{ kPanelDivId , kWetOutGainId , " wetOutGainId " } ,
{ kPanelDivId , kDryGainId , " dryGainId " } ,
2021-11-01 14:28:44 +00:00
{ kPanelDivId , kMidiThruCheckId , " midiThruCheckId " } ,
{ kPanelDivId , kCurMidiEvtCntId , " curMidiEvtCntId " } ,
{ kPanelDivId , kTotalMidiEvtCntId , " totalMidiEvtCntId " } ,
{ kPanelDivId , kCurAudioSecsId , " curAudioSecsId " } ,
{ kPanelDivId , kTotalAudioSecsId , " totalAudioSecsId " } ,
{ kPanelDivId , kSaveBtnId , " saveBtnId " } ,
{ kPanelDivId , kLoadBtnId , " loadBtnId " } ,
2021-11-14 18:11:11 +00:00
{ kPanelDivId , kBegPlayLocNumbId , " begLocNumbId " } ,
{ kPanelDivId , kEndPlayLocNumbId , " endLocNumbId " } ,
2021-11-06 02:28:38 +00:00
{ kPanelDivId , kInsertLocId , " insertLocId " } ,
{ kPanelDivId , kInsertBtnId , " insertBtnId " } ,
2021-11-14 18:11:11 +00:00
{ kPanelDivId , kDeleteBtnId , " deleteBtnId " } ,
2021-12-28 01:32:56 +00:00
{ kPanelDivId , kStatusId , " statusId " } ,
2021-12-30 02:57:04 +00:00
{ kPanelDivId , kLogId , " logId " } ,
2021-11-06 02:28:38 +00:00
2021-12-28 01:32:56 +00:00
{ kPanelDivId , kFragListId , " fragListId " } ,
{ kFragListId , kFragPanelId , " fragPanelId " } ,
{ kFragPanelId , kFragBegLocId , " fragBegLocId " } ,
2021-11-06 02:28:38 +00:00
{ kFragPanelId , kFragEndLocId , " fragEndLocId " } ,
{ kFragPanelId , kFragPresetRowId , " fragPresetRowId " } ,
2021-12-28 01:32:56 +00:00
{ kFragPanelId , kFragInGainId , " fragInGainId " } ,
{ kFragPanelId , kFragOutGainId , " fragOutGainId " } ,
2021-11-06 02:28:38 +00:00
{ kFragPanelId , kFragWetDryGainId , " fragWetDryGainId " } ,
2021-12-28 01:32:56 +00:00
{ kFragPanelId , kFragFadeOutMsId , " fragFadeOutMsId " } ,
{ kFragPanelId , kFragBegPlayLocId , " fragBegPlayLocId " } ,
{ kFragPanelId , kFragEndPlayLocId , " fragEndPlayLocId " } ,
{ kFragPanelId , kFragPlayBtnId , " fragPlayBtnId " } ,
{ kFragPanelId , kFragNoteId , " fragNoteId " } ,
2021-11-06 02:28:38 +00:00
2021-11-01 14:28:44 +00:00
} ;
unsigned mapN = sizeof ( mapA ) / sizeof ( mapA [ 0 ] ) ;
typedef struct loc_map_str
{
unsigned loc ;
time : : spec_t timestamp ;
} loc_map_t ;
2021-11-14 18:11:11 +00:00
typedef struct ui_blob_str
{
unsigned fragId ;
unsigned varId ;
unsigned presetId ;
} ui_blob_t ;
2021-11-01 14:28:44 +00:00
typedef struct app_str
{
2021-11-06 02:28:38 +00:00
io : : handle_t ioH ;
2021-11-01 14:28:44 +00:00
2021-11-06 02:28:38 +00:00
const char * record_dir ;
2021-12-19 17:18:22 +00:00
const char * record_fn ;
2021-11-06 02:28:38 +00:00
const char * record_fn_ext ;
const char * scoreFn ;
2022-01-22 14:55:17 +00:00
const object_t * midi_play_record_cfg ;
2021-11-06 02:28:38 +00:00
const object_t * frag_panel_cfg ;
const object_t * presets_cfg ;
2021-12-11 20:21:03 +00:00
const object_t * flow_cfg ;
2021-11-01 14:28:44 +00:00
midi_record_play : : handle_t mrpH ;
score : : handle_t scoreH ;
loc_map_t * locMap ;
unsigned locMapN ;
2021-11-06 02:28:38 +00:00
2021-12-12 21:47:41 +00:00
unsigned insertLoc ; // last valid insert location id received from the GUI
2021-11-06 02:28:38 +00:00
2021-12-30 02:57:04 +00:00
unsigned minLoc ;
unsigned maxLoc ;
2021-12-28 01:32:56 +00:00
unsigned beg_play_loc ;
unsigned end_play_loc ;
2021-12-12 21:47:41 +00:00
time : : spec_t beg_play_timestamp ;
time : : spec_t end_play_timestamp ;
2021-11-14 18:11:11 +00:00
2021-11-06 02:28:38 +00:00
preset_sel : : handle_t psH ;
2021-12-12 21:47:41 +00:00
io_flow : : handle_t ioFlowH ;
2021-12-28 01:32:56 +00:00
2021-12-19 17:18:22 +00:00
unsigned tmp ;
double crossFadeSrate ;
unsigned crossFadeCnt ;
2022-01-22 14:55:17 +00:00
bool printMidiFl ;
2021-11-01 14:28:44 +00:00
} app_t ;
2021-11-03 15:09:07 +00:00
rc_t _parseCfg ( app_t * app , const object_t * cfg , const object_t * & params_cfgRef )
2021-11-01 14:28:44 +00:00
{
rc_t rc = kOkRC ;
2021-12-11 20:21:03 +00:00
if ( ( rc = cfg - > getv ( " params " , params_cfgRef ,
" flow " , app - > flow_cfg ) ) ! = kOkRC )
2021-11-01 14:28:44 +00:00
{
rc = cwLogError ( kSyntaxErrorRC , " Preset Select App 'params' cfg record not found. " ) ;
goto errLabel ;
}
2022-01-22 14:55:17 +00:00
if ( ( rc = params_cfgRef - > getv ( " record_dir " , app - > record_dir ,
" record_fn " , app - > record_fn ,
" record_fn_ext " , app - > record_fn_ext ,
" score_fn " , app - > scoreFn ,
" midi_play_record " , app - > midi_play_record_cfg ,
" frag_panel " , app - > frag_panel_cfg ,
" presets " , app - > presets_cfg ,
" crossFadeSrate " , app - > crossFadeSrate ,
" crossFadeCount " , app - > crossFadeCnt ) ) ! = kOkRC )
2021-11-01 14:28:44 +00:00
{
rc = cwLogError ( kSyntaxErrorRC , " Preset Select App configuration parse failed. " ) ;
}
// verify that the output directory exists
if ( ( rc = filesys : : isDir ( app - > record_dir ) ) ! = kOkRC )
if ( ( rc = filesys : : makeDir ( app - > record_dir ) ) ! = kOkRC )
rc = cwLogError ( rc , " Unable to create the base output directory:%s. " , cwStringNullGuard ( app - > record_dir ) ) ;
2021-11-06 02:28:38 +00:00
app - > insertLoc = kInvalidId ; // initialize 'insertLoc' to be invalid
2021-11-01 14:28:44 +00:00
errLabel :
return rc ;
}
2021-12-28 01:32:56 +00:00
void _set_statusv ( app_t * app , const char * fmt , va_list vl )
{
const int sN = 128 ;
char s [ sN ] ;
2021-12-30 02:57:04 +00:00
vsnprintf ( s , sN , fmt , vl ) ;
2021-12-28 01:32:56 +00:00
uiSendValue ( app - > ioH , uiFindElementUuId ( app - > ioH , kStatusId ) , s ) ;
}
2021-12-30 02:57:04 +00:00
2021-12-28 01:32:56 +00:00
void _set_status ( app_t * app , const char * fmt , . . . )
{
va_list vl ;
va_start ( vl , fmt ) ;
_set_statusv ( app , fmt , vl ) ;
va_end ( vl ) ;
}
2021-12-30 02:57:04 +00:00
void _clear_status ( app_t * app )
{
_set_status ( app , " Ok " ) ;
}
void _log_output_func ( void * arg , unsigned level , const char * text )
{
app_t * app = ( app_t * ) arg ;
unsigned logUuId = uiFindElementUuId ( app - > ioH , kLogId ) ;
uiSetLogLine ( app - > ioH , logUuId , text ) ;
log : : defaultOutput ( nullptr , level , text ) ;
}
2021-11-01 14:28:44 +00:00
rc_t _free ( app_t & app )
{
2021-11-06 02:28:38 +00:00
preset_sel : : destroy ( app . psH ) ;
2021-12-11 20:21:03 +00:00
io_flow : : destroy ( app . ioFlowH ) ;
2021-12-30 02:57:04 +00:00
midi_record_play : : destroy ( app . mrpH ) ;
score : : destroy ( app . scoreH ) ;
2021-11-01 14:28:44 +00:00
mem : : release ( app . locMap ) ;
return kOkRC ;
}
2021-12-12 21:47:41 +00:00
rc_t _apply_preset ( app_t * app , const time : : spec_t & ts , const preset_sel : : frag_t * frag = nullptr )
{
if ( frag = = nullptr )
preset_sel : : track_timestamp ( app - > psH , ts , frag ) ;
if ( frag = = nullptr )
cwLogInfo ( " No preset fragment was found for the requested timestamp. " ) ;
else
{
2021-12-28 01:32:56 +00:00
unsigned preset_idx ;
if ( ( preset_idx = fragment_play_preset_index ( frag ) ) = = kInvalidIdx )
cwLogInfo ( " No preset has been assigned to the fragment at end loc. '%i'. " , frag - > endLoc ) ;
else
{
const char * preset_label = preset_sel : : preset_label ( app - > psH , preset_idx ) ;
2021-12-19 17:18:22 +00:00
2022-01-22 14:55:17 +00:00
cwLogInfo ( " Apply preset: '%s'. " , preset_idx = = kInvalidIdx ? " <invalid> " : preset_label ) ;
2021-12-28 01:32:56 +00:00
if ( preset_label ! = nullptr )
{
io_flow : : apply_preset ( app - > ioFlowH , flow_cross : : kNextDestId , preset_label ) ;
2021-12-12 21:47:41 +00:00
2022-01-22 14:55:17 +00:00
io_flow : : set_variable_value ( app - > ioFlowH , flow_cross : : kNextDestId , " wet_in_gain " , " gain " , flow : : kAnyChIdx , ( dsp : : real_t ) frag - > igain ) ;
io_flow : : set_variable_value ( app - > ioFlowH , flow_cross : : kNextDestId , " wet_out_gain " , " gain " , flow : : kAnyChIdx , ( dsp : : real_t ) frag - > ogain ) ;
io_flow : : set_variable_value ( app - > ioFlowH , flow_cross : : kNextDestId , " wd_bal " , " in " , flow : : kAnyChIdx , ( dsp : : real_t ) frag - > wetDryGain ) ;
2021-12-28 01:32:56 +00:00
io_flow : : begin_cross_fade ( app - > ioFlowH , frag - > fadeOutMs ) ;
}
}
2021-12-12 21:47:41 +00:00
}
return kOkRC ;
}
2022-01-22 14:55:17 +00:00
// Turn on the selection border for the clicked fragment
rc_t _do_select_frag ( app_t * app , unsigned clickedUuId )
{
rc_t rc = kOkRC ;
// get the last selected fragment
unsigned prevFragId = preset_sel : : ui_select_fragment_id ( app - > psH ) ;
unsigned prevUuId = preset_sel : : frag_to_gui_id ( app - > psH , prevFragId , false ) ;
// is the last selected fragment the same as the clicked fragment
bool reclickFl = prevUuId = = clickedUuId ;
// if a different fragment was clicked then deselect the last fragment in the UI
if ( ! reclickFl )
{
if ( prevUuId ! = kInvalidId )
io : : uiSetSelect ( app - > ioH , prevUuId , false ) ;
// select or deselect the clicked fragment
io : : uiSetSelect ( app - > ioH , clickedUuId , ! reclickFl ) ;
}
// Note: calls to uiSetSelect() produce callbacks to _onUiSelect().
return rc ;
}
2021-11-01 14:28:44 +00:00
void _midi_play_callback ( void * arg , unsigned id , const time : : spec_t timestamp , uint8_t ch , uint8_t status , uint8_t d0 , uint8_t d1 )
{
app_t * app = ( app_t * ) arg ;
if ( id ! = kInvalidId )
{
2022-01-22 14:55:17 +00:00
if ( app - > printMidiFl )
{
const unsigned buf_byte_cnt = 256 ;
char buf [ buf_byte_cnt ] ;
event_to_string ( app - > scoreH , id , buf , buf_byte_cnt ) ;
printf ( " %s \n " , buf ) ;
}
2021-12-12 21:47:41 +00:00
const preset_sel : : frag_t * f = nullptr ;
if ( preset_sel : : track_timestamp ( app - > psH , timestamp , f ) )
{
2021-12-28 01:32:56 +00:00
//printf("NEW FRAG: id:%i loc:%i\n", f->fragId, f->endLoc );
2022-01-22 14:55:17 +00:00
_apply_preset ( app , timestamp , f ) ;
if ( f ! = nullptr )
_do_select_frag ( app , f - > guiUuId ) ;
2021-12-12 21:47:41 +00:00
}
2021-11-01 14:28:44 +00:00
}
}
2021-11-06 02:28:38 +00:00
2021-12-28 01:32:56 +00:00
loc_map_t * _find_loc ( app_t * app , unsigned loc )
{
unsigned i = 0 ;
for ( ; i < app - > locMapN ; + + i )
if ( app - > locMap [ i ] . loc = = loc )
return app - > locMap + i ;
return nullptr ;
}
2022-01-22 14:55:17 +00:00
rc_t _do_stop_play ( app_t * app )
{
rc_t rc = kOkRC ;
if ( ( rc = midi_record_play : : stop ( app - > mrpH ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " MIDI stop failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
2021-12-28 01:32:56 +00:00
rc_t _do_play ( app_t * app , unsigned begLoc , unsigned endLoc )
{
rc_t rc = kOkRC ;
bool rewindFl = true ;
loc_map_t * begMap = nullptr ;
loc_map_t * endMap = nullptr ;
2022-01-22 14:55:17 +00:00
// if the player is already playing then stop it
if ( midi_record_play : : is_started ( app - > mrpH ) )
{
rc = _do_stop_play ( app ) ;
goto errLabel ;
}
2021-12-28 01:32:56 +00:00
if ( ( begMap = _find_loc ( app , begLoc ) ) = = nullptr )
{
rc = cwLogError ( kInvalidArgRC , " The begin play location is not valid. " ) ;
goto errLabel ;
}
if ( ( endMap = _find_loc ( app , endLoc ) ) = = nullptr )
{
rc = cwLogError ( kInvalidArgRC , " The end play location is not valid. " ) ;
goto errLabel ;
}
app - > beg_play_timestamp = begMap - > timestamp ;
app - > end_play_timestamp = endMap - > timestamp ;
if ( ! time : : isZero ( app - > beg_play_timestamp ) )
{
// seek the player to the requested loc
if ( ( rc = midi_record_play : : seek ( app - > mrpH , app - > beg_play_timestamp ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " MIDI seek failed. " ) ;
goto errLabel ;
}
rewindFl = false ;
}
// apply the preset which is active at the start time
if ( ( rc = _apply_preset ( app , app - > beg_play_timestamp ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Preset application failed prior to MIDI start. " ) ;
goto errLabel ;
}
// start the MIDI playback
if ( ( rc = midi_record_play : : start ( app - > mrpH , rewindFl , & app - > end_play_timestamp ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " MIDI start failed. " ) ;
goto errLabel ;
}
io : : uiSendValue ( app - > ioH , uiFindElementUuId ( app - > ioH , kCurMidiEvtCntId ) , midi_record_play : : event_index ( app - > mrpH ) ) ;
errLabel :
return rc ;
}
rc_t _do_play_fragment ( app_t * app , unsigned fragId )
{
rc_t rc ;
unsigned begLoc = 0 ;
unsigned endLoc = 0 ;
if ( ( rc = get_value ( app - > psH , fragId , preset_sel : : kBegPlayLocVarId , kInvalidId , begLoc ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Could not retrieve the begin play location for fragment id:%i. " , fragId ) ;
goto errLabel ;
}
if ( ( rc = get_value ( app - > psH , fragId , preset_sel : : kEndPlayLocVarId , kInvalidId , endLoc ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Could not retrieve the begin play location for fragment id:%i. " , fragId ) ;
goto errLabel ;
}
rc = _do_play ( app , begLoc , endLoc ) ;
errLabel :
return rc ;
}
2021-11-06 02:28:38 +00:00
void _update_event_ui ( app_t * app )
{
io : : uiSendValue ( app - > ioH , uiFindElementUuId ( app - > ioH , kCurMidiEvtCntId ) , midi_record_play : : event_index ( app - > mrpH ) ) ;
io : : uiSendValue ( app - > ioH , uiFindElementUuId ( app - > ioH , kTotalMidiEvtCntId ) , midi_record_play : : event_count ( app - > mrpH ) ) ;
}
2021-12-19 17:18:22 +00:00
// Update the UI with the value from the the fragment data record.
2021-11-06 02:28:38 +00:00
template < typename T >
rc_t _update_frag_ui ( app_t * app , unsigned fragId , unsigned psVarId , unsigned psPresetId , unsigned uiParentUuId , unsigned uiVarAppId , unsigned uiChanId , T & valRef )
{
rc_t rc = kOkRC ;
unsigned uuid = kInvalidId ;
// Get the value from the data record
if ( ( rc = preset_sel : : get_value ( app - > psH , fragId , psVarId , psPresetId , valRef ) ) ! = kOkRC )
{
2021-12-28 01:32:56 +00:00
rc = cwLogError ( rc , " Unable to locate the preset value for var:%i preset:%i. " , psVarId , psPresetId ) ;
2021-11-06 02:28:38 +00:00
goto errLabel ;
}
// Get the UI uuId
if ( ( uuid = io : : uiFindElementUuId ( app - > ioH , uiParentUuId , uiVarAppId , uiChanId ) ) = = kInvalidId )
{
rc = cwLogError ( rc , " Unable to locate the UI uuid for appid:%i chanId:%i. " , uiVarAppId , uiChanId ) ;
goto errLabel ;
}
// Send the value to the UI
if ( ( rc = io : : uiSendValue ( app - > ioH , uuid , valRef ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Transmission of fragment value failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
2021-11-14 18:11:11 +00:00
// Get the endLoc associated with this fragment id
rc_t _frag_id_to_endloc ( app_t * app , unsigned fragId , unsigned & endLocRef )
{
rc_t rc = kOkRC ;
endLocRef = kInvalidId ;
if ( ( rc = get_value ( app - > psH , fragId , preset_sel : : kEndLocVarId , kInvalidId , endLocRef ) ) ! = kOkRC )
rc = cwLogError ( rc , " Unable to get the 'end loc' value for fragment id:%i. " , fragId ) ;
return rc ;
}
// Update the preset select check boxes on a fragment panel
rc_t _update_frag_select_flags ( app_t * app , unsigned fragId , unsigned fragEndLoc = kInvalidId )
{
rc_t rc = kOkRC ;
// if
if ( fragEndLoc = = kInvalidId )
{
// get the endLoc associated with this fragment
rc = _frag_id_to_endloc ( app , fragId , fragEndLoc ) ;
}
if ( rc = = kOkRC )
{
bool bValue ;
unsigned uValue ;
2021-12-28 01:32:56 +00:00
unsigned fragPanelUuId ;
2021-11-14 18:11:11 +00:00
// The uiChan is the fragment endLoc
unsigned uiChanId = fragEndLoc ;
2021-12-28 01:32:56 +00:00
// Get the fragPanelUUid
get_value ( app - > psH , fragId , preset_sel : : kGuiUuIdVarId , kInvalidId , fragPanelUuId ) ;
2021-11-14 18:11:11 +00:00
// uuid of the frag preset row
unsigned fragPresetRowUuId = io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragPresetRowId , uiChanId ) ;
2021-12-28 01:32:56 +00:00
2021-11-14 18:11:11 +00:00
// Update each fragment preset control UI by getting it's current value from the fragment data record
for ( unsigned preset_idx = 0 ; preset_idx < preset_sel : : preset_count ( app - > psH ) ; + + preset_idx )
{
_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 ) ;
}
}
return rc ;
}
// Update the fragment UI withh the fragment record associated with 'fragId'
2021-11-06 02:28:38 +00:00
rc_t _update_frag_ui ( app_t * app , unsigned fragId )
{
2021-12-28 01:32:56 +00:00
// Notes:
2021-11-06 02:28:38 +00:00
// uiChanId = endLoc for panel values
// or uiChanId = preset_index for preset values
rc_t rc = kOkRC ;
unsigned endLoc ;
2021-11-14 18:11:11 +00:00
// get the endLoc for this fragment
if ( ( rc = _frag_id_to_endloc ( app , fragId , endLoc ) ) = = kOkRC )
2021-11-06 02:28:38 +00:00
{
unsigned uValue ;
double dValue ;
2021-12-28 01:32:56 +00:00
const char * sValue ;
2021-11-14 18:11:11 +00:00
unsigned uiChanId = endLoc ;
2021-12-28 01:32:56 +00:00
unsigned fragPanelUuId = kInvalidId ;
2021-11-06 02:28:38 +00:00
2021-12-28 01:32:56 +00:00
get_value ( app - > psH , fragId , preset_sel : : kGuiUuIdVarId , kInvalidId , fragPanelUuId ) ;
2021-11-06 02:28:38 +00:00
2021-12-28 01:32:56 +00:00
_update_frag_ui ( app , fragId , preset_sel : : kBegLocVarId , kInvalidId , fragPanelUuId , kFragBegLocId , uiChanId , uValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kEndLocVarId , kInvalidId , fragPanelUuId , kFragEndLocId , uiChanId , uValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kInGainVarId , kInvalidId , fragPanelUuId , kFragInGainId , uiChanId , dValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kInGainVarId , kInvalidId , fragPanelUuId , kFragOutGainId , uiChanId , dValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kFadeOutMsVarId , kInvalidId , fragPanelUuId , kFragFadeOutMsId , uiChanId , dValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kWetGainVarId , kInvalidId , fragPanelUuId , kFragWetDryGainId , uiChanId , dValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kBegPlayLocVarId , kInvalidId , fragPanelUuId , kFragBegPlayLocId , uiChanId , uValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kEndPlayLocVarId , kInvalidId , fragPanelUuId , kFragEndPlayLocId , uiChanId , uValue ) ;
_update_frag_ui ( app , fragId , preset_sel : : kNoteVarId , kInvalidId , fragPanelUuId , kFragNoteId , uiChanId , sValue ) ;
2021-11-14 18:11:11 +00:00
_update_frag_select_flags ( app , fragId , endLoc ) ;
2021-11-06 02:28:38 +00:00
}
return rc ;
}
2021-12-30 02:57:04 +00:00
rc_t _frag_uuid_to_blob ( app_t * app , unsigned uuId , ui_blob_t * & blobRef )
{
unsigned blobByteN = 0 ;
if ( ( blobRef = ( ui_blob_t * ) io : : uiGetBlob ( app - > ioH , uuId , blobByteN ) ) = = nullptr | | blobByteN ! = sizeof ( ui_blob_t ) )
return cwLogError ( kInvalidStateRC , " A fragment UI blob was missing or corrupt for GUI uuid:%i. " , uuId ) ;
return kOkRC ;
}
void _enable_global_play_btn ( app_t * app , bool enableFl )
{
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kStartBtnId ) , enableFl ) ;
//io::uiSetEnable( app->ioH, io::uiFindElementUuId( app->ioH, kStopBtnId ), enableFl );
}
void _enable_frag_play_btn ( app_t * app , ui_blob_t * blob , unsigned , const char * ) { }
void _enable_frag_play_btn ( app_t * app , ui_blob_t * blob , const char * , unsigned ) { }
void _enable_frag_play_btn ( app_t * app , ui_blob_t * blob , unsigned begPlayLoc , unsigned endPlayLoc )
{
bool enableFl = begPlayLoc < endPlayLoc ;
unsigned fragUuId = kInvalidId ;
unsigned fragPlayBtnUuId = kInvalidId ;
if ( ( fragUuId = frag_to_gui_id ( app - > psH , blob - > fragId ) ) ! = kInvalidId )
if ( ( fragPlayBtnUuId = uiFindElementUuId ( app - > ioH , fragUuId , kFragPlayBtnId , blob - > presetId ) ) ! = kInvalidId )
{
uiSetEnable ( app - > ioH , fragPlayBtnUuId , enableFl ) ;
if ( enableFl )
_clear_status ( app ) ;
else
_set_status ( app , " Invalid fragment play range. " ) ;
}
}
void _disable_frag_play_btn ( app_t * app , unsigned fragBegEndUuId )
{
ui_blob_t * blob = nullptr ;
if ( _frag_uuid_to_blob ( app , fragBegEndUuId , blob ) = = kOkRC )
_enable_frag_play_btn ( app , blob , 1 , ( unsigned ) 0 ) ;
}
2021-12-19 17:18:22 +00:00
// Called when a UI value is changed in a fragment panel (e.g. gain, fadeMs, ...)
2021-11-06 02:28:38 +00:00
template < typename T >
2021-11-14 18:11:11 +00:00
rc_t _on_ui_frag_value ( app_t * app , unsigned uuId , const T & value )
2021-11-06 02:28:38 +00:00
{
2021-11-14 18:11:11 +00:00
rc_t rc = kOkRC ;
ui_blob_t * blob = nullptr ;
2021-12-30 02:57:04 +00:00
if ( ( rc = _frag_uuid_to_blob ( app , uuId , blob ) ) ! = kOkRC )
goto errLabel ;
2021-11-14 18:11:11 +00:00
rc = preset_sel : : set_value ( app - > psH , blob - > fragId , blob - > varId , blob - > presetId , value ) ;
if ( rc ! = kOkRC )
{
// TODO: Set the error indicator on the GUI
}
else
{
// TODO: Clear the error indicator on the GUI
}
2021-12-28 01:32:56 +00:00
//
switch ( blob - > varId )
{
case preset_sel : : kPresetSelectVarId :
_update_frag_select_flags ( app , blob - > fragId ) ;
break ;
case preset_sel : : kPlayBtnVarId :
_do_play_fragment ( app , blob - > fragId ) ;
break ;
2021-12-30 02:57:04 +00:00
case preset_sel : : kBegPlayLocVarId :
{
unsigned endPlayLoc ;
get_value ( app - > psH , blob - > fragId , preset_sel : : kEndPlayLocVarId , blob - > presetId , endPlayLoc ) ;
_enable_frag_play_btn ( app , blob , value , endPlayLoc ) ;
}
break ;
case preset_sel : : kEndPlayLocVarId :
{
unsigned begPlayLoc ;
get_value ( app - > psH , blob - > fragId , preset_sel : : kBegPlayLocVarId , blob - > presetId , begPlayLoc ) ;
_enable_frag_play_btn ( app , blob , begPlayLoc , value ) ;
}
break ;
2021-12-28 01:32:56 +00:00
}
2021-12-30 02:57:04 +00:00
errLabel :
2021-11-06 02:28:38 +00:00
return rc ;
}
2021-12-19 17:18:22 +00:00
rc_t _frag_set_ui_blob ( app_t * app , unsigned uuId , unsigned fragId , unsigned varId , unsigned presetId )
{
ui_blob_t blob = { . fragId = fragId , . varId = varId , . presetId = presetId } ;
return io : : uiSetBlob ( app - > ioH , uuId , & blob , sizeof ( blob ) ) ;
}
2021-11-06 02:28:38 +00:00
2021-12-19 17:18:22 +00:00
rc_t _create_frag_preset_ctl ( app_t * app , unsigned fragId , unsigned fragPresetRowUuId , unsigned presetN , unsigned preset_idx )
{
rc_t rc = kOkRC ;
unsigned colUuId = kInvalidId ;
unsigned uuId = kInvalidId ;
const char * nullEleName = nullptr ;
const char * nullClass = nullptr ;
unsigned invalidAppId = kInvalidId ;
unsigned chanId = preset_idx ; // chanId is the preset id
const char * presetLabel = preset_sel : : preset_label ( app - > psH , preset_idx ) ;
assert ( presetLabel ! = nullptr ) ;
// preset control column container
if ( ( rc = io : : uiCreateDiv ( app - > ioH , colUuId , fragPresetRowUuId , nullEleName , invalidAppId , chanId , " col fragPresetCtl " , nullptr ) ) ! = kOkRC )
goto errLabel ;
// preset select check
if ( ( rc = io : : uiCreateCheck ( app - > ioH , uuId , colUuId , nullEleName , kFragPresetSelId , chanId , nullClass , presetLabel ) ) ! = kOkRC )
goto errLabel ;
// store a connection for the select control back to the fragment record
_frag_set_ui_blob ( app , uuId , fragId , preset_sel : : kPresetSelectVarId , preset_idx ) ;
// preset order number
if ( ( rc = io : : uiCreateNumb ( app - > ioH , uuId , colUuId , nullEleName , kFragPresetOrderId , chanId , nullClass , nullptr , 0 , presetN , 1 , 0 ) ) ! = kOkRC )
goto errLabel ;
// store a connection for the select control back to the fragment record
_frag_set_ui_blob ( app , uuId , fragId , preset_sel : : kPresetOrderVarId , preset_idx ) ;
errLabel :
if ( rc ! = kOkRC )
rc = cwLogError ( rc , " Preset control index '%i' create failed. " ) ;
return rc ;
}
2021-12-28 01:32:56 +00:00
rc_t _create_frag_ui ( app_t * app , unsigned endLoc , unsigned fragId )
2021-11-01 14:28:44 +00:00
{
2021-12-19 17:18:22 +00:00
rc_t rc = kOkRC ;
unsigned fragListUuId = io : : uiFindElementUuId ( app - > ioH , kFragListId ) ;
unsigned fragChanId = endLoc ; // use the frag. endLoc as the channel id
unsigned fragPanelUuId = kInvalidId ;
2021-12-28 01:32:56 +00:00
unsigned fragBegLocUuId = kInvalidId ;
2021-12-19 17:18:22 +00:00
unsigned fragEndLocUuId = kInvalidId ;
unsigned fragPresetRowUuId = kInvalidId ;
unsigned presetN = preset_sel : : preset_count ( app - > psH ) ;
2021-12-30 02:57:04 +00:00
unsigned fragBegLoc = 0 ;
2021-12-19 17:18:22 +00:00
// create the UI object
if ( ( rc = io : : uiCreateFromObject ( app - > ioH , app - > frag_panel_cfg , fragListUuId , fragChanId ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " The fragments UI object creation failed. " ) ;
goto errLabel ;
}
// get the uuid's of the new fragment panel and the endloc number display
2021-12-28 01:32:56 +00:00
fragPanelUuId = io : : uiFindElementUuId ( app - > ioH , fragListUuId , kFragPanelId , fragChanId ) ;
fragBegLocUuId = io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragBegLocId , fragChanId ) ;
2021-12-19 17:18:22 +00:00
fragEndLocUuId = io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragEndLocId , fragChanId ) ;
fragPresetRowUuId = io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragPresetRowId , fragChanId ) ;
assert ( fragPanelUuId ! = kInvalidId ) ;
2021-12-28 01:32:56 +00:00
assert ( fragBegLocUuId ! = kInvalidId ) ;
2021-12-19 17:18:22 +00:00
assert ( fragEndLocUuId ! = kInvalidId ) ;
assert ( fragPresetRowUuId ! = kInvalidId ) ;
// Make the fragment panel clickable
io : : uiSetClickable ( app - > ioH , fragPanelUuId ) ;
// Set the fragment panel order
io : : uiSetOrderKey ( app - > ioH , fragPanelUuId , endLoc ) ;
2021-12-30 02:57:04 +00:00
// Set the fragment beg/end play range
get_value ( app - > psH , fragId , preset_sel : : kBegPlayLocVarId , kInvalidId , fragBegLoc ) ;
uiSetNumbRange ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragBegPlayLocId , fragChanId ) , app - > minLoc , app - > maxLoc , 1 , 0 , fragBegLoc ) ;
uiSetNumbRange ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragEndPlayLocId , fragChanId ) , app - > minLoc , app - > maxLoc , 1 , 0 , endLoc ) ;
2021-12-19 17:18:22 +00:00
// Attach blobs to the UI to allow convenient access back to the prese_sel data record
2021-12-28 01:32:56 +00:00
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragInGainId , fragChanId ) , fragId , preset_sel : : kInGainVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragOutGainId , fragChanId ) , fragId , preset_sel : : kOutGainVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragWetDryGainId , fragChanId ) , fragId , preset_sel : : kWetGainVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragFadeOutMsId , fragChanId ) , fragId , preset_sel : : kFadeOutMsVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragBegPlayLocId , fragChanId ) , fragId , preset_sel : : kBegPlayLocVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragEndPlayLocId , fragChanId ) , fragId , preset_sel : : kEndPlayLocVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragPlayBtnId , fragChanId ) , fragId , preset_sel : : kPlayBtnVarId , kInvalidId ) ;
_frag_set_ui_blob ( app , io : : uiFindElementUuId ( app - > ioH , fragPanelUuId , kFragNoteId , fragChanId ) , fragId , preset_sel : : kNoteVarId , kInvalidId ) ;
2021-11-01 14:28:44 +00:00
2021-12-19 17:18:22 +00:00
// create each of the preset controls
for ( unsigned preset_idx = 0 ; preset_idx < presetN ; + + preset_idx )
2021-12-28 01:32:56 +00:00
if ( ( rc = _create_frag_preset_ctl ( app , fragId , fragPresetRowUuId , presetN , preset_idx ) ) ! = kOkRC )
2021-12-19 17:18:22 +00:00
goto errLabel ;
2021-12-30 02:57:04 +00:00
// set the uuid associated with this fragment
2021-12-28 01:32:56 +00:00
preset_sel : : set_value ( app - > psH , fragId , preset_sel : : kGuiUuIdVarId , kInvalidId , fragPanelUuId ) ;
2021-12-19 17:18:22 +00:00
errLabel :
return rc ;
}
rc_t _restore ( app_t * app )
{
rc_t rc = kOkRC ;
char * fn = nullptr ;
const preset_sel : : frag_t * f = nullptr ;
// form the output file name
if ( ( fn = filesys : : makeFn ( app - > record_dir , app - > record_fn , app - > record_fn_ext , NULL ) ) = = nullptr )
{
rc = cwLogError ( kOpFailRC , " The preset select filename could not formed. " ) ;
goto errLabel ;
}
if ( ! filesys : : isFile ( fn ) )
{
cwLogInfo ( " The preset selection data file: '%s' does not exist. " , cwStringNullGuard ( fn ) ) ;
goto errLabel ;
}
// read the preset data file
if ( ( rc = preset_sel : : read ( app - > psH , fn ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " File write failed on preset select. " ) ;
goto errLabel ;
}
preset_sel : : report ( app - > psH ) ;
2021-11-01 14:28:44 +00:00
2021-12-19 17:18:22 +00:00
f = preset_sel : : get_fragment_base ( app - > psH ) ;
for ( ; f ! = nullptr ; f = f - > link )
{
2021-12-28 01:32:56 +00:00
unsigned fragId = f - > fragId ;
2021-12-19 17:18:22 +00:00
if ( ( rc = _create_frag_ui ( app , f - > endLoc , fragId ) ) ! = kOkRC )
2021-11-01 14:28:44 +00:00
{
2021-12-19 17:18:22 +00:00
cwLogError ( rc , " Frag UI create failed. " ) ;
2021-11-01 14:28:44 +00:00
goto errLabel ;
}
2021-12-19 17:18:22 +00:00
_update_frag_ui ( app , fragId ) ;
2021-11-01 14:28:44 +00:00
}
2021-12-19 17:18:22 +00:00
errLabel :
mem : : release ( fn ) ;
return rc ;
}
rc_t _on_ui_save ( app_t * app )
{
rc_t rc = kOkRC ;
char * fn = nullptr ;
// form the output file name
if ( ( fn = filesys : : makeFn ( app - > record_dir , app - > record_fn , app - > record_fn_ext , NULL ) ) = = nullptr )
{
rc = cwLogError ( kOpFailRC , " The preset select filename could not formed. " ) ;
goto errLabel ;
}
// write the preset data file
if ( ( rc = preset_sel : : write ( app - > psH , fn ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " File write failed on preset select. " ) ;
goto errLabel ;
2021-11-01 14:28:44 +00:00
}
errLabel :
2021-12-19 17:18:22 +00:00
mem : : release ( fn ) ;
2021-12-30 02:57:04 +00:00
if ( rc = = kOkRC )
_clear_status ( app ) ;
else
_set_status ( app , " Save failed. " ) ;
2021-12-19 17:18:22 +00:00
return rc ;
2021-11-01 14:28:44 +00:00
}
2021-12-28 01:32:56 +00:00
rc_t _do_load ( app_t * app )
2021-11-01 14:28:44 +00:00
{
rc_t rc = kOkRC ;
const score : : event_t * e = nullptr ;
unsigned midiEventN = 0 ;
midi_record_play : : midi_msg_t * m = nullptr ;
2021-12-30 02:57:04 +00:00
// if the score is already loaded
if ( app - > scoreH . isValid ( ) )
return rc ;
cwLogInfo ( " Loading " ) ;
_set_status ( app , " Loading... " ) ;
2021-11-01 14:28:44 +00:00
// create the score
if ( ( rc = score : : create ( app - > scoreH , app - > scoreFn ) ) ! = kOkRC )
{
cwLogError ( rc , " Score create failed on '%s'. " , app - > scoreFn ) ;
goto errLabel ;
}
// get the count of MIDI events
if ( ( e = score : : base_event ( app - > scoreH ) ) ! = nullptr )
for ( ; e ! = nullptr ; e = e - > link )
if ( e - > status ! = 0 )
midiEventN + = 1 ;
// copy the MIDI events
if ( ( e = score : : base_event ( app - > scoreH ) ) ! = nullptr )
{
// allocate the locMap[]
mem : : free ( app - > locMap ) ;
app - > locMap = mem : : allocZ < loc_map_t > ( midiEventN ) ;
app - > locMapN = midiEventN ;
2021-12-30 02:57:04 +00:00
app - > minLoc = midiEventN ;
app - > maxLoc = 0 ;
2021-11-01 14:28:44 +00:00
// allocate the the player msg array
m = mem : : allocZ < midi_record_play : : midi_msg_t > ( midiEventN ) ;
// load the player msg array
for ( unsigned i = 0 ; e ! = nullptr & & i < midiEventN ; e = e - > link )
if ( e - > status ! = 0 )
{
time : : millisecondsToSpec ( m [ i ] . timestamp , ( unsigned ) ( e - > sec * 1000 ) ) ;
m [ i ] . ch = e - > status & 0x0f ;
m [ i ] . status = e - > status & 0xf0 ;
m [ i ] . d0 = e - > d0 ;
m [ i ] . d1 = e - > d1 ;
m [ i ] . id = e - > uid ;
app - > locMap [ i ] . loc = e - > loc ;
app - > locMap [ i ] . timestamp = m [ i ] . timestamp ;
2021-12-30 02:57:04 +00:00
app - > minLoc = std : : min ( app - > minLoc , e - > loc ) ;
app - > maxLoc = std : : max ( app - > maxLoc , e - > loc ) ;
2021-11-01 14:28:44 +00:00
+ + i ;
}
// load the player with the msg list
if ( ( rc = midi_record_play : : load ( app - > mrpH , m , midiEventN ) ) ! = kOkRC )
{
cwLogError ( rc , " MIDI player load failed. " ) ;
goto errLabel ;
}
mem : : free ( m ) ;
}
2021-12-30 02:57:04 +00:00
// set the range of the global play location controls
io : : uiSetNumbRange ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kBegPlayLocNumbId ) , app - > minLoc , app - > maxLoc , 1 , 0 , app - > minLoc ) ;
io : : uiSetNumbRange ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kEndPlayLocNumbId ) , app - > minLoc , app - > maxLoc , 1 , 0 , app - > maxLoc ) ;
2021-11-06 02:28:38 +00:00
// enable the 'End Loc' number box since the score is loaded
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kInsertLocId ) , true ) ;
// update the current event and event count
_update_event_ui ( app ) ;
2021-11-14 18:11:11 +00:00
2021-12-30 02:57:04 +00:00
2021-11-14 18:11:11 +00:00
// enable the start/stop buttons
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kStartBtnId ) , true ) ;
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kStopBtnId ) , true ) ;
2021-12-19 17:18:22 +00:00
// restore the fragment records
if ( ( rc = _restore ( app ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Restore failed. " ) ;
goto errLabel ;
}
2021-12-30 02:57:04 +00:00
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kLoadBtnId ) , false ) ;
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kSaveBtnId ) , true ) ;
2021-11-01 14:28:44 +00:00
cwLogInfo ( " '%s' loaded. " , app - > scoreFn ) ;
errLabel :
2021-11-06 02:28:38 +00:00
_update_event_ui ( app ) ;
2021-12-30 02:57:04 +00:00
if ( rc ! = kOkRC )
_set_status ( app , " Load failed. " ) ;
else
_set_status ( app , " %i MIDI events loaded. " , midiEventN ) ;
2021-11-01 14:28:44 +00:00
return rc ;
}
2021-12-28 01:32:56 +00:00
2021-11-01 14:28:44 +00:00
rc_t _on_ui_start ( app_t * app )
{
2021-12-28 01:32:56 +00:00
return _do_play ( app , app - > beg_play_loc , app - > end_play_loc ) ;
2021-11-01 14:28:44 +00:00
}
rc_t _set_midi_thru_state ( app_t * app , bool thru_fl )
{
rc_t rc = kOkRC ;
if ( ( rc = midi_record_play : : set_thru_state ( app - > mrpH , thru_fl ) ) ! = kOkRC )
rc = cwLogError ( rc , " %s MIDI thru state failed. " , thru_fl ? " Enable " : " Disable " ) ;
return rc ;
}
2021-11-14 18:11:11 +00:00
bool _is_valid_insert_loc ( app_t * app , unsigned loc )
{
bool fl0 = _find_loc ( app , loc ) ! = nullptr ;
bool fl1 = preset_sel : : is_fragment_loc ( app - > psH , loc ) = = false ;
return fl0 & & fl1 ;
}
2021-11-06 02:28:38 +00:00
2021-12-30 02:57:04 +00:00
// Called when the global play locations change
2021-11-14 18:11:11 +00:00
rc_t _on_ui_play_loc ( app_t * app , unsigned appId , unsigned loc )
2021-11-01 14:28:44 +00:00
{
2021-11-14 18:11:11 +00:00
rc_t rc = kOkRC ;
2021-11-06 02:28:38 +00:00
2022-01-22 14:55:17 +00:00
// verify that the location exists
if ( _find_loc ( app , loc ) = = nullptr )
_set_status ( app , " %i is an invalid location. " , loc ) ;
else
2021-11-06 02:28:38 +00:00
{
2022-01-22 14:55:17 +00:00
switch ( appId )
{
case kBegPlayLocNumbId :
app - > beg_play_loc = loc ;
break ;
2021-11-14 18:11:11 +00:00
2022-01-22 14:55:17 +00:00
case kEndPlayLocNumbId :
app - > end_play_loc = loc ;
break ;
}
bool enableFl = app - > beg_play_loc < app - > end_play_loc ;
2021-12-30 02:57:04 +00:00
2022-01-22 14:55:17 +00:00
_enable_global_play_btn ( app , enableFl ) ;
if ( enableFl )
_clear_status ( app ) ;
else
_set_status ( app , " Invalid play location range. " ) ;
}
2021-11-14 18:11:11 +00:00
return rc ;
}
2021-11-06 02:28:38 +00:00
2021-11-14 18:11:11 +00:00
rc_t _on_ui_insert_loc ( app_t * app , unsigned insertLoc )
{
rc_t rc = kOkRC ;
bool enableFl = _is_valid_insert_loc ( app , insertLoc ) ;
unsigned insertBtnUuId = io : : uiFindElementUuId ( app - > ioH , kInsertBtnId ) ;
io : : uiSetEnable ( app - > ioH , insertBtnUuId , enableFl ) ;
if ( enableFl )
{
app - > insertLoc = insertLoc ;
2021-12-30 02:57:04 +00:00
_clear_status ( app ) ;
2021-11-14 18:11:11 +00:00
}
else
{
app - > insertLoc = kInvalidId ;
2021-12-30 02:57:04 +00:00
_set_status ( app , " Location '%i' is not valid. " , insertLoc ) ;
2021-11-14 18:11:11 +00:00
}
2021-11-06 02:28:38 +00:00
return rc ;
}
rc_t _on_ui_insert_btn ( app_t * app )
{
2021-12-30 02:57:04 +00:00
rc_t rc = kOkRC ;
unsigned fragId = kInvalidId ;
loc_map_t * loc_ts = nullptr ;
const preset_sel : : frag_t * f = nullptr ; ;
2021-11-06 02:28:38 +00:00
// verify that frag panel resource object is initiailized
if ( app - > frag_panel_cfg = = nullptr )
{
rc = cwLogError ( kInvalidStateRC , " The fragment UI resource was not initialized. " ) ;
goto errLabel ;
}
// verify that the insertion location is valid
if ( app - > insertLoc = = kInvalidId )
{
rc = cwLogError ( kInvalidIdRC , " The new fragment's 'End Loc' is not valid. " ) ;
goto errLabel ;
}
2021-12-12 21:47:41 +00:00
// verify that the end-loc is not already in use - this shouldn't be possible because the 'insert' btn should be disabled if the 'insertLoc' is not valid
if ( preset_sel : : is_fragment_loc ( app - > psH , app - > insertLoc ) )
{
rc = cwLogError ( kInvalidIdRC , " The new fragment's 'End Loc' is already in use. " ) ;
goto errLabel ;
}
// get the timestamp assoc'd with the the 'end-loc'
if ( ( loc_ts = _find_loc ( app , app - > insertLoc ) ) = = nullptr )
{
rc = cwLogError ( kOpFailRC , " The time stamp associated with the 'End Loc' '%i' could not be found. " , app - > insertLoc ) ;
goto errLabel ;
}
2021-12-28 01:32:56 +00:00
// create the data record associated with the new fragment.
if ( ( rc = preset_sel : : create_fragment ( app - > psH , app - > insertLoc , loc_ts - > timestamp , fragId ) ) ! = kOkRC )
2021-11-06 02:28:38 +00:00
{
2021-12-28 01:32:56 +00:00
rc = cwLogError ( rc , " Fragment data record create failed. " ) ;
2021-11-06 02:28:38 +00:00
goto errLabel ;
2021-11-01 14:28:44 +00:00
}
2021-12-28 01:32:56 +00:00
// create the fragment UI panel
if ( ( rc = _create_frag_ui ( app , app - > insertLoc , fragId ) ) ! = kOkRC )
2021-11-06 02:28:38 +00:00
{
2021-12-28 01:32:56 +00:00
rc = cwLogError ( rc , " Fragment UI panel create failed. " ) ;
2021-11-06 02:28:38 +00:00
goto errLabel ;
}
2021-11-14 18:11:11 +00:00
2021-12-28 01:32:56 +00:00
2021-11-06 02:28:38 +00:00
// update the fragment UI
2021-12-19 17:18:22 +00:00
_update_frag_ui ( app , fragId ) ;
2021-11-06 02:28:38 +00:00
2021-12-30 02:57:04 +00:00
if ( ( f = get_fragment ( app - > psH , fragId ) ) ! = nullptr & & f - > link ! = nullptr )
_update_frag_ui ( app , f - > link - > fragId ) ;
2021-11-06 02:28:38 +00:00
errLabel :
2021-11-01 14:28:44 +00:00
return rc ;
2021-11-06 02:28:38 +00:00
2021-11-01 14:28:44 +00:00
}
2021-11-14 18:11:11 +00:00
rc_t _on_ui_delete_btn ( app_t * app )
{
rc_t rc = kOkRC ;
unsigned fragId = kInvalidId ;
2021-12-30 02:57:04 +00:00
unsigned uuId = kInvalidId ;
2021-11-14 18:11:11 +00:00
// get the fragment id (uuid) of the selected fragment
if ( ( fragId = preset_sel : : ui_select_fragment_id ( app - > psH ) ) = = kInvalidId )
{
rc = cwLogError ( kInvalidStateRC , " There is no selected fragment to delete. " ) ;
goto errLabel ;
}
2021-12-30 02:57:04 +00:00
// locate the uuid assocated with the specified fragid
if ( ( uuId = preset_sel : : frag_to_gui_id ( app - > psH , fragId ) ) = = kInvalidId )
{
rc = cwLogError ( kInvalidIdRC , " The uuId associated with the fragment id %i could not be found. " , fragId ) ;
goto errLabel ;
}
2021-11-14 18:11:11 +00:00
// delete the fragment data record
2021-12-19 17:18:22 +00:00
if ( ( rc = preset_sel : : delete_fragment ( app - > psH , fragId ) ) ! = kOkRC )
2021-11-14 18:11:11 +00:00
goto errLabel ;
// delete the fragment UI element
2021-12-30 02:57:04 +00:00
if ( ( rc = io : : uiDestroyElement ( app - > ioH , uuId ) ) ! = kOkRC )
2021-11-14 18:11:11 +00:00
goto errLabel ;
errLabel :
if ( rc ! = kOkRC )
rc = cwLogError ( rc , " Fragment delete failed. " ) ;
2022-01-22 14:55:17 +00:00
else
cwLogInfo ( " Fragment %i deleted. " , fragId ) ;
return rc ;
}
void _on_echo_midi_enable ( app_t * app , unsigned uuId , unsigned mrp_dev_idx )
{
if ( mrp_dev_idx < = midi_record_play : : device_count ( app - > mrpH ) )
{
bool enableFl = midi_record_play : : is_device_enabled ( app - > mrpH , mrp_dev_idx ) ;
io : : uiSendValue ( app - > ioH , uuId , enableFl ) ;
}
}
void _on_midi_enable ( app_t * app , unsigned checkAppId , unsigned mrp_dev_idx , bool enableFl )
{
unsigned midi_dev_n = midi_record_play : : device_count ( app - > mrpH ) ;
if ( mrp_dev_idx < midi_dev_n )
midi_record_play : : enable_device ( app - > mrpH , mrp_dev_idx , enableFl ) ;
else
cwLogError ( kInvalidArgRC , " %i is not a valid MIDI device index for device count:%i. " , mrp_dev_idx , midi_dev_n ) ;
}
rc_t _on_echo_master_value ( app_t * app , unsigned varId , unsigned uuId )
{
rc_t rc = kOkRC ;
double val = 0 ;
if ( ( rc = get_value ( app - > psH , kInvalidId , varId , kInvalidId , val ) ) ! = kOkRC )
rc = cwLogError ( rc , " Unable to get the master value for var id:%i. " , varId ) ;
else
io : : uiSendValue ( app - > ioH , uuId , val ) ;
return rc ;
}
rc_t _on_master_value ( app_t * app , const char * inst_label , const char * var_label , unsigned varId , double value )
{
rc_t rc = kOkRC ;
if ( ( rc = preset_sel : : set_value ( app - > psH , kInvalidId , varId , kInvalidId , value ) ) ! = kOkRC )
rc = cwLogError ( rc , " Master value set failed on varId:%i %s.%s. " , varId , cwStringNullGuard ( inst_label ) , cwStringNullGuard ( var_label ) ) ;
else
if ( ( rc = io_flow : : set_variable_value ( app - > ioFlowH , flow_cross : : kAllDestId , inst_label , var_label , flow : : kAnyChIdx , ( dsp : : real_t ) value ) ) ! = kOkRC )
rc = cwLogError ( rc , " Master value send failed on %s.%s. " , cwStringNullGuard ( inst_label ) , cwStringNullGuard ( var_label ) ) ;
2021-11-14 18:11:11 +00:00
return rc ;
}
2021-11-01 14:28:44 +00:00
rc_t _onUiInit ( app_t * app , const io : : ui_msg_t & m )
{
rc_t rc = kOkRC ;
2021-11-06 02:28:38 +00:00
_update_event_ui ( app ) ;
2021-11-14 18:11:11 +00:00
// disable start and stop buttons until a score is loaded
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kStartBtnId ) , false ) ;
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kStopBtnId ) , false ) ;
2021-12-30 02:57:04 +00:00
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kSaveBtnId ) , false ) ;
2021-11-14 18:11:11 +00:00
2021-11-06 02:28:38 +00:00
const preset_sel : : frag_t * f = preset_sel : : get_fragment_base ( app - > psH ) ;
for ( ; f ! = nullptr ; f = f - > link )
_update_frag_ui ( app , f - > fragId ) ;
2022-01-22 14:55:17 +00:00
_do_load ( app ) ;
2021-11-01 14:28:44 +00:00
return rc ;
}
rc_t _onUiValue ( app_t * app , const io : : ui_msg_t & m )
{
rc_t rc = kOkRC ;
switch ( m . appId )
{
case kQuitBtnId :
io : : stop ( app - > ioH ) ;
break ;
case kIoReportBtnId :
io : : report ( app - > ioH ) ;
break ;
2022-01-22 14:55:17 +00:00
case kNetPrintBtnId :
io_flow : : print_network ( app - > ioFlowH , flow_cross : : kCurDestId ) ;
break ;
2021-11-01 14:28:44 +00:00
case kReportBtnId :
2021-12-19 17:18:22 +00:00
//preset_sel::report( app->psH );
2021-12-30 02:57:04 +00:00
//io_flow::apply_preset( app->ioFlowH, 2000.0, app->tmp==0 ? "a" : "b");
//app->tmp = !app->tmp;
2022-01-22 14:55:17 +00:00
io_flow : : print ( app - > ioFlowH ) ;
2021-11-01 14:28:44 +00:00
break ;
case kSaveBtnId :
_on_ui_save ( app ) ;
break ;
case kLoadBtnId :
2021-12-28 01:32:56 +00:00
_do_load ( app ) ;
2021-11-01 14:28:44 +00:00
break ;
case kMidiThruCheckId :
cwLogInfo ( " MIDI thru:%i " , m . value - > u . b ) ;
_set_midi_thru_state ( app , m . value - > u . b ) ;
break ;
case kStartBtnId :
_on_ui_start ( app ) ;
break ;
case kStopBtnId :
2022-01-22 14:55:17 +00:00
_do_stop_play ( app ) ;
break ;
case kPrintMidiCheckId :
app - > printMidiFl = m . value - > u . b ;
break ;
case kPianoMidiCheckId :
_on_midi_enable ( app , m . appId , kPiano_MRP_DevIdx , m . value - > u . b ) ;
break ;
case kSamplerMidiCheckId :
_on_midi_enable ( app , m . appId , kSampler_MRP_DevIdx , m . value - > u . b ) ;
2021-11-01 14:28:44 +00:00
break ;
2022-01-22 14:55:17 +00:00
case kWetInGainId :
_on_master_value ( app , " mstr_wet_in_gain " , " gain " , preset_sel : : kMasterWetInGainVarId , m . value - > u . d ) ;
break ;
case kWetOutGainId :
_on_master_value ( app , " mstr_wet_out_gain " , " gain " , preset_sel : : kMasterWetOutGainVarId , m . value - > u . d ) ;
break ;
case kDryGainId :
_on_master_value ( app , " mstr_dry_out_gain " , " gain " , preset_sel : : kMasterDryGainVarId , m . value - > u . d ) ;
break ;
case kSyncDelayMsId :
_on_master_value ( app , " sync_delay " , " delayMs " , preset_sel : : kMasterSyncDelayMsVarId , ( double ) m . value - > u . i ) ;
break ;
2021-11-14 18:11:11 +00:00
case kBegPlayLocNumbId :
_on_ui_play_loc ( app , m . appId , m . value - > u . i ) ;
break ;
case kEndPlayLocNumbId :
_on_ui_play_loc ( app , m . appId , m . value - > u . i ) ;
2021-11-01 14:28:44 +00:00
break ;
2021-11-06 02:28:38 +00:00
case kInsertLocId :
2021-11-14 18:11:11 +00:00
_on_ui_insert_loc ( app , m . value - > u . u ) ;
2021-11-06 02:28:38 +00:00
break ;
case kInsertBtnId :
_on_ui_insert_btn ( app ) ;
break ;
case kDeleteBtnId :
2021-11-14 18:11:11 +00:00
_on_ui_delete_btn ( app ) ;
2021-11-06 02:28:38 +00:00
break ;
2021-12-28 01:32:56 +00:00
case kFragInGainId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . d ) ;
break ;
case kFragOutGainId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . d ) ;
2021-11-06 02:28:38 +00:00
break ;
case kFragWetDryGainId :
2021-12-28 01:32:56 +00:00
//printf("UI wet/dry:%f\n",m.value->u.d);
2021-11-14 18:11:11 +00:00
_on_ui_frag_value ( app , m . uuId , m . value - > u . d ) ;
2021-11-06 02:28:38 +00:00
break ;
case kFragFadeOutMsId :
2021-12-19 17:18:22 +00:00
_on_ui_frag_value ( app , m . uuId , m . value - > u . u ) ;
2021-11-06 02:28:38 +00:00
break ;
2021-12-28 01:32:56 +00:00
case kFragBegPlayLocId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . u ) ;
break ;
case kFragEndPlayLocId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . u ) ;
break ;
case kFragPlayBtnId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . b ) ;
break ;
case kFragNoteId :
_on_ui_frag_value ( app , m . uuId , m . value - > u . s ) ;
break ;
2021-11-06 02:28:38 +00:00
case kFragPresetOrderId :
2021-11-14 18:11:11 +00:00
_on_ui_frag_value ( app , m . uuId , m . value - > u . u ) ;
2021-11-06 02:28:38 +00:00
break ;
case kFragPresetSelId :
2021-11-14 18:11:11 +00:00
_on_ui_frag_value ( app , m . uuId , m . value - > u . b ) ;
2021-11-06 02:28:38 +00:00
break ;
2021-11-01 14:28:44 +00:00
}
return rc ;
}
2021-11-14 18:11:11 +00:00
2021-12-30 02:57:04 +00:00
rc_t _onUiCorrupt ( app_t * app , const io : : ui_msg_t & m )
{
switch ( m . appId )
{
case kBegPlayLocNumbId :
case kEndPlayLocNumbId :
_enable_global_play_btn ( app , false ) ;
break ;
case kInsertLocId :
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kInsertBtnId ) , false ) ;
break ;
case kFragBegPlayLocId :
case kFragEndPlayLocId :
_disable_frag_play_btn ( app , m . uuId ) ;
break ;
default :
break ;
}
return kOkRC ;
}
2021-11-14 18:11:11 +00:00
rc_t _onUiSelect ( app_t * app , const io : : ui_msg_t & m )
{
2021-12-30 02:57:04 +00:00
rc_t rc = kOkRC ;
bool selectFl = m . value - > u . b ; // True/False if the fragment is being selected/deselected
unsigned fragId = kInvalidId ;
if ( ( fragId = preset_sel : : gui_to_frag_id ( app - > psH , m . uuId ) ) = = kInvalidId )
{
rc = cwLogError ( kInvalidIdRC , " The fragment assoicated with the UuId %i could not be found. " , m . uuId ) ;
goto errLabel ;
}
2021-11-14 18:11:11 +00:00
// track the currently selected fragment.
2021-12-30 02:57:04 +00:00
preset_sel : : ui_select_fragment ( app - > psH , fragId , selectFl ) ;
2021-11-14 18:11:11 +00:00
// enable/disable the delete fragment button
io : : uiSetEnable ( app - > ioH , io : : uiFindElementUuId ( app - > ioH , kDeleteBtnId ) , selectFl ) ;
2021-12-30 02:57:04 +00:00
errLabel :
2021-11-14 18:11:11 +00:00
return rc ;
}
2022-01-22 14:55:17 +00:00
2021-11-01 14:28:44 +00:00
rc_t _onUiEcho ( app_t * app , const io : : ui_msg_t & m )
{
rc_t rc = kOkRC ;
2022-01-22 14:55:17 +00:00
switch ( m . appId )
{
case kPrintMidiCheckId :
break ;
case kPianoMidiCheckId :
_on_echo_midi_enable ( app , m . uuId , kPiano_MRP_DevIdx ) ;
break ;
case kSamplerMidiCheckId :
_on_echo_midi_enable ( app , m . uuId , kSampler_MRP_DevIdx ) ;
break ;
case kWetInGainId :
_on_echo_master_value ( app , preset_sel : : kMasterWetInGainVarId , m . uuId ) ;
break ;
case kWetOutGainId :
_on_echo_master_value ( app , preset_sel : : kMasterWetOutGainVarId , m . uuId ) ;
break ;
case kDryGainId :
_on_echo_master_value ( app , preset_sel : : kMasterDryGainVarId , m . uuId ) ;
break ;
case kSyncDelayMsId :
_on_echo_master_value ( app , preset_sel : : kMasterSyncDelayMsVarId , m . uuId ) ;
break ;
}
2021-11-01 14:28:44 +00:00
return rc ;
}
rc_t _ui_callback ( app_t * app , const io : : ui_msg_t & m )
{
rc_t rc = kOkRC ;
switch ( m . opId )
{
case ui : : kConnectOpId :
cwLogInfo ( " UI Connected: wsSessId:%i. " , m . wsSessId ) ;
break ;
case ui : : kDisconnectOpId :
cwLogInfo ( " UI Disconnected: wsSessId:%i. " , m . wsSessId ) ;
break ;
case ui : : kInitOpId :
_onUiInit ( app , m ) ;
break ;
case ui : : kValueOpId :
_onUiValue ( app , m ) ;
break ;
2021-12-30 02:57:04 +00:00
case ui : : kCorruptOpId :
_onUiCorrupt ( app , m ) ;
break ;
2021-11-14 18:11:11 +00:00
case ui : : kClickOpId :
2022-01-22 14:55:17 +00:00
_do_select_frag ( app , m . uuId ) ;
2021-11-14 18:11:11 +00:00
break ;
case ui : : kSelectOpId :
_onUiSelect ( app , m ) ;
break ;
2021-11-01 14:28:44 +00:00
case ui : : kEchoOpId :
_onUiEcho ( app , m ) ;
break ;
case ui : : kIdleOpId :
break ;
case ui : : kInvalidOpId :
// fall through
default :
assert ( 0 ) ;
break ;
}
return rc ;
}
// The main application callback
rc_t _io_callback ( void * arg , const io : : msg_t * m )
{
rc_t rc = kOkRC ;
app_t * app = reinterpret_cast < app_t * > ( arg ) ;
if ( app - > mrpH . isValid ( ) )
{
midi_record_play : : exec ( app - > mrpH , * m ) ;
if ( midi_record_play : : is_started ( app - > mrpH ) )
2021-11-03 15:09:07 +00:00
io : : uiSendValue ( app - > ioH , uiFindElementUuId ( app - > ioH , kCurMidiEvtCntId ) , midi_record_play : : event_index ( app - > mrpH ) ) ;
2021-11-01 14:28:44 +00:00
}
2021-12-11 20:21:03 +00:00
if ( app - > ioFlowH . isValid ( ) )
{
io_flow : : exec ( app - > ioFlowH , * m ) ;
}
2021-11-01 14:28:44 +00:00
switch ( m - > tid )
{
case io : : kTimerTId :
break ;
case io : : kSerialTId :
break ;
case io : : kMidiTId :
break ;
case io : : kAudioTId :
break ;
case io : : kAudioMeterTId :
break ;
case io : : kSockTId :
break ;
case io : : kWebSockTId :
break ;
case io : : kUiTId :
rc = _ui_callback ( app , m - > u . ui ) ;
break ;
default :
assert ( 0 ) ;
}
return rc ;
}
}
}
2021-12-11 20:21:03 +00:00
cw : : rc_t cw : : preset_sel_app : : main ( const object_t * cfg , const object_t * flow_proc_dict )
2021-11-01 14:28:44 +00:00
{
rc_t rc ;
2021-11-06 02:28:38 +00:00
app_t app = { } ;
2021-11-03 15:09:07 +00:00
const object_t * params_cfg = nullptr ;
2021-11-01 14:28:44 +00:00
// Parse the configuration
2021-11-03 15:09:07 +00:00
if ( ( rc = _parseCfg ( & app , cfg , params_cfg ) ) ! = kOkRC )
2021-11-01 14:28:44 +00:00
goto errLabel ;
// create the io framework instance
if ( ( rc = io : : create ( app . ioH , cfg , _io_callback , & app , mapA , mapN ) ) ! = kOkRC )
{
rc = cwLogError ( kOpFailRC , " IO Framework create failed. " ) ;
goto errLabel ;
}
2021-12-30 02:57:04 +00:00
log : : setOutputCb ( log : : globalHandle ( ) , _log_output_func , & app ) ;
2021-11-06 02:28:38 +00:00
// create the preset selection state object
if ( ( rc = create ( app . psH , app . presets_cfg ) ) ! = kOkRC )
{
rc = cwLogError ( kOpFailRC , " Preset state control object create failed. " ) ;
goto errLabel ;
}
2021-11-01 14:28:44 +00:00
// create the MIDI record-play object
2022-01-22 14:55:17 +00:00
if ( ( rc = midi_record_play : : create ( app . mrpH , app . ioH , * app . midi_play_record_cfg , _midi_play_callback , & app ) ) ! = kOkRC )
2021-11-01 14:28:44 +00:00
{
rc = cwLogError ( rc , " MIDI record-play object create failed. " ) ;
goto errLabel ;
}
2022-01-22 14:55:17 +00:00
2021-12-11 20:21:03 +00:00
// create the IO Flow controller
2021-12-19 17:18:22 +00:00
if ( app . flow_cfg = = nullptr | | flow_proc_dict = = nullptr | | ( rc = io_flow : : create ( app . ioFlowH , app . ioH , app . crossFadeSrate , app . crossFadeCnt , * flow_proc_dict , * app . flow_cfg ) ) ! = kOkRC )
2021-12-11 20:21:03 +00:00
{
rc = cwLogError ( rc , " The IO Flow controller create failed. " ) ;
goto errLabel ;
}
2021-11-01 14:28:44 +00:00
// start the io framework instance
if ( ( rc = io : : start ( app . ioH ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " Preset-select app start failed. " ) ;
goto errLabel ;
}
2021-12-28 01:32:56 +00:00
2021-11-01 14:28:44 +00:00
// execute the io framework
while ( ! isShuttingDown ( app . ioH ) )
{
exec ( app . ioH ) ;
sleepMs ( 50 ) ;
}
2021-12-28 01:32:56 +00:00
// stop the io framework
2021-12-19 17:18:22 +00:00
if ( ( rc = io : : stop ( app . ioH ) ) ! = kOkRC )
{
rc = cwLogError ( rc , " IO API stop failed. " ) ;
goto errLabel ;
}
2021-11-01 14:28:44 +00:00
errLabel :
2021-12-19 17:18:22 +00:00
2021-11-01 14:28:44 +00:00
_free ( app ) ;
io : : destroy ( app . ioH ) ;
printf ( " Preset-select Done. \n " ) ;
return rc ;
}