Selaa lähdekoodia

cmXScore.h/c : Added cmXScoreWriteCsv().

master
Kevin Larke 8 vuotta sitten
vanhempi
commit
8b2c47f64d
2 muutettua tiedostoa jossa 372 lisäystä ja 38 poistoa
  1. 362
    36
      app/cmXScore.c
  2. 10
    2
      app/cmXScore.h

+ 362
- 36
app/cmXScore.c Näytä tiedosto

@@ -12,6 +12,8 @@
12 12
 #include "cmXScore.h"
13 13
 #include "cmTime.h"
14 14
 #include "cmMidi.h"
15
+#include "cmLex.h"
16
+#include "cmCsv.h"
15 17
 
16 18
 cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
17 19
 
@@ -33,7 +35,6 @@ enum
33 35
 };
34 36
 
35 37
 
36
-
37 38
 typedef struct cmXsNote_str
38 39
 {
39 40
   unsigned             flags;    // See k???XsFl 
@@ -41,11 +42,11 @@ typedef struct cmXsNote_str
41 42
   unsigned             tick;     // 
42 43
   unsigned             duration; // duration in ticks
43 44
   unsigned             rvalue;   // 1/type = rythmic value (1/4=quarter note, 1/8=eighth note, ...)
45
+  const cmChar_t*      tvalue;   // text value
44 46
   struct cmXsNote_str* mlink;    // measure note list 
45 47
   struct cmXsNote_str* slink;    // time sorted event list
46 48
 } cmXsNote_t;
47 49
 
48
-
49 50
 typedef struct cmXsVoice_str
50 51
 {
51 52
   unsigned              id;    // Voice id
@@ -55,14 +56,13 @@ typedef struct cmXsVoice_str
55 56
 
56 57
 typedef struct cmXsMeas_str
57 58
 {
58
-  unsigned             number;  // Measure number
59
-  
60
-  unsigned             divisions; 
61
-  unsigned             beats;
62
-  unsigned             beat_type;
59
+  unsigned number;      // Measure number
60
+  unsigned divisions;   // ticks-per-quarter-note
61
+  unsigned beats;       // beats per measure
62
+  unsigned beat_type;   // whole/half/quarter/eighth ...
63 63
   
64
-  cmXsVoice_t*         voiceL;  // List of voices in this measure   
65
-  cmXsNote_t*          noteL;   // List of time sorted notes in this measure
64
+  cmXsVoice_t* voiceL;  // List of voices in this measure   
65
+  cmXsNote_t*  noteL;   // List of time sorted notes in this measure
66 66
   
67 67
   struct cmXsMeas_str* link;    // Link to other measures in this part.
68 68
 } cmXsMeas_t;
@@ -76,10 +76,11 @@ typedef struct cmXsPart_str
76 76
 
77 77
 typedef struct
78 78
 {
79
-  cmErr_t              err;
80
-  cmXmlH_t             xmlH;
81
-  cmLHeapH_t           lhH;
82
-  cmXsPart_t*          partL;
79
+  cmErr_t     err;
80
+  cmXmlH_t    xmlH;
81
+  cmLHeapH_t  lhH;
82
+  cmXsPart_t* partL;
83
+  cmCsvH_t    csvH;  
83 84
 } cmXScore_t;
84 85
 
85 86
 cmXScore_t* _cmXScoreHandleToPtr( cmXsH_t h )
@@ -94,12 +95,13 @@ cmXsRC_t _cmXScoreFinalize( cmXScore_t* p )
94 95
   cmXsRC_t rc = kOkXsRC;
95 96
 
96 97
   // release the XML file
97
-  if( cmXmlIsValid(p->xmlH) )
98
-    cmXmlFree( &p->xmlH );
98
+  cmXmlFree( &p->xmlH );
99 99
 
100 100
   // release the local linked heap memory
101
-  if( cmLHeapIsValid(p->lhH) )
102
-    cmLHeapDestroy(&p->lhH);
101
+  cmLHeapDestroy(&p->lhH);
102
+
103
+  // release the CSV output object
104
+  cmCsvFinalize(&p->csvH);
103 105
   
104 106
   cmMemFree(p);
105 107
   
@@ -241,6 +243,7 @@ unsigned _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const
241 243
 
242 244
   map_t mapV[] =
243 245
   {
246
+    {  -1, "measure" },  // whole measure rest
244 247
     {   1, "whole"   },
245 248
     {   2, "half"    },
246 249
     {   4, "quarter" },
@@ -254,7 +257,15 @@ unsigned _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const
254 257
 
255 258
   const cmChar_t* str;
256 259
   if((str = cmXmlNodeValue(nnp,label,NULL)) == NULL)
260
+  {
261
+    if((nnp = cmXmlSearch(nnp,"rest",NULL,0)) != NULL )
262
+    {
263
+      const cmXmlAttr_t* a;
264
+      if((a = cmXmlFindAttrib(nnp,"measure")) != NULL && cmTextCmp(a->value,"yes")==0)
265
+        return -1;
266
+    }
257 267
     return 0;
268
+  }
258 269
   
259 270
   unsigned i;
260 271
   for(i=0; mapV[i].rvalue!=0; ++i)
@@ -354,7 +365,7 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
354 365
   return _cmXScorePushNote(p, meas, voiceId, note );
355 366
 }
356 367
 
357
-cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, unsigned duration, unsigned rvalue, unsigned flags )
368
+cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, unsigned duration, unsigned rvalue, const cmChar_t* tvalue, unsigned flags )
358 369
 {
359 370
   cmXsNote_t* note    = cmLhAllocZ(p->lhH,cmXsNote_t,1);
360 371
   unsigned    voiceId = 0;    // non-note's are always assigned to voiceId=0;
@@ -362,6 +373,7 @@ cmXsRC_t _cmXScorePushNonNote( cmXScore_t* p, cmXsMeas_t* meas, unsigned tick, u
362 373
   note->tick     = tick;
363 374
   note->flags    = flags;
364 375
   note->rvalue   = rvalue;
376
+  note->tvalue   = tvalue;
365 377
   note->duration = duration;
366 378
   
367 379
   return _cmXScorePushNote(p, meas, voiceId, note );
@@ -374,6 +386,7 @@ cmXsRC_t  _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
374 386
   unsigned           flags    = 0;
375 387
   int                offset   = 0;
376 388
   unsigned           rvalue   = 0;
389
+  const cmChar_t*    tvalue   = NULL;
377 390
   unsigned           duration = 0;
378 391
 
379 392
   
@@ -419,16 +432,14 @@ cmXsRC_t  _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
419 432
   {
420 433
     if((a = cmXmlFindAttrib(np,"enclosure")) != NULL && cmTextCmp(a->value,"rectangle")==0 )
421 434
     {
422
-      if( cmXmlNodeUInt(np,&rvalue,NULL) != kOkXsRC )
423
-        return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Error reading section number on line %i.",np->line);
435
+      if( cmTextIsEmpty( tvalue = np->dataStr ) )
436
+        return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Section number is blank or missing on line %i.",np->line);
424 437
 
425
-      printf("rvalue=%i\n",rvalue);
426
-      
427 438
       flags = kSectionXsFl;
428 439
     }
429 440
   }
430 441
 
431
-  return _cmXScorePushNonNote(p,meas,tick+offset,duration,rvalue,flags);            
442
+  return _cmXScorePushNonNote(p,meas,tick+offset,duration,rvalue,tvalue,flags);            
432 443
       
433 444
 }
434 445
 
@@ -458,16 +469,15 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
458 469
   }
459 470
   
460 471
   // get measure attributes node
461
-  if((np = cmXmlSearch(mnp,"attributes",NULL,0)) == NULL)
462
-    return rc;                  // (this measure does not have any attributes)
463
-
464
-
465
-  cmXmlNodeUInt(np,&meas->divisions,"divisions",NULL);
466
-  cmXmlNodeUInt(np,&meas->beats,    "time","beats",NULL);
467
-  cmXmlNodeUInt(np,&meas->beat_type,"time","beat-type",NULL);
468
-
472
+  if((np = cmXmlSearch(mnp,"attributes",NULL,0)) != NULL)
473
+  {
474
+    cmXmlNodeUInt(np,&meas->divisions,"divisions",NULL);
475
+    cmXmlNodeUInt(np,&meas->beats,    "time","beats",NULL);
476
+    cmXmlNodeUInt(np,&meas->beat_type,"time","beat-type",NULL);
477
+  }
478
+  
469 479
   // store the bar line
470
-  if((rc = _cmXScorePushNonNote(p,meas,tick,0,0,kBarXsFl)) != kOkXsRC )
480
+  if((rc = _cmXScorePushNonNote(p,meas,tick,0,0,NULL,kBarXsFl)) != kOkXsRC )
471 481
     return rc;
472 482
 
473 483
   
@@ -595,6 +605,8 @@ cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
595 605
     goto errLabel;
596 606
   }
597 607
 
608
+  //cmXmlPrint(p->xmlH,&ctx->rpt);  
609
+
598 610
   // parse the part-list
599 611
   if((rc = _cmXScoreParsePartList( p )) != kOkXsRC )
600 612
     goto errLabel;
@@ -606,7 +618,11 @@ cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
606 618
       goto errLabel;
607 619
 
608 620
   // fill in the note->slink chain to link the notes in each measure in time order
609
-  _cmXScoreSort(p); 
621
+  _cmXScoreSort(p);
622
+
623
+  // CSV output initialize failed.
624
+  if( cmCsvInitialize(&p->csvH,ctx) != kOkCsvRC )
625
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output object create failed.");
610 626
   
611 627
  errLabel:
612 628
   if( rc != kOkXsRC )
@@ -655,17 +671,326 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
655 671
   cmRptPrintf(rpt,"      %5i %5i %2i %3s %s%s%s%s%s%s%s%s%s",note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P);
656 672
 
657 673
   if( cmIsFlag(note->flags,kSectionXsFl) )
658
-    cmRptPrintf(rpt," %i",note->rvalue);
674
+    cmRptPrintf(rpt," %i",cmStringNullGuard(note->tvalue));
659 675
 
660 676
   printf("\n");
661 677
   
662 678
 }
663 679
 
664
-void  cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
680
+/*
681
+  kMidiFileIdColScIdx= 0,  
682
+  kTypeLabelColScIdx = 3,
683
+  kDSecsColScIdx     = 4,
684
+  kSecsColScIdx      = 5,
685
+  kD0ColScIdx        = 9,
686
+  kD1ColScIdx        = 10,
687
+  kPitchColScIdx     = 11,
688
+  kBarColScIdx       = 13,
689
+  kSkipColScIdx      = 14,
690
+  kEvenColScIdx      = 15,
691
+  kGraceColScIdx     = 16,
692
+  kTempoColScIdx     = 17,
693
+  kFracColScIdx      = 18,
694
+  kDynColScIdx       = 19,
695
+  kSectionColScIdx   = 20,
696
+  kRecdPlayColScIdx  = 21,
697
+  kRemarkColScIdx    = 22
698
+ */
699
+
700
+
701
+cmXsRC_t _cmXScoreWriteCsvHdr( cmXScore_t* p )
665 702
 {
666
-  cmXScore_t* p = _cmXScoreHandleToPtr(h);
703
+  const cmChar_t* s[] =
704
+  {
705
+    "id","trk","evt","opcode","dticks","micros","status",
706
+    "meta","ch","d0","d1","arg0","arg1","bar","skip",
707
+    "even","grace","tempo","t frac","dyn","section","play_recd","remark",NULL
708
+  };
667 709
 
710
+  cmCsvCell_t* lcp = NULL;
711
+  
712
+  if(  cmCsvAppendRow( p->csvH, &lcp, cmCsvInsertSymText(p->csvH,s[0]), 0, 0 ) != kOkCsvRC )
713
+    return cmErrMsg(&p->err,kCsvFailXsRC,"CSV append row failed.");
714
+  
715
+  unsigned i;
716
+  for(i=1; s[i]!=NULL; ++i)
717
+  {
718
+    if( cmCsvInsertTextColAfter(p->csvH, lcp, &lcp, s[i], 0 ) != kOkCsvRC )
719
+      return cmErrMsg(&p->err,kCsvFailXsRC,"CSV error inserting CSV title %i.\n",i);
720
+
721
+  }
722
+
723
+  return kOkXsRC;
724
+}
725
+
726
+cmXsRC_t _cmXScoreWriteCsvBlankCols( cmXScore_t* p, unsigned cnt, cmCsvCell_t** leftCellPtrPtr )
727
+{
728
+  unsigned i;
729
+  for(i=0; i<cnt; ++i)
730
+    if( cmCsvInsertTextColAfter(p->csvH,*leftCellPtrPtr,leftCellPtrPtr,0,0) != kOkCsvRC )
731
+      return cmErrMsg(&p->err,kCsvFailXsRC,"CSV output failed on blank column.");
732
+
733
+  return kOkCsvRC;    
734
+}
735
+
736
+cmXsRC_t _cmXScoreWriteCsvRow(
737
+  cmXScore_t*     p,
738
+  unsigned        rowIdx,
739
+  unsigned        bar,
740
+  const cmChar_t* sectionStr,
741
+  const cmChar_t* opCodeStr,
742
+  double          dsecs,
743
+  double          secs,
744
+  unsigned        d0,
745
+  unsigned        d1,
746
+  unsigned        pitch,
747
+  double          frac,
748
+  unsigned        flags )
749
+{
750
+  cmXsRC_t     rc  = kOkXsRC;
751
+  cmCsvCell_t* lcp = NULL;
752
+
753
+  // append an empty row to the CSV object
754
+  if(  cmCsvAppendRow( p->csvH, &lcp, cmCsvInsertSymUInt(p->csvH, rowIdx ), 0, 0 ) != kOkCsvRC )
755
+  {
756
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV append row failed.");
757
+    goto errLabel;
758
+  }
759
+
760
+  /*
761
+  // col 0 : blanks
762
+  if( cmCsvInsertUIntColAfter(p->csvH, lcp, &lcp, rowIdx,    0 ) != kOkCsvRC )
763
+  {
764
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output row index failed.");
765
+    goto errLabel;
766
+  }
767
+  */
768
+  
769
+  // cols 1,2
770
+  if((rc = _cmXScoreWriteCsvBlankCols(p,2,&lcp)) != kOkXsRC )
771
+    goto errLabel;
772
+
773
+  // col 3 : output the opcode
774
+  if( cmCsvInsertTextColAfter(p->csvH,lcp,&lcp,opCodeStr,0) != kOkCsvRC )
775
+  {
776
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on opcode label.");
777
+    goto errLabel;
778
+  }
779
+
780
+  // col 4 : dsecs
781
+  if( cmCsvInsertDoubleColAfter(p->csvH,lcp,&lcp,dsecs,0) != kOkCsvRC )
782
+  {
783
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'dsecs'.");
784
+    goto errLabel;
785
+  }
786
+
787
+  // col 5 : secs
788
+  if( cmCsvInsertDoubleColAfter(p->csvH,lcp,&lcp,secs,0) != kOkCsvRC )
789
+  {
790
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'secs'.");
791
+    goto errLabel;
792
+  }
793
+  
794
+  // cols 6,7,8 blanks
795
+  if((rc = _cmXScoreWriteCsvBlankCols(p,3,&lcp)) != kOkXsRC )
796
+    goto errLabel;
797
+
798
+  // col 9 : d0
799
+  if( cmCsvInsertUIntColAfter(p->csvH,lcp,&lcp,d0,0) != kOkCsvRC )
800
+  {
801
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'd0'.");
802
+    goto errLabel;
803
+  }
804
+
805
+  // col 10 : d1
806
+  if( cmCsvInsertUIntColAfter(p->csvH,lcp,&lcp,d1,0) != kOkCsvRC )
807
+  {
808
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'd1'.");
809
+    goto errLabel;
810
+  }
811
+
812
+  // col 11 : pitch
813
+  if( cmCsvInsertUIntColAfter(p->csvH,lcp,&lcp,pitch,0) != kOkCsvRC )
814
+  {
815
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'pitch'.");
816
+    goto errLabel;
817
+  }
818
+  
819
+  // col 12 : blanks
820
+  if((rc = _cmXScoreWriteCsvBlankCols(p,1 + (cmIsFlag(flags,kBarXsFl) ? 0 : 1), &lcp)) != kOkXsRC )
821
+    goto errLabel;
822
+
823
+  // col 13 : bar number
824
+  if( cmIsFlag(flags,kBarXsFl) )
825
+  {
826
+    if( cmCsvInsertUIntColAfter(p->csvH,lcp,&lcp,bar,0) != kOkCsvRC )
827
+    {
828
+      rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 'pitch'.");
829
+      goto errLabel;
830
+    }
831
+  }
832
+
833
+  // col 14 : skip (blank for now)
834
+  if((rc = _cmXScoreWriteCsvBlankCols(p,1,&lcp)) != kOkXsRC )
835
+    goto errLabel;
836
+
837
+  // col 15: even
838
+  if( cmCsvInsertTextColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kEvenXsFl) ? "e" : "",0) != kOkCsvRC )
839
+  {
840
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
841
+    goto errLabel;
842
+  }
843
+
844
+  // col 16: grace
845
+  if( cmCsvInsertTextColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kGraceXsFl) ? "g" : "",0) != kOkCsvRC )
846
+  {
847
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
848
+    goto errLabel;
849
+  }
850
+  
851
+  // col 17: tempo
852
+  if( cmCsvInsertTextColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kTempoXsFl) ? "t" : "",0) != kOkCsvRC )
853
+  {
854
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
855
+    goto errLabel;
856
+  }
857
+  
858
+  // col 18: frac
859
+  if( frac == 0 )
860
+  {
861
+    if((rc = _cmXScoreWriteCsvBlankCols(p,1,&lcp)) != kOkXsRC )
862
+      goto errLabel;
863
+  }
864
+  else
865
+  {
866
+    if( cmCsvInsertDoubleColAfter(p->csvH,lcp,&lcp,1.0/frac,0) != kOkCsvRC )
867
+    {
868
+      rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on 't frac'.");
869
+      goto errLabel;
870
+    }
871
+  }
872
+  
873
+  // col 19: dynamic marking (blank for now)
874
+  if((rc = _cmXScoreWriteCsvBlankCols(p,1,&lcp)) != kOkXsRC )
875
+    goto errLabel;
876
+  
877
+  // col 20: section
878
+  if( cmCsvInsertTextColAfter(p->csvH,lcp,&lcp,cmIsFlag(flags,kSectionXsFl) ? sectionStr : "",0) != kOkCsvRC )
879
+  {
880
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV insert failed on eveness flag label.");
881
+    goto errLabel;
882
+  }
883
+  
884
+
885
+  // col 21, 22 : recd-play, remark (blank for now)
886
+  if((rc = _cmXScoreWriteCsvBlankCols(p,2,&lcp)) != kOkXsRC )
887
+    goto errLabel;
888
+  
889
+ errLabel:
890
+  return rc;
891
+  
892
+}
893
+
894
+cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn )
895
+{
896
+  cmXsRC_t        rc           = kOkXsRC;
897
+  cmXScore_t*     p            = _cmXScoreHandleToPtr(h);
898
+  unsigned        rowIdx       = 1;
899
+  double          tpqn         = 0; // ticks per quarter note
900
+  double          tps          = 0; // ticks per second
901
+  double          sec          = 0; // current time in seconds
902
+  const cmChar_t* sectionIdStr = NULL;
903
+        
904
+  
905
+  if( !cmCsvIsValid(p->csvH) )
906
+    return cmErrMsg(&p->err,kCsvFailXsRC,"The CSV output object is not initialized.");
907
+
908
+  if((rc = _cmXScoreWriteCsvHdr( p )) != kOkXsRC )
909
+    goto errLabel;
910
+  
911
+  cmXsPart_t* pp = p->partL;
912
+  for(; pp!=NULL; pp=pp->link)
913
+  {
914
+    cmXsMeas_t* mp = pp->measL;
915
+    for(; mp!=NULL; mp=mp->link)
916
+    {
917
+      if( mp->divisions != 0 )
918
+        tpqn = mp->divisions;
919
+      
920
+      cmXsNote_t* np = mp->noteL;
921
+      
922
+      double sec0 = sec;
923
+      
924
+      for(; np!=NULL; np=np->slink)
925
+      {
926
+
927
+        //  
928
+        if( cmIsFlag(np->flags,kMetronomeXsFl) )
929
+        {
930
+          double bpm = np->duration;
931
+          double bps = bpm / 60.0;
932
+          tps = bps * tpqn;
933
+        }
934
+
935
+        double meas_sec = tps == 0 ? 0 : np->tick / tps;
936
+        double sec1     = sec  + meas_sec;
937
+        double dsecs    = sec1 - sec0;
938
+        sec0            = sec1;
939
+
940
+        // if this is a section event
941
+        if( cmIsFlag(np->flags,kSectionXsFl) )
942
+          sectionIdStr = np->tvalue;
943
+        
944
+        // if this is a bar event
945
+        if( cmIsFlag(np->flags,kBarXsFl) )
946
+        {
947
+          _cmXScoreWriteCsvRow(p,rowIdx,mp->number,NULL,"bar",dsecs,sec1,0,0,0,0,np->flags);
948
+        }
949
+        else
950
+          
951
+        // if this is a pedal event
952
+        if( cmIsFlag(np->flags,kPedalDnXsFl|kPedalUpXsFl|kPedalUpDnXsFl) )
953
+        {
954
+          unsigned d0 = 64; // pedal MIDI ctl id
955
+          unsigned d1 = cmIsFlag(np->flags,kPedalDnXsFl) ? 64 : 0; // pedal-dn: d1>=64 pedal-up:<64
956
+          _cmXScoreWriteCsvRow(p,rowIdx,mp->number,NULL,"ctl",dsecs,sec1,d0,d1,0,0,np->flags);
957
+        }
958
+        else 
959
+
960
+
961
+          // if this is a sounding note event
962
+          if( cmIsNotFlag(np->flags,kRestXsFl) )
963
+          {
964
+            double frac = np->rvalue + (cmIsFlag(np->flags,kDotXsFl) ? (np->rvalue/2) : 0);
965
+        
966
+            // 
967
+            _cmXScoreWriteCsvRow(p,rowIdx,mp->number,sectionIdStr,"non",dsecs,sec1,0,0,np->pitch,frac,np->flags);
968
+            sectionIdStr = NULL;
969
+          }
970
+        
971
+        rowIdx += 1;
972
+        
973
+
974
+      }
975
+
976
+      sec = sec0;
977
+    }
978
+    
979
+  }
980
+
981
+  if( cmCsvWrite( p->csvH, csvFn ) != kOkCsvRC )
982
+    rc = cmErrMsg(&p->err,kCsvFailXsRC,"The CSV output write failed on file '%s'.",csvFn);
983
+
984
+ errLabel:
985
+  return rc;
986
+}
987
+
988
+
989
+void  cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
990
+{
991
+  cmXScore_t* p  = _cmXScoreHandleToPtr(h);
668 992
   cmXsPart_t* pp = p->partL;
993
+  
669 994
   for(; pp!=NULL; pp=pp->link)
670 995
   {
671 996
     cmRptPrintf(rpt,"Part:%s\n",pp->idStr);
@@ -708,6 +1033,7 @@ cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
708 1033
   if((rc = cmXScoreInitialize( ctx, &h, fn)) != kOkXsRC )
709 1034
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
710 1035
 
1036
+  cmXScoreWriteCsv(h,"/home/kevin/temp/a0.csv");
711 1037
   cmXScoreReport(h,&ctx->rpt,true);
712 1038
   
713 1039
   return cmXScoreFinalize(&h);

+ 10
- 2
app/cmXScore.h Näytä tiedosto

@@ -10,7 +10,8 @@ extern "C" {
10 10
     kOkXsRC = cmOkRC,
11 11
     kXmlFailXsRC,
12 12
     kLHeapFailXsRC,
13
-    kSyntaxErrorXsRC
13
+    kSyntaxErrorXsRC,
14
+    kCsvFailXsRC
14 15
   };
15 16
 
16 17
   typedef cmRC_t     cmXsRC_t;
@@ -28,12 +29,19 @@ extern "C" {
28 29
   //
29 30
   // 3) How to assigned dynamic markings.
30 31
   // 4) Tempo syntax is inconsistent.
31
-
32
+  // 5) Heel is not being recognized
33
+  // 6) Sostenuto pedal events are not being parsed.
34
+  // 7) What is a 'pedal-change' event vs. a 'pedal-stop' event.
35
+  // 8) Verify the colors.
36
+  // 9) Remove blank bars at end.
37
+ 
32 38
   cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn );
33 39
   cmXsRC_t cmXScoreFinalize( cmXsH_t* hp );
34 40
 
35 41
   bool     cmXScoreIsValid( cmXsH_t h );
36 42
 
43
+  cmXsRC_t cmXScoreWriteCsv( cmXsH_t h, const cmChar_t* csvFn );
44
+
37 45
   void     cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl );
38 46
 
39 47
   cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn );

Loading…
Peruuta
Tallenna