浏览代码

cmXScore.c : Added use of cmSeqAlign in _cmXScoreProcessMidi().

master
kevin 8 年前
父节点
当前提交
7fcce19799
共有 1 个文件被更改,包括 78 次插入11 次删除
  1. 78
    11
      app/cmXScore.c

+ 78
- 11
app/cmXScore.c 查看文件

@@ -1,6 +1,7 @@
1 1
 #include "cmPrefix.h"
2 2
 #include "cmGlobal.h"
3 3
 #include "cmFloatTypes.h"
4
+#include "cmComplexTypes.h"
4 5
 #include "cmRpt.h"
5 6
 #include "cmErr.h"
6 7
 #include "cmCtx.h"
@@ -16,6 +17,16 @@
16 17
 #include "cmLex.h"
17 18
 #include "cmCsv.h"
18 19
 
20
+#include "cmFile.h"
21
+#include "cmSymTbl.h"
22
+#include "cmAudioFile.h"
23
+#include "cmAudioFile.h"
24
+#include "cmProcObj.h"
25
+#include "cmProcTemplate.h"
26
+#include "cmProc.h"
27
+#include "cmProc2.h"
28
+#include "cmProc5.h"
29
+
19 30
 cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
20 31
 
21 32
 enum
@@ -51,9 +62,10 @@ typedef struct cmXsNote_str
51 62
   cmChar_t                    step;     // A-G
52 63
   unsigned                    octave;   // sci pitch octave
53 64
   int                         alter;    // +n=sharps,-n=flats
54
-  unsigned                    staff;
65
+  unsigned                    staff;    // 1=treble 2=bass
55 66
   unsigned                    tick;     // 
56 67
   unsigned                    duration; // duration in ticks
68
+  unsigned                    locIdx;    // location index (chords share the same location index)
57 69
   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, ...)
58 70
   const cmChar_t*             tvalue;   // text value
59 71
 
@@ -706,6 +718,8 @@ cmXsRC_t _cmXScoreParsePart( cmXScore_t* p, cmXsPart_t* pp )
706 718
   return rc;
707 719
 }
708 720
 
721
+// Insert note 'np' into the sorted note list based at 's0'.
722
+// Return a pointer to the base of the list after the insertion.
709 723
 cmXsNote_t*  _cmXScoreInsertSortedNote( cmXsNote_t* s0, cmXsNote_t* np )
710 724
 {
711 725
   if( s0 == NULL )
@@ -740,9 +754,11 @@ cmXsNote_t*  _cmXScoreInsertSortedNote( cmXsNote_t* s0, cmXsNote_t* np )
740 754
 
741 755
 void _cmXScoreSort( cmXScore_t* p )
742 756
 {
757
+  // for each part
743 758
   cmXsPart_t* pp = p->partL;
744 759
   for(; pp!=NULL; pp=pp->link)
745 760
   {
761
+    // for each measure in this part
746 762
     cmXsMeas_t* mp = pp->measL;
747 763
     for(; mp!=NULL; mp=mp->link)
748 764
     {   
@@ -750,6 +766,7 @@ void _cmXScoreSort( cmXScore_t* p )
750 766
       cmXsVoice_t* vp = mp->voiceL;
751 767
       for(; vp!=NULL; vp=vp->link)
752 768
       {
769
+        // for each note in this measure
753 770
         cmXsNote_t* np = vp->noteL;
754 771
         for(; np!=NULL; np=np->mlink)
755 772
           mp->noteL = _cmXScoreInsertSortedNote(mp->noteL,np);        
@@ -797,27 +814,44 @@ bool  _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* np )
797 814
   return false;
798 815
 }
799 816
 
800
-void  _cmXScoreProcessTies( cmXScore_t* p )
817
+void  _cmXScoreResolveTiesAndLoc( cmXScore_t* p )
801 818
 {
802
-  unsigned n = 0;
803
-  unsigned m = 0;
819
+  unsigned n   = 0;
820
+  unsigned m   = 0;
804 821
   
805 822
   cmXsPart_t* pp = p->partL;
806 823
   for(; pp!=NULL; pp=pp->link)
807 824
   {
825
+    unsigned locIdx = 1;
808 826
     cmXsMeas_t* mp = pp->measL;
809 827
     for(; mp!=NULL; mp=mp->link)
810 828
     {
829
+      cmXsNote_t* n0 = NULL;
811 830
       cmXsNote_t* np = mp->noteL;
812 831
       
813 832
       for(; np!=NULL; np=np->slink)
833
+      {
834
+        // if this note begins a tie and has not yet been  processed
835
+        // (A note that continues a tie and therefore has a kTieBegXsFl set
836
+        //  may have already been processed by an earlier tied note.)
814 837
         if( cmIsFlag(np->flags,kTieBegXsFl) && cmIsNotFlag(np->flags,kTieProcXsFl))
815 838
         {
816 839
           if( _cmXScoreFindTiedNote(p,mp,np) )
817 840
             m += 1;
818 841
           n += 1;
819
-        } 
820
-        
842
+        }
843
+
844
+        // set the location 
845
+        if( cmIsFlag(np->flags,kOnsetXsFl) )
846
+        {
847
+          if( n0!=NULL && n0->tick!=np->tick)
848
+            locIdx += 1;
849
+
850
+          np->locIdx = locIdx;
851
+          n0         = np;
852
+        }
853
+
854
+      } 
821 855
     }
822 856
   }
823 857
 
@@ -911,6 +945,7 @@ cmXsNote_t* _cmXScoreNextNote( cmXsPart_t* pp, cmXsNote_t* note )
911 945
   return note;
912 946
 }
913 947
 
948
+
914 949
 cmXsRC_t    _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* midiFn)
915 950
 {
916 951
   cmXsRC_t                 rc   = kOkXsRC;
@@ -924,6 +959,8 @@ cmXsRC_t    _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* mi
924 959
   if( cmMidiFileOpen(ctx, &mfH, midiFn ) != kOkMfRC )
925 960
     return cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object could not be opened from '%s'.",cmStringNullGuard(midiFn));
926 961
 
962
+  cmMidiFilePrintMsgs(mfH, p->err.rpt );
963
+  
927 964
   if( (m = cmMidiFileMsgArray(mfH)) == NULL || (mN = cmMidiFileMsgCount(mfH)) == 0 )
928 965
   {
929 966
     rc = cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object appears to be empty.");
@@ -936,6 +973,37 @@ cmXsRC_t    _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* mi
936 973
     goto errLabel;
937 974
   }
938 975
 
976
+  cmCtx*        c = cmCtxAlloc( NULL, p->err.rpt, cmLHeapNullHandle, cmSymTblNullHandle );
977
+  cmSeqAlign_t* s = cmSeqAlignAlloc(c,NULL);
978
+  unsigned      offs = 0;
979
+  
980
+  for(; note!=NULL; note=_cmXScoreNextNote(p->partL,note))
981
+  {
982
+    if( cmIsFlag(note->flags,kGraceXsFl) )
983
+      offs += 1;
984
+    
985
+    cmSeqAlignInsert(s,0,note->locIdx+offs,note->pitch);
986
+  }
987
+
988
+  unsigned locIdx = 1;
989
+  for(i=0,j=0; i<mN; ++i)
990
+    if( (m[i]!=NULL) && cmMidiIsChStatus(m[i]->status) && cmMidiIsNoteOn(m[i]->status) && (m[i]->u.chMsgPtr->d1>0) )
991
+    {
992
+      if( m[j]->atick != m[i]->atick )
993
+        locIdx += 1;
994
+      
995
+      cmSeqAlignInsert(s,1,locIdx,m[i]->u.chMsgPtr->d0);
996
+
997
+      //printf("%i : %s\n",locIdx,cmMidiToSciPitch(m[i]->u.chMsgPtr->d0,NULL,0));
998
+      
999
+      j = i;
1000
+    }
1001
+
1002
+  cmSeqAlignReport(s,p->err.rpt);
1003
+  cmSeqAlignFree(&s);
1004
+  cmCtxFree(&c);
1005
+  goto errLabel;
1006
+
939 1007
   printf(" i     j    score    midi\n");
940 1008
   printf("---- ---- --- ---- --- ----\n");
941 1009
   
@@ -1002,7 +1070,7 @@ cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, c
1002 1070
   // fill in the note->slink chain to link the notes in each measure in time order
1003 1071
   _cmXScoreSort(p);
1004 1072
 
1005
-  _cmXScoreProcessTies(p);
1073
+  _cmXScoreResolveTiesAndLoc(p);
1006 1074
 
1007 1075
   //_cmXScoreResolveOctaveShift(p);
1008 1076
 
@@ -1065,9 +1133,8 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
1065 1133
   cmChar_t N[] = {'\0','\0','\0','\0'};
1066 1134
   cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
1067 1135
   snprintf(N,4,"%c%c%1i",note->step,acc,note->octave);
1068
-  
1069
-  
1070
-  cmRptPrintf(rpt,"      %3i %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",note->voice->id,note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P,S,H,T0,T1);
1136
+    
1137
+  cmRptPrintf(rpt,"      %3i %5i %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",note->voice->id,note->locIdx,note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P,S,H,T0,T1);
1071 1138
 
1072 1139
   if( cmIsFlag(note->flags,kSectionXsFl) )
1073 1140
     cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
@@ -1474,7 +1541,7 @@ cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midi
1474 1541
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
1475 1542
 
1476 1543
   cmXScoreWriteCsv(h,"/Users/kevin/temp/a0.csv");
1477
-  cmXScoreReport(h,&ctx->rpt,false);
1544
+  cmXScoreReport(h,&ctx->rpt,true);
1478 1545
   
1479 1546
   return cmXScoreFinalize(&h);
1480 1547
 

正在加载...
取消
保存