瀏覽代碼

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

master
kevin 11 年之前
父節點
當前提交
85393d61c9
共有 2 個文件被更改,包括 199 次插入57 次删除
  1. 151
    51
      cmProc4.c
  2. 48
    6
      cmProc4.h

+ 151
- 51
cmProc4.c 查看文件

1246
       p->loc[ei+i].evtV     = cmMemAllocZ(cmScAlignScEvt_t,n);
1246
       p->loc[ei+i].evtV     = cmMemAllocZ(cmScAlignScEvt_t,n);
1247
       p->loc[ei+i].scLocIdx = li;
1247
       p->loc[ei+i].scLocIdx = li;
1248
       p->loc[ei+i].barNumb  = lp->barNumb;
1248
       p->loc[ei+i].barNumb  = lp->barNumb;
1249
+
1249
       for(j=0,k=0; j<lp->evtCnt; ++j)
1250
       for(j=0,k=0; j<lp->evtCnt; ++j)
1250
         if( lp->evtArray[j]->type == kNonEvtScId )
1251
         if( lp->evtArray[j]->type == kNonEvtScId )
1251
         {
1252
         {
1252
           p->loc[ei+i].evtV[k].pitch    = lp->evtArray[j]->pitch;
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
           ++k;
1254
           ++k;
1255
         }
1255
         }
1256
 
1256
 
1311
 
1311
 
1312
   //_cmScAlignPrint(p);
1312
   //_cmScAlignPrint(p);
1313
 
1313
 
1314
+  cmScAlignReset(p,0);
1315
+
1314
   return rc;
1316
   return rc;
1315
 }
1317
 }
1316
 
1318
 
1329
   p->mbi         = p->mn;
1331
   p->mbi         = p->mn;
1330
   p->mni         = 0;
1332
   p->mni         = 0;
1331
   p->begScanLocIdx = begScanLocIdx;
1333
   p->begScanLocIdx = begScanLocIdx;
1334
+  p->begSyncLocIdx = cmInvalidIdx;
1332
   p->s_opt       = DBL_MAX;
1335
   p->s_opt       = DBL_MAX;
1336
+  p->esi         = cmInvalidIdx;
1333
   p->missCnt     = 0;
1337
   p->missCnt     = 0;
1334
   p->scanCnt     = 0;
1338
   p->scanCnt     = 0;
1335
   p->ri          = 0;
1339
   p->ri          = 0;
1391
     return false;
1395
     return false;
1392
 
1396
 
1393
   unsigned i,j;
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
       cmScAlignLoc_t* loc   = p->loc + p->begScanLocIdx + j - 1;
1402
       cmScAlignLoc_t* loc   = p->loc + p->begScanLocIdx + j - 1;
1398
       unsigned        pitch = p->midiBuf[i-1].pitch;
1403
       unsigned        pitch = p->midiBuf[i-1].pitch;
1585
   return p->s_opt;
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
   bool fl    = p->mbi > 0;
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
   cmScAlignInputMidi(p,smpIdx,status,d0,d1);
1599
   cmScAlignInputMidi(p,smpIdx,status,d0,d1);
1594
 
1600
 
1601
+  // if the MIDI buffer transitioned to full then perform an initial scan sync.
1595
   if( fl && p->mbi == 0 )
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
   else
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
 bool  cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
1617
 bool  cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
1922
 }
1929
 }
1923
 
1930
 
1924
 
1931
 
1925
-bool cmScAlignStep(  cmScAlign* p )
1932
+cmRC_t cmScAlignStep(  cmScAlign* p )
1926
 {
1933
 {
1927
   int      i;
1934
   int      i;
1928
   unsigned pitch          = p->midiBuf[ p->mn-1 ].pitch;
1935
   unsigned pitch          = p->midiBuf[ p->mn-1 ].pitch;
1930
 
1937
 
1931
   // the tracker must be sync'd to step
1938
   // the tracker must be sync'd to step
1932
   if( p->esi == cmInvalidIdx )
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
   // if the end of the score has been reached
1942
   // if the end of the score has been reached
1936
   if( p->esi + 1 >= p->locN )
1943
   if( p->esi + 1 >= p->locN )
1937
-    return cmInvalidIdx;
1944
+    return cmEofRC;
1938
     
1945
     
1939
   // attempt to match to next location first
1946
   // attempt to match to next location first
1940
   if( _cmScAlignIsMatch(p->loc + p->esi + 1, pitch) )
1947
   if( _cmScAlignIsMatch(p->loc + p->esi + 1, pitch) )
1982
 
1989
 
1983
     // if the scan failed find a match
1990
     // if the scan failed find a match
1984
     if( bsi == cmInvalidIdx )
1991
     if( bsi == cmInvalidIdx )
1985
-      return false;
1992
+      return cmCtxRtCondition( &p->obj, cmSubSysFailRC, "Scan resync. failed."); 
1986
 
1993
 
1987
     //if( bsi != cmInvalidIdx )
1994
     //if( bsi != cmInvalidIdx )
1988
     //  _cmScAlignPrintPath(p, p->p_opt, bsi );
1995
     //  _cmScAlignPrintPath(p, p->p_opt, bsi );
1989
   }
1996
   }
1990
 
1997
 
1991
-  return true;
1998
+  return cmOkRC;
1992
 }
1999
 }
1993
 
2000
 
1994
 
2001
 
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
   // determine the scH score begin and end indexes
2258
   // determine the scH score begin and end indexes
2233
   unsigned bsi = cmScoreLocCount(p->scH);
2259
   unsigned bsi = cmScoreLocCount(p->scH);
2256
 
2282
 
2257
   cmScAlignPrint_t* a   = cmMemAllocZ(cmScAlignPrint_t,aan);
2283
   cmScAlignPrint_t* a   = cmMemAllocZ(cmScAlignPrint_t,aan);
2258
   unsigned          an  = 0;
2284
   unsigned          an  = 0;
2259
-  unsigned          scNoteCnt = 0;
2285
+  unsigned          scNoteCnt = 0; // notes in the score
2260
   unsigned          matchCnt  = 0; // matched score notes
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
   // create a record for each score event
2290
   // create a record for each score event
2264
   for(i=bsi; i<=esi; ++i)
2291
   for(i=bsi; i<=esi; ++i)
2364
 
2391
 
2365
   //_cmScAlignPrintList(a,an);
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
   // for each result record ...
2398
   // for each result record ...
2368
   for(i=0; i<p->ri; ++i)
2399
   for(i=0; i<p->ri; ++i)
2369
   {
2400
   {
2370
     cmScAlignResult_t* rp       = p->res + i; 
2401
     cmScAlignResult_t* rp       = p->res + i; 
2371
-    unsigned           scLocIdx = cmInvalidIdx;
2372
     cmScAlignPrint_t*  pp       = NULL;
2402
     cmScAlignPrint_t*  pp       = NULL;
2373
     cmScAlignPrint_t*  dpp      = NULL;
2403
     cmScAlignPrint_t*  dpp      = NULL;
2374
     unsigned           dmin;
2404
     unsigned           dmin;
2377
     if(rp->foundFl)
2407
     if(rp->foundFl)
2378
       continue;
2408
       continue;
2379
 
2409
 
2410
+    // find the print recd with the closest mni
2380
     for(j=0; j<an; ++j)
2411
     for(j=0; j<an; ++j)
2381
     {
2412
     {
2382
       pp = a + j;
2413
       pp = a + j;
2402
 
2433
 
2403
     if( rp->mni > dpp->mni )
2434
     if( rp->mni > dpp->mni )
2404
       ++j;
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
     an = _cmScAlignPrintExpand(a,aan,j,an);
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
     ++wrongCnt;
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
   //_cmScAlignPrintList(a,an);
2451
   //_cmScAlignPrintList(a,an);
2423
 
2452
 
2424
   //_cmScAlignPrintReport(p,a,an,bsi,esi);
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
   assert( top != NULL );
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
     top = &mep->obj;
2476
     top = &mep->obj;
2437
 
2477
 
2441
 
2481
 
2442
     // if the time line MIDI msg a note-on
2482
     // if the time line MIDI msg a note-on
2443
     if( mep->msg->status == kNoteOnMdId )
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
 void cmScAlignCb( void* cbArg, unsigned scLocIdx, unsigned mni, unsigned pitch, unsigned vel )
2510
 void cmScAlignCb( void* cbArg, unsigned scLocIdx, unsigned mni, unsigned pitch, unsigned vel )
2453
 {
2511
 {
2467
   unsigned   markCharCnt = 31;
2525
   unsigned   markCharCnt = 31;
2468
   cmChar_t   markText[ markCharCnt+1 ];
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
   p->cbArg = p; // set the callback arg. 
2534
   p->cbArg = p; // set the callback arg. 
2471
   
2535
   
2472
   // for each marker
2536
   // for each marker
2479
     cmTlMarker_t*  mp    = cmTimeLineMarkerFind( tlH, markText );
2543
     cmTlMarker_t*  mp    = cmTimeLineMarkerFind( tlH, markText );
2480
     if( mp == NULL )
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
       continue;
2547
       continue;
2484
     }
2548
     }
2485
 
2549
 
2486
     // skip markers which do not contain text
2550
     // skip markers which do not contain text
2487
     if( cmTextIsEmpty(mp->text) )
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
       continue;
2554
       continue;
2491
     }
2555
     }
2492
 
2556
 
2493
     // reset the score follower to the beginnig of the score
2557
     // reset the score follower to the beginnig of the score
2494
     cmScAlignReset(p,0);
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
     // scan to the beginning of the marker
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
       //_cmScAlignPrintMtx(p);
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
       //_cmScAlignPrintPath(p, p->p_opt, bsi );
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
     //break;  // ONLY USE ONE MARKER DURING TESTING
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
   cmScAlignFree(&p);  
2620
   cmScAlignFree(&p);  
2521
   cmCtxFree(&ctx);
2621
   cmCtxFree(&ctx);

+ 48
- 6
cmProc4.h 查看文件

196
 
196
 
197
 // Main test function.
197
 // Main test function.
198
 void ed_main();
198
 void ed_main();
199
-
200
 //=======================================================================================================================
199
 //=======================================================================================================================
201
 
200
 
201
+ 
202
+//=======================================================================================================================
202
 enum 
203
 enum 
203
 { 
204
 { 
204
   kSaMinIdx, 
205
   kSaMinIdx, 
208
   kSaCnt 
209
   kSaCnt 
209
 };
210
 };
210
 
211
 
212
+// Dynamic Programming (DP) matrix element
211
 typedef struct
213
 typedef struct
212
 {
214
 {
213
-  unsigned v[kSaCnt];
215
+  unsigned v[kSaCnt]; // 
214
   bool     matchFl;   // if this is a substitute; is it also a match?
216
   bool     matchFl;   // if this is a substitute; is it also a match?
215
   bool     transFl;   // if this is a substitute; is this the second element in a reversed pair?
217
   bool     transFl;   // if this is a substitute; is this the second element in a reversed pair?
216
 } cmScAlignVal_t;
218
 } cmScAlignVal_t;
217
 
219
 
220
+// List record used to track a path through the DP matrix p->m[,]
218
 typedef struct cmScAlignPath_str
221
 typedef struct cmScAlignPath_str
219
 {
222
 {
220
   unsigned                  code;
223
   unsigned                  code;
226
   struct cmScAlignPath_str* next;
229
   struct cmScAlignPath_str* next;
227
 } cmScAlignPath_t;
230
 } cmScAlignPath_t;
228
 
231
 
232
+// Score note event record
229
 typedef struct
233
 typedef struct
230
 {
234
 {
231
   unsigned pitch;
235
   unsigned pitch;
232
-  unsigned scEvtIdx;
233
-  bool     matchFl;
234
 } cmScAlignScEvt_t;
236
 } cmScAlignScEvt_t;
235
 
237
 
238
+// Score location record. 
236
 typedef struct
239
 typedef struct
237
 {
240
 {
238
   unsigned          evtCnt;         // 
241
   unsigned          evtCnt;         // 
296
   bool                printFl;
299
   bool                printFl;
297
 
300
 
298
   unsigned            begScanLocIdx; // begin the search at this score locations scWnd[begScanLocIdx:begScanLocIdx+p->cn-1]
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
   unsigned            resN;  // count of records in res[] == 2*cmScoreEvtCount()
304
   unsigned            resN;  // count of records in res[] == 2*cmScoreEvtCount()
301
   cmScAlignResult_t*  res;   // res[resN]
305
   cmScAlignResult_t*  res;   // res[resN]
313
 cmRC_t     cmScAlignFinal( cmScAlign* p );
317
 cmRC_t     cmScAlignFinal( cmScAlign* p );
314
 void       cmScAlignReset( cmScAlign* p, unsigned begScanLocIdx );
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
 bool       cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
322
 bool       cmScAlignInputMidi(  cmScAlign* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
319
 
323
 
327
 // Step forward/back by p->stepCnt from p->esi.
331
 // Step forward/back by p->stepCnt from p->esi.
328
 // If more than p->maxStepMissCnt consecutive MIDI events are 
332
 // If more than p->maxStepMissCnt consecutive MIDI events are 
329
 // missed then automatically run cmScAlignScan().
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
 unsigned   cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
338
 unsigned   cmScAlignScanToTimeLineEvent( cmScAlign* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
333
 
339
 
336
 // notes in each marker region and the score. 
342
 // notes in each marker region and the score. 
337
 void       cmScAlignScanMarkers(  cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
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
 #ifdef __cplusplus
381
 #ifdef __cplusplus
340
 }
382
 }
341
 #endif
383
 #endif

Loading…
取消
儲存