Browse Source

cmScore.h/c : Initial implementation of cmScoreFileFromMidi().

master
kevin 10 years ago
parent
commit
72b65a1904
2 changed files with 132 additions and 2 deletions
  1. 127
    0
      app/cmScore.c
  2. 5
    2
      app/cmScore.h

+ 127
- 0
app/cmScore.c View File

@@ -1955,6 +1955,133 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt )
1955 1955
   }
1956 1956
 }
1957 1957
 
1958
+cmScRC_t      cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn )
1959
+{
1960
+  cmScRC_t      rc  = kOkScRC;
1961
+  cmMidiFileH_t mfH = cmMidiFileNullHandle;
1962
+  cmCsvH_t      csvH = cmCsvNullHandle;
1963
+  cmErr_t       err;
1964
+  
1965
+  cmErrSetup(&err,&ctx->rpt,"MIDI to Score");
1966
+
1967
+  if( cmMidiFileOpen(midiFn, &mfH, ctx ) != kOkMfRC )
1968
+    return cmErrMsg(&err,kMidiFileFailScRC,"Unable to open the MIDI file '%s'.",midiFn);
1969
+
1970
+  if( cmCsvInitialize(&csvH,ctx) != kOkCsvRC )
1971
+  {
1972
+    cmErrMsg(&err,kCsvFailScRC,"Unable to initialize the CSV file: '%s'.",scoreFn);
1973
+    goto errLabel;
1974
+  }
1975
+
1976
+  // Convert the track message 'dtick' field to delta-microseconds.
1977
+  cmMidiFileTickToMicros(mfH);
1978
+
1979
+  unsigned                 msgCnt = cmMidiFileMsgCount(mfH);
1980
+  unsigned                 i;
1981
+  const cmMidiTrackMsg_t** tmpp   = cmMidiFileMsgArray(mfH);
1982
+  double                   acc_secs = 0;
1983
+  for(i=0; i<msgCnt; ++i)
1984
+  {
1985
+    const cmMidiTrackMsg_t* tmp    = tmpp[i];
1986
+    cmCsvCell_t*            cp     = NULL;
1987
+    unsigned                lexTId = 0;
1988
+    const cmChar_t*         opStr  = NULL;
1989
+    unsigned                midiCh  = 0;
1990
+    unsigned                d0     = 0;
1991
+    unsigned                d1     = 0;
1992
+    double dsecs = (double)tmp->dtick / 1000000.0;
1993
+    
1994
+    acc_secs += dsecs;
1995
+
1996
+    if( tmp->status == 0xff )
1997
+      opStr = cmMidiMetaStatusToLabel(tmp->metaId);
1998
+    else
1999
+    {
2000
+      opStr = cmMidiStatusToLabel(tmp->status);
2001
+      if( cmMidiIsChStatus( tmp->status ) )
2002
+      {
2003
+        midiCh = tmp->u.chMsgPtr->ch;
2004
+        d0     = tmp->u.chMsgPtr->d0;
2005
+        d1     = tmp->u.chMsgPtr->d1;
2006
+      }
2007
+    }
2008
+
2009
+    if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymUInt(csvH,i), kIntCsvTFl, lexTId ) != kOkCsvRC )
2010
+    {
2011
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn));
2012
+      goto errLabel;
2013
+    }
2014
+
2015
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->trkIdx, lexTId ) != kOkCsvRC )
2016
+    {
2017
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'trk' column in '%s'.",cmStringNullGuard(scoreFn));
2018
+      goto errLabel;
2019
+    }
2020
+
2021
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 0, lexTId ) != kOkCsvRC )
2022
+    {
2023
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'evt' column in '%s'.",cmStringNullGuard(scoreFn));
2024
+      goto errLabel;
2025
+    }
2026
+
2027
+    if( cmCsvInsertTextColAfter(csvH, cp, &cp, opStr, lexTId ) != kOkCsvRC )
2028
+    {
2029
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn));
2030
+      goto errLabel;
2031
+    }
2032
+
2033
+    if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, dsecs, lexTId ) != kOkCsvRC )
2034
+    {
2035
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'dticks' column in '%s'.",cmStringNullGuard(scoreFn));
2036
+      goto errLabel;
2037
+    }
2038
+
2039
+    if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, acc_secs, lexTId ) != kOkCsvRC )
2040
+    {
2041
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'micros' column in '%s'.",cmStringNullGuard(scoreFn));
2042
+      goto errLabel;
2043
+    }
2044
+    
2045
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->status, lexTId ) != kOkCsvRC )
2046
+    {
2047
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'status' column in '%s'.",cmStringNullGuard(scoreFn));
2048
+      goto errLabel;
2049
+    }
2050
+
2051
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->metaId, lexTId ) != kOkCsvRC )
2052
+    {
2053
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'meta' column in '%s'.",cmStringNullGuard(scoreFn));
2054
+      goto errLabel;
2055
+    }
2056
+
2057
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, midiCh, lexTId ) != kOkCsvRC )
2058
+    {
2059
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'ch' column in '%s'.",cmStringNullGuard(scoreFn));
2060
+      goto errLabel;
2061
+    }
2062
+
2063
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d0, lexTId ) != kOkCsvRC )
2064
+    {
2065
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd0' column in '%s'.",cmStringNullGuard(scoreFn));
2066
+      goto errLabel;
2067
+    }
2068
+
2069
+    if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d1, lexTId ) != kOkCsvRC )
2070
+    {
2071
+      cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd1' column in '%s'.",cmStringNullGuard(scoreFn));
2072
+      goto errLabel;
2073
+    }
2074
+
2075
+
2076
+  }
2077
+  
2078
+ errLabel:
2079
+   cmMidiFileClose(&mfH);
2080
+   cmCsvFinalize(&csvH);
2081
+
2082
+   return rc;
2083
+}
2084
+
1958 2085
 void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1959 2086
 {
1960 2087
   cmScH_t h = cmScNullHandle;

+ 5
- 2
app/cmScore.h View File

@@ -12,8 +12,8 @@ extern "C" {
12 12
     kSyntaxErrScRC,
13 13
     kInvalidIdxScRC,
14 14
     kTimeLineFailScRC,
15
-    kInvalidDynRefCntScRC
16
-  
15
+    kInvalidDynRefCntScRC,
16
+    kMidiFileFailScRC
17 17
   };
18 18
 
19 19
   enum
@@ -235,6 +235,9 @@ extern "C" {
235 235
 
236 236
   void          cmScorePrint( cmScH_t h, cmRpt_t* rpt );
237 237
 
238
+  // Generate a new score file from a MIDI file.
239
+  cmScRC_t      cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn );
240
+
238 241
   void          cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn );
239 242
 
240 243
 

Loading…
Cancel
Save