Merge branch 'master' of gitea.larke.org:kevin/libcw

This commit is contained in:
kevin 2022-10-01 19:05:22 -04:00
commit f82c440e33
4 changed files with 142 additions and 17 deletions

View File

@ -281,7 +281,7 @@ namespace cw
rc_t _event_callback( midi_record_play_t* p, unsigned id, const time::spec_t timestamp, unsigned loc, uint8_t ch, uint8_t status, uint8_t d0, uint8_t d1, bool log_fl=true )
{
rc_t rc = kOkRC;
bool quiet_flag = true;
// if we have arrived at the stop time
bool after_stop_time_fl = !time::isZero(p->end_play_event_timestamp) && time::isGT(timestamp,p->end_play_event_timestamp);
bool after_all_off_fl = after_stop_time_fl && time::isGT(timestamp,p->all_off_timestamp);
@ -331,8 +331,11 @@ namespace cw
else
if( d1 == p->midiDevA[i].pedalDownHalfVelId )
out_d1 = p->midiDevA[i].pedalDownHalfVel;
else
cwLogError(kInvalidIdRC,"Unexpected pedal down velocity (%i) during pedal velocity mapping.",d1);
else
{
if(!quiet_flag)
cwLogError(kInvalidIdRC,"Unexpected pedal down velocity (%i) during pedal velocity mapping.",d1);
}
}
}

View File

@ -218,7 +218,8 @@ namespace cw
unsigned locMapN;
unsigned insertLoc; // last valid insert location id received from the GUI
unsigned lastPlayedLoc;
unsigned minLoc;
unsigned maxLoc;
@ -346,11 +347,14 @@ namespace cw
return kOkRC;
}
rc_t _apply_preset( app_t* app, const time::spec_t& ts, const preset_sel::frag_t* frag=nullptr )
rc_t _apply_preset( app_t* app, const time::spec_t& ts, unsigned loc, const preset_sel::frag_t* frag=nullptr )
{
if( frag == nullptr )
preset_sel::track_timestamp( app->psH, ts, frag);
{
//preset_sel::track_timestamp( app->psH, ts, frag);
preset_sel::track_loc( app->psH, loc, frag);
}
if( frag == nullptr )
cwLogInfo("No preset fragment was found for the requested timestamp.");
else
@ -445,13 +449,21 @@ namespace cw
if( midi_record_play::is_started(app->mrpH) )
{
const preset_sel::frag_t* f = nullptr;
if( preset_sel::track_timestamp( app->psH, timestamp, f ) )
{
//printf("NEW FRAG: id:%i loc:%i\n", f->fragId, f->endLoc );
_apply_preset( app, timestamp, f );
//if( preset_sel::track_timestamp( app->psH, timestamp, f ) )
if( f != nullptr )
_do_select_frag( app, f->guiUuId );
// ZERO SHOULD BE A VALID LOC VALUE - MAKE -1 THE INVALID LOC VALUE
if( loc != 0 )
{
if( preset_sel::track_loc( app->psH, loc, f ) )
{
//printf("NEW FRAG: id:%i loc:%i\n", f->fragId, f->endLoc );
_apply_preset( app, timestamp, loc, f );
if( f != nullptr )
_do_select_frag( app, f->guiUuId );
}
}
}
break;
@ -498,6 +510,7 @@ namespace cw
bool rewindFl = true;
loc_map_t* begMap = nullptr;
loc_map_t* endMap = nullptr;
unsigned cur_loc = 0;
// if the player is already playing then stop it
if( midi_record_play::is_started(app->mrpH) )
@ -537,7 +550,7 @@ namespace cw
}
// apply the preset which is active at the start time
if((rc = _apply_preset( app, app->beg_play_timestamp )) != kOkRC )
if((rc = _apply_preset( app, app->beg_play_timestamp, app->beg_play_loc )) != kOkRC )
{
rc = cwLogError(rc,"Preset application failed prior to MIDI start.");
goto errLabel;
@ -550,8 +563,11 @@ namespace cw
goto errLabel;
}
io::uiSendValue( app->ioH, uiFindElementUuId(app->ioH,kCurMidiEvtCntId), midi_record_play::event_loc(app->mrpH) );
if((cur_loc = midi_record_play::event_loc(app->mrpH)) > app->lastPlayedLoc )
{
io::uiSendValue( app->ioH, uiFindElementUuId(app->ioH,kCurMidiEvtCntId), cur_loc );
app->lastPlayedLoc = cur_loc;
}
errLabel:
return rc;
@ -1878,7 +1894,15 @@ namespace cw
{
midi_record_play::exec( app->mrpH, *m );
if( midi_record_play::is_started(app->mrpH) )
io::uiSendValue( app->ioH, uiFindElementUuId(app->ioH,kCurMidiEvtCntId), midi_record_play::event_loc(app->mrpH) );
{
unsigned cur_loc = midi_record_play::event_loc(app->mrpH);
if( cur_loc > app->lastPlayedLoc )
{
io::uiSendValue( app->ioH, uiFindElementUuId(app->ioH,kCurMidiEvtCntId), cur_loc );
app->lastPlayedLoc = cur_loc;
}
}
}
if( app->ioFlowH.isValid() )

View File

@ -200,6 +200,56 @@ namespace cw
return nullptr;
}
bool _loc_is_in_frag( const frag_t* f, unsigned loc )
{
// if f is the earliest fragment
if( f->prev == nullptr )
return loc <= f->endLoc;
// else f->prev->end_loc < loc && loc <= f->end_loc
return f->prev->endLoc < loc && loc <= f->endLoc;
}
bool _loc_is_before_frag( const frag_t* f, unsigned loc )
{
// if loc is past f
if( loc > f->endLoc )
return false;
// loc may now only be inside or before f
// if f is the first frag then loc must be inside it
if( f->prev == nullptr )
return false;
// is loc before f
return loc <= f->prev->endLoc;
}
bool _loc_is_after_frag( const frag_t* f, unsigned loc )
{
return loc > f->endLoc;
}
// Scan from through the fragment list to find the fragment containing loc.
frag_t* _fast_loc_to_frag( preset_sel_t* p, unsigned loc, frag_t* init_frag=nullptr )
{
frag_t* f = init_frag==nullptr ? p->fragL : init_frag;
for(; f!=nullptr; f=f->link)
if( _loc_is_in_frag(f,loc) )
return f;
return nullptr;
}
rc_t _validate_preset_id( const frag_t* frag, unsigned preset_id )
@ -826,6 +876,51 @@ bool cw::preset_sel::track_timestamp( handle_t h, const time::spec_t& ts, const
return frag_changed_fl;
}
void cw::preset_sel::track_loc_reset( handle_t h )
{
preset_sel_t* p = _handleToPtr(h);
p->last_ts_frag = nullptr;
}
bool cw::preset_sel::track_loc( handle_t h, unsigned loc, const cw::preset_sel::frag_t*& frag_Ref )
{
preset_sel_t* p = _handleToPtr(h);
frag_t* f = nullptr;
bool frag_changed_fl = false;
// if this is the first call to 'track_timestamp()'.
if( p->last_ts_frag == nullptr )
f = _fast_loc_to_frag(p,loc);
else
// if the 'ts' is in the same frag as previous call.
if( _loc_is_in_frag(p->last_ts_frag,loc) )
f = p->last_ts_frag;
else
// if 'ts' is in a later frag
if( _loc_is_after_frag(p->last_ts_frag,loc) )
f = _fast_loc_to_frag(p,loc,p->last_ts_frag);
else // ts is prior to 'last_ts_frag'
f = _fast_loc_to_frag(p,loc);
// 'f' will be null at this point if 'ts' is past the last preset.
// In this case we should leave 'last_ts_frag' unchanged.
// if 'f' is valid but different from 'last_ts_frag'
if( f != nullptr && f != p->last_ts_frag )
{
p->last_ts_frag = f;
frag_changed_fl = true;
}
frag_Ref = p->last_ts_frag;
return frag_changed_fl;
}
unsigned cw::preset_sel::fragment_play_preset_index( const frag_t* frag, unsigned preset_seq_idx )
{
unsigned n = 0;

View File

@ -115,6 +115,9 @@ namespace cw
void track_timestamp_reset( handle_t h );
bool track_timestamp( handle_t h, const time::spec_t& ts, const cw::preset_sel::frag_t*& frag_Ref );
void track_loc_reset( handle_t h );
bool track_loc( handle_t h, unsigned loc, const cw::preset_sel::frag_t*& frag_Ref );
// Return the preset index marked to play on this fragment.
unsigned fragment_play_preset_index( const frag_t* frag, unsigned preset_seq_idx=kInvalidIdx );