cmProc4.h : Updated comments and formatting.
This commit is contained in:
parent
b67964871f
commit
3e5af0773e
515
cmProc4.h
515
cmProc4.h
@ -5,30 +5,30 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned smpIdx; // time tag sample index for val
|
unsigned smpIdx; // time tag sample index for val
|
||||||
cmMidiByte_t val; //
|
cmMidiByte_t val; //
|
||||||
bool validFl; //
|
bool validFl; //
|
||||||
} cmScFolBufEle_t;
|
} cmScFolBufEle_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned pitch;
|
unsigned pitch;
|
||||||
unsigned scEvtIdx;
|
unsigned scEvtIdx;
|
||||||
} cmScFolEvt_t;
|
} cmScFolEvt_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned evtCnt; //
|
unsigned evtCnt; //
|
||||||
cmScFolEvt_t* evtV; // pitchV[pitchCnt]
|
cmScFolEvt_t* evtV; // pitchV[pitchCnt]
|
||||||
unsigned scIdx; // index of the score loc (into cmScoreEvt[]) at this location
|
unsigned scIdx; // index of the score loc (into cmScoreEvt[]) at this location
|
||||||
int barNumb; // bar number of this location
|
int barNumb; // bar number of this location
|
||||||
} cmScFolLoc_t;
|
} cmScFolLoc_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmObj obj;
|
cmObj obj;
|
||||||
cmReal_t srate; //
|
cmReal_t srate; //
|
||||||
cmScH_t scH; // score handle
|
cmScH_t scH; // score handle
|
||||||
@ -53,39 +53,39 @@ typedef struct
|
|||||||
unsigned skipCnt; // notes skipped due to velocity
|
unsigned skipCnt; // notes skipped due to velocity
|
||||||
unsigned ret_idx; // last tracked location
|
unsigned ret_idx; // last tracked location
|
||||||
|
|
||||||
} cmScFol;
|
} cmScFol;
|
||||||
|
|
||||||
cmScFol* cmScFolAlloc( cmCtx* ctx, cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
cmScFol* cmScFolAlloc( cmCtx* ctx, cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
||||||
cmRC_t cmScFolFree( cmScFol** pp );
|
cmRC_t cmScFolFree( cmScFol** pp );
|
||||||
cmRC_t cmScFolInit( cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
cmRC_t cmScFolInit( cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
||||||
cmRC_t cmScFolFinal( cmScFol* p );
|
cmRC_t cmScFolFinal( cmScFol* p );
|
||||||
|
|
||||||
// Jump to a score location and reset the internal state of the follower.
|
// Jump to a score location and reset the internal state of the follower.
|
||||||
cmRC_t cmScFolReset( cmScFol* p, unsigned scoreIndex );
|
cmRC_t cmScFolReset( cmScFol* p, unsigned scoreIndex );
|
||||||
|
|
||||||
// Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
|
// Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
|
||||||
// all others are ignored.
|
// all others are ignored.
|
||||||
unsigned cmScFolExec( cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
unsigned cmScFolExec( cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned pitch;
|
unsigned pitch;
|
||||||
unsigned scEvtIdx;
|
unsigned scEvtIdx;
|
||||||
bool matchFl;
|
bool matchFl;
|
||||||
} cmScTrkEvt_t;
|
} cmScTrkEvt_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned evtCnt; //
|
unsigned evtCnt; //
|
||||||
cmScTrkEvt_t* evtV; // evtV[evtCnt]
|
cmScTrkEvt_t* evtV; // evtV[evtCnt]
|
||||||
unsigned scIdx; // index of the score event (into cmScoreEvt[]) at this location
|
unsigned scIdx; // index of the score event (into cmScoreEvt[]) at this location
|
||||||
int barNumb; // bar number of this location
|
int barNumb; // bar number of this location
|
||||||
} cmScTrkLoc_t;
|
} cmScTrkLoc_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmObj obj;
|
cmObj obj;
|
||||||
cmScFol* sfp;
|
cmScFol* sfp;
|
||||||
double srate;
|
double srate;
|
||||||
@ -100,66 +100,66 @@ typedef struct
|
|||||||
int curLocIdx;
|
int curLocIdx;
|
||||||
unsigned evtIndex;
|
unsigned evtIndex;
|
||||||
|
|
||||||
} cmScTrk;
|
} cmScTrk;
|
||||||
|
|
||||||
cmScTrk* cmScTrkAlloc( cmCtx* ctx, cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
cmScTrk* cmScTrkAlloc( cmCtx* ctx, cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
||||||
cmRC_t cmScTrkFree( cmScTrk** pp );
|
cmRC_t cmScTrkFree( cmScTrk** pp );
|
||||||
cmRC_t cmScTrkInit( cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
cmRC_t cmScTrkInit( cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
|
||||||
cmRC_t cmScTrkFinal( cmScTrk* p );
|
cmRC_t cmScTrkFinal( cmScTrk* p );
|
||||||
|
|
||||||
// Jump to a score location and reset the internal state of the follower.
|
// Jump to a score location and reset the internal state of the follower.
|
||||||
cmRC_t cmScTrkReset( cmScTrk* p, unsigned scoreIndex );
|
cmRC_t cmScTrkReset( cmScTrk* p, unsigned scoreIndex );
|
||||||
|
|
||||||
// Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
|
// Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
|
||||||
// all others are ignored.
|
// all others are ignored.
|
||||||
unsigned cmScTrkExec( cmScTrk* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
unsigned cmScTrkExec( cmScTrk* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
//
|
//
|
||||||
// Simplified string alignment function based on Levenshtein edit distance.
|
// Simplified string alignment function based on Levenshtein edit distance.
|
||||||
//
|
//
|
||||||
enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt };
|
enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt };
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned v[kEdCnt];
|
unsigned v[kEdCnt];
|
||||||
bool matchFl;
|
bool matchFl;
|
||||||
bool transFl;
|
bool transFl;
|
||||||
} ed_val;
|
} ed_val;
|
||||||
|
|
||||||
typedef struct ed_path_str
|
typedef struct ed_path_str
|
||||||
{
|
{
|
||||||
unsigned code;
|
unsigned code;
|
||||||
unsigned ri;
|
unsigned ri;
|
||||||
unsigned ci;
|
unsigned ci;
|
||||||
bool matchFl;
|
bool matchFl;
|
||||||
bool transFl;
|
bool transFl;
|
||||||
struct ed_path_str* next;
|
struct ed_path_str* next;
|
||||||
} ed_path;
|
} ed_path;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Backtracking:
|
Backtracking:
|
||||||
m[rn,cn] is organized to indicate the mutation operations
|
m[rn,cn] is organized to indicate the mutation operations
|
||||||
on s0[0:rn-1] or s1[0:cn-1] during backtracking.
|
on s0[0:rn-1] or s1[0:cn-1] during backtracking.
|
||||||
Backtracking begins at cell m[rn-1,cn-1] and proceeds
|
Backtracking begins at cell m[rn-1,cn-1] and proceeds
|
||||||
up and left toward m[0,0]. The action to perform during
|
up and left toward m[0,0]. The action to perform during
|
||||||
backtracking is determined by examinging which values
|
backtracking is determined by examinging which values
|
||||||
int m[].v[1:3] match m[].v[0].
|
int m[].v[1:3] match m[].v[0].
|
||||||
Match Next Cell
|
Match Next Cell
|
||||||
Index Operation Location
|
Index Operation Location
|
||||||
----- ------------------------ ------------------------
|
----- ------------------------ ------------------------
|
||||||
1 Substitute char s0[ri-1] move diagonally; up-left
|
1 Substitute char s0[ri-1] move diagonally; up-left
|
||||||
2 Delete char s0[ri-1] move up.
|
2 Delete char s0[ri-1] move up.
|
||||||
3 Delete char s1[ci-1] move left.
|
3 Delete char s1[ci-1] move left.
|
||||||
(same as inserting blank
|
(same as inserting blank
|
||||||
into after s[ri-1]
|
into after s[ri-1]
|
||||||
|
|
||||||
Note that more than one value in m[].v[1:3] may match
|
Note that more than one value in m[].v[1:3] may match
|
||||||
m[].v[0]. In this case the candidate solution branches
|
m[].v[0]. In this case the candidate solution branches
|
||||||
at this point in the candidate selection processes.
|
at this point in the candidate selection processes.
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const char* s0; // forms rows of m[] - mutate to match s1 - rn=strlen(s0)
|
const char* s0; // forms rows of m[] - mutate to match s1 - rn=strlen(s0)
|
||||||
const char* s1; // forms columns of m[] - target string - cn=strlen(s1)
|
const char* s1; // forms columns of m[] - target string - cn=strlen(s1)
|
||||||
unsigned rn; // length of s0 + 1
|
unsigned rn; // length of s0 + 1
|
||||||
@ -172,60 +172,60 @@ typedef struct
|
|||||||
ed_path* p_opt; // p_opt[pn] current best alignment
|
ed_path* p_opt; // p_opt[pn] current best alignment
|
||||||
double s_opt; // score of the current best alignment
|
double s_opt; // score of the current best alignment
|
||||||
|
|
||||||
} ed_r;
|
} ed_r;
|
||||||
|
|
||||||
// print the DP matrix ed_r.m[rn,cn].
|
// print the DP matrix ed_r.m[rn,cn].
|
||||||
void ed_print_mtx( ed_r* r );
|
void ed_print_mtx( ed_r* r );
|
||||||
|
|
||||||
// Initialize ed_r.
|
// Initialize ed_r.
|
||||||
void ed_init( ed_r* r, const char* s0, const char* s1 );
|
void ed_init( ed_r* r, const char* s0, const char* s1 );
|
||||||
|
|
||||||
// Fill in the DP matrix.
|
// Fill in the DP matrix.
|
||||||
void ed_calc_mtx( ed_r* r );
|
void ed_calc_mtx( ed_r* r );
|
||||||
|
|
||||||
// Traverse the possible alignments in the DP matrix and determine the optimal alignment.
|
// Traverse the possible alignments in the DP matrix and determine the optimal alignment.
|
||||||
void ed_align( ed_r* r );
|
void ed_align( ed_r* r );
|
||||||
|
|
||||||
// Print the optimal alignment p_opt[]
|
// Print the optimal alignment p_opt[]
|
||||||
void ed_print_opt( ed_r* r );
|
void ed_print_opt( ed_r* r );
|
||||||
|
|
||||||
// Free resource allocated by ed_init().
|
// Free resource allocated by ed_init().
|
||||||
void ed_free(ed_r* r);
|
void ed_free(ed_r* r);
|
||||||
|
|
||||||
// Main test function.
|
// Main test function.
|
||||||
void ed_main();
|
void ed_main();
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kSmMinIdx, //
|
kSmMinIdx, //
|
||||||
kSmSubIdx, // 'substitute' - may or may not match
|
kSmSubIdx, // 'substitute' - may or may not match
|
||||||
kSmDelIdx, // 'delete' - delete a MIDI note
|
kSmDelIdx, // 'delete' - delete a MIDI note
|
||||||
kSmInsIdx, // 'insert' - insert a space in the score
|
kSmInsIdx, // 'insert' - insert a space in the score
|
||||||
kSmCnt
|
kSmCnt
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kSmMatchFl = 0x01,
|
kSmMatchFl = 0x01,
|
||||||
kSmTransFl = 0x02,
|
kSmTransFl = 0x02,
|
||||||
kSmTruePosFl = 0x04,
|
kSmTruePosFl = 0x04,
|
||||||
kSmFalsePosFl = 0x08,
|
kSmFalsePosFl = 0x08,
|
||||||
kSmBarFl = 0x10,
|
kSmBarFl = 0x10,
|
||||||
kSmNoteFl = 0x20
|
kSmNoteFl = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dynamic Programming (DP) matrix element
|
// Dynamic Programming (DP) matrix element
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned v[kSmCnt]; // cost for each operation
|
unsigned v[kSmCnt]; // cost for each operation
|
||||||
unsigned flags; // cmSmMatchFl | cmSmTransFl
|
unsigned flags; // cmSmMatchFl | cmSmTransFl
|
||||||
unsigned scEvtIdx;
|
unsigned scEvtIdx;
|
||||||
} cmScMatchVal_t;
|
} cmScMatchVal_t;
|
||||||
|
|
||||||
// List record used to track a path through the DP matrix p->m[,]
|
// List record used to track a path through the DP matrix p->m[,]
|
||||||
typedef struct cmScMatchPath_str
|
typedef struct cmScMatchPath_str
|
||||||
{
|
{
|
||||||
unsigned code; // kSmXXXIdx
|
unsigned code; // kSmXXXIdx
|
||||||
unsigned ri; // matrix row index
|
unsigned ri; // matrix row index
|
||||||
unsigned ci; // matrix col index
|
unsigned ci; // matrix col index
|
||||||
@ -233,22 +233,22 @@ typedef struct cmScMatchPath_str
|
|||||||
unsigned locIdx; // p->loc index or cmInvalidIdx
|
unsigned locIdx; // p->loc index or cmInvalidIdx
|
||||||
unsigned scEvtIdx; // scScore event index
|
unsigned scEvtIdx; // scScore event index
|
||||||
struct cmScMatchPath_str* next; //
|
struct cmScMatchPath_str* next; //
|
||||||
} cmScMatchPath_t;
|
} cmScMatchPath_t;
|
||||||
|
|
||||||
typedef struct cmScMatchEvt_str
|
typedef struct cmScMatchEvt_str
|
||||||
{
|
{
|
||||||
unsigned pitch; //
|
unsigned pitch; //
|
||||||
unsigned scEvtIdx; // scScore event index
|
unsigned scEvtIdx; // scScore event index
|
||||||
} cmScMatchEvt_t;
|
} cmScMatchEvt_t;
|
||||||
|
|
||||||
// Score location record.
|
// Score location record.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned evtCnt; //
|
unsigned evtCnt; //
|
||||||
cmScMatchEvt_t* evtV; // evtV[evtCnt]
|
cmScMatchEvt_t* evtV; // evtV[evtCnt]
|
||||||
unsigned scLocIdx; // scH score location index
|
unsigned scLocIdx; // scH score location index
|
||||||
int barNumb; // bar number of this location
|
int barNumb; // bar number of this location
|
||||||
} cmScMatchLoc_t;
|
} cmScMatchLoc_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -260,8 +260,8 @@ typedef struct
|
|||||||
unsigned scEvtIdx; // cmScore event index assoc'd with this event
|
unsigned scEvtIdx; // cmScore event index assoc'd with this event
|
||||||
} cmScMatchMidi_t;
|
} cmScMatchMidi_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmObj obj; //
|
cmObj obj; //
|
||||||
cmScH_t scH; // cmScore handle
|
cmScH_t scH; // cmScore handle
|
||||||
unsigned locN; //
|
unsigned locN; //
|
||||||
@ -279,33 +279,33 @@ typedef struct
|
|||||||
cmScMatchPath_t* p_cur; // current path linked list
|
cmScMatchPath_t* p_cur; // current path linked list
|
||||||
cmScMatchPath_t* p_opt; // p_opt[pn] - current best alignment as a linked list
|
cmScMatchPath_t* p_opt; // p_opt[pn] - current best alignment as a linked list
|
||||||
double opt_cost; // last p_opt cost set by cmScMatchExec()
|
double opt_cost; // last p_opt cost set by cmScMatchExec()
|
||||||
} cmScMatch;
|
} cmScMatch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1) This matcher cannot handle multiple instances of the same pitch occuring
|
1) This matcher cannot handle multiple instances of the same pitch occuring
|
||||||
at the same 'location'.
|
at the same 'location'.
|
||||||
|
|
||||||
2) Because each note of a chord is spread out over multiple locations, and
|
2) Because each note of a chord is spread out over multiple locations, and
|
||||||
there is no way to indicate that a note in the chord is already 'in-use'.
|
there is no way to indicate that a note in the chord is already 'in-use'.
|
||||||
If a MIDI note which is part of the chord is repeated, in error, it will
|
If a MIDI note which is part of the chord is repeated, in error, it will
|
||||||
apear to be correct (a positive match will be assigned to
|
apear to be correct (a positive match will be assigned to
|
||||||
the second (and possible successive notes)).
|
the second (and possible successive notes)).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cmScMatch* cmScMatchAlloc( cmCtx* c, cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
cmScMatch* cmScMatchAlloc( cmCtx* c, cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
||||||
cmRC_t cmScMatchFree( cmScMatch** pp );
|
cmRC_t cmScMatchFree( cmScMatch** pp );
|
||||||
cmRC_t cmScMatchInit( cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
cmRC_t cmScMatchInit( cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
||||||
cmRC_t cmScMatchFinal( cmScMatch* p );
|
cmRC_t cmScMatchFinal( cmScMatch* p );
|
||||||
|
|
||||||
// Locate the position in p->loc[locIdx:locIdx+locN-1] which bests
|
// Locate the position in p->loc[locIdx:locIdx+locN-1] which bests
|
||||||
// matches midiV[midiN].
|
// matches midiV[midiN].
|
||||||
// The result of this function is to update p_opt[]
|
// The result of this function is to update p_opt[]
|
||||||
// The optimal path p_opt[] will only be updated if the edit_cost associated 'midiV[midiN]'.
|
// The optimal path p_opt[] will only be updated if the edit_cost associated 'midiV[midiN]'.
|
||||||
// with the best match is less than 'min_cost'.
|
// with the best match is less than 'min_cost'.
|
||||||
// Set 'min_cost' to DBL_MAX to force p_opt[] to be updated.
|
// Set 'min_cost' to DBL_MAX to force p_opt[] to be updated.
|
||||||
// Returns cmEofRC if locIdx + locN > p->locN - note that this is not
|
// Returns cmEofRC if locIdx + locN > p->locN - note that this is not
|
||||||
// necessarily an error.
|
// necessarily an error.
|
||||||
cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost );
|
cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
|
||||||
@ -321,8 +321,8 @@ cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const c
|
|||||||
unsigned flags;
|
unsigned flags;
|
||||||
} cmScMatcherResult_t;
|
} cmScMatcherResult_t;
|
||||||
|
|
||||||
struct cmScMatcher_str;
|
struct cmScMatcher_str;
|
||||||
typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatcherResult_t* rp );
|
typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatcherResult_t* rp );
|
||||||
|
|
||||||
typedef struct cmScMatcher_str
|
typedef struct cmScMatcher_str
|
||||||
{
|
{
|
||||||
@ -350,73 +350,74 @@ typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatch
|
|||||||
unsigned scanCnt; // current count of times a resync-scan was executed during cmScMatcherStep()
|
unsigned scanCnt; // current count of times a resync-scan was executed during cmScMatcherStep()
|
||||||
|
|
||||||
bool printFl;
|
bool printFl;
|
||||||
} cmScMatcher;
|
} cmScMatcher;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cmScMatcher* cmScMatcherAlloc(
|
cmScMatcher* cmScMatcherAlloc(
|
||||||
cmCtx* c, // Program context.
|
cmCtx* c, // Program context.
|
||||||
cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher.
|
cmScMatcher* p, // Existing cmScMatcher to reallocate or NULL to allocate a new cmScMatcher.
|
||||||
double srate, // System sample rate.
|
double srate, // System sample rate.
|
||||||
cmScH_t scH, // Score handle. See cmScore.h.
|
cmScH_t scH, // Score handle. See cmScore.h.
|
||||||
unsigned scWndN, // Length of the scores active search area. ** See Note.
|
unsigned scWndN, // Length of the scores active search area. ** See Notes.
|
||||||
unsigned midiWndN, // Length of the MIDI active note buffer. ** See Note.
|
unsigned midiWndN, // Length of the MIDI active note buffer. ** See Notes.
|
||||||
cmScMatcherCb_t cbFunc, // A cmScMatcherCb_t function to be called to notify the recipient of changes in the score matcher status.
|
cmScMatcherCb_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'.
|
void* cbArg ); // User argument to 'cbFunc'.
|
||||||
|
|
||||||
// The cmScMatcher maintains an internal cmScMatch object which is used to attempt to find the
|
// Notes:
|
||||||
// best match between the current MIDI active note buffer and the current score search area.
|
// The cmScMatcher maintains an internal cmScMatch object which is used to attempt to find the
|
||||||
// 'scWndN' is used to set the cmScMatch 'locN' argument.
|
// best match between the current MIDI active note buffer and the current score search area.
|
||||||
// 'midiWndN' sets the length of the MIDI FIFO which is used to match to the score with
|
// 'scWndN' is used to set the cmScMatch 'locN' argument.
|
||||||
// each recceived MIDI note.
|
// 'midiWndN' sets the length of the MIDI FIFO which is used to match to the score with
|
||||||
// 'midiWndN' must be <= 'scWndN'.
|
// each recceived MIDI note.
|
||||||
|
// 'midiWndN' must be <= 'scWndN'.
|
||||||
|
|
||||||
cmRC_t cmScMatcherFree( cmScMatcher** pp );
|
cmRC_t cmScMatcherFree( cmScMatcher** pp );
|
||||||
cmRC_t cmScMatcherInit( cmScMatcher* p, double srate, cmScH_t scH, unsigned scWndN, unsigned midiWndN, cmScMatcherCb_t cbFunc, void* cbArg );
|
cmRC_t cmScMatcherInit( cmScMatcher* p, double srate, cmScH_t scH, unsigned scWndN, unsigned midiWndN, cmScMatcherCb_t cbFunc, void* cbArg );
|
||||||
cmRC_t cmScMatcherFinal( cmScMatcher* p );
|
cmRC_t cmScMatcherFinal( cmScMatcher* p );
|
||||||
|
|
||||||
// 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[].
|
// 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[].
|
||||||
cmRC_t cmScMatcherReset( cmScMatcher* p, unsigned scLocIdx );
|
cmRC_t cmScMatcherReset( cmScMatcher* p, unsigned scLocIdx );
|
||||||
|
|
||||||
// Slide a score window 'hopCnt' times, beginning at 'bli' (an
|
// Slide a score window 'hopCnt' times, beginning at 'bli' (an
|
||||||
// index int p->mp->loc[]) looking for the best match to p->midiBuf[].
|
// index int p->mp->loc[]) looking for the best match to p->midiBuf[].
|
||||||
// The score window contain scWndN (p->mp->mcn-1) score locations.
|
// The score window contain scWndN (p->mp->mcn-1) score locations.
|
||||||
// Returns the index into p->mp->loc[] of the start of the best
|
// Returns the index into p->mp->loc[] of the start of the best
|
||||||
// match score window. The score associated
|
// match score window. The score associated
|
||||||
// with this match is stored in s_opt.
|
// with this match is stored in s_opt.
|
||||||
unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt );
|
unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt );
|
||||||
|
|
||||||
// Step forward/back by p->stepCnt from p->eli.
|
// Step forward/back by p->stepCnt from p->eli.
|
||||||
// p->eli must therefore be valid prior to calling this function.
|
// p->eli must therefore be valid prior to calling this function.
|
||||||
// If more than p->maxMissCnt consecutive MIDI events are
|
// If more than p->maxMissCnt consecutive MIDI events are
|
||||||
// missed then automatically run cmScAlignScan().
|
// missed then automatically run cmScAlignScan().
|
||||||
// Return cmEofRC if the end of the score is encountered.
|
// Return cmEofRC if the end of the score is encountered.
|
||||||
// Return cmSubSysFailRC if an internal scan resync. failed.
|
// Return cmSubSysFailRC if an internal scan resync. failed.
|
||||||
cmRC_t cmScMatcherStep( cmScMatcher* p );
|
cmRC_t cmScMatcherStep( cmScMatcher* p );
|
||||||
|
|
||||||
// This function calls cmScMatcherScan() and cmScMatcherStep() internally.
|
// This function calls cmScMatcherScan() and cmScMatcherStep() internally.
|
||||||
// If 'status' is not kNonMidiMdId then the function returns without changing the
|
// If 'status' is not kNonMidiMdId then the function returns without changing the
|
||||||
// state of the object.
|
// 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
|
// 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
|
// 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
|
// match, the MIDI note in p->midiBuf[] associated with this match
|
||||||
// will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr
|
// will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr
|
||||||
// will be set with the matched scLocIdx of the match.
|
// will be set with the matched scLocIdx of the match.
|
||||||
// If this call does not result in a successful match *scLocIdxPtr is set
|
// If this call does not result in a successful match *scLocIdxPtr is set
|
||||||
// to cmInvalidIdx.
|
// to cmInvalidIdx.
|
||||||
// Return:
|
// Return:
|
||||||
// cmOkRC - Continue processing MIDI events.
|
// cmOkRC - Continue processing MIDI events.
|
||||||
// cmEofRC - The end of the score was encountered.
|
// cmEofRC - The end of the score was encountered.
|
||||||
// cmInvalidArgRC - scan failed or the object was in an invalid state to attempt a match.
|
// cmInvalidArgRC - scan failed or the object was in an invalid state to attempt a match.
|
||||||
// cmSubSysFailRC - a scan resync failed in cmScMatcherStep().
|
// cmSubSysFailRC - a scan resync failed in cmScMatcherStep().
|
||||||
cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1, unsigned* scLocIdxPtr );
|
cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1, unsigned* scLocIdxPtr );
|
||||||
|
|
||||||
void cmScMatcherPrint( cmScMatcher* p );
|
void cmScMatcherPrint( cmScMatcher* p );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmScoreSet_t* sp; // ptr to this set in the score
|
cmScoreSet_t* sp; // ptr to this set in the score
|
||||||
|
|
||||||
unsigned bsei; // begin score event index
|
unsigned bsei; // begin score event index
|
||||||
@ -433,10 +434,10 @@ typedef struct
|
|||||||
double match_cost; // cost of the match to the performance divided by sp->eleCnt
|
double match_cost; // cost of the match to the performance divided by sp->eleCnt
|
||||||
|
|
||||||
|
|
||||||
} cmScMeasSet_t;
|
} cmScMeasSet_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmObj obj;
|
cmObj obj;
|
||||||
double srate; //
|
double srate; //
|
||||||
cmScMatch* mp; //
|
cmScMatch* mp; //
|
||||||
@ -455,48 +456,48 @@ typedef struct
|
|||||||
|
|
||||||
unsigned vsi; // set[vsi:nsi-1] indicates sets with new values following a call to cmScMeasExec()
|
unsigned vsi; // set[vsi:nsi-1] indicates sets with new values following a call to cmScMeasExec()
|
||||||
unsigned vsli; // vsli:nsli-1 indicates cmScore loc's to check for section triggers following a call to cmScMeasExec()
|
unsigned vsli; // vsli:nsli-1 indicates cmScore loc's to check for section triggers following a call to cmScMeasExec()
|
||||||
} cmScMeas;
|
} cmScMeas;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Notes:
|
// Notes:
|
||||||
//
|
//
|
||||||
// 1) midiBuf[] stores all MIDI notes for the duration of the performance
|
// 1) midiBuf[] stores all MIDI notes for the duration of the performance
|
||||||
// it is initialized to 2*score_event_count.
|
// it is initialized to 2*score_event_count.
|
||||||
//
|
//
|
||||||
// 2) dynRef[] is the gives the MIDI velocity range for each dynamics
|
// 2) dynRef[] is the gives the MIDI velocity range for each dynamics
|
||||||
// category: pppp-fff
|
// category: pppp-fff
|
||||||
//
|
//
|
||||||
// 3) See a cmDspKr.c _cmScFolMatcherCb() for an example of how
|
// 3) See a cmDspKr.c _cmScFolMatcherCb() for an example of how
|
||||||
// cmScMeas.vsi and cmScMeas.vsli are used to act on the results of
|
// cmScMeas.vsi and cmScMeas.vsli are used to act on the results of
|
||||||
// a call to cmMeasExec().
|
// a call to cmMeasExec().
|
||||||
|
|
||||||
cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
||||||
cmRC_t cmScMeasFree( cmScMeas** pp );
|
cmRC_t cmScMeasFree( cmScMeas** pp );
|
||||||
cmRC_t cmScMeasInit( cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
cmRC_t cmScMeasInit( cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
||||||
cmRC_t cmScMeasFinal( cmScMeas* p );
|
cmRC_t cmScMeasFinal( cmScMeas* p );
|
||||||
|
|
||||||
// Empty MIDI buffer and set the next set nsi and nsli to zero.
|
// Empty MIDI buffer and set the next set nsi and nsli to zero.
|
||||||
cmRC_t cmScMeasReset( cmScMeas* p );
|
cmRC_t cmScMeasReset( cmScMeas* p );
|
||||||
|
|
||||||
// This function is called for each input MIDI note which is assigned a
|
// This function is called for each input MIDI note which is assigned a
|
||||||
// score location by cmScMatcher.
|
// score location by cmScMatcher.
|
||||||
// 'mni' is the MIDI event index which uniquely identifies this MIDI event.
|
// 'mni' is the MIDI event index which uniquely identifies this MIDI event.
|
||||||
// 'locIdx' is the location index into cmScMatcher.mp->loc[] associated with
|
// 'locIdx' is the location index into cmScMatcher.mp->loc[] associated with
|
||||||
// this event.
|
// this event.
|
||||||
cmRC_t cmScMeasExec( cmScMeas* p, unsigned mni, unsigned locIdx, unsigned scEvtIdx, unsigned flags, unsigned smpIdx, unsigned pitch, unsigned vel );
|
cmRC_t cmScMeasExec( cmScMeas* p, unsigned mni, unsigned locIdx, unsigned scEvtIdx, unsigned flags, unsigned smpIdx, unsigned pitch, unsigned vel );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
|
||||||
unsigned cmScAlignScanToTimeLineEvent( cmScMatcher* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
|
unsigned cmScAlignScanToTimeLineEvent( cmScMatcher* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
|
||||||
|
|
||||||
// Given a score, a time-line, and a marker on the time line scan the
|
// Given a score, a time-line, and a marker on the time line scan the
|
||||||
// entire score looking for the best match between the first 'midiN'
|
// entire score looking for the best match between the first 'midiN'
|
||||||
// notes in each marker region and the score.
|
// notes in each marker region and the score.
|
||||||
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
|
void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
/*
|
/*
|
||||||
Syntax: <loc> <mod> <var> <type> <params>
|
Syntax: <loc> <mod> <var> <type> <params>
|
||||||
<loc> - score location
|
<loc> - score location
|
||||||
<mod> - name of the modulator
|
<mod> - name of the modulator
|
||||||
<var> - variable name
|
<var> - variable name
|
||||||
@ -514,46 +515,46 @@ Syntax: <loc> <mod> <var> <type> <params>
|
|||||||
The value of parameters may be literal numeric values or may refer to
|
The value of parameters may be literal numeric values or may refer to
|
||||||
variables by their name.
|
variables by their name.
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
set = set <var> to <val> which may be a literal or another variable.
|
set = set <var> to <val> which may be a literal or another variable.
|
||||||
line = ramp from its current value to <val> over <dur> seconds
|
line = ramp from its current value to <val> over <dur> seconds
|
||||||
sline = set <var> to <val> and ramp to <end> over <dur> seconds
|
sline = set <var> to <val> and ramp to <end> over <dur> seconds
|
||||||
post = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg)
|
post = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kInvalidModTId,
|
kInvalidModTId,
|
||||||
kSetModTId, // set variable to parray[0] at scLocIdx
|
kSetModTId, // set variable to parray[0] at scLocIdx
|
||||||
kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds
|
kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds
|
||||||
kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
|
kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
|
||||||
kPostModTId, //
|
kPostModTId, //
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kActiveModFl = 0x01, // this variable is on the 'active' list
|
kActiveModFl = 0x01, // this variable is on the 'active' list
|
||||||
kCalcModFl = 0x02 // when this variable is used as a parameter it's value must be calculated rather than used directly.
|
kCalcModFl = 0x02 // when this variable is used as a parameter it's value must be calculated rather than used directly.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmScModEntry_str;
|
struct cmScModEntry_str;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
kInvalidModPId,
|
kInvalidModPId,
|
||||||
kLiteralModPId, // this is a literal value
|
kLiteralModPId, // this is a literal value
|
||||||
kSymbolModPId //
|
kSymbolModPId //
|
||||||
} cmScModPId_t;
|
} cmScModPId_t;
|
||||||
|
|
||||||
typedef struct cmScModParam_str
|
typedef struct cmScModParam_str
|
||||||
{
|
{
|
||||||
cmScModPId_t pid; // parameter type: literal or symbol
|
cmScModPId_t pid; // parameter type: literal or symbol
|
||||||
unsigned symId; // symbol of external and internal variables
|
unsigned symId; // symbol of external and internal variables
|
||||||
double val; // value of literals
|
double val; // value of literals
|
||||||
} cmScModParam_t;
|
} cmScModParam_t;
|
||||||
|
|
||||||
typedef struct cmScModVar_str
|
typedef struct cmScModVar_str
|
||||||
{
|
{
|
||||||
unsigned flags; // see kXXXModFl flags above.
|
unsigned flags; // see kXXXModFl flags above.
|
||||||
unsigned varSymId; // variable name
|
unsigned varSymId; // variable name
|
||||||
unsigned outVarId; // output var id
|
unsigned outVarId; // output var id
|
||||||
@ -566,14 +567,14 @@ typedef struct cmScModVar_str
|
|||||||
struct cmScModEntry_str* entry; // last entry assoc'd with this value
|
struct cmScModEntry_str* entry; // last entry assoc'd with this value
|
||||||
struct cmScModVar_str* vlink; // p->vlist link
|
struct cmScModVar_str* vlink; // p->vlist link
|
||||||
struct cmScModVar_str* alink; // p->alist link
|
struct cmScModVar_str* alink; // p->alist link
|
||||||
} cmScModVar_t;
|
} cmScModVar_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Each entry gives a time tagged location and some parameters
|
// Each entry gives a time tagged location and some parameters
|
||||||
// for an algorthm which is used to set/modulate a value.
|
// for an algorthm which is used to set/modulate a value.
|
||||||
typedef struct cmScModEntry_str
|
typedef struct cmScModEntry_str
|
||||||
{
|
{
|
||||||
unsigned scLocIdx; // entry start time
|
unsigned scLocIdx; // entry start time
|
||||||
unsigned typeId; // variable type
|
unsigned typeId; // variable type
|
||||||
cmScModParam_t beg; // parameter values
|
cmScModParam_t beg; // parameter values
|
||||||
@ -583,12 +584,12 @@ typedef struct cmScModEntry_str
|
|||||||
cmScModParam_t max; // max value for this variable
|
cmScModParam_t max; // max value for this variable
|
||||||
cmScModParam_t rate; // update rate in milliseconds (DBL_MAX to disable)
|
cmScModParam_t rate; // update rate in milliseconds (DBL_MAX to disable)
|
||||||
cmScModVar_t* varPtr; // target variable
|
cmScModVar_t* varPtr; // target variable
|
||||||
} cmScModEntry_t;
|
} cmScModEntry_t;
|
||||||
|
|
||||||
typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value, bool postFl );
|
typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value, bool postFl );
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmObj obj;
|
cmObj obj;
|
||||||
cmChar_t* fn; // modulator score file
|
cmChar_t* fn; // modulator score file
|
||||||
unsigned modSymId; // modulator name
|
unsigned modSymId; // modulator name
|
||||||
@ -605,25 +606,25 @@ typedef struct
|
|||||||
unsigned nei; // next entry index
|
unsigned nei; // next entry index
|
||||||
unsigned outVarCnt; // count of unique vars that are targets of entry recds
|
unsigned outVarCnt; // count of unique vars that are targets of entry recds
|
||||||
bool postFl; // send a 'post' msg after each transmission
|
bool postFl; // send a 'post' msg after each transmission
|
||||||
} cmScModulator;
|
} cmScModulator;
|
||||||
|
|
||||||
|
|
||||||
cmScModulator* cmScModulatorAlloc( cmCtx* c, cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
|
cmScModulator* cmScModulatorAlloc( cmCtx* c, cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
|
||||||
cmRC_t cmScModulatorFree( cmScModulator** pp );
|
cmRC_t cmScModulatorFree( cmScModulator** pp );
|
||||||
cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
|
cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
|
||||||
cmRC_t cmScModulatorFinal( cmScModulator* p );
|
cmRC_t cmScModulatorFinal( cmScModulator* p );
|
||||||
|
|
||||||
// Return count of variables.
|
// Return count of variables.
|
||||||
unsigned cmScModulatorOutVarCount( cmScModulator* p );
|
unsigned cmScModulatorOutVarCount( cmScModulator* p );
|
||||||
|
|
||||||
// Return a pointer to the variable at vlist[idx].
|
// Return a pointer to the variable at vlist[idx].
|
||||||
cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx );
|
cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx );
|
||||||
|
|
||||||
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max );
|
cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max );
|
||||||
|
|
||||||
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx );
|
cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx );
|
||||||
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
|
cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
|
||||||
cmRC_t cmScModulatorDump( cmScModulator* p );
|
cmRC_t cmScModulatorDump( cmScModulator* p );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user