Browse Source

cmProc4.h/c: Refinements to cmScAlign and initial interface for cmScMeas.

master
kevin 11 years ago
parent
commit
85393d61c9
2 changed files with 199 additions and 57 deletions
  1. 151
    51
      cmProc4.c
  2. 48
    6
      cmProc4.h

+ 151
- 51
cmProc4.c View File

@@ -1246,11 +1246,11 @@ cmRC_t     cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
1246 1246
       p->loc[ei+i].evtV     = cmMemAllocZ(cmScAlignScEvt_t,n);
1247 1247
       p->loc[ei+i].scLocIdx = li;
1248 1248
       p->loc[ei+i].barNumb  = lp->barNumb;
1249
+
1249 1250
       for(j=0,k=0; j<lp->evtCnt; ++j)
1250 1251
         if( lp->evtArray[j]->type == kNonEvtScId )
1251 1252
         {
1252 1253
           p->loc[ei+i].evtV[k].pitch    = lp->evtArray[j]->pitch;
1253
-          p->loc[ei+i].evtV[k].scEvtIdx = lp->evtArray[j]->index;
1254 1254
           ++k;
1255 1255
         }
1256 1256
 
@@ -1311,6 +1311,8 @@ cmRC_t     cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
1311 1311
 
1312 1312
   //_cmScAlignPrint(p);
1313 1313
 
1314
+  cmScAlignReset(p,0);
1315
+
1314 1316
   return rc;
1315 1317
 }
1316 1318
 
@@ -1329,7 +1331,9 @@ void cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx )
1329 1331
   p->mbi         = p->mn;
1330 1332
   p->mni         = 0;
1331 1333
   p->begScanLocIdx = begScanLocIdx;
1334
+  p->begSyncLocIdx = cmInvalidIdx;
1332 1335
   p->s_opt       = DBL_MAX;
1336
+  p->esi         = cmInvalidIdx;
1333 1337
   p->missCnt     = 0;
1334 1338
   p->scanCnt     = 0;
1335 1339
   p->ri          = 0;
@@ -1391,8 +1395,9 @@ bool _cmScAlignCalcMtx( cmScAlign* p )
1391 1395
     return false;
1392 1396
 
1393 1397
   unsigned i,j;
1394
-  for(i=1; i<p->rn; ++i)
1395
-    for(j=1; j<p->cn; ++j)
1398
+
1399
+  for(j=1; j<p->cn; ++j)
1400
+    for(i=1; i<p->rn; ++i)
1396 1401
     {
1397 1402
       cmScAlignLoc_t* loc   = p->loc + p->begScanLocIdx + j - 1;
1398 1403
       unsigned        pitch = p->midiBuf[i-1].pitch;
@@ -1585,26 +1590,28 @@ double _cmScAlign( cmScAlign* p )
1585 1590
   return p->s_opt;
1586 1591
 }
1587 1592
 
1588
-bool  cmScAlignExec(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
1593
+cmRC_t  cmScAlignExec(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
1589 1594
 {
1590 1595
   bool fl    = p->mbi > 0;
1591
-  bool retFl = true;
1596
+  cmRC_t rc = cmOkRC;
1592 1597
 
1598
+  // update the MIDI buffer with the incoming note
1593 1599
   cmScAlignInputMidi(p,smpIdx,status,d0,d1);
1594 1600
 
1601
+  // if the MIDI buffer transitioned to full then perform an initial scan sync.
1595 1602
   if( fl && p->mbi == 0 )
1596 1603
   {
1597
-    if( cmScAlignScan(p,cmInvalidCnt) == cmInvalidIdx )
1598
-      retFl = false;
1604
+    if( (p->begSyncLocIdx = cmScAlignScan(p,cmInvalidCnt)) == cmInvalidIdx )
1605
+      rc = cmInvalidArgRC; // signal init. scan sync. fail
1599 1606
   }
1600 1607
   else
1601 1608
   {
1602
-    if( !fl && p->mbi == 0 )
1603
-      if( !cmScAlignStep(p) )
1604
-        retFl = false;
1609
+    // if the MIDI buffer is full then perform a step sync.
1610
+    if( !fl && p->mbi == 0 ) 
1611
+      rc = cmScAlignStep(p);
1605 1612
   }
1606 1613
 
1607
-  return retFl;
1614
+  return rc;
1608 1615
 }
1609 1616
 
1610 1617
 bool  cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
@@ -1922,7 +1929,7 @@ unsigned cmScAlignScan( cmScAlign* p, unsigned scanCnt )
1922 1929
 }
1923 1930
 
1924 1931
 
1925
-bool cmScAlignStep(  cmScAlign* p )
1932
+cmRC_t cmScAlignStep(  cmScAlign* p )
1926 1933
 {
1927 1934
   int      i;
1928 1935
   unsigned pitch          = p->midiBuf[ p->mn-1 ].pitch;
@@ -1930,11 +1937,11 @@ bool cmScAlignStep(  cmScAlign* p )
1930 1937
 
1931 1938
   // the tracker must be sync'd to step
1932 1939
   if( p->esi == cmInvalidIdx )
1933
-    return false;
1934
-  
1940
+    return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The p->esi value must be valid to perform a step operation."); 
1941
+
1935 1942
   // if the end of the score has been reached
1936 1943
   if( p->esi + 1 >= p->locN )
1937
-    return cmInvalidIdx;
1944
+    return cmEofRC;
1938 1945
     
1939 1946
   // attempt to match to next location first
1940 1947
   if( _cmScAlignIsMatch(p->loc + p->esi + 1, pitch) )
@@ -1982,13 +1989,13 @@ bool cmScAlignStep(  cmScAlign* p )
1982 1989
 
1983 1990
     // if the scan failed find a match
1984 1991
     if( bsi == cmInvalidIdx )
1985
-      return false;
1992
+      return cmCtxRtCondition( &p->obj, cmSubSysFailRC, "Scan resync. failed."); 
1986 1993
 
1987 1994
     //if( bsi != cmInvalidIdx )
1988 1995
     //  _cmScAlignPrintPath(p, p->p_opt, bsi );
1989 1996
   }
1990 1997
 
1991
-  return true;
1998
+  return cmOkRC;
1992 1999
 }
1993 2000
 
1994 2001
 
@@ -2227,7 +2234,26 @@ void _cmScAlignPrintReport( cmScAlign* p, cmScAlignPrint_t* a, unsigned an, unsi
2227 2234
 
2228 2235
 }
2229 2236
 
2230
-void _cmScAlignPrintResult( cmScAlign* p )
2237
+// The goal of this function is to create a cmScAlignPrint_t array containing
2238
+// one record for each score bar, score note and errant MIDI note.
2239
+// The function works by first creating a record for each score bar and note
2240
+// and then scanning the cmScAlignResult_t array (p->res[]) for each result
2241
+// record create by an earlier call to _cmScAlignCb().  A result record can 
2242
+// uniquely indicates one of the following result states based on receiving
2243
+// a MIDI event.
2244
+// Match      - locIdx!=cmInvalidIdx matchFl==true  mni!=cmInvalidIdx
2245
+// Mis-match  - locIdx!=cmInvalidIdx matchFl==false mni!=cmInvalidIdx
2246
+// Delete     - locIdx==cmInvalidIdx matchFl==false mni!=cmInvalidIdx
2247
+// Insert     - locIdx==cmInvalidIdx matchFl==false mni==cmInvalidIdx
2248
+//
2249
+// This is made slightly more complicated by the fact that a given MIDI event
2250
+// may generate more than one result record.  This can occur when the 
2251
+// tracker is in 'step' mode and generates a result record with a given state
2252
+// as a result of a given MIDI note and then reconsiders that MIDI note
2253
+// while during a subsequent 'scan' mode resync. operation.  For example
2254
+// a MIDI note which generate a 'delete' result during a step operation 
2255
+// may later generate a match result during a scan. 
2256
+double _cmScAlignPrintResult( cmScAlign* p )
2231 2257
 {
2232 2258
   // determine the scH score begin and end indexes
2233 2259
   unsigned bsi = cmScoreLocCount(p->scH);
@@ -2256,9 +2282,10 @@ void _cmScAlignPrintResult( cmScAlign* p )
2256 2282
 
2257 2283
   cmScAlignPrint_t* a   = cmMemAllocZ(cmScAlignPrint_t,aan);
2258 2284
   unsigned          an  = 0;
2259
-  unsigned          scNoteCnt = 0;
2285
+  unsigned          scNoteCnt = 0; // notes in the score
2260 2286
   unsigned          matchCnt  = 0; // matched score notes
2261
-  unsigned          wrongCnt  = 0; // unmatched midi notes
2287
+  unsigned          wrongCnt  = 0; // errant midi notes
2288
+  unsigned          skipCnt   = 0; // skipped score events
2262 2289
 
2263 2290
   // create a record for each score event
2264 2291
   for(i=bsi; i<=esi; ++i)
@@ -2364,11 +2391,14 @@ void _cmScAlignPrintResult( cmScAlign* p )
2364 2391
 
2365 2392
   //_cmScAlignPrintList(a,an);
2366 2393
 
2394
+  // Insert records into the print record array (a[](
2395
+  // to represent errant MIDI notes. (Notes which 
2396
+  // were played but do not match any notes in the score.)
2397
+  
2367 2398
   // for each result record ...
2368 2399
   for(i=0; i<p->ri; ++i)
2369 2400
   {
2370 2401
     cmScAlignResult_t* rp       = p->res + i; 
2371
-    unsigned           scLocIdx = cmInvalidIdx;
2372 2402
     cmScAlignPrint_t*  pp       = NULL;
2373 2403
     cmScAlignPrint_t*  dpp      = NULL;
2374 2404
     unsigned           dmin;
@@ -2377,6 +2407,7 @@ void _cmScAlignPrintResult( cmScAlign* p )
2377 2407
     if(rp->foundFl)
2378 2408
       continue;
2379 2409
 
2410
+    // find the print recd with the closest mni
2380 2411
     for(j=0; j<an; ++j)
2381 2412
     {
2382 2413
       pp = a + j;
@@ -2402,36 +2433,45 @@ void _cmScAlignPrintResult( cmScAlign* p )
2402 2433
 
2403 2434
     if( rp->mni > dpp->mni )
2404 2435
       ++j;
2405
-      
2406
-    scLocIdx = dpp->scLocIdx;
2407 2436
 
2437
+    assert( rp->locIdx == cmInvalidIdx );
2438
+    
2439
+    // insert a print recd before or after the closest print recd
2408 2440
     an = _cmScAlignPrintExpand(a,aan,j,an);
2409
-
2410
-    if( rp->locIdx != cmInvalidIdx )
2411
-    {
2412
-      assert( rp->locIdx != cmInvalidIdx && rp->locIdx < p->locN );
2413
-      scLocIdx = p->loc[ rp->locIdx ].scLocIdx;
2414
-    }
2441
+    _cmScAlignPrintSet(a + j, rp, kMidiErrSaFl, dpp->scLocIdx  );
2415 2442
 
2416 2443
     ++wrongCnt;
2417
-
2418
-    _cmScAlignPrintSet(a + j, rp, kMidiErrSaFl, scLocIdx  );
2419 2444
     
2420 2445
   }
2421 2446
 
2447
+  for(i=0; i<an; ++i)
2448
+    if( cmIsFlag(a[i].flags,kScNoteSaFl) && (a[i].mni == cmInvalidIdx || cmIsFlag(a[i].flags,kSubsErrSaFl)))
2449
+      ++skipCnt;
2450
+
2422 2451
   //_cmScAlignPrintList(a,an);
2423 2452
 
2424 2453
   //_cmScAlignPrintReport(p,a,an,bsi,esi);
2425
-  printf("score notes:%i match:%i wrong:%i \n",scNoteCnt,matchCnt,wrongCnt);
2454
+
2455
+  double prec = (double)2.0 * matchCnt / (matchCnt + wrongCnt);
2456
+  double rcal = (double)2.0 * matchCnt / (matchCnt + skipCnt);
2457
+  double fmeas = prec * rcal / (prec + rcal);
2458
+
2459
+  printf("midi:%i scans:%i score notes:%i match:%i skip:%i wrong:%i : %f\n",p->mni,p->scanCnt,scNoteCnt,matchCnt,skipCnt,wrongCnt,fmeas);
2460
+
2461
+  cmMemFree(a);
2462
+
2463
+  return fmeas;
2426 2464
 }
2427 2465
 
2428
-unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx )
2466
+
2467
+cmRC_t cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx )
2429 2468
 {
2430 2469
   assert( top != NULL );
2431
-  cmTlMidiEvt_t* mep   = NULL;
2470
+  cmTlMidiEvt_t* mep = NULL;
2471
+  cmRC_t         rc  = cmOkRC;
2432 2472
   
2433
-  // get the next time MIDI msg 
2434
-  while( (mep = cmTlNextMidiEvtObjPtr(tlH, top, top->seqId )) != NULL )
2473
+  // as long as more MIDI events are available get the next MIDI msg 
2474
+  while( rc==cmOkRC && (mep = cmTlNextMidiEvtObjPtr(tlH, top, top->seqId )) != NULL )
2435 2475
   {
2436 2476
     top = &mep->obj;
2437 2477
 
@@ -2441,13 +2481,31 @@ unsigned cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top
2441 2481
 
2442 2482
     // if the time line MIDI msg a note-on
2443 2483
     if( mep->msg->status == kNoteOnMdId )
2444
-      if( !cmScAlignExec(p, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1 ) )
2445
-        return cmInvalidIdx;
2484
+    {
2485
+      rc = cmScAlignExec(p, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1 );
2486
+
2487
+      switch( rc )
2488
+      {
2489
+        case cmOkRC:        // continue processing MIDI events
2490
+          break;
2491
+
2492
+        case cmEofRC:       // end of the score was encountered
2493
+          break;
2494
+
2495
+        case cmInvalidArgRC: // p->esi was not set correctly
2496
+          break;
2497
+
2498
+        case cmSubSysFailRC: // scan resync failed
2499
+          break;
2500
+      }
2501
+    }
2446 2502
   }
2447 2503
 
2448
-  return p->esi;
2449
-}
2504
+  if( rc == cmEofRC )
2505
+    rc = cmOkRC;
2450 2506
 
2507
+  return rc;
2508
+}
2451 2509
 
2452 2510
 void cmScAlignCb( void* cbArg, unsigned scLocIdx, unsigned mni, unsigned pitch, unsigned vel )
2453 2511
 {
@@ -2467,6 +2525,12 @@ void       cmScAlignScanMarkers(  cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH )
2467 2525
   unsigned   markCharCnt = 31;
2468 2526
   cmChar_t   markText[ markCharCnt+1 ];
2469 2527
 
2528
+  double     scoreThresh  = 0.5;
2529
+  unsigned   candCnt      = 0;
2530
+  unsigned   initFailCnt  = 0;
2531
+  unsigned   otherFailCnt = 0;
2532
+  unsigned   scoreFailCnt = 0;
2533
+
2470 2534
   p->cbArg = p; // set the callback arg. 
2471 2535
   
2472 2536
   // for each marker
@@ -2479,43 +2543,79 @@ void       cmScAlignScanMarkers(  cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH )
2479 2543
     cmTlMarker_t*  mp    = cmTimeLineMarkerFind( tlH, markText );
2480 2544
     if( mp == NULL )
2481 2545
     {
2482
-      printf("The marker '%s' was not found.\n",markText);  
2546
+      printf("The marker '%s' was not found.\n\n",markText);  
2483 2547
       continue;
2484 2548
     }
2485 2549
 
2486 2550
     // skip markers which do not contain text
2487 2551
     if( cmTextIsEmpty(mp->text) )
2488 2552
     {
2489
-      printf("The marker '%s' is being skipped because it has no text.\n",markText);  
2553
+      printf("The marker '%s' is being skipped because it has no text.\n\n",markText);  
2490 2554
       continue;
2491 2555
     }
2492 2556
 
2493 2557
     // reset the score follower to the beginnig of the score
2494 2558
     cmScAlignReset(p,0);
2495 2559
 
2496
-    //printf("%s %5.2f %5.2f %5.2f\n",markText,(double)(mp->obj.begSmpIdx)/p->srate,(double)(mp->obj.durSmpCnt)/p->srate,(double)(mp->obj.begSmpIdx+mp->obj.durSmpCnt)/p->srate);
2560
+    ++candCnt;
2497 2561
 
2498 2562
     // scan to the beginning of the marker
2499
-    unsigned bsi = cmScAlignScanToTimeLineEvent(p,tlH,&mp->obj,mp->obj.seqSmpIdx+mp->obj.durSmpCnt);
2500
-    
2501
-    if( bsi != cmInvalidIdx )
2563
+    cmRC_t rc = cmScAlignScanToTimeLineEvent(p,tlH,&mp->obj,mp->obj.seqSmpIdx+mp->obj.durSmpCnt);
2564
+    bool   pfl = true;
2565
+
2566
+    if( rc != cmOkRC || p->begSyncLocIdx==cmInvalidIdx)
2567
+    {
2568
+      if( p->begSyncLocIdx == cmInvalidIdx )
2569
+        rc = cmInvalidArgRC;
2570
+
2571
+      if( p->mni == 0 )
2572
+      {
2573
+        printf("mark:%i midi:%i Not enough MIDI notes to fill the scan buffer.\n",i,p->mni);
2574
+        pfl = false;
2575
+      }
2576
+      else
2577
+      {
2578
+        switch(rc)
2579
+        {
2580
+          case cmInvalidArgRC:
2581
+            printf("mark:%i INITIAL SYNC FAIL\n",i);
2582
+            ++initFailCnt;
2583
+            pfl = false;
2584
+            break;
2585
+
2586
+          case cmSubSysFailRC:
2587
+            printf("mark:%i SCAN RESYNC FAIL\n",i);
2588
+            ++otherFailCnt;
2589
+            break;
2590
+
2591
+          default:
2592
+            printf("mark:%i UNKNOWN FAIL\n",i);
2593
+            ++otherFailCnt;
2594
+        }
2595
+      }
2596
+    }
2597
+
2598
+    if( pfl )
2502 2599
     {      
2503 2600
       //_cmScAlignPrintMtx(p);
2504
-      printf("mark:%i scans:%4i loc:%4i bar:%4i score:%5.2f miss:%i text:'%s'\n",i,p->scanCnt,bsi,p->loc[bsi].barNumb,p->s_opt,p->missCnt,mp->text);
2601
+      printf("mark:%i scans:%4i loc:%4i bar:%4i score:%5.2f miss:%i text:'%s'\n",i,p->scanCnt,p->begSyncLocIdx,p->loc[p->begSyncLocIdx].barNumb,p->s_opt,p->missCnt,mp->text);
2505 2602
       //_cmScAlignPrintPath(p, p->p_opt, bsi );
2506 2603
 
2507
-      printf("mark:%i scans:%i midi:%i text:'%s'\n",i,p->scanCnt,p->mni,mp->text);
2604
+      //printf("mark:%i scans:%i midi:%i text:'%s'\n",i,p->scanCnt,p->mni,mp->text);
2508 2605
 
2509
-      _cmScAlignPrintResult(p);
2606
+      if( _cmScAlignPrintResult(p) < scoreThresh )
2607
+        ++scoreFailCnt;
2510 2608
 
2511
-      printf("\n");
2512 2609
     }
2610
+
2513 2611
     
2514 2612
     //break;  // ONLY USE ONE MARKER DURING TESTING
2515 2613
 
2516
-  }
2614
+    printf("\n");
2517 2615
 
2616
+  }
2518 2617
 
2618
+  printf("cand:%i fail:%i - init:%i score:%i other:%i\n\n",candCnt,initFailCnt+scoreFailCnt+otherFailCnt,initFailCnt,scoreFailCnt,otherFailCnt);
2519 2619
 
2520 2620
   cmScAlignFree(&p);  
2521 2621
   cmCtxFree(&ctx);

+ 48
- 6
cmProc4.h View File

@@ -196,9 +196,10 @@ void ed_free(ed_r* r);
196 196
 
197 197
 // Main test function.
198 198
 void ed_main();
199
-
200 199
 //=======================================================================================================================
201 200
 
201
+ 
202
+//=======================================================================================================================
202 203
 enum 
203 204
 { 
204 205
   kSaMinIdx, 
@@ -208,13 +209,15 @@ enum
208 209
   kSaCnt 
209 210
 };
210 211
 
212
+// Dynamic Programming (DP) matrix element
211 213
 typedef struct
212 214
 {
213
-  unsigned v[kSaCnt];
215
+  unsigned v[kSaCnt]; // 
214 216
   bool     matchFl;   // if this is a substitute; is it also a match?
215 217
   bool     transFl;   // if this is a substitute; is this the second element in a reversed pair?
216 218
 } cmScAlignVal_t;
217 219
 
220
+// List record used to track a path through the DP matrix p->m[,]
218 221
 typedef struct cmScAlignPath_str
219 222
 {
220 223
   unsigned                  code;
@@ -226,13 +229,13 @@ typedef struct cmScAlignPath_str
226 229
   struct cmScAlignPath_str* next;
227 230
 } cmScAlignPath_t;
228 231
 
232
+// Score note event record
229 233
 typedef struct
230 234
 {
231 235
   unsigned pitch;
232
-  unsigned scEvtIdx;
233
-  bool     matchFl;
234 236
 } cmScAlignScEvt_t;
235 237
 
238
+// Score location record. 
236 239
 typedef struct
237 240
 {
238 241
   unsigned          evtCnt;         // 
@@ -296,6 +299,7 @@ typedef struct
296 299
   bool                printFl;
297 300
 
298 301
   unsigned            begScanLocIdx; // begin the search at this score locations scWnd[begScanLocIdx:begScanLocIdx+p->cn-1]
302
+  unsigned            begSyncLocIdx; // initial sync location
299 303
 
300 304
   unsigned            resN;  // count of records in res[] == 2*cmScoreEvtCount()
301 305
   cmScAlignResult_t*  res;   // res[resN]
@@ -313,7 +317,7 @@ cmRC_t     cmScAlignInit( cmScAlign* p, cmScAlignCb_t cbFunc, void* cbArg, cmRea
313 317
 cmRC_t     cmScAlignFinal( cmScAlign* p );
314 318
 void       cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx );
315 319
 
316
-bool       cmScAlignExec(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
320
+cmRC_t     cmScAlignExec(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
317 321
 
318 322
 bool       cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
319 323
 
@@ -327,7 +331,9 @@ unsigned   cmScAlignScan( cmScAlign* p, unsigned scanCnt );
327 331
 // Step forward/back by p->stepCnt from p->esi.
328 332
 // If more than p->maxStepMissCnt consecutive MIDI events are 
329 333
 // missed then automatically run cmScAlignScan().
330
-bool cmScAlignStep(  cmScAlign* p );
334
+// Return cmEofRC if the end of the score is encountered.
335
+// Return cmSubSysFailRC if an internal scan resync. failed.
336
+cmRC_t     cmScAlignStep(  cmScAlign* p );
331 337
 
332 338
 unsigned   cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
333 339
 
@@ -336,6 +342,42 @@ unsigned   cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* t
336 342
 // notes in each marker region and the score. 
337 343
 void       cmScAlignScanMarkers(  cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
338 344
 
345
+//=======================================================================================================================
346
+
347
+typedef struct
348
+{
349
+  unsigned mni;
350
+  unsigned locIdx;
351
+  unsigned pitch;
352
+  unsigned vel;
353
+  unsigned smpIdx;
354
+} cmScMeasMidi_t;
355
+
356
+typedef struct
357
+{
358
+  cmScoreSet_t* set;  // A pointer to defining score set
359
+  unsigned      bli;  // Begin index into sap->loc[].
360
+  unsigned      eli;  // End index into sap->loc[].
361
+  unsigned      bmi;  // Begin index into midi[].
362
+  unsigned      emi;  // End index into midi[].
363
+  double*       val;  // val[sap->eleCnt]  
364
+} cmScMeasSet_t;
365
+
366
+typedef struct
367
+{
368
+  cmObj            obj;
369
+  cmScAlign*       sap;
370
+  unsigned         mn;
371
+  cmScMeasMidi_t*  midi;
372
+} cmScMeas;
373
+
374
+cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, double srate, cmScH_t scH );
375
+cmRC_t    cmScMeasFree(  cmScMeas** pp );
376
+cmRC_t    cmScMeasInit(  cmScMeas* p, double srate, cmScH_t scH );
377
+cmRC_t    cmScMeasFinal( cmScMeas* p );
378
+cmRC_t    cmScMeasExec( cmScMeas* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1, unsigned scLocIdx );
379
+
380
+
339 381
 #ifdef __cplusplus
340 382
 }
341 383
 #endif

Loading…
Cancel
Save