瀏覽代碼

cmScoreMatchGraphic.h/c : Added cmScoreMatchGraphicUpdateMidiFromScore() to set the MIDI note velocities based on the score velocities.

master
kevin 8 年之前
父節點
當前提交
3acdeb61a0
共有 2 個檔案被更改,包括 71 行新增4 行删除
  1. 64
    3
      app/cmScoreMatchGraphic.c
  2. 7
    1
      app/cmScoreMatchGraphic.h

+ 64
- 3
app/cmScoreMatchGraphic.c 查看文件

89
 typedef struct
89
 typedef struct
90
 {
90
 {
91
   cmErr_t      err;
91
   cmErr_t      err;
92
-  
92
+
93
+  cmChar_t*    scFn;
93
   cmSmgSc_t*   scV;    // scV[scN] score bars and notes
94
   cmSmgSc_t*   scV;    // scV[scN] score bars and notes
94
   unsigned     scN;
95
   unsigned     scN;
95
   
96
   
99
   cmSmgLine_t* lines;  // Graphic lines used to indicate that a midi event matches to multiple score notes.
100
   cmSmgLine_t* lines;  // Graphic lines used to indicate that a midi event matches to multiple score notes.
100
                        // (Each match after the first gets a line from the box representing the midi event
101
                        // (Each match after the first gets a line from the box representing the midi event
101
                        //  to the matching score event)
102
                        //  to the matching score event)
102
-  
103
+
104
+  cmChar_t*    mfFn;   // MIDI file name
103
   cmSmgMidi_t* mV;     // mV[mN] midi note-on events
105
   cmSmgMidi_t* mV;     // mV[mN] midi note-on events
104
   unsigned     mN;
106
   unsigned     mN;
105
   double       mfDurSecs; // midi file duration in seconds
107
   double       mfDurSecs; // midi file duration in seconds
120
 cmSmgRC_t _cmSmgFree( cmSmg_t* p )
122
 cmSmgRC_t _cmSmgFree( cmSmg_t* p )
121
 {
123
 {
122
   unsigned i;
124
   unsigned i;
125
+
123
   
126
   
124
   for(i=0; i<p->mN; ++i)
127
   for(i=0; i<p->mN; ++i)
125
   {
128
   {
155
     cmMemFree(l0);
158
     cmMemFree(l0);
156
     l0 = l1;
159
     l0 = l1;
157
   }
160
   }
158
-  
161
+
162
+  cmMemFree(p->scFn);
163
+  cmMemFree(p->mfFn);
159
   cmMemFree(p->scV);
164
   cmMemFree(p->scV);
160
   cmMemFree(p->mV);
165
   cmMemFree(p->mV);
161
   cmMemFree(p->locV);
166
   cmMemFree(p->locV);
198
   if( cmScoreInitialize(ctx,&scH,scoreFn,44100.0, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
203
   if( cmScoreInitialize(ctx,&scH,scoreFn,44100.0, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
199
     return cmErrMsg(&p->err,kScoreFailSmgRC,"Score initializatio failed on '%s'.",cmStringNullGuard(scoreFn));
204
     return cmErrMsg(&p->err,kScoreFailSmgRC,"Score initializatio failed on '%s'.",cmStringNullGuard(scoreFn));
200
 
205
 
206
+  p->scFn = cmMemAllocStr(scoreFn);
201
   p->scN  = cmScoreEvtCount(scH);
207
   p->scN  = cmScoreEvtCount(scH);
202
   p->scV  = cmMemAllocZ(cmSmgSc_t,p->scN);
208
   p->scV  = cmMemAllocZ(cmSmgSc_t,p->scN);
203
   
209
   
269
   p->mV        = cmMemAllocZ(cmSmgMidi_t,mN);
275
   p->mV        = cmMemAllocZ(cmSmgMidi_t,mN);
270
   p->mN        = mN;
276
   p->mN        = mN;
271
   p->mfDurSecs = cmMidiFileDurSecs(mfH);
277
   p->mfDurSecs = cmMidiFileDurSecs(mfH);
278
+  p->mfFn      = cmMemAllocStr(midiFn);
272
   
279
   
273
   for(i=0,j=0; i<mN; ++i)
280
   for(i=0,j=0; i<mN; ++i)
274
     if( (mV[i]!=NULL) && cmMidiIsChStatus(mV[i]->status) && cmMidiIsNoteOn(mV[i]->status) && (mV[i]->u.chMsgPtr->d1>0) )          
281
     if( (mV[i]!=NULL) && cmMidiIsChStatus(mV[i]->status) && cmMidiIsNoteOn(mV[i]->status) && (mV[i]->u.chMsgPtr->d1>0) )          
606
   return rc;
613
   return rc;
607
   
614
   
608
 }
615
 }
616
+
617
+cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, const cmChar_t* newMidiFn )
618
+{
619
+  cmSmgRC_t     rc  = kOkSmgRC;
620
+  cmSmg_t*      p   = _cmSmgHandleToPtr(h);
621
+  unsigned      i   = 0;
622
+  cmMidiFileH_t mfH = cmMidiFileNullHandle;
623
+  cmScH_t       scH = cmScNullHandle;
624
+  
625
+  if( cmMidiFileOpen(ctx, &mfH, p->mfFn ) != kOkMfRC )
626
+    return cmErrMsg(&p->err,kMidiFileFailSmgRC,"MIDI file open failed on '%s'.",cmStringNullGuard(p->mfFn));
627
+  
628
+  if( cmScoreInitialize(ctx,&scH,p->scFn,44100.0, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
629
+  {
630
+    rc = cmErrMsg(&p->err,kScoreFailSmgRC,"Score initializatio failed on '%s'.",cmStringNullGuard(p->scFn));
631
+    goto errLabel;
632
+  } 
633
+  
634
+  for(i=0; i<p->mN; ++i)
635
+  {
636
+    cmSmgMidi_t* mr = p->mV + i;
637
+
638
+    // only update midi events which were matched exactly once
639
+    if( mr->matchV==NULL || mr->matchV->link!=NULL  )
640
+      continue;
641
+
642
+    // locate the matched score event
643
+    const cmScoreEvt_t* s= cmScoreIdToEvt( scH, mr->matchV->score->csvEventId );
644
+    assert( s!=NULL );
645
+
646
+    // assign the score velocity to the MIDI file
647
+    if(cmMidiFileSetVelocity( mfH, mr->uid, s->vel ) != kOkMfRC )
648
+    {
649
+      rc = cmErrMsg(&p->err,kOpFailSmgRC,"Set velocify operation failed.");
650
+      goto errLabel;
651
+    }
652
+
653
+  }
654
+
655
+  // write the updated MIDI file
656
+  if( cmMidiFileWrite( mfH, newMidiFn ) != kOkMfRC )
657
+  {
658
+    rc = cmErrMsg(&p->err,kMidiFileFailSmgRC,"MIDI file write failed on '%s'.",cmStringNullGuard(newMidiFn));
659
+    goto errLabel;
660
+  }
661
+
662
+
663
+ errLabel:
664
+  cmMidiFileClose(&mfH);
665
+  cmScoreFinalize(&scH);
666
+  
667
+  return rc;
668
+ 
669
+}

+ 7
- 1
app/cmScoreMatchGraphic.h 查看文件

10
     kOkSmgRC = cmOkRC,
10
     kOkSmgRC = cmOkRC,
11
     kFileSmgRC,
11
     kFileSmgRC,
12
     kScoreFailSmgRC,
12
     kScoreFailSmgRC,
13
-    kMidiFileFailSmgRC
13
+    kMidiFileFailSmgRC,
14
+    kOpFailSmgRC
14
   };
15
   };
15
   
16
   
16
   typedef cmRC_t     cmSmgRC_t;
17
   typedef cmRC_t     cmSmgRC_t;
27
   // Generate a set of markers for use in a cmTimeLine file which forms a marked area
28
   // Generate a set of markers for use in a cmTimeLine file which forms a marked area
28
   // beginning at each bar line and ends at the end of the file.
29
   // beginning at each bar line and ends at the end of the file.
29
   cmSmgRC_t cmScoreMatchGraphicGenTimeLineBars( cmSmgH_t h, const cmChar_t* fn, unsigned srate );
30
   cmSmgRC_t cmScoreMatchGraphicGenTimeLineBars( cmSmgH_t h, const cmChar_t* fn, unsigned srate );
31
+
32
+  // Update the MIDI file velocity values and insert pedal events
33
+  // from from score into MIDI file and then write the updated MIDI
34
+  // file to 'newMidiFn'.
35
+  cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, const cmChar_t* newMidiFn );
30
   
36
   
31
 #ifdef __cplusplus
37
 #ifdef __cplusplus
32
 }
38
 }

Loading…
取消
儲存