MIDI2TXT.CPP
上传用户:sun1865
上传日期:2008-12-23
资源大小:59k
文件大小:28k
源码类别:

midi

开发平台:

Visual C++

  1. static char* version = "midi2txt v1.14 by Guter Nagler (" __DATE__ ")";
  2. #include "midiio.hpp"
  3. #include "miditime.hpp"
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include <string.h>
  7. #ifdef __MSDOS__
  8. #include <dos.h>
  9. #else
  10. #endif
  11. #include "gnadvert.h"
  12. // values for info_
  13. #define ONLY_ERRORS -2
  14. #define ONLY_LYRICS -1
  15. #define ONLY_CHUNK   0
  16. #define ONLY_SHORT   1
  17. #define ONLY_INFO    2
  18. #define ALL_EVENTS   3
  19. static FILE* outputf = NULL;
  20. static const char* versioninfo(int version)
  21. {
  22.   switch(version)
  23.   {
  24.   case 0: return "single multichanneltrack";
  25.   case 1: return "several tracks with seperated channels to play all at once";
  26.   case 2: return "several multichanneltracks to play one by one";
  27.   default: return "unknown version";
  28.   }
  29. }
  30. class MidiPrint : public MidiRead
  31. {
  32. public:
  33.   MidiPrint(char* name);
  34.   virtual ~MidiPrint();
  35.   virtual void head(unsigned version, unsigned tracks, unsigned unitperbeat);
  36.   void garbage(FILE* f, long datapos, long datalen);
  37.   virtual void track(int trackno, long length, int channel);
  38.   virtual void endtrack(int trackno);
  39.   virtual void seqnumber(unsigned int seqno);
  40.   virtual void text(int what, unsigned len, char* whattext, unsigned char* txt);
  41.   virtual void meta(int what, unsigned len, unsigned char* data);
  42.   virtual void meta(int what, FILE* f, long datapos, long datalen);
  43.   virtual void end();
  44.   virtual void prefixchannel(unsigned char channel);
  45.   virtual void prefixport(unsigned char port);
  46.   virtual void smpteofs(int mode, int hour, int min, int sec, int frame, int fracframe);
  47.   virtual void tact(int nom, int denom, int unitsperbeat, int notes32perbeat);
  48.   virtual void tempo(unsigned long ticks);
  49.   virtual void key(int signature, int isminor);
  50.   virtual void program(int prg, int channel);
  51.   virtual void control(int channel, int what, int value);
  52.     virtual void highbank(int channel, int val);
  53.     virtual void wheel(int channel, int val);
  54.     virtual void breath(int channel, int val);
  55.     virtual void foot(int channel, int val);
  56.     virtual void portamentotime(int channel, int val);
  57.     virtual void data(int channel, int val);
  58.     virtual void volume(int channel, int val);
  59.     virtual void balance(int channel, int val);
  60.     virtual void expression(int channel, int val);
  61.     virtual void lowbank(int channel, int val);
  62.     virtual void hold(int channel, int val);
  63.     virtual void reverb(int channel, int val);
  64.     virtual void chorus(int channel, int val);
  65.     virtual void datainc(int channel, int val);
  66.     virtual void datadec(int channel, int val);
  67.     virtual void lowrpn(int channel, int val);
  68.     virtual void highrpn(int channel, int val);
  69.     virtual void pitchbendrange(int channel, int val);
  70.   virtual void noteon(int channel, int note, int vel);
  71.   virtual void noteoff(int channel, int note, int vel);
  72.   virtual void time(unsigned long ticks);
  73.   virtual void pitchbend(int channel, int val);
  74.   virtual void polyaftertouch(int channel, int note, int val);
  75.   virtual void aftertouch(int channel, int val);
  76.   virtual void songpos(unsigned pos);
  77.   virtual void songselect(unsigned char song);
  78.   virtual void tunerequest();
  79.   virtual void timingclock();
  80.   virtual void start();
  81.   virtual void cont();
  82.   virtual void stop();
  83.   virtual void activesense();
  84.   virtual void sysex(unsigned syslen, unsigned char* sysdata);
  85.   virtual void sysex(FILE* f, long sysdatapos, long sysdatalen);
  86.   virtual void gmreset();
  87.   virtual void gsreset();
  88.   virtual void gsexit();
  89.   virtual void xgreset();
  90.   virtual void endmidi();
  91.   virtual void error(const char* msg);
  92.   virtual void percent(int perc);
  93.   void printchannel(int channel);
  94.   void printcurpos(unsigned long units);
  95.   int info_;
  96.   int printunits_;
  97.   int printms_;
  98.   int marktact_;
  99.   long errorcnt_;
  100.   int printdecimal_; // no program, notes names etc.
  101.   int printchannel_;
  102. private:
  103.   int indent_;
  104.   MidiTimeTable* tactinfo_;
  105.   char hastempochanges_; // can't print milliseconds in tracks 2,3... if tempo changes
  106.   int nl_;
  107.   int endmark_;  // each track should contain FF 2F 00 as last command
  108.   void indent();
  109.   void hex(FILE* f, long pos, long len, FILE* outputf);
  110.   void printxf();
  111.   int runxftrack(int trackno);
  112. };
  113. MidiPrint::MidiPrint(char* name) : MidiRead(name, NULL, MIDI_PRELOAD)
  114. {
  115.   indent_ = 0;
  116.   info_ = ALL_EVENTS;
  117.   marktact_ = printms_ = 0;
  118.   nl_ = 1;
  119.   errorcnt_ = 0;
  120.   hastempochanges_ = 0;
  121.   printdecimal_ = 0;
  122.   printchannel_ = 0;
  123.   tactinfo_ = 0;
  124. }
  125. MidiPrint::~MidiPrint()
  126. {
  127.   delete tactinfo_;
  128.   tactinfo_ = 0;
  129. }
  130. void MidiPrint::indent()
  131. {
  132.  for (; indent_ > 0; indent_--)
  133.     fputc(' ', outputf);
  134. }
  135. void MidiPrint::head(unsigned version, unsigned tracks, unsigned unitperbeat)
  136. {
  137.   if (marktact_)
  138.   {
  139.     tactinfo_ = new MidiTimeTable(midiname(), getf());
  140.     if (tactinfo_)
  141.     {
  142.       if (!tactinfo_->run())
  143.       {
  144.         delete tactinfo_;
  145.         tactinfo_ = 0;
  146.       }
  147.     }
  148.   }
  149.   if (midiname_)
  150.     fprintf(outputf, "// %sn", midiname_);
  151.   if (getcurpos() != 14)
  152.     fprintf(outputf, " // Warning: %ld bytes garbage at beginning of filen", getcurpos() - 14);
  153.   if (tracks_ == 0 && info_ == ONLY_ERRORS)
  154.     error("no track found");
  155.   if (info_ == ONLY_SHORT || info_ == ONLY_LYRICS || info_ == ONLY_ERRORS)
  156.     return;
  157.   fprintf(outputf, "mthdn");
  158.   fprintf(outputf, "  version %d // %sn", version, versioninfo(version));
  159.   fprintf(outputf, "  // %d track%sn", tracks, tracks != 1 ? "s" : "");
  160.   fprintf(outputf, "  unit %d // is 1/4n", unitperbeat);
  161.   if (tracklen_ > 6)
  162.   {
  163.     fprintf(outputf, "// Warning: %ld bytes garbage in header:n", tracklen_ - 6);
  164.     hex(getf(), getcurpos(), tracklen_ - 6, outputf);
  165.   }
  166.   fprintf(outputf, "end mthdn");
  167. }
  168. void MidiPrint::track(int trackno, long /*length*/, int channel)
  169. {
  170.   endmark_ = 0;
  171.   if (info_ == ONLY_SHORT || info_ == ONLY_LYRICS || info_ == ONLY_ERRORS)
  172.     return;
  173.   fprintf(outputf, "nmtrk");
  174.   if (channel >= 0)
  175.     fprintf(outputf, "(%d)", channel+1);
  176.   else if (channel == MULTICHANNEL)
  177.     fprintf(outputf, " // multichannel track");
  178.   fprintf(outputf, "  // track %d", trackno);
  179.   fprintf(outputf, "n");
  180. }
  181. void MidiPrint::endtrack(int /*trackno*/)
  182. {
  183.   if (!endmark_ && info_ != ONLY_CHUNK)
  184.     fprintf(outputf, " // Warning: end of track meta event missingn");
  185.   if (info_ == ONLY_SHORT || info_ == ONLY_ERRORS)
  186.     return;
  187.   if (info_ == ONLY_LYRICS)
  188.   {
  189.     if (!nl_)
  190.     {
  191.       nl_ = 1;
  192.       fprintf(outputf, "n");
  193.     }
  194.     return;
  195.   }
  196.   if (info_ >= ALL_EVENTS)
  197.     fprintf(outputf, "n");
  198.   fprintf(outputf, "end mtrkn");
  199. }
  200. void printchar(int c)
  201. {
  202.   if (c < 0)
  203.     return;
  204.   if (c == '\')
  205.     fprintf(outputf, "\\");
  206.   else if (c == '"')
  207.     fprintf(outputf, "\"");
  208.   else if (c != 0 && (isprint(c) || strchr("剶亷櫄