Browse Source

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

master
kevin 8 years ago
parent
commit
7fcce19799
1 changed files with 78 additions and 11 deletions
  1. 78
    11
      app/cmXScore.c

+ 78
- 11
app/cmXScore.c View File

1
 #include "cmPrefix.h"
1
 #include "cmPrefix.h"
2
 #include "cmGlobal.h"
2
 #include "cmGlobal.h"
3
 #include "cmFloatTypes.h"
3
 #include "cmFloatTypes.h"
4
+#include "cmComplexTypes.h"
4
 #include "cmRpt.h"
5
 #include "cmRpt.h"
5
 #include "cmErr.h"
6
 #include "cmErr.h"
6
 #include "cmCtx.h"
7
 #include "cmCtx.h"
16
 #include "cmLex.h"
17
 #include "cmLex.h"
17
 #include "cmCsv.h"
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
 cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
30
 cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
20
 
31
 
21
 enum
32
 enum
51
   cmChar_t                    step;     // A-G
62
   cmChar_t                    step;     // A-G
52
   unsigned                    octave;   // sci pitch octave
63
   unsigned                    octave;   // sci pitch octave
53
   int                         alter;    // +n=sharps,-n=flats
64
   int                         alter;    // +n=sharps,-n=flats
54
-  unsigned                    staff;
65
+  unsigned                    staff;    // 1=treble 2=bass
55
   unsigned                    tick;     // 
66
   unsigned                    tick;     // 
56
   unsigned                    duration; // duration in ticks
67
   unsigned                    duration; // duration in ticks
68
+  unsigned                    locIdx;    // location index (chords share the same location index)
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, ...)
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
   const cmChar_t*             tvalue;   // text value
70
   const cmChar_t*             tvalue;   // text value
59
 
71
 
706
   return rc;
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
 cmXsNote_t*  _cmXScoreInsertSortedNote( cmXsNote_t* s0, cmXsNote_t* np )
723
 cmXsNote_t*  _cmXScoreInsertSortedNote( cmXsNote_t* s0, cmXsNote_t* np )
710
 {
724
 {
711
   if( s0 == NULL )
725
   if( s0 == NULL )
740
 
754
 
741
 void _cmXScoreSort( cmXScore_t* p )
755
 void _cmXScoreSort( cmXScore_t* p )
742
 {
756
 {
757
+  // for each part
743
   cmXsPart_t* pp = p->partL;
758
   cmXsPart_t* pp = p->partL;
744
   for(; pp!=NULL; pp=pp->link)
759
   for(; pp!=NULL; pp=pp->link)
745
   {
760
   {
761
+    // for each measure in this part
746
     cmXsMeas_t* mp = pp->measL;
762
     cmXsMeas_t* mp = pp->measL;
747
     for(; mp!=NULL; mp=mp->link)
763
     for(; mp!=NULL; mp=mp->link)
748
     {   
764
     {   
750
       cmXsVoice_t* vp = mp->voiceL;
766
       cmXsVoice_t* vp = mp->voiceL;
751
       for(; vp!=NULL; vp=vp->link)
767
       for(; vp!=NULL; vp=vp->link)
752
       {
768
       {
769
+        // for each note in this measure
753
         cmXsNote_t* np = vp->noteL;
770
         cmXsNote_t* np = vp->noteL;
754
         for(; np!=NULL; np=np->mlink)
771
         for(; np!=NULL; np=np->mlink)
755
           mp->noteL = _cmXScoreInsertSortedNote(mp->noteL,np);        
772
           mp->noteL = _cmXScoreInsertSortedNote(mp->noteL,np);        
797
   return false;
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
   cmXsPart_t* pp = p->partL;
822
   cmXsPart_t* pp = p->partL;
806
   for(; pp!=NULL; pp=pp->link)
823
   for(; pp!=NULL; pp=pp->link)
807
   {
824
   {
825
+    unsigned locIdx = 1;
808
     cmXsMeas_t* mp = pp->measL;
826
     cmXsMeas_t* mp = pp->measL;
809
     for(; mp!=NULL; mp=mp->link)
827
     for(; mp!=NULL; mp=mp->link)
810
     {
828
     {
829
+      cmXsNote_t* n0 = NULL;
811
       cmXsNote_t* np = mp->noteL;
830
       cmXsNote_t* np = mp->noteL;
812
       
831
       
813
       for(; np!=NULL; np=np->slink)
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
         if( cmIsFlag(np->flags,kTieBegXsFl) && cmIsNotFlag(np->flags,kTieProcXsFl))
837
         if( cmIsFlag(np->flags,kTieBegXsFl) && cmIsNotFlag(np->flags,kTieProcXsFl))
815
         {
838
         {
816
           if( _cmXScoreFindTiedNote(p,mp,np) )
839
           if( _cmXScoreFindTiedNote(p,mp,np) )
817
             m += 1;
840
             m += 1;
818
           n += 1;
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
   return note;
945
   return note;
912
 }
946
 }
913
 
947
 
948
+
914
 cmXsRC_t    _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* midiFn)
949
 cmXsRC_t    _cmXScoreProcessMidi(cmXScore_t* p, cmCtx_t* ctx, const cmChar_t* midiFn)
915
 {
950
 {
916
   cmXsRC_t                 rc   = kOkXsRC;
951
   cmXsRC_t                 rc   = kOkXsRC;
924
   if( cmMidiFileOpen(ctx, &mfH, midiFn ) != kOkMfRC )
959
   if( cmMidiFileOpen(ctx, &mfH, midiFn ) != kOkMfRC )
925
     return cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object could not be opened from '%s'.",cmStringNullGuard(midiFn));
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
   if( (m = cmMidiFileMsgArray(mfH)) == NULL || (mN = cmMidiFileMsgCount(mfH)) == 0 )
964
   if( (m = cmMidiFileMsgArray(mfH)) == NULL || (mN = cmMidiFileMsgCount(mfH)) == 0 )
928
   {
965
   {
929
     rc = cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object appears to be empty.");
966
     rc = cmErrMsg(&p->err,kMidiFailXsRC,"The MIDI file object appears to be empty.");
936
     goto errLabel;
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
   printf(" i     j    score    midi\n");
1007
   printf(" i     j    score    midi\n");
940
   printf("---- ---- --- ---- --- ----\n");
1008
   printf("---- ---- --- ---- --- ----\n");
941
   
1009
   
1002
   // fill in the note->slink chain to link the notes in each measure in time order
1070
   // fill in the note->slink chain to link the notes in each measure in time order
1003
   _cmXScoreSort(p);
1071
   _cmXScoreSort(p);
1004
 
1072
 
1005
-  _cmXScoreProcessTies(p);
1073
+  _cmXScoreResolveTiesAndLoc(p);
1006
 
1074
 
1007
   //_cmXScoreResolveOctaveShift(p);
1075
   //_cmXScoreResolveOctaveShift(p);
1008
 
1076
 
1065
   cmChar_t N[] = {'\0','\0','\0','\0'};
1133
   cmChar_t N[] = {'\0','\0','\0','\0'};
1066
   cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
1134
   cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
1067
   snprintf(N,4,"%c%c%1i",note->step,acc,note->octave);
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
   if( cmIsFlag(note->flags,kSectionXsFl) )
1139
   if( cmIsFlag(note->flags,kSectionXsFl) )
1073
     cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
1140
     cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
1474
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
1541
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
1475
 
1542
 
1476
   cmXScoreWriteCsv(h,"/Users/kevin/temp/a0.csv");
1543
   cmXScoreWriteCsv(h,"/Users/kevin/temp/a0.csv");
1477
-  cmXScoreReport(h,&ctx->rpt,false);
1544
+  cmXScoreReport(h,&ctx->rpt,true);
1478
   
1545
   
1479
   return cmXScoreFinalize(&h);
1546
   return cmXScoreFinalize(&h);
1480
 
1547
 

Loading…
Cancel
Save