|
@@ -12,6 +12,7 @@
|
12
|
12
|
#include "cmXScore.h"
|
13
|
13
|
#include "cmTime.h"
|
14
|
14
|
#include "cmMidi.h"
|
|
15
|
+#include "cmMidiFile.h"
|
15
|
16
|
#include "cmLex.h"
|
16
|
17
|
#include "cmCsv.h"
|
17
|
18
|
|
|
@@ -35,7 +36,8 @@ enum
|
35
|
36
|
kPedalDnXsFl = 0x02000,
|
36
|
37
|
kPedalUpXsFl = 0x04000,
|
37
|
38
|
kPedalUpDnXsFl = 0x08000,
|
38
|
|
- kMetronomeXsFl = 0x10000 // duration holds BPM
|
|
39
|
+ kMetronomeXsFl = 0x10000, // duration holds BPM
|
|
40
|
+ kOnsetXsFl = 0x20000 // this is a sounding note
|
39
|
41
|
};
|
40
|
42
|
|
41
|
43
|
struct cmXsMeas_str;
|
|
@@ -45,16 +47,18 @@ typedef struct cmXsNote_str
|
45
|
47
|
{
|
46
|
48
|
unsigned flags; // See k???XsFl
|
47
|
49
|
unsigned pitch; // midi pitch
|
|
50
|
+ unsigned velocity; // midi velocity
|
48
|
51
|
cmChar_t step; // A-G
|
49
|
52
|
unsigned octave; // sci pitch octave
|
50
|
53
|
int alter; // +n=sharps,-n=flats
|
|
54
|
+ unsigned staff;
|
51
|
55
|
unsigned tick; //
|
52
|
56
|
unsigned duration; // duration in ticks
|
53
|
57
|
double rvalue; // 1/rvalue = rythmic value (1/0.5 double whole 1/1 whole 1/2 half 1/4=quarter note, 1/8=eighth note, ...)
|
54
|
58
|
const cmChar_t* tvalue; // text value
|
55
|
59
|
|
56
|
|
- const struct cmXsVoice_str* voice; // voice this note belongs to
|
57
|
|
- const struct cmXsMeas_str* meas; // measure this note belongs to
|
|
60
|
+ struct cmXsVoice_str* voice; // voice this note belongs to
|
|
61
|
+ struct cmXsMeas_str* meas; // measure this note belongs to
|
58
|
62
|
|
59
|
63
|
const cmXmlNode_t* xmlNode; // note xml ptr
|
60
|
64
|
|
|
@@ -63,15 +67,6 @@ typedef struct cmXsNote_str
|
63
|
67
|
|
64
|
68
|
} cmXsNote_t;
|
65
|
69
|
|
66
|
|
-typedef struct cmXsConnect_str
|
67
|
|
-{
|
68
|
|
- bool doneFl; // this tie has been completed (slurs only occur in pairs)
|
69
|
|
- bool closeFl;// this tie was properly closed
|
70
|
|
- const cmXsNote_t* note; // associated
|
71
|
|
- struct cmXsConnect_str* nlink; // next connected note
|
72
|
|
- struct cmXsConnect_str* link; // p->tieL,p->slurL links
|
73
|
|
-} cmXsConnect_t;
|
74
|
|
-
|
75
|
70
|
typedef struct cmXsVoice_str
|
76
|
71
|
{
|
77
|
72
|
unsigned id; // Voice id
|
|
@@ -79,6 +74,17 @@ typedef struct cmXsVoice_str
|
79
|
74
|
struct cmXsVoice_str* link; // Link to other voices in this measure
|
80
|
75
|
} cmXsVoice_t;
|
81
|
76
|
|
|
77
|
+typedef struct cmXsSpan_str
|
|
78
|
+{
|
|
79
|
+ unsigned staff;
|
|
80
|
+ unsigned number;
|
|
81
|
+ struct cmXsMeas_str* meas;
|
|
82
|
+ unsigned tick0;
|
|
83
|
+ unsigned tick1;
|
|
84
|
+ int pitch_offset;
|
|
85
|
+ struct cmXsSpan_str* link;
|
|
86
|
+} cmXsSpan_t;
|
|
87
|
+
|
82
|
88
|
typedef struct cmXsMeas_str
|
83
|
89
|
{
|
84
|
90
|
unsigned number; // Measure number
|
|
@@ -107,8 +113,7 @@ typedef struct
|
107
|
113
|
cmXsPart_t* partL;
|
108
|
114
|
cmCsvH_t csvH;
|
109
|
115
|
|
110
|
|
- cmXsConnect_t* slurL;
|
111
|
|
- cmXsConnect_t* tieL;
|
|
116
|
+ cmXsSpan_t* spanL;
|
112
|
117
|
} cmXScore_t;
|
113
|
118
|
|
114
|
119
|
cmXScore_t* _cmXScoreHandleToPtr( cmXsH_t h )
|
|
@@ -262,6 +267,7 @@ cmXsRC_t _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
|
262
|
267
|
np->step = *step;
|
263
|
268
|
np->octave = octave;
|
264
|
269
|
np->alter = alter;
|
|
270
|
+ np->flags |= kOnsetXsFl;
|
265
|
271
|
|
266
|
272
|
return rc;
|
267
|
273
|
}
|
|
@@ -400,8 +406,9 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
|
400
|
406
|
if((rc = _cmXScoreParsePitch(p,nnp,note)) != kOkXsRC )
|
401
|
407
|
return rc;
|
402
|
408
|
|
403
|
|
- // get the note duration
|
404
|
|
- cmXmlNodeUInt(nnp,¬e->duration,"duration",NULL);
|
|
409
|
+
|
|
410
|
+ cmXmlNodeUInt(nnp,¬e->duration,"duration",NULL); // get the note duration
|
|
411
|
+ cmXmlNodeUInt(nnp,¬e->staff,"staff",NULL); // get th staff number
|
405
|
412
|
|
406
|
413
|
// is 'rest'
|
407
|
414
|
if( cmXmlNodeHasChild(nnp,"rest",NULL) )
|
|
@@ -472,6 +479,45 @@ cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_
|
472
|
479
|
return _cmXScorePushNote(p, meas, voiceId, note );
|
473
|
480
|
}
|
474
|
481
|
|
|
482
|
+cmXsSpan_t* _cmXScoreFindOpenOctaveShift( cmXScore_t* p, unsigned staff, unsigned number )
|
|
483
|
+{
|
|
484
|
+ cmXsSpan_t* s = p->spanL;
|
|
485
|
+ for(; s!=NULL; s=s->link)
|
|
486
|
+ if( s->tick1 == -1 && s->staff == staff && s->number == number )
|
|
487
|
+ return s;
|
|
488
|
+
|
|
489
|
+ return NULL;
|
|
490
|
+}
|
|
491
|
+
|
|
492
|
+cmXsRC_t _cmXScorePushOctaveShift(cmXScore_t* p, cmXsMeas_t* meas, unsigned staff, unsigned span_number, const cmChar_t* type_str, unsigned tick)
|
|
493
|
+{
|
|
494
|
+ assert( meas != NULL);
|
|
495
|
+
|
|
496
|
+ cmXsSpan_t* s;
|
|
497
|
+ if( cmTextCmp(type_str,"stop") == 0 )
|
|
498
|
+ {
|
|
499
|
+ if((s = _cmXScoreFindOpenOctaveShift(p,staff,span_number)) == NULL )
|
|
500
|
+ return cmErrWarnMsg(&p->err,kUnterminatedOctaveShiftXsrRC,"An illegal octave shift was encounted in meas %i.\n",meas->number);
|
|
501
|
+
|
|
502
|
+ s->tick1 = tick;
|
|
503
|
+ }
|
|
504
|
+ else
|
|
505
|
+ {
|
|
506
|
+ s = cmLhAllocZ(p->lhH,cmXsSpan_t,1);
|
|
507
|
+ s->staff = staff;
|
|
508
|
+ s->meas = meas;
|
|
509
|
+ s->number = span_number;
|
|
510
|
+ s->tick0 = tick;
|
|
511
|
+ s->tick1 = -1;
|
|
512
|
+ s->pitch_offset = cmTextCmp(type_str,"up")==0 ? -12 : 12;
|
|
513
|
+ s->link = p->spanL;
|
|
514
|
+ p->spanL = s;
|
|
515
|
+ }
|
|
516
|
+
|
|
517
|
+ return kOkXsRC;
|
|
518
|
+}
|
|
519
|
+
|
|
520
|
+
|
475
|
521
|
cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* dnp, unsigned tick)
|
476
|
522
|
{
|
477
|
523
|
cmXsRC_t rc = kOkXsRC;
|
|
@@ -483,9 +529,11 @@ cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
|
483
|
529
|
const cmChar_t* tvalue = NULL;
|
484
|
530
|
unsigned duration = 0;
|
485
|
531
|
bool pushFl = true;
|
486
|
|
-
|
487
|
|
- cmXmlNodeInt(dnp, &offset, "offset", NULL );
|
488
|
|
-
|
|
532
|
+ unsigned staff = 0;
|
|
533
|
+
|
|
534
|
+ cmXmlNodeInt( dnp, &offset, "offset", NULL );
|
|
535
|
+ cmXmlNodeUInt(dnp, &staff, "staff", NULL );
|
|
536
|
+
|
489
|
537
|
// if this is a metronome direction
|
490
|
538
|
if((np = cmXmlSearch( dnp, "metronome", NULL, 0)) != NULL )
|
491
|
539
|
{
|
|
@@ -532,6 +580,24 @@ cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
|
532
|
580
|
}
|
533
|
581
|
}
|
534
|
582
|
else
|
|
583
|
+
|
|
584
|
+ // if this is an 'octave-shift' direction
|
|
585
|
+ if((np = cmXmlSearch( dnp, "octave-shift", NULL, 0)) != NULL )
|
|
586
|
+ {
|
|
587
|
+ unsigned span_number = -1;
|
|
588
|
+ if( cmXmlAttrUInt(np,"number",&span_number) != kOkXmlRC )
|
|
589
|
+ return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Octave-shift is missing a 'number' attribute.");
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+ if((a = cmXmlFindAttrib(np,"type")) == NULL)
|
|
593
|
+ return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Octave-shift is missing a 'type' attribute.");
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+ rc = _cmXScorePushOctaveShift(p,meas,staff,span_number,a->value,tick+offset);
|
|
597
|
+
|
|
598
|
+ pushFl = false;
|
|
599
|
+ }
|
|
600
|
+ else
|
535
|
601
|
{
|
536
|
602
|
pushFl = false;
|
537
|
603
|
}
|
|
@@ -549,6 +615,7 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
549
|
615
|
const cmXmlNode_t* np = NULL;
|
550
|
616
|
unsigned tick = 0;
|
551
|
617
|
unsigned tick0= 0;
|
|
618
|
+ cmXsMeas_t* m = NULL;
|
552
|
619
|
|
553
|
620
|
// allocate the 'measure' record
|
554
|
621
|
cmXsMeas_t* meas = cmLhAllocZ(p->lhH,cmXsMeas_t,1);
|
|
@@ -561,11 +628,14 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
561
|
628
|
pp->measL = meas;
|
562
|
629
|
else
|
563
|
630
|
{
|
564
|
|
- cmXsMeas_t* m = pp->measL;
|
|
631
|
+ m = pp->measL;
|
565
|
632
|
while( m->link != NULL )
|
566
|
633
|
m = m->link;
|
567
|
634
|
|
568
|
|
- m->link = meas;
|
|
635
|
+ m->link = meas;
|
|
636
|
+ meas->divisions = m->divisions;
|
|
637
|
+ meas->beats = m->beats;
|
|
638
|
+ meas->beat_type = m->beat_type;
|
569
|
639
|
}
|
570
|
640
|
|
571
|
641
|
// get measure attributes node
|
|
@@ -597,7 +667,11 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
597
|
667
|
{
|
598
|
668
|
unsigned backup;
|
599
|
669
|
cmXmlNodeUInt(np,&backup,"duration",NULL);
|
600
|
|
- tick -= backup;
|
|
670
|
+ if( backup > tick )
|
|
671
|
+ tick = 0;
|
|
672
|
+ else
|
|
673
|
+ tick -= backup;
|
|
674
|
+
|
601
|
675
|
tick0 = tick;
|
602
|
676
|
}
|
603
|
677
|
else
|
|
@@ -701,6 +775,7 @@ bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* np )
|
701
|
775
|
if( /*nnp->voice->id == np->voice->id &&*/ nnp->step == np->step && nnp->octave == np->octave )
|
702
|
776
|
{
|
703
|
777
|
nnp->flags |= kTieProcXsFl;
|
|
778
|
+ nnp->flags = cmClrFlag(nnp->flags,kOnsetXsFl);
|
704
|
779
|
|
705
|
780
|
if( cmIsNotFlag(nnp->flags,kTieBegXsFl) )
|
706
|
781
|
{
|
|
@@ -749,7 +824,148 @@ void _cmXScoreProcessTies( cmXScore_t* p )
|
749
|
824
|
printf("Found:%i Not Found:%i\n",m,n-m);
|
750
|
825
|
}
|
751
|
826
|
|
752
|
|
-cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
|
|
827
|
+cmXsRC_t _cmXScoreResolveOctaveShift( cmXScore_t* p )
|
|
828
|
+{
|
|
829
|
+
|
|
830
|
+ const cmXsSpan_t* s;
|
|
831
|
+ for(s=p->spanL; s!=NULL; s=s->link)
|
|
832
|
+ {
|
|
833
|
+ if( s->tick1 == -1)
|
|
834
|
+ {
|
|
835
|
+ cmErrWarnMsg(&p->err,kSyntaxErrorXsRC,"An unterminated octave shift span was encountered in measure %i staff=%i.",s->meas->number,s->staff);
|
|
836
|
+ }
|
|
837
|
+ else
|
|
838
|
+ {
|
|
839
|
+ cmXsMeas_t* m = p->partL->measL;
|
|
840
|
+ for(; m!=NULL; m=m->link)
|
|
841
|
+ if( m->number == s->meas->number )
|
|
842
|
+ break;
|
|
843
|
+
|
|
844
|
+ assert( m != NULL );
|
|
845
|
+
|
|
846
|
+ cmXsNote_t* note = m->noteL;
|
|
847
|
+ for(; note!=NULL; note=note->slink)
|
|
848
|
+ if( note->staff==s->staff && s->tick0 <= note->tick && note->tick < s->tick1 )
|
|
849
|
+ note->pitch += s->pitch_offset;
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+ }
|
|
853
|
+ }
|
|
854
|
+
|
|
855
|
+ return kOkXsRC;
|
|
856
|
+}
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+cmXsMeas_t* _cmXScoreNextNonEmptyMeas( cmXsPart_t* pp, cmXsMeas_t* meas )
|
|
860
|
+{
|
|
861
|
+ if( meas == NULL )
|
|
862
|
+ {
|
|
863
|
+ if( pp==NULL || pp->measL==NULL )
|
|
864
|
+ return NULL;
|
|
865
|
+
|
|
866
|
+ meas = pp->measL;
|
|
867
|
+ }
|
|
868
|
+ else
|
|
869
|
+ {
|
|
870
|
+ meas = meas->link;
|
|
871
|
+ }
|
|
872
|
+
|
|
873
|
+ while( meas != NULL && meas->noteL == NULL )
|
|
874
|
+ meas=meas->link;
|
|
875
|
+
|
|
876
|
+ return meas;
|
|
877
|
+}
|
|
878
|
+
|
|
879
|
+cmXsNote_t* _cmXScoreNextNote( cmXsPart_t* pp, cmXsNote_t* note )
|
|
880
|
+{
|
|
881
|
+ // meas should always be valid (unless this is the first note in the score)
|
|
882
|
+ cmXsMeas_t* meas = note==NULL ? NULL : note->meas;
|
|
883
|
+
|
|
884
|
+ do
|
|
885
|
+ {
|
|
886
|
+ if( note == NULL || note->slink==NULL )
|
|
887
|
+ {
|
|
888
|
+ if((meas = _cmXScoreNextNonEmptyMeas(pp,meas)) == NULL)
|
|
889
|
+ return NULL;
|
|
890
|
+
|
|
891
|
+ assert( meas->noteL != NULL );
|
|
892
|
+
|
|
893
|
+ note = meas->noteL;
|
|
894
|
+ }
|
|
895
|
+ else
|
|
896
|
+ {
|
|
897
|
+ note = note->slink;
|
|
898
|
+ }
|
|
899
|
+
|
|
900
|
+ assert( note != NULL );
|
|
901
|
+
|
|
902
|
+ meas = note->meas;
|
|
903
|
+
|
|
904
|
+ // note is now set to a non-NULL candidate note - advance to a sounding note
|
|
905
|
+ while( note!=NULL && cmIsNotFlag(note->flags,kOnsetXsFl) )
|
|
906
|
+ note = note->slink;
|
|
907
|
+
|
|
908
|
+ // if no note was found in this measure
|
|
909
|
+ }while( note == NULL );
|
|
910
|
+
|
|
911
|
+ return note;
|
|
912
|
+}
|
|
913
|
+
|
|
914
|
+cmXsRC_t _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* midiFn)
|
|
915
|
+{
|
|
916
|
+ cmXsRC_t rc = kOkXsRC;
|
|
917
|
+ cmMidiFileH_t mfH = cmMidiFileNullHandle;
|
|
918
|
+ const cmMidiTrackMsg_t** m = NULL;
|
|
919
|
+ unsigned mN = 0;
|
|
920
|
+ unsigned i = 0;
|
|
921
|
+ unsigned j = 0;
|
|
922
|
+ cmXsNote_t* note = NULL;
|
|
923
|
+
|
|
924
|
+ if( cmMidiFileOpen(ctx, &mfH, midiFn ) != kOkMfRC )
|
|
925
|
+ return cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object could not be opened from '%s'.",cmStringNullGuard(midiFn));
|
|
926
|
+
|
|
927
|
+ if( (m = cmMidiFileMsgArray(mfH)) == NULL || (mN = cmMidiFileMsgCount(mfH)) == 0 )
|
|
928
|
+ {
|
|
929
|
+ rc = cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object appears to be empty.");
|
|
930
|
+ goto errLabel;
|
|
931
|
+ }
|
|
932
|
+
|
|
933
|
+ if((note = _cmXScoreNextNote(p->partL,NULL)) == NULL)
|
|
934
|
+ {
|
|
935
|
+ rc = cmErrWarnMsg(&p->err,kSyntaxErrorXsRC,"No MIDI processing to be done. The score appears to be empty.");
|
|
936
|
+ goto errLabel;
|
|
937
|
+ }
|
|
938
|
+
|
|
939
|
+ printf(" i j score midi\n");
|
|
940
|
+ printf("---- ---- --- ---- --- ----\n");
|
|
941
|
+
|
|
942
|
+ for(j=0; note!=NULL; note=_cmXScoreNextNote(p->partL,note),++j)
|
|
943
|
+ {
|
|
944
|
+ unsigned midiPitch = 0;
|
|
945
|
+ for(; i<mN; ++i)
|
|
946
|
+ if( m[i]!=NULL && cmMidiIsChStatus(m[i]->status) && cmMidiIsNoteOn(m[i]->status) && m[i]->u.chMsgPtr->d1>0 )
|
|
947
|
+ {
|
|
948
|
+ midiPitch = m[i]->u.chMsgPtr->d0;
|
|
949
|
+ ++i;
|
|
950
|
+ break;
|
|
951
|
+ }
|
|
952
|
+
|
|
953
|
+ char buf[6];
|
|
954
|
+ printf("%4i %4i %3i %4s %3i %4s\n",j,i,
|
|
955
|
+ note->pitch,
|
|
956
|
+ cmMidiToSciPitch(note->pitch,NULL,0),
|
|
957
|
+ midiPitch,
|
|
958
|
+ cmMidiToSciPitch(midiPitch,buf,5));
|
|
959
|
+
|
|
960
|
+ }
|
|
961
|
+
|
|
962
|
+ errLabel:
|
|
963
|
+ cmMidiFileClose(&mfH);
|
|
964
|
+ return rc;
|
|
965
|
+}
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* midiFn )
|
753
|
969
|
{
|
754
|
970
|
cmXsRC_t rc = kOkXsRC;
|
755
|
971
|
|
|
@@ -788,13 +1004,14 @@ cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
|
788
|
1004
|
|
789
|
1005
|
_cmXScoreProcessTies(p);
|
790
|
1006
|
|
|
1007
|
+ //_cmXScoreResolveOctaveShift(p);
|
|
1008
|
+
|
|
1009
|
+ if( midiFn != NULL )
|
|
1010
|
+ _cmXScoreProcessMidi(p,ctx,midiFn);
|
|
1011
|
+
|
791
|
1012
|
// CSV output initialize failed.
|
792
|
1013
|
if( cmCsvInitialize(&p->csvH,ctx) != kOkCsvRC )
|
793
|
1014
|
rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output object create failed.");
|
794
|
|
-
|
795
|
|
- cmXsConnect_t* c = p->tieL;
|
796
|
|
- for(; c!=NULL; c=c->link)
|
797
|
|
- cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tie begun from note on line %i was not terminated. (pitch=%i)",c->note->xmlNode->line,c->note->pitch);
|
798
|
1015
|
|
799
|
1016
|
errLabel:
|
800
|
1017
|
if( rc != kOkXsRC )
|
|
@@ -858,8 +1075,6 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
|
858
|
1075
|
if( cmIsFlag(note->flags,kMetronomeXsFl) )
|
859
|
1076
|
cmRptPrintf(rpt," %i bpm",note->duration);
|
860
|
1077
|
|
861
|
|
- printf("\n");
|
862
|
|
-
|
863
|
1078
|
}
|
864
|
1079
|
|
865
|
1080
|
/*
|
|
@@ -1183,13 +1398,21 @@ void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
1183
|
1398
|
const cmXsMeas_t* meas = pp->measL;
|
1184
|
1399
|
for(; meas!=NULL; meas=meas->link)
|
1185
|
1400
|
{
|
1186
|
|
- cmRptPrintf(rpt," %i : div:%i beat:%i beat-type:%i\n",meas->number,meas->divisions,meas->beats,meas->beat_type);
|
|
1401
|
+ cmRptPrintf(rpt," %i : div:%i beat:%i beat-type:%i (%i)\n",meas->number,meas->divisions,meas->beats,meas->beat_type,meas->divisions*meas->beats);
|
1187
|
1402
|
|
1188
|
1403
|
if( sortFl )
|
1189
|
1404
|
{
|
1190
|
1405
|
const cmXsNote_t* note = meas->noteL;
|
1191
|
1406
|
for(; note!=NULL; note=note->slink)
|
1192
|
|
- _cmXScoreReportNote(rpt,note);
|
|
1407
|
+ {
|
|
1408
|
+ _cmXScoreReportNote(rpt,note);
|
|
1409
|
+
|
|
1410
|
+ if( note->slink!=NULL || note->voice->id==0)
|
|
1411
|
+ cmRptPrintf(rpt,"\n");
|
|
1412
|
+ else
|
|
1413
|
+ cmRptPrintf(rpt," %i\n", note->tick + note->duration);
|
|
1414
|
+ }
|
|
1415
|
+
|
1193
|
1416
|
}
|
1194
|
1417
|
else
|
1195
|
1418
|
{
|
|
@@ -1202,9 +1425,21 @@ void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
1202
|
1425
|
cmRptPrintf(rpt," voice:%i\n",v->id);
|
1203
|
1426
|
|
1204
|
1427
|
for(; note!=NULL; note=note->mlink)
|
|
1428
|
+ {
|
1205
|
1429
|
_cmXScoreReportNote(rpt,note);
|
|
1430
|
+
|
|
1431
|
+ if( note->mlink!=NULL || note->voice->id==0)
|
|
1432
|
+ cmRptPrintf(rpt,"\n");
|
|
1433
|
+ else
|
|
1434
|
+ cmRptPrintf(rpt," %i\n", note->tick + note->duration);
|
|
1435
|
+ }
|
|
1436
|
+
|
1206
|
1437
|
}
|
1207
|
|
- }
|
|
1438
|
+ }
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
1208
|
1443
|
}
|
1209
|
1444
|
}
|
1210
|
1445
|
}
|
|
@@ -1230,16 +1465,16 @@ cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
|
1230
|
1465
|
}
|
1231
|
1466
|
}
|
1232
|
1467
|
|
1233
|
|
-cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
|
1468
|
+cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midiFn )
|
1234
|
1469
|
{
|
1235
|
1470
|
cmXsRC_t rc;
|
1236
|
1471
|
cmXsH_t h = cmXsNullHandle;
|
1237
|
1472
|
|
1238
|
|
- if((rc = cmXScoreInitialize( ctx, &h, fn)) != kOkXsRC )
|
|
1473
|
+ if((rc = cmXScoreInitialize( ctx, &h, xmlFn, midiFn)) != kOkXsRC )
|
1239
|
1474
|
return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
|
1240
|
1475
|
|
1241
|
1476
|
cmXScoreWriteCsv(h,"/Users/kevin/temp/a0.csv");
|
1242
|
|
- cmXScoreReport(h,&ctx->rpt,true);
|
|
1477
|
+ cmXScoreReport(h,&ctx->rpt,false);
|
1243
|
1478
|
|
1244
|
1479
|
return cmXScoreFinalize(&h);
|
1245
|
1480
|
|