|
@@ -89,7 +89,8 @@ typedef struct
|
89
|
89
|
typedef struct
|
90
|
90
|
{
|
91
|
91
|
cmErr_t err;
|
92
|
|
-
|
|
92
|
+
|
|
93
|
+ cmChar_t* scFn;
|
93
|
94
|
cmSmgSc_t* scV; // scV[scN] score bars and notes
|
94
|
95
|
unsigned scN;
|
95
|
96
|
|
|
@@ -99,7 +100,8 @@ typedef struct
|
99
|
100
|
cmSmgLine_t* lines; // Graphic lines used to indicate that a midi event matches to multiple score notes.
|
100
|
101
|
// (Each match after the first gets a line from the box representing the midi event
|
101
|
102
|
// to the matching score event)
|
102
|
|
-
|
|
103
|
+
|
|
104
|
+ cmChar_t* mfFn; // MIDI file name
|
103
|
105
|
cmSmgMidi_t* mV; // mV[mN] midi note-on events
|
104
|
106
|
unsigned mN;
|
105
|
107
|
double mfDurSecs; // midi file duration in seconds
|
|
@@ -120,6 +122,7 @@ cmSmg_t* _cmSmgHandleToPtr( cmSmgH_t h )
|
120
|
122
|
cmSmgRC_t _cmSmgFree( cmSmg_t* p )
|
121
|
123
|
{
|
122
|
124
|
unsigned i;
|
|
125
|
+
|
123
|
126
|
|
124
|
127
|
for(i=0; i<p->mN; ++i)
|
125
|
128
|
{
|
|
@@ -155,7 +158,9 @@ cmSmgRC_t _cmSmgFree( cmSmg_t* p )
|
155
|
158
|
cmMemFree(l0);
|
156
|
159
|
l0 = l1;
|
157
|
160
|
}
|
158
|
|
-
|
|
161
|
+
|
|
162
|
+ cmMemFree(p->scFn);
|
|
163
|
+ cmMemFree(p->mfFn);
|
159
|
164
|
cmMemFree(p->scV);
|
160
|
165
|
cmMemFree(p->mV);
|
161
|
166
|
cmMemFree(p->locV);
|
|
@@ -198,6 +203,7 @@ cmSmgRC_t _cmSmgInitFromScore( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* scoreFn
|
198
|
203
|
if( cmScoreInitialize(ctx,&scH,scoreFn,44100.0, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
|
199
|
204
|
return cmErrMsg(&p->err,kScoreFailSmgRC,"Score initializatio failed on '%s'.",cmStringNullGuard(scoreFn));
|
200
|
205
|
|
|
206
|
+ p->scFn = cmMemAllocStr(scoreFn);
|
201
|
207
|
p->scN = cmScoreEvtCount(scH);
|
202
|
208
|
p->scV = cmMemAllocZ(cmSmgSc_t,p->scN);
|
203
|
209
|
|
|
@@ -269,6 +275,7 @@ cmSmgRC_t _cmSmgInitFromMidi( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* midiFn )
|
269
|
275
|
p->mV = cmMemAllocZ(cmSmgMidi_t,mN);
|
270
|
276
|
p->mN = mN;
|
271
|
277
|
p->mfDurSecs = cmMidiFileDurSecs(mfH);
|
|
278
|
+ p->mfFn = cmMemAllocStr(midiFn);
|
272
|
279
|
|
273
|
280
|
for(i=0,j=0; i<mN; ++i)
|
274
|
281
|
if( (mV[i]!=NULL) && cmMidiIsChStatus(mV[i]->status) && cmMidiIsNoteOn(mV[i]->status) && (mV[i]->u.chMsgPtr->d1>0) )
|
|
@@ -606,3 +613,57 @@ cmSmgRC_t cmScoreMatchGraphicGenTimeLineBars( cmSmgH_t h, const cmChar_t* fn, un
|
606
|
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
|
+}
|