|
@@ -28,7 +28,8 @@ enum
|
28
|
28
|
kPedalSmgFl = 0x0008,
|
29
|
29
|
kSostSmgFl = 0x0010,
|
30
|
30
|
kMidiSmgFl = 0x0020,
|
31
|
|
- kNoMatchSmgFl = 0x0040
|
|
31
|
+ kNoMatchSmgFl = 0x0040,
|
|
32
|
+ kPedalDnSmgFl = 0x0080
|
32
|
33
|
};
|
33
|
34
|
|
34
|
35
|
// Graphic box representing a score label or MIDI event
|
|
@@ -246,6 +247,8 @@ cmSmgRC_t _cmSmgInitFromScore( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* scoreFn
|
246
|
247
|
|
247
|
248
|
if( e->pitch == kSostenutoCtlMdId )
|
248
|
249
|
flags |= kSostSmgFl;
|
|
250
|
+
|
|
251
|
+ flags |= cmIsFlag(e->flags,kPedalDnScFl) ? kPedalDnSmgFl : 0;
|
249
|
252
|
|
250
|
253
|
break;
|
251
|
254
|
}
|
|
@@ -635,26 +638,91 @@ cmSmgRC_t cmScoreMatchGraphicGenTimeLineBars( cmSmgH_t h, const cmChar_t* fn, un
|
635
|
638
|
return rc;
|
636
|
639
|
|
637
|
640
|
}
|
638
|
|
-/*
|
639
|
|
-cmSmRC_t _cmScoreMatchGraphicUpdateSostenuto( cmSmg_t* p, cmMidiFileH_t mfH, cmScH_t scH )
|
|
641
|
+
|
|
642
|
+// Find the first MIDI event that matches this score event
|
|
643
|
+const cmSmgMidi_t* _cmScoreMatchGraphicScoreToMatchedMidiEvent( cmSmg_t* p, const cmSmgSc_t* sc )
|
640
|
644
|
{
|
641
|
|
- unsigned evtN = cmScoreEvtCount(scH);
|
642
|
645
|
unsigned i;
|
643
|
|
- const cmScoreEvt_t* e;
|
644
|
|
- const cmScoreEvt_t* e0 = NULL;
|
645
|
|
- for(i=0; i<evtN; ++i)
|
646
|
|
-
|
647
|
|
- if( e->type == kNonEvtScId )
|
648
|
|
-
|
649
|
|
-
|
|
646
|
+ for(i=0; i<p->mN; ++i)
|
|
647
|
+ {
|
|
648
|
+ const cmSmgMatch_t* m = p->mV[i].matchV;
|
650
|
649
|
|
651
|
|
-
|
652
|
|
- if( e->type == kPedalEvtScId && e->pitch == kSostenutoCtlMdId )
|
|
650
|
+ for(; m != NULL; m=m->link )
|
|
651
|
+ if( sc->csvEventId == m->score->csvEventId )
|
|
652
|
+ return p->mV + i;
|
|
653
|
+
|
|
654
|
+ }
|
|
655
|
+
|
|
656
|
+ return NULL;
|
|
657
|
+}
|
|
658
|
+
|
|
659
|
+cmSmgRC_t _cmScoreMatchGraphicInsertMidiMsg( cmSmg_t* p, cmMidiFileH_t mfH, bool pedalDnFl, const cmSmgSc_t* s )
|
|
660
|
+{
|
|
661
|
+ const cmSmgMidi_t* m;
|
|
662
|
+
|
|
663
|
+ // locate the MIDI event associated with the reference event
|
|
664
|
+ if((m =_cmScoreMatchGraphicScoreToMatchedMidiEvent( p, s )) == NULL )
|
|
665
|
+ return cmErrWarnMsg(&p->err,kMatchFailSmgRC,"A sostenuto pedal msg could not be aligned to a note event.");
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+ int dtick_offset = pedalDnFl ? 1 : -1;
|
|
669
|
+ cmMidiByte_t midi_vel = pedalDnFl ? 64 : 0;
|
|
670
|
+ cmMidiByte_t midi_ch = 0;
|
|
671
|
+
|
|
672
|
+ printf("pedal:%s\n",pedalDnFl?"down":"up");
|
|
673
|
+
|
|
674
|
+ // insert a pedal msg relative to the reference event
|
|
675
|
+ if( cmMidiFileInsertMsg(mfH, m->uid, dtick_offset, midi_ch, kCtlMdId, kSostenutoCtlMdId, midi_vel ) != kOkMfRC )
|
|
676
|
+ return cmErrWarnMsg(&p->err,kMidiFileFailSmgRC,"MIDI msg insert failed.");
|
|
677
|
+
|
|
678
|
+ return kOkSmgRC;
|
|
679
|
+
|
|
680
|
+}
|
|
681
|
+
|
|
682
|
+cmSmgRC_t _cmScoreMatchGraphicUpdateSostenuto( cmSmg_t* p, cmMidiFileH_t mfH )
|
|
683
|
+{
|
|
684
|
+ cmSmgRC_t rc = kOkSmgRC;
|
|
685
|
+ unsigned i, j = cmInvalidIdx;
|
|
686
|
+ bool pedalUpFl = false;
|
|
687
|
+
|
|
688
|
+ for(i=0; i<p->scN; ++i)
|
|
689
|
+ {
|
|
690
|
+ switch( p->scV[i].type )
|
653
|
691
|
{
|
654
|
|
-
|
|
692
|
+ case kNonEvtScId:
|
|
693
|
+ {
|
|
694
|
+ if( pedalUpFl )
|
|
695
|
+ {
|
|
696
|
+ _cmScoreMatchGraphicInsertMidiMsg(p, mfH, false, p->scV + i );
|
|
697
|
+ pedalUpFl = false;
|
|
698
|
+ }
|
|
699
|
+
|
|
700
|
+ j = i; // store the index of this note event (it may be needed if the next event is a sost. pedal evt.)
|
|
701
|
+ }
|
|
702
|
+ break;
|
|
703
|
+
|
|
704
|
+ case kPedalEvtScId:
|
|
705
|
+ // if this is a sost pedal event
|
|
706
|
+ if( cmIsFlag(p->scV[i].box->flags,kSostSmgFl) )
|
|
707
|
+ {
|
|
708
|
+ if( cmIsFlag(p->scV[i].box->flags,kPedalDnSmgFl) )
|
|
709
|
+ {
|
|
710
|
+ assert( j != cmInvalidIdx );
|
|
711
|
+ _cmScoreMatchGraphicInsertMidiMsg(p, mfH, true, p->scV + j );
|
|
712
|
+ }
|
|
713
|
+ else
|
|
714
|
+ {
|
|
715
|
+ pedalUpFl = true; // insert a pedal up message before the next note-on
|
|
716
|
+ }
|
|
717
|
+ }
|
|
718
|
+
|
|
719
|
+ default:
|
|
720
|
+ break;
|
655
|
721
|
}
|
|
722
|
+ }
|
|
723
|
+ return rc;
|
656
|
724
|
}
|
657
|
|
-*/
|
|
725
|
+
|
658
|
726
|
cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, const cmChar_t* newMidiFn )
|
659
|
727
|
{
|
660
|
728
|
cmSmgRC_t rc = kOkSmgRC;
|
|
@@ -696,6 +764,9 @@ cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, cons
|
696
|
764
|
|
697
|
765
|
}
|
698
|
766
|
|
|
767
|
+ // update the sostenuto pedal msg's in the MIDI file.
|
|
768
|
+ _cmScoreMatchGraphicUpdateSostenuto(p, mfH );
|
|
769
|
+
|
699
|
770
|
// write the updated MIDI file
|
700
|
771
|
if( cmMidiFileWrite( mfH, newMidiFn ) != kOkMfRC )
|
701
|
772
|
{
|
|
@@ -703,6 +774,8 @@ cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, cons
|
703
|
774
|
goto errLabel;
|
704
|
775
|
}
|
705
|
776
|
|
|
777
|
+ cmMidiFilePrintMsgs(mfH, p->err.rpt );
|
|
778
|
+
|
706
|
779
|
|
707
|
780
|
errLabel:
|
708
|
781
|
cmMidiFileClose(&mfH);
|