Browse Source

cmProc4.h/c Added cmScTrk object.

master
kevin 11 years ago
parent
commit
4c8b5915ad
2 changed files with 381 additions and 107 deletions
  1. 323
    101
      cmProc4.c
  2. 58
    6
      cmProc4.h

+ 323
- 101
cmProc4.c View File

@@ -46,7 +46,7 @@ cmRC_t   cmScFolFree(  cmScFol** pp )
46 46
 
47 47
   unsigned i;
48 48
   for(i=0; i<p->locN; ++i)
49
-    cmMemFree(p->loc[i].pitchV);
49
+    cmMemFree(p->loc[i].evtV);
50 50
 
51 51
   cmMemFree(p->loc);
52 52
   cmMemFree(p->bufV);
@@ -67,8 +67,8 @@ void _cmScFolPrint( cmScFol* p )
67 67
   for(i=0; i<p->locN; ++i)
68 68
   {
69 69
     printf("%2i %5i ",p->loc[i].barNumb,p->loc[i].scIdx);
70
-    for(j=0; j<p->loc[i].pitchCnt; ++j)
71
-      printf("%s ",cmMidiToSciPitch(p->loc[i].pitchV[j],NULL,0));
70
+    for(j=0; j<p->loc[i].evtCnt; ++j)
71
+      printf("%s ",cmMidiToSciPitch(p->loc[i].evtV[j].pitch,NULL,0));
72 72
     printf("\n");
73 73
   }
74 74
 }
@@ -127,87 +127,62 @@ cmRC_t   cmScFolInit(  cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, u
127 127
   p->skipCnt        = 0;
128 128
   p->ret_idx        = cmInvalidIdx;
129 129
 
130
-  int i,n;
131
-  double        maxDSecs = 0;   // max time between score entries to be considered simultaneous
132
-  cmScoreEvt_t* e0p      = NULL;
133
-  int           j0       = 0;
134
-
135
-  // for each score event
136
-  for(i=0,n=0; i<p->locN; ++i)
130
+  // for each score location
131
+  unsigned li,ei;
132
+  
133
+  for(li=0,ei=0; li<cmScoreLocCount(p->scH); ++li)
137 134
   {
138
-    cmScoreEvt_t* ep = cmScoreEvt(scH,i);
135
+    unsigned i,n;
139 136
 
140
-    // if the event is not a note then ignore it
141
-    if( ep->type == kNonEvtScId )
142
-    {
143
-      assert( j0+n < p->locN );
137
+    const cmScoreLoc_t* lp = cmScoreLoc(p->scH,li);
144 138
 
145
-      p->loc[j0+n].scIdx  = i;
146
-      p->loc[j0+n].barNumb = ep->barNumb;
139
+    // count the number of note events at location li
140
+    for(n=0,i=0; i<lp->evtCnt; ++i)
141
+      if( lp->evtArray[i]->type == kNonEvtScId )
142
+        ++n;
147 143
 
148
-      // if the first event has not yet been selected
149
-      if( e0p == NULL )
150
-      {
151
-        e0p = ep;
152
-        n   = 1;
153
-      }
154
-      else
155
-      {
156
-        // time can never reverse
157
-        assert( ep->secs >= e0p->secs );  
158
-
159
-        // calc seconds between first event and current event
160
-        double dsecs = ep->secs - e0p->secs;
144
+    assert( ei+n <= p->locN );
161 145
 
162
-        // if the first event and current event are simultaneous...
163
-        if( dsecs <= maxDSecs )
164
-          ++n;   // ... incr. the count of simultaneous events
165
-        else
146
+    // duplicate each note at location li n times
147
+    for(i=0; i<n; ++i)
148
+    {
149
+      unsigned j,k;
150
+
151
+      p->loc[ei+i].evtCnt = n;
152
+      p->loc[ei+i].evtV   = cmMemAllocZ(cmScFolEvt_t,n);
153
+      p->loc[ei+i].scIdx    = li;
154
+      p->loc[ei+i].barNumb  = lp->barNumb;
155
+      for(j=0,k=0; j<lp->evtCnt; ++j)
156
+        if( lp->evtArray[j]->type == kNonEvtScId )
166 157
         {
167
-          int k;
168
-          //  ... a complete set of simultaneous events have been located
169
-          // duplicate all the events at each of their respective time locations
170
-          for(k=0; k<n; ++k)
171
-          {
172
-            int m;
173
-            assert( j0+k < p->locN );
174
-
175
-            p->loc[j0+k].pitchCnt = n;
176
-            p->loc[j0+k].pitchV   = cmMemAllocZ(unsigned,n);
177
-
178
-            for(m=0; m<n; ++m)
179
-            {
180
-              cmScoreEvt_t* tp = cmScoreEvt(scH,p->loc[j0+m].scIdx);
181
-              assert(tp!=NULL);
182
-              p->loc[j0+k].pitchV[m] = tp->pitch;
183
-            }
184
-          }
185
-          
186
-          e0p = ep;
187
-          j0 += n;
188
-          n   = 1;
158
+          p->loc[ei+i].evtV[k].pitch    = lp->evtArray[j]->pitch;
159
+          p->loc[ei+i].evtV[k].scEvtIdx = lp->evtArray[j]->index;
160
+          ++k;
189 161
         }
190
-      }
162
+
191 163
     }
164
+
165
+    ei += n;
166
+    
192 167
   }
193 168
 
194
-  p->locN = j0;
169
+  p->locN = ei;
195 170
 
196 171
   //_cmScFolPrint(p);
197 172
 
198 173
   return rc;
199 174
 }
200 175
 
201
-cmRC_t   cmScFolReset(   cmScFol* p, unsigned scoreIndex )
176
+cmRC_t   cmScFolReset(   cmScFol* p, unsigned scEvtIdx )
202 177
 {
203
-  int i;
178
+  int i,j;
204 179
 
205 180
   // empty the event buffer
206 181
   memset(p->bufV,0,sizeof(cmScFolBufEle_t)*p->bufN);
207 182
 
208 183
   // don't allow the score index to be prior to the first note
209
-  if( scoreIndex < p->loc[0].scIdx )
210
-    scoreIndex = p->loc[0].scIdx;
184
+  //if( scEvtIdx < p->loc[0].scIdx )
185
+  //  scEvtIdx = p->loc[0].scIdx;
211 186
 
212 187
   p->sei      = cmInvalidIdx;
213 188
   p->sbi      = cmInvalidIdx;
@@ -218,22 +193,23 @@ cmRC_t   cmScFolReset(   cmScFol* p, unsigned scoreIndex )
218 193
   p->ret_idx  = cmInvalidIdx;
219 194
 
220 195
   // locate the score element in svV[] that is closest to,
221
-  // and possibly after, scoreIndex.
196
+  // and possibly after, scEvtIdx.
222 197
   for(i=0; i<p->locN-1; ++i)
223
-    if( p->loc[i].scIdx <= scoreIndex && scoreIndex < p->loc[i+1].scIdx  )
224
-    {
225
-      p->sbi = i;
226
-      break;
227
-    }
198
+  {
199
+    for(j=0; j<p->loc[i].evtCnt; ++j)
200
+      if( p->loc[i].evtV[j].scEvtIdx <= scEvtIdx )
201
+        p->sbi = i;
202
+      else
203
+        break;
204
+  }
228 205
 
229 206
   // locate the score element at the end of the look-ahead region
230
-  for(; i<p->locN-1; ++i)
231
-    if( p->loc[i].scIdx <= scoreIndex + p->msln && scoreIndex + p->msln < p->loc[i+1].scIdx )
232
-    {
233
-      p->sei = i;
234
-      break;
235
-    }
236
-
207
+  for(; i<p->locN; ++i)
208
+  {
209
+    for(j=0; j<p->loc[i].evtCnt; ++j)
210
+      if( p->loc[i].evtV[j].scEvtIdx <= scEvtIdx + p->msln )
211
+        p->sei = i;
212
+  }
237 213
 
238 214
   return cmOkRC;
239 215
 }
@@ -241,8 +217,8 @@ cmRC_t   cmScFolReset(   cmScFol* p, unsigned scoreIndex )
241 217
 bool  _cmScFolIsMatch( const cmScFolLoc_t* loc, unsigned pitch )
242 218
 {
243 219
   unsigned i;
244
-  for(i=0; i<loc->pitchCnt; ++i)
245
-    if( loc->pitchV[i] == pitch )
220
+  for(i=0; i<loc->evtCnt; ++i)
221
+    if( loc->evtV[i].pitch == pitch )
246 222
       return true;
247 223
   return false;
248 224
 }
@@ -301,8 +277,8 @@ void _cmScFolRpt0( cmScFol* p, unsigned locIdx, unsigned locN, const cmScFolBufE
301 277
   printf("\n");
302 278
 
303 279
   for(n=0,i=0; i<locN; ++i)
304
-    if( p->loc[locIdx+i].pitchCnt > n )
305
-      n = p->loc[locIdx+i].pitchCnt;
280
+    if( p->loc[locIdx+i].evtCnt > n )
281
+      n = p->loc[locIdx+i].evtCnt;
306 282
 
307 283
   --n;
308 284
   for(; n>=0; --n)
@@ -310,8 +286,8 @@ void _cmScFolRpt0( cmScFol* p, unsigned locIdx, unsigned locN, const cmScFolBufE
310 286
     printf("sc%1i: ",n);
311 287
     for(i=0; i<locN; ++i)
312 288
     {
313
-      if( n < p->loc[locIdx+i].pitchCnt )
314
-        printf("%4s ",cmMidiToSciPitch(p->loc[locIdx+i].pitchV[n],NULL,0));
289
+      if( n < p->loc[locIdx+i].evtCnt )
290
+        printf("%4s ",cmMidiToSciPitch(p->loc[locIdx+i].evtV[n].pitch,NULL,0));
315 291
       else
316 292
         printf("     ");
317 293
     }
@@ -338,9 +314,13 @@ void _cmScFolRpt1( cmScFol*p, unsigned minDist, unsigned ret_idx, unsigned d1, u
338 314
 
339 315
 unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
340 316
 {
341
-
342 317
   unsigned ret_idx = cmInvalidIdx;
343
-  //unsigned ebuf[ p->bufN ];
318
+
319
+  if( p->sbi == cmInvalidIdx )
320
+  {
321
+    cmCtxRtCondition( &p->obj, cmInvalidArgRC, "An initial score search location has not been set." );
322
+    return ret_idx;
323
+  }
344 324
 
345 325
   if( status != kNoteOnMdId )
346 326
     return ret_idx;
@@ -362,21 +342,7 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
362 342
 
363 343
   // fill in ebuf[] with the valid values in bufV[]
364 344
   int en = cmMin(p->eventIdx,p->bufN);
365
-  int i  = p->eventIdx>=p->bufN ? 0 : p->bufN-p->eventIdx-1;
366
-
367
-  /*
368
-  int i  = p->bufN-1;
369
-  int en = 0;
370
-  for(; i>=0; --i,++en)
371
-  {
372
-    if( p->bufV[i].validFl)
373
-      ebuf[i] = p->bufV[i].val;
374
-    else
375
-      break;
376
-  }
377
-  ++i;  // increment i to the first valid element in ebuf[].
378
-  */
379
-
345
+  int bbi  = p->eventIdx>=p->bufN ? 0 : p->bufN-p->eventIdx;
380 346
 
381 347
 
382 348
   // en is the count of valid elements in ebuf[].
@@ -396,7 +362,7 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
396 362
   for(j=0; p->sbi+en+j-1 <= p->sei; ++j)
397 363
   {
398 364
     // use <= minDist to choose the latest window with the lowest match
399
-    if((dist = _cmScFolDist(p->bufN, p->edWndMtx, p->bufV+i, p->loc + p->sbi+j, en )) < minDist )
365
+    if((dist = _cmScFolDist(p->bufN, p->edWndMtx, p->bufV+bbi, p->loc + p->sbi+j, en )) < minDist )
400 366
     {
401 367
       // only make an eql match if the posn is greater than the last location 
402 368
       if( dist==minDist && p->ret_idx != cmInvalidId && p->ret_idx >= p->sbi+minIdx+en-1 )
@@ -410,7 +376,7 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
410 376
   // The best fit is on the score window: p->loc[sbi+minIdx : sbi+minIdx+en-1 ]
411 377
 
412 378
   if( p->printFl )
413
-    _cmScFolRpt0( p, p->sbi, p->sei-p->sbi+1, p->bufV+i, en, minIdx );
379
+    _cmScFolRpt0( p, p->sbi, p->sei-p->sbi+1, p->bufV+bbi, en, minIdx );
414 380
     
415 381
   // save current missCnt for later printing
416 382
   unsigned missCnt = p->missCnt;
@@ -449,7 +415,7 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
449 415
     {
450 416
       // Look backward from the closest match location for a match to the current pitch.
451 417
       // The backward search scope is limited by the current value of 'missCnt'.
452
-
418
+      unsigned i;
453 419
       j = p->sbi+minIdx+en-2;
454 420
       for(i=1; i+1 <= p->bufN && j>=p->sbi && i<=p->missCnt; ++i,--j)
455 421
       {
@@ -469,6 +435,7 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
469 435
       // If the backward search did not find a match - look forward
470 436
       if( ret_idx == cmInvalidIdx )
471 437
       {
438
+        unsigned i;
472 439
         j = p->sbi+minIdx+en;
473 440
         for(i=0; j<=p->sei && i<p->forwardCnt; ++i,++j)
474 441
           if( _cmScFolIsMatch(p->loc+j,p->bufV[p->bufN-1].val) )
@@ -540,7 +507,262 @@ unsigned   cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByt
540 507
     p->sbi = p->sei  - p->bufN + 1;
541 508
   }
542 509
 
510
+  if( ret_idx != cmInvalidIdx )
511
+    ret_idx = p->loc[ret_idx].scIdx;
512
+
513
+  return ret_idx;
514
+}
515
+
516
+
517
+
518
+//=======================================================================================================================
519
+
520
+cmScTrk* cmScTrkAlloc( cmCtx* c, cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel )
521
+{
522
+  cmScTrk* op = cmObjAlloc(cmScTrk,c,p);
523
+
524
+  op->sfp = cmScFolAlloc(c,NULL,srate,scH,bufN,minWndLookAhead,maxWndCnt,minVel);
525
+
526
+  if( srate != 0 )
527
+    if( cmScTrkInit(op,srate,scH,bufN,minWndLookAhead,maxWndCnt,minVel) != cmOkRC )
528
+      cmScTrkFree(&op);
529
+  return op;
530
+}
531
+
532
+cmRC_t   cmScTrkFree(  cmScTrk** pp )
533
+{
534
+  cmRC_t rc = cmOkRC;
535
+  if( pp==NULL || *pp==NULL )
536
+    return rc;
537
+
538
+  cmScTrk* p = *pp;
539
+  if((rc = cmScTrkFinal(p)) != cmOkRC )
540
+    return rc;
541
+
542
+  cmScFolFree(&p->sfp);
543
+
544
+  cmObjFree(pp);
545
+  return rc;
546
+
547
+}
548
+
549
+void _cmScTrkPrint( cmScTrk* p )
550
+{
551
+  int i,j;
552
+  for(i=0; i<p->locN; ++i)
553
+  {
554
+    printf("%2i %5i ",p->loc[i].barNumb,p->loc[i].scIdx);
555
+    for(j=0; j<p->loc[i].evtCnt; ++j)
556
+      printf("%s ",cmMidiToSciPitch(p->loc[i].evtV[j].pitch,NULL,0));
557
+    printf("\n");
558
+  }
559
+}
560
+
561
+cmRC_t   cmScTrkInit(  cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel )
562
+{
563
+  cmRC_t rc;
564
+  if((rc = cmScTrkFinal(p)) != cmOkRC )
565
+    return rc;
566
+
567
+  if( minWndLookAhead > maxWndCnt )
568
+    return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The score follower look-ahead count (%i) must be less than the max. window length (%i).",minWndLookAhead,maxWndCnt); 
569
+
570
+  if((rc = cmScFolInit(p->sfp,srate,scH,bufN,minWndLookAhead,maxWndCnt,minVel)) != cmOkRC )
571
+    return rc;
572
+  
573
+  p->srate          = srate;
574
+  p->scH            = scH;
575
+  p->locN           = cmScoreLocCount(scH);
576
+  p->loc            = cmMemResizeZ(cmScTrkLoc_t,p->loc,p->locN);
577
+  p->minVel         = minVel;
578
+  p->maxWndCnt      = maxWndCnt;
579
+  p->minWndLookAhead= 3; //minWndLookAhead;
580
+  p->printFl        = false;
581
+  p->curLocIdx      = cmInvalidIdx;
582
+  p->evtIndex       = 0;
583
+
584
+  // for each score location
585
+  unsigned li;
586
+  
587
+  for(li=0; li<cmScoreLocCount(p->scH); ++li)
588
+  {
589
+    unsigned i,j,k,n;
590
+
591
+    const cmScoreLoc_t* lp = cmScoreLoc(p->scH,li);
592
+
593
+    // count the number of note events at location li
594
+    for(n=0,i=0; i<lp->evtCnt; ++i)
595
+      if( lp->evtArray[i]->type == kNonEvtScId )
596
+        ++n;
597
+
598
+    p->loc[li].evtCnt   = n;
599
+    p->loc[li].evtV     = cmMemAllocZ(cmScTrkEvt_t,n);
600
+    p->loc[li].scIdx    = li;
601
+    p->loc[li].barNumb  = lp->barNumb;
602
+    for(j=0,k=0; j<lp->evtCnt; ++j)
603
+      if( lp->evtArray[j]->type == kNonEvtScId )
604
+      {
605
+        p->loc[li].evtV[k].pitch    = lp->evtArray[j]->pitch;
606
+        p->loc[li].evtV[k].scEvtIdx = lp->evtArray[j]->index;
607
+        ++k;
608
+      }
609
+  }
610
+
611
+  //_cmScTrkPrint(p);
612
+
613
+  return rc;
614
+}
615
+
616
+cmRC_t   cmScTrkFinal( cmScTrk* p )
617
+{
618
+  unsigned i;
619
+  for(i=0; i<p->locN; ++i)
620
+    cmMemPtrFree(&p->loc[i].evtV);
621
+
622
+  return cmOkRC; 
623
+}
624
+
625
+cmRC_t   cmScTrkReset( cmScTrk* p, unsigned scEvtIdx )
626
+{
627
+  unsigned i;
628
+
629
+  cmScFolReset(p->sfp,scEvtIdx);
630
+
631
+  p->curLocIdx = cmInvalidIdx;
632
+  p->evtIndex  = 0;
633
+
634
+
635
+  // locate the score element in svV[] that is closest to,
636
+  // and possibly after, scEvtIdx.
637
+  for(i=0; i<p->locN; ++i)
638
+  {
639
+    unsigned j;
640
+
641
+    for(j=0; j<p->loc[i].evtCnt; ++j)
642
+    {
643
+      p->loc[i].evtV[j].matchFl = false;
644
+
645
+      // it is possible that scEvtIdx is before the first event included in p->loc[0]
646
+      // using the p->curLocIdx==cmInvalidIdx forces the first evt in p->loc[0] to be
647
+      // selected in this case
648
+      if( p->loc[i].evtV[j].scEvtIdx <= scEvtIdx || p->curLocIdx==cmInvalidIdx  )
649
+        p->curLocIdx = i;
650
+    }
651
+  }
652
+
653
+  if( p->curLocIdx == cmInvalidIdx )
654
+    return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The initial score search location event %i was not found.", scEvtIdx );
655
+
656
+  return cmOkRC;
657
+}
658
+
659
+unsigned _cmScTrkIsMatch(cmScTrk* p, int d, unsigned pitch )
660
+{
661
+  if( 0 <= p->curLocIdx + d && p->curLocIdx+1 < p->locN )
662
+  {
663
+    unsigned i;
664
+    const cmScTrkLoc_t* lp = p->loc + p->curLocIdx + d;
665
+    for(i=0; i<lp->evtCnt; ++i)
666
+      if( lp->evtV[i].pitch == pitch && lp->evtV[i].matchFl==false)
667
+        return i;      
668
+  }
669
+  return cmInvalidIdx;
670
+}
671
+
672
+void _cmScTrkRpt0( cmScTrk* p,  unsigned pitch, unsigned vel, unsigned nli, unsigned nei )
673
+{
674
+  bool missFl = nli==cmInvalidIdx || nei==cmInvalidIdx;
675
+
676
+  printf("------- event:%i %s vel:%i cur:%i new:%i %s-------\n",p->evtIndex,cmMidiToSciPitch(pitch,NULL,0),vel,p->curLocIdx,nli,missFl?"MISS ":"");
677
+
678
+  int bi = p->curLocIdx < p->minWndLookAhead ? 0 : p->curLocIdx - p->minWndLookAhead;  
679
+  int ei = cmMin(p->locN-1,p->curLocIdx+p->minWndLookAhead);
680
+  unsigned i,n=0;
681
+  for(i=bi; i<=ei; ++i)
682
+    if( p->loc[i].evtCnt>n )
683
+      n = p->loc[i].evtCnt;
684
+    
685
+  printf("loc  ");
686
+  for(i=bi; i<=ei; ++i)
687
+    printf("%4i   ",i);
688
+  printf("\n");
689
+
690
+  for(i=0; i<n; ++i)
691
+  {
692
+    unsigned j;
693
+    printf("sc%2i ",i);
694
+    for(j=bi; j<=ei; ++j)
695
+    {
696
+      if( i < p->loc[j].evtCnt )
697
+      {
698
+        char* X = p->loc[j].evtV[i].matchFl ?  "__" : "  ";
699
+
700
+        if( nli==j && nei==i)
701
+        {
702
+          X = "**";
703
+          assert( p->loc[j].evtV[i].pitch == pitch );
704
+        }
705
+
706
+        printf("%4s%s ",cmMidiToSciPitch(p->loc[j].evtV[i].pitch,NULL,0),X);
707
+      }
708
+      else
709
+        printf("       ");
710
+    }
711
+    printf("\n");
712
+  }
713
+
714
+}
715
+
716
+
717
+unsigned cmScTrkExec(  cmScTrk* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 )
718
+{
719
+  unsigned ret_idx = cmInvalidIdx;
720
+
721
+  //cmScFolExec(p->sfp, smpIdx, status, d0, d1);
722
+
723
+  if( status != kNoteOnMdId )
724
+    return cmInvalidIdx;
725
+
726
+  if( p->curLocIdx == cmInvalidIdx )
727
+  {
728
+    cmCtxRtCondition( &p->obj, cmInvalidArgRC, "An initial score search location has not been set." );
729
+    return cmInvalidIdx;
730
+  }
731
+ 
732
+  int i,nei,nli=cmInvalidIdx;
733
+
734
+  // try to match curLocIdx first
735
+  if((nei = _cmScTrkIsMatch(p,0,d0)) != cmInvalidIdx )
736
+    nli = p->curLocIdx;
737
+
738
+  for(i=1; nei==cmInvalidIdx && i<p->minWndLookAhead; ++i)
739
+  {
740
+    // go forward 
741
+    if((nei = _cmScTrkIsMatch(p,i,d0)) != cmInvalidIdx )
742
+      nli = p->curLocIdx + i;
743
+    else
744
+      // go backward
745
+      if((nei = _cmScTrkIsMatch(p,-i,d0)) != cmInvalidIdx )
746
+        nli = p->curLocIdx - i;
747
+  }
748
+  
749
+  if( p->printFl )
750
+  {
751
+    _cmScTrkRpt0(p, d0, d1, nli, nei );
752
+  }
753
+
754
+
755
+  if( nli != cmInvalidIdx )
756
+  {
757
+    p->loc[nli].evtV[nei].matchFl = true;
758
+    ret_idx = p->loc[nli].scIdx;
759
+    
760
+    if( nli > p->curLocIdx )
761
+      p->curLocIdx = nli;
762
+        
763
+  }
543 764
 
765
+  ++p->evtIndex;
544 766
 
545 767
   return ret_idx;
546 768
 }

+ 58
- 6
cmProc4.h View File

@@ -11,16 +11,21 @@ typedef struct
11 11
 {
12 12
   unsigned     smpIdx;  // time tag sample index for val
13 13
   cmMidiByte_t val;     //
14
-  bool         validFl; //
15
-  
14
+  bool         validFl; //  
16 15
 } cmScFolBufEle_t;
17 16
 
18 17
 typedef struct
19 18
 {
20
-  unsigned  pitchCnt; // 
21
-  unsigned* pitchV;   // pitchV[pitchCnt]
22
-  unsigned  scIdx;    // index of the score event (into cmScoreEvt[]) at this location 
23
-  int       barNumb;  // bar number of this location
19
+  unsigned pitch;
20
+  unsigned scEvtIdx;
21
+} cmScFolEvt_t;
22
+
23
+typedef struct
24
+{
25
+  unsigned      evtCnt; // 
26
+  cmScFolEvt_t* evtV;   // pitchV[pitchCnt]
27
+  unsigned      scIdx;    // index of the score loc (into cmScoreEvt[]) at this location 
28
+  int           barNumb;  // bar number of this location
24 29
 } cmScFolLoc_t;
25 30
 
26 31
 
@@ -63,6 +68,53 @@ cmRC_t   cmScFolReset( cmScFol* p, unsigned scoreIndex );
63 68
 // Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
64 69
 // all others are ignored.
65 70
 unsigned cmScFolExec(  cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
71
+
72
+//=======================================================================================================================
73
+
74
+typedef struct
75
+{
76
+  unsigned pitch;
77
+  unsigned scEvtIdx;
78
+  bool     matchFl;
79
+} cmScTrkEvt_t;
80
+
81
+typedef struct
82
+{
83
+  unsigned      evtCnt;         // 
84
+  cmScTrkEvt_t* evtV;           // evtV[evtCnt]
85
+  unsigned      scIdx;          // index of the score event (into cmScoreEvt[]) at this location 
86
+  int           barNumb;        // bar number of this location
87
+} cmScTrkLoc_t;
88
+
89
+typedef struct
90
+{
91
+  cmObj         obj;
92
+  cmScFol*      sfp; 
93
+  double        srate;
94
+  cmScH_t       scH;
95
+  unsigned      locN;
96
+  cmScTrkLoc_t* loc;
97
+  unsigned      minVel;
98
+  unsigned      maxWndCnt;
99
+  unsigned      minWndLookAhead;
100
+  bool          printFl;
101
+
102
+  int           curLocIdx;
103
+  unsigned      evtIndex;
104
+
105
+} cmScTrk;
106
+
107
+cmScTrk* cmScTrkAlloc( cmCtx* ctx, cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
108
+cmRC_t   cmScTrkFree(  cmScTrk** pp );
109
+cmRC_t   cmScTrkInit(  cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
110
+cmRC_t   cmScTrkFinal( cmScTrk* p );
111
+
112
+// Jump to a score location and reset the internal state of the follower.
113
+cmRC_t   cmScTrkReset( cmScTrk* p, unsigned scoreIndex );
114
+
115
+// Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
116
+// all others are ignored.
117
+unsigned cmScTrkExec(  cmScTrk* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
66 118
   
67 119
 
68 120
 #ifdef __cplusplus

Loading…
Cancel
Save