cwScoreFollower.h/cpp : Added sync_perf_to_score(), perf_count(), and per_base().

This commit is contained in:
kevin 2023-05-25 16:11:34 -04:00
parent cee91b11a6
commit 9595a7552c
2 changed files with 63 additions and 6 deletions

View File

@ -9,6 +9,7 @@
#include "cwMidi.h"
#include "cwMidiFile.h"
#include "cwCmInterface.h"
#include "cwScoreFollowerPerf.h"
#include "cwScoreFollower.h"
#include "cwMidiState.h"
@ -405,10 +406,8 @@ cw::rc_t cw::score_follower::exec( handle_t h, double sec, unsigned smpIdx, uns
}
return rc;
}
const unsigned* cw::score_follower::current_match_id_array( handle_t h, unsigned& cur_match_id_array_cnt_ref )
{
score_follower_t* p = _handleToPtr(h);
@ -458,9 +457,59 @@ bool cw::score_follower::is_loc_in_range( handle_t h, unsigned loc )
unsigned cw::score_follower::has_stored_performance( handle_t h )
{
score_follower_t* p = _handleToPtr(h);
return p->perf_idx > 0;
return p->perf_idx > 0 && p->matcher->ri > 0;
}
cw::rc_t cw::score_follower::sync_perf_to_score( handle_t h )
{
rc_t rc = kOkRC;
score_follower_t* p = _handleToPtr(h);
if( !has_stored_performance(h) )
{
rc = cwLogError(kInvalidStateRC,"No performance to sync.");
goto errLabel;
}
for(unsigned i=0; i<p->matcher->ri; ++i)
{
unsigned perf_idx = p->matcher->res[i].muid;
// the matcher result 'muid' is the perf. array index of the matching perf. record
if( perf_idx >= p->perf_idx )
{
rc = cwLogError(kInvalidStateRC,"Inconsistent match to perf. map: index mismatch.");
goto errLabel;
}
// verify the pitch of the matching records
if( p->perfA[ perf_idx ].pitch != p->matcher->res[i].pitch )
{
rc = cwLogError(kInvalidStateRC,"Inconsistent match to perf. map: pitch mismatch %i != %i.",p->perfA[ perf_idx ].pitch ,p->matcher->res[i].pitch);
goto errLabel;
}
assert( p->matcher->res[i].scEvtIdx == kInvalidIdx || p->matcher->res[i].scEvtIdx < p->cmLocToCwLocN );
if( p->matcher->res[i].scEvtIdx != kInvalidIdx )
p->perfA[ perf_idx ].loc = p->cmLocToCwLocA[ p->matcher->res[i].scEvtIdx ];
}
errLabel:
return rc;
}
unsigned cw::score_follower::perf_count( handle_t h )
{
score_follower_t* p = _handleToPtr(h);
return p->perfN;
}
const cw::score_follower::ssf_note_on_t* cw::score_follower::perf_base( handle_t h )
{
score_follower_t* p = _handleToPtr(h);
return p->perfA;
}
cw::rc_t cw::score_follower::write_svg_file( handle_t h, const char* out_fname, bool show_muid_fl )
{

View File

@ -5,7 +5,6 @@ namespace cw
{
namespace score_follower
{
typedef handle< struct score_follower_str > handle_t;
rc_t create( handle_t& hRef, const object_t* cfg, cm::handle_t cmCtxH, double srate );
@ -24,12 +23,21 @@ namespace cw
// Clear the match id array. This should be done to empty the current_match_id_array()
void clear_match_id_array( handle_t h );
// Get the min and max cw loc values for the current score.
rc_t cw_loc_range( handle_t h, unsigned& minLocRef, unsigned& maxLocRef );
bool is_loc_in_range( handle_t h, unsigned loc );
unsigned has_stored_performance( handle_t h );
// Set the 'loc' field on the stored performance from the stored score following info.
rc_t sync_perf_to_score( handle_t h );
// Return the count of stored performance records in the performance array.
unsigned perf_count( handle_t h );
// Return the base of the stored performance array.
const score_follower::ssf_note_on_t* perf_base( handle_t h );
// Write an SVG file containing a graphic view of the score following results since the last call to reset().
// Set show_muid_fl to true to display the 'muid' of the performed notes in the
// SVG rendering, otherwise the performed note sequence (order of arrival) id is shown.