|
@@ -131,11 +131,11 @@ typedef struct
|
131
|
131
|
|
132
|
132
|
typedef struct ed_path_str
|
133
|
133
|
{
|
134
|
|
- unsigned code;
|
135
|
|
- unsigned ri;
|
136
|
|
- unsigned ci;
|
137
|
|
- bool matchFl;
|
138
|
|
- bool transFl;
|
|
134
|
+ unsigned code;
|
|
135
|
+ unsigned ri;
|
|
136
|
+ unsigned ci;
|
|
137
|
+ bool matchFl;
|
|
138
|
+ bool transFl;
|
139
|
139
|
struct ed_path_str* next;
|
140
|
140
|
} ed_path;
|
141
|
141
|
|
|
@@ -222,17 +222,19 @@ typedef struct
|
222
|
222
|
{
|
223
|
223
|
unsigned v[kSmCnt]; // cost for each operation
|
224
|
224
|
unsigned flags; // cmSmMatchFl | cmSmTransFl
|
|
225
|
+ unsigned scEvtIdx;
|
225
|
226
|
} cmScMatchVal_t;
|
226
|
227
|
|
227
|
228
|
// List record used to track a path through the DP matrix p->m[,]
|
228
|
229
|
typedef struct cmScMatchPath_str
|
229
|
230
|
{
|
230
|
|
- unsigned code; // kSmXXXIdx
|
231
|
|
- unsigned ri; // matrix row index
|
232
|
|
- unsigned ci; // matrix col index
|
233
|
|
- unsigned flags; // cmSmMatchFl | cmSmTransFl
|
234
|
|
- unsigned locIdx; // p->loc index or cmInvalidIdx
|
235
|
|
- struct cmScMatchPath_str* next; //
|
|
231
|
+ unsigned code; // kSmXXXIdx
|
|
232
|
+ unsigned ri; // matrix row index
|
|
233
|
+ unsigned ci; // matrix col index
|
|
234
|
+ unsigned flags; // cmSmMatchFl | cmSmTransFl
|
|
235
|
+ unsigned locIdx; // p->loc index or cmInvalidIdx
|
|
236
|
+ unsigned scEvtIdx; // scScore event index
|
|
237
|
+ struct cmScMatchPath_str* next; //
|
236
|
238
|
} cmScMatchPath_t;
|
237
|
239
|
|
238
|
240
|
typedef struct cmScMatchEvt_str
|
|
@@ -250,52 +252,70 @@ typedef struct
|
250
|
252
|
int barNumb; // bar number of this location
|
251
|
253
|
} cmScMatchLoc_t;
|
252
|
254
|
|
|
255
|
+ typedef struct
|
|
256
|
+ {
|
|
257
|
+ unsigned mni; // unique identifier for this MIDI note - used to recognize when the cmScMatcher backtracks.
|
|
258
|
+ unsigned smpIdx; // time stamp of this event
|
|
259
|
+ unsigned pitch; // MIDI note pitch
|
|
260
|
+ unsigned vel; // " " velocity
|
|
261
|
+ unsigned locIdx; // location assoc'd with this MIDI evt (cmInvalidIdx if not a matching or non-matching 'substitute')
|
|
262
|
+ unsigned scEvtIdx; // cmScore event index assoc'd with this event
|
|
263
|
+ } cmScMatchMidi_t;
|
|
264
|
+
|
253
|
265
|
typedef struct
|
254
|
266
|
{
|
255
|
267
|
cmObj obj; //
|
256
|
268
|
cmScH_t scH; // cmScore handle
|
257
|
269
|
unsigned locN; //
|
258
|
270
|
cmScMatchLoc_t* loc; // loc[locN]
|
259
|
|
- unsigned mrn; // max row count (midi)
|
260
|
|
- unsigned rn; // cur row count
|
261
|
|
- unsigned mcn; // max column count (score)
|
262
|
|
- unsigned cn; // cur column count
|
|
271
|
+ unsigned mrn; // max m[] row count (midi)
|
|
272
|
+ unsigned rn; // cur m[] row count
|
|
273
|
+ unsigned mcn; // max m[] column count (score)
|
|
274
|
+ unsigned cn; // cur m[] column count
|
263
|
275
|
unsigned mmn; // max length of midiBuf[] (mrn-1)
|
264
|
276
|
unsigned msn; // max length of score window (mcn-1)
|
265
|
277
|
cmScMatchVal_t* m; // m[mrn,mcn] DP matrix
|
266
|
278
|
unsigned pn; // mrn+mcn
|
267
|
|
- cmScMatchPath_t* p_mem; // pmem[ 2*pn ];
|
|
279
|
+ cmScMatchPath_t* p_mem; // pmem[ 2*pn ] - path memory
|
268
|
280
|
cmScMatchPath_t* p_avl; // available path record linked list
|
269
|
281
|
cmScMatchPath_t* p_cur; // current path linked list
|
270
|
|
- cmScMatchPath_t* p_opt; // p_opt[pn] current best alignment
|
271
|
|
- double opt_cost; // p_opt cost set by cmScMatchExec()
|
|
282
|
+ cmScMatchPath_t* p_opt; // p_opt[pn] - current best alignment as a linked list
|
|
283
|
+ double opt_cost; // last p_opt cost set by cmScMatchExec()
|
272
|
284
|
} cmScMatch;
|
273
|
285
|
|
|
286
|
+/*
|
|
287
|
+1) This matcher cannot handle multiple instances of the same pitch occuring
|
|
288
|
+at the same 'location'.
|
|
289
|
+
|
|
290
|
+2) Because each note of a chord is spread out over multiple locations, and
|
|
291
|
+there is no way to indicate that a note in the chord is already 'in-use'.
|
|
292
|
+If a MIDI note which is part of the chord is repeated, in error, it will
|
|
293
|
+apear to be correct (a positive match will be assigned to
|
|
294
|
+the second (and possible successive notes)).
|
|
295
|
+ */
|
|
296
|
+
|
274
|
297
|
cmScMatch* cmScMatchAlloc( cmCtx* c, cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
275
|
298
|
cmRC_t cmScMatchFree( cmScMatch** pp );
|
276
|
299
|
cmRC_t cmScMatchInit( cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
|
277
|
300
|
cmRC_t cmScMatchFinal( cmScMatch* p );
|
278
|
301
|
|
279
|
|
-// Returns cmEofRC if locIdx + locN > p->locN - note that this is not necessarily an error.
|
280
|
|
-// The optimal path p_opt[] will only be updated if the edit cost is less than min_cost.
|
281
|
|
-// Set min_cost to DBL_MAX to force p_opt[] to be updated.
|
282
|
|
-cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const unsigned* midiPitchV, unsigned midiPitchN, double min_cost );
|
|
302
|
+// Locate the position in p->loc[locIdx:locIdx+locN-1] which bests
|
|
303
|
+// matches midiV[midiN].
|
|
304
|
+// The result of this function is to update p_opt[]
|
|
305
|
+// The optimal path p_opt[] will only be updated if the edit_cost associated 'midiV[midiN]'.
|
|
306
|
+// with the best match is less than 'min_cost'.
|
|
307
|
+// Set 'min_cost' to DBL_MAX to force p_opt[] to be updated.
|
|
308
|
+// Returns cmEofRC if locIdx + locN > p->locN - note that this is not
|
|
309
|
+// necessarily an error.
|
|
310
|
+cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost );
|
283
|
311
|
|
284
|
312
|
//=======================================================================================================================
|
285
|
313
|
|
286
|
|
- typedef struct
|
287
|
|
- {
|
288
|
|
- unsigned locIdx; // location assoc'd with this MIDI evt (cmInvalidIdx if not a positive-match)
|
289
|
|
- //unsigned cbCnt; // count of times this event has been sent via the callback
|
290
|
|
- unsigned mni; // unique identifier for this event since previous call to cmScAlignReset().
|
291
|
|
- unsigned smpIdx; // time stamp of this event
|
292
|
|
- unsigned pitch; // MIDI note pitch
|
293
|
|
- unsigned vel; // " " velocity
|
294
|
|
- } cmScMatcherMidi_t;
|
295
|
314
|
|
296
|
315
|
typedef struct
|
297
|
316
|
{
|
298
|
317
|
unsigned locIdx;
|
|
318
|
+ unsigned scEvtIdx;
|
299
|
319
|
unsigned mni;
|
300
|
320
|
unsigned smpIdx;
|
301
|
321
|
unsigned pitch;
|
|
@@ -313,7 +333,7 @@ typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatch
|
313
|
333
|
void* cbArg;
|
314
|
334
|
cmScMatch* mp;
|
315
|
335
|
unsigned mn;
|
316
|
|
- cmScMatcherMidi_t* midiBuf; // midiBuf[mn]
|
|
336
|
+ cmScMatchMidi_t* midiBuf; // midiBuf[mn]
|
317
|
337
|
|
318
|
338
|
cmScMatcherResult_t* res; // res[rn]
|
319
|
339
|
unsigned rn; // length of res[]
|
|
@@ -362,24 +382,15 @@ cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, c
|
362
|
382
|
|
363
|
383
|
typedef struct
|
364
|
384
|
{
|
365
|
|
- unsigned mni;
|
366
|
|
- unsigned scEvtIdx;
|
367
|
|
- unsigned locIdx;
|
368
|
|
- unsigned smpIdx;
|
369
|
|
- unsigned pitch;
|
370
|
|
- unsigned vel;
|
371
|
|
-} cmScMeasMidi_t;
|
372
|
|
-
|
|
385
|
+ cmScoreSet_t* sp; // ptr to this set in the score
|
373
|
386
|
|
374
|
|
-typedef struct
|
375
|
|
-{
|
376
|
387
|
unsigned bsei; // begin score event index
|
377
|
388
|
unsigned esei; // end score event index
|
378
|
389
|
|
379
|
|
- unsigned bsli; //
|
|
390
|
+ unsigned bsli; // beg score loc index
|
380
|
391
|
unsigned esli; // end score loc index
|
381
|
392
|
|
382
|
|
- unsigned bli; //
|
|
393
|
+ unsigned bli; //
|
383
|
394
|
unsigned eli; //
|
384
|
395
|
|
385
|
396
|
} cmScMeasSet_t;
|
|
@@ -387,25 +398,42 @@ typedef struct
|
387
|
398
|
typedef struct
|
388
|
399
|
{
|
389
|
400
|
cmObj obj;
|
390
|
|
- cmScMatch* mp;
|
391
|
|
- unsigned mi; // next avail recd in midiBuf[]
|
|
401
|
+ cmScMatch* mp; //
|
|
402
|
+ unsigned mii; // next avail recd in midiBuf[]
|
392
|
403
|
unsigned mn; // length of of midiBuf[]
|
393
|
|
- cmScMeasMidi_t* midiBuf; // midiBuf[mn]
|
|
404
|
+ cmScMatchMidi_t* midiBuf; // midiBuf[mn]
|
394
|
405
|
|
395
|
406
|
unsigned sn; // length of set[]
|
396
|
407
|
cmScMeasSet_t* set; // set[sn]
|
397
|
408
|
|
|
409
|
+ unsigned dn; // length of dynRef[]
|
|
410
|
+ unsigned* dynRef; // dynRef[dn]
|
|
411
|
+
|
398
|
412
|
unsigned nsi; // next set index
|
399
|
413
|
unsigned nsli; // next score location index
|
400
|
414
|
|
401
|
|
-
|
|
415
|
+ double srate; // sample rate from schore
|
402
|
416
|
} cmScMeas;
|
403
|
417
|
|
404
|
|
-cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, cmScH_t scH );
|
|
418
|
+// Notes:
|
|
419
|
+// 1) midiBuf[] stores all MIDI notes for the duration of the performance
|
|
420
|
+// it is initialized to 2*score_event_count.
|
|
421
|
+// 2) dynRef][ is the gives the MIDI velocity range for each dynamics
|
|
422
|
+// category: pppp-fff
|
|
423
|
+//
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
405
|
427
|
cmRC_t cmScMeasFree( cmScMeas** pp );
|
406
|
|
-cmRC_t cmScMeasInit( cmScMeas* p, cmScH_t scH );
|
|
428
|
+cmRC_t cmScMeasInit( cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
|
407
|
429
|
cmRC_t cmScMeasFinal( cmScMeas* p );
|
408
|
|
-cmRC_t cmScMeasExec( cmScMeas* p, unsigned mni, unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
|
|
430
|
+
|
|
431
|
+// This function is called for each input MIDI note which is assigned a
|
|
432
|
+// score location by cmScMatcher.
|
|
433
|
+// 'mni' is the MIDI event index which uniquely identifies this MIDI event.
|
|
434
|
+// 'locIdx' is the location index into cmScMatcher.mp->loc[] associated with
|
|
435
|
+// this event.
|
|
436
|
+cmRC_t cmScMeasExec( cmScMeas* p, unsigned mni, unsigned locIdx, unsigned scEvtIdx, unsigned flags, unsigned smpIdx, unsigned pitch, unsigned vel );
|
409
|
437
|
|
410
|
438
|
|
411
|
439
|
//=======================================================================================================================
|