124 lines
5.9 KiB
C
124 lines
5.9 KiB
C
|
#ifndef cwSfTracker_h
|
||
|
#define cwSfTracker_h
|
||
|
|
||
|
namespace cw
|
||
|
{
|
||
|
namespace sftrack
|
||
|
{
|
||
|
typedef struct result_str
|
||
|
{
|
||
|
unsigned locIdx; // index into cmScMatch_t.loc[]
|
||
|
unsigned scEvtIdx; // score event index
|
||
|
unsigned mni; // index of the performed MIDI event associated with this score location
|
||
|
unsigned smpIdx; // sample time index of performed MIDI event
|
||
|
unsigned muid; // MIDI file event msg unique id (See cmMidiTrackMsg_t.uid)
|
||
|
unsigned pitch; // performed pitch
|
||
|
unsigned vel; // performed velocity
|
||
|
unsigned flags; // smTruePosFl | smFalsePosFl
|
||
|
} result_t;
|
||
|
|
||
|
|
||
|
struct sftrack_str;
|
||
|
typedef void (*callback_func_t)( void* arg, result_t* rp );
|
||
|
|
||
|
typedef struct sftrack_str
|
||
|
{
|
||
|
callback_func_t cbFunc;
|
||
|
void* cbArg;
|
||
|
sfmatch::handle_t matchH;
|
||
|
unsigned mn; // size of midiBuf[]
|
||
|
sfmatch::midi_t* midiBuf; // midiBuf[mn]
|
||
|
|
||
|
result_t* res; // res[rn]
|
||
|
unsigned rn; // length of res[] (set to 2*score event count)
|
||
|
unsigned ri; // next avail res[] recd.
|
||
|
|
||
|
double s_opt; //
|
||
|
unsigned missCnt; // current count of consecutive trailing non-matches
|
||
|
unsigned ili; // index into loc[] to start scan following reset
|
||
|
unsigned eli; // index into loc[] of the last positive match.
|
||
|
unsigned mni; // current count of MIDI events since the last call to cmScMatcherReset()
|
||
|
unsigned mbi; // index of oldest MIDI event in midiBuf[]; stays at 0 when the buffer is full.
|
||
|
unsigned begSyncLocIdx; // start of score window, in mp->loc[], of best match in previous scan
|
||
|
unsigned initHopCnt; // max window hops during the initial (when the MIDI buffer fills for first time) sync scan
|
||
|
unsigned stepCnt; // count of forward/backward score loc's to examine for a match during cmScMatcherStep().
|
||
|
unsigned maxMissCnt; // max. number of consecutive non-matches during step prior to executing a scan.
|
||
|
unsigned scanCnt; // current count of times a resync-scan was executed during cmScMatcherStep()
|
||
|
|
||
|
bool printFl;
|
||
|
} sftrack_t;
|
||
|
|
||
|
typedef handle<struct sftrack_str> handle_t;
|
||
|
|
||
|
rc_t create( handle_t& hRef,
|
||
|
double srate, // System sample rate.
|
||
|
sfscore::handle_t scH, // Score handle. See cmScore.h.
|
||
|
unsigned scWndN, // Length of the scores active search area. ** See Notes.
|
||
|
unsigned midiWndN, // Length of the MIDI active note buffer. ** See Notes.
|
||
|
callback_func_t cbFunc, // A cmScMatcherCb_t function to be called to notify the recipient of changes in the score matcher status.
|
||
|
void* cbArg ); // User argument to 'cbFunc'.
|
||
|
|
||
|
// Notes:
|
||
|
// The cmScMatcher maintains an internal cmScMatch object which is used to attempt to find the
|
||
|
// best match between the current MIDI active note buffer and the current score search area.
|
||
|
// 'scWndN' is used to set the cmScMatch 'locN' argument.
|
||
|
// 'midiWndN' sets the length of the MIDI FIFO which is used to match to the score with
|
||
|
// each recceived MIDI note.
|
||
|
// 'midiWndN' must be <= 'scWndN'.
|
||
|
|
||
|
rc_t destroy( handle_t& hRef );
|
||
|
|
||
|
// 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[].
|
||
|
rc_t reset( handle_t h, unsigned scLocIdx );
|
||
|
|
||
|
// Slide a score window 'hopCnt' times, beginning at 'bli' (an
|
||
|
// index into p->mp->loc[]) looking for the best match to p->midiBuf[].
|
||
|
// The score window contain scWndN (p->mp->mcn-1) score locations.
|
||
|
// Returns the index into p->mp->loc[] of the start of the best
|
||
|
// match score window. The score associated
|
||
|
// with this match is stored in s_opt.
|
||
|
//unsigned scan( handle_t h, unsigned bli, unsigned hopCnt );
|
||
|
|
||
|
// Step forward/back by p->stepCnt from p->eli.
|
||
|
// p->eli must therefore be valid prior to calling this function.
|
||
|
// If more than p->maxMissCnt consecutive MIDI events are
|
||
|
// missed then automatically run cmScAlignScan().
|
||
|
// Return cmEofRC if the end of the score is encountered.
|
||
|
// Return cmSubSysFailRC if an internal scan resync. failed.
|
||
|
//rc_t step( handle_t h );
|
||
|
|
||
|
// This function calls cmScMatcherScan() and cmScMatcherStep() internally.
|
||
|
// If 'status' is not kNonMidiMdId then the function returns without changing the
|
||
|
// state of the object. In other words the matcher only recognizes MIDI note-on messages.
|
||
|
// If the MIDI note passed by the call results in a successful match then
|
||
|
// p->eli will be updated to the location in p->mp->loc[] of the latest
|
||
|
// match, the MIDI note in p->midiBuf[] associated with this match
|
||
|
// will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr
|
||
|
// will be set with the matched scLocIdx of the match.
|
||
|
// If this call does not result in a successful match *scLocIdxPtr is set
|
||
|
// to cmInvalidIdx.
|
||
|
// 'muid' is the unique id associated with this MIDI event under the circumstances
|
||
|
// that the event came from a MIDI file. See cmMidiFile.h cmMidiTrackMsg_t.uid.
|
||
|
// Return:
|
||
|
// cmOkRC - Continue processing MIDI events.
|
||
|
// cmEofRC - The end of the score was encountered.
|
||
|
// cmInvalidArgRC - scan failed or the object was in an invalid state to attempt a match.
|
||
|
// cmSubSysFailRC - a scan resync failed in cmScMatcherStep().
|
||
|
rc_t exec( handle_t h,
|
||
|
unsigned smpIdx,
|
||
|
unsigned muid,
|
||
|
unsigned status,
|
||
|
midi::byte_t d0,
|
||
|
midi::byte_t d1,
|
||
|
unsigned* scLocIdxPtr );
|
||
|
|
||
|
void print( handle_t h );
|
||
|
|
||
|
rc_t test( const object_t* cfg );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|