精华内容
下载资源
问答
  • 用于MIDI格式音乐的水印算法程序,有MATLAB实现程序和说明
  • midi格式音乐大合集

    2015-08-29 14:13:48
    整合了网上大多数mid音乐,包括“173首流行midi铃声”“490首midi四和弦”以及几百个经典游戏midi配乐或主题曲,足够让你回忆起塞班时代的种种经典...
  • midi格式音乐都无法播放

    千次阅读 2014-12-13 11:13:46
    故障的原因:为什么电脑玩游戏,看DVD时声音正常,而播放MIDI音乐文件时却没有声音? 故障分析:出现上述故障现象可能有以下三种情况。 1、使用的是ISA声卡,一些比较老的ISA声卡由于是16位模式,因此与32位...

    故障的原因:为什么电脑玩游戏,看DVD时声音正常,而播放MIDI音乐文件时却没有声音?

    故障分析:出现上述故障现象可能有以下三种情况。

    1、使用的是ISA声卡,一些比较老的ISA声卡由于是16位模式,因此与32位模式不兼容,从而造成MIDI播放不正常。

    2、如今流行的PCI声卡大多采用波表合成技术,如果播放MIDI音乐文件时不能放音,则很可能是因为没有加载适当的波表音色库。解决方法是,可以从声卡驱动程序光盘上找到波表音色库文件进行安装,如果没有,可以到厂商网站上下载一个。

    3、Windows音量控制中的MIDI通道没有启动或者设置了静音模式。

    如果是MIDI通道没有启动造成的故障问题,那么可以通过以下操作步骤解决。

    1、打开“控制面板”窗口,然后双击“系统”图标,弹出“系统属性”对话框。单击“硬件”选项卡的“设备管理器”窗口,双击“声音、视频和游戏控制器”。

    2、双击声卡,打开声卡属性窗口。如果不知道声卡名称,可以用鲁大师检测,或者检阅声卡文档。

    3、选择“属性”选项卡,双击“MIDI设备和仪器”,在展开的列表中可以看到Realtek High Definiton Audio项。

    4、选中Realtek High Definiton Audio项,单击“属性”按钮,选中“在此设备上使用MIDI功能”单选按钮,再连续单击“确定”按钮退出。

    如果是设置成了静音模式,那么可以在操作系统中打开“声音和音频设备属性”对话框,切换至“选项”卡,在"MIDI音乐播放"选项组中选择合适的播放设备即可,如果是由于在Windows音量控制中的MIDI通道设置成了静音模式,那么将静音模式去掉即可。

    展开全文
  • 大家都知道,HTML5 Audio标签能够支持wav, webm, mp3, ogg, acc等格式,但是有个很重要的音乐文件格式midi(扩展名mid)却在各大浏览器中都没有内置的支持,因为mid文件并不像其他声音文件那样记录声音的采样信息,...

    大家都知道,HTML5 Audio标签能够支持wav, webm, mp3, ogg, acc等格式,但是有个很重要的音乐文件格式midi(扩展名mid)却在各大浏览器中都没有内置的支持,因为mid文件并不像其他声音文件那样记录声音的采样信息,而是记录了乐器的演奏指令,二者的原理截然不同。

    mid文件格式的最突出的有点是文件极小,几分钟的音乐可能只有几K的文件大小,mp3等其他格式则至少要几M以上,所以midi在手机和web上有很大的优势,特别是适合做各种铃声,背景音乐。

    标签已经过时了,很多浏览器都不再支持。

    无论是标准组织,还是浏览器厂商,都主张使用来播放音频文件。

    考虑到要求支持MIDI的广泛呼声,W3C有指定了一个Web MIDI API草案,但这个草案还非常新,浏览器还没有支持。

    为了让midi在html5 audio上播放出来,需要动用Javascript 来处理。

    我这里推荐3个非常好的Javascript实现的audio播放midi:

    MIDI.js - Sequencing in Javascript.

    这是一个js库,封装了一些接口方便web开发者调用播放mid音乐文件。

    L3Byb3h5L2h0dHAvd3d3LnNpbHZlcmxpZ2h0Y2hpbmEubmV0L3VwbG9hZHMvYWxsaW1nLzEyMDgwMi8yMjMzMDk1NDM5LTAuanBn.jpg

    Color Piano V2

    这是一个彩色钢琴,你可以手动弹奏,也可以自动弹奏动态加载的mid文件。

    L3Byb3h5L2h0dHAvd3d3LnNpbHZlcmxpZ2h0Y2hpbmEubmV0L3VwbG9hZHMvYWxsaW1nLzEyMDgwMi8yMjMzMDk0VTctMS5qcGc=.jpg

    Audiotool

    这是一个强大的电子音乐合成工具了,没有一点器乐知识的话,可能基本不懂用了,比如我。

    L3Byb3h5L2h0dHAvd3d3LnNpbHZlcmxpZ2h0Y2hpbmEubmV0L3VwbG9hZHMvYWxsaW1nLzEyMDgwMi8yMjMzMDlFSi0yLmpwZw==.jpg

    展开全文
  • 音乐汽车人 使用深度学习生成流行音乐! 您也可以通过网络应用进行试验 概述 NLP的最新进展在生成文本方面产生了惊人的。 架构是其背后的重要原因。 该项目旨在利用这些强大的语言模型并将其应用于音乐。 它建立在...
  • MIDI音乐音轨分离程序

    2010-06-06 22:25:27
    本程序可以实现midi格式音乐各个音轨的分离。每个音轨生成一个单独的文件,这样可以单独收听每个乐器的声音(也可能多个乐器一个音轨)
  • 2018-11-14 MIDI音乐格式笔记学习梁子20163933reference: ... 关于MIDI文件格式 目前已知的: .mid文件属于二进制文件,可以通过电脑或者手机上的音乐播放器...若需要阅读(观看)midi格式文件,可以使用binary vi...

    2018-11-14 MIDI音乐格式笔记学习

    reference:
    https://www.midifan.com/modulearticle-detailview-901.htm

    关于MIDI文件格式

    目前已知的:

    1. .mid文件属于二进制文件,可以通过电脑或者手机上的音乐播放器直接播放。
    2. 若需要阅读(观看)midi格式文件,可以使用binary viewer等二进制读取器打开。

    通过研究,格式如下:

    文件格式

    主要包含两部分:首部块(Header chunk)音轨块(track chunk)
    其格式分别为:

    MThd <数据长度> <Header数据> //首部块
    MTrk <数据长度> <Track模块> //音轨块

    例如读取到的:
    MIDI源码之一
    其中:

    Header Chunk

    /* 
    4D 54 68 64 
    00 00 00 06 
    00 01                 ff ff
    00 06                 nn nn 指定轨道数:实际音轨数加上全局的音轨
    00 60                 dd dd指定基本时间:一般为120 (00 78),即一个四分音符的tick数,tick是MIDI中的最小时间单位
    */
    
    char Midild[4];  //MIDI文件头标志,一般为MThd 
    long length;     //文件首部数据长度(除它本身和文件头标志专用的字节以外),通常他设置为6,即下面三个部分的字节长度
    int format;        //表示MIDI文件存放的格式,包括:                                
    // 0)当format为0时只有一个Track Chunk,
    // 1)当format为1时有一个或多个Track Chunk
    // 2)当format为2时只有一个或多个各自独立的Track Chunk
    int TrackNum; 
    int division;   //指定了计数的方法
    

    其中对于division的详细说明:
    division讲解

    在上面我们注意到以下问题:上面的数据结构默认了:long类型是4Byte,int为2Byte,char为1Byte。

    音轨块 track chunk

    音轨块用来播放音乐文件的数据信息,每一个track chunk对应着一组MIDI码,它由**头部信息和若干个音轨事件(mtrk event)**构成。
    头部为:

    /* 头部信息
    4D 54 72 6B      ASCII:Mtrk
    00 00 00 0C                 表示后面有12位的数据
    */
    /*
    00 FF 58 04 04 02 18 08 00 FE 2E 00 
    
    
    */
    
    char TrackChunkId[4];      //Track Chunk标志MTrk
    long TrackChunkMsgLength;  //该Track Chunk信息长度

    Mtrk event是由事件计数值(dela-time)和event(MIDI码信息)组合而成的,即
    < Mtrk > = < dela-time > < event >
    emmmmm

    使用WriteLengthToBuf()函数

    目的是为了完成时间值二进制的转换

    源代码(这个C代码不是我写的,但是值得学习)

      #include <stdlib.h>
      #include <stdio.h>
      #include <io.h>
      #include <string.h>
      #define C1 60 //C调1的键名值
      #define FOURPAINUM 64 //1/4音符计数
      #define MIDICLOCK 24 //每1/64音符的MIDICLOCK数
      #define JumpNullChar(x) / //跳过空字符
       { /
       while(*x==' ' /
       ||*x=='/t' /
       ||*x=='/n' /
       ||*x=='|') /
       x++; /
       };
      enum ERRORCODE{ //处理错误信息
       ChangeOK, //转换成功
       TextFileNotOpen, //文本文件不能打开
       MidiFileCanNotCreate, //指定的MIDI文件不能建立
       TextFileToBig, //文本文件太大
       MallocError, //内存分配错误
       InvalideChar, //在文本文件中出现了非法字符
       NotFoundTrack, //没有找到指定的磁道信息
       NotMIDITextFile, //文本文件不是MIDI文本文件
       };
      void SWAP(char *x,char *y) //两数据交换
      { char i;
       i=*x;
       *x=*y;
       *y=i;
      }
      union LENGHT
      { long length;
      char b[4];
      } ;
      struct MH { //MIDI文件头
      char MidiId[4]; //MIDI文件标志MThd
      long length; //头部信息长度
      int format; //存放的格式
      int ntracks; //磁道数目
      int PerPaiNum; //每节计算器值
      };
      struct TH //音轨头
      { char TrackId[4]; //磁道标志MTrk
       long length; //信息长度
      } ;
      class MIDI
      {
      public:
      char ErrorMsg[100]; //错误信息
      private:
      unsigned char *TextFileBuf,
       *TextFileOldBuf;
      unsigned char *MidiFileBuf,
       *MidiFileOldBuf;
      char OneVal; //某调时,1的健值
      char PaiNum; //第一小节节拍总数
      char OnePaiToneNum; //用几分音符作为一基本拍
      public:
      //将符全MIDI书定格式的文本文件生成MIDI文件
      int ChangeTextToMidi(char *TextFileName,
       char *MidiFileName);
      char *GetErrorMsg() //获取错误信息
       { return(ErrorMsg);}
      private:
      char GetCurPaiSpeed(int n); //取当前拍的按下强度
      void WriteSoundSize(char ntrack,unsigned int );
      void SetOnePaiToneNum(int n)
       { OnePaiToneNum=n; };
      void SetOneVal(char *m) ; //取m大调或小调时,1的实际键值
      char GetToneNum(char c, //取记名对应的键值
       char flag) ;
      void WriteMHToFile(long length, //建立MIDI文件头
       int format,
       int ntracks,
       int PerPaiNum,
       FILE *fp);
      void WriteTHToFile(long lenght,
       FILE *fp); //建立MIDI磁道头
      void WriteTrackMsgToFile(FILE *fp);
      //将磁道音乐信息定入文件中
      void WriteSpeed(int speed);
      void SetPaiNum(int n)
       { PaiNum=n;}
      long NewLong(long n); //新的long值
      int NewInt(int n) //新的int值
       { return(n<<8|n>>8);}
      //将n改为可变长度,内入buf处
      void WriteLenghtToBuf(unsigned long n,
       char *buf);
      void ChangePrommgram(char channel, //设置音色
       char promgram);
      void NoteOn (char n, //演奏乐音
       char speed,
       unsigned long delaytime);
      void WriteNoteOn(char,char,char ,unsigned long) ;
      void WriteTextMsg(char *msg); //定一串文本信息
      void WriteTimeSignature(char n, //设置时间信息
       char d);
      void WriteTrackEndMsg(); //设置磁道结束信息
      };
    
      /**************************************************
      /* 作用:将符合MIDI文本文件的text文件转换成MIDI */
      /* 文件. */
      /* 入口参数:TextFileName 文本文件名 */
      /* MidiFileName MIDI文件名 */
      /* 出口参数:见 ERRORCODE 说明 */
      /*************************************************/
      int MIDI::ChangeTextToMidi(char *TextFileName,
      char *MidiFileName)
      { int tracks,ntrack,delaytime;
      int speed,IsFirst,nn,dd;
      unsigned char buf[80],*msgbuf,c;
      FILE *TextFp,*MidiFp;
      long FileSize;
      char SpeedVal;
      TextFp=fopen(TextFileName,"r");
      if (TextFp==NULL)
      {sprintf(ErrorMsg,
      "文本文件[%s]不能打开。/n",TextFileName);
       return(TextFileNotOpen);
       }
      fseek(TextFp,0,SEEK_END); /*测试文件大小*/
      FileSize=ftell(TextFp);
      TextFileBuf=(char *)malloc(FileSize);/*为文件分配内存*/
      if (TextFileBuf==NULL)
      { sprintf(ErrorMsg,
      "文本文件[%s]太大,没有足够的内存处理。/n",
      TextFileName);
       fclose(TextFp);
       return(TextFileToBig);
      }
      memset(TextFileBuf,0,FileSize);
      MidiFileBuf=(char *) malloc(FileSize*4);
      if ( MidiFileBuf==NULL)
      { sprintf(ErrorMsg,"不能为MIDI文件分配内存。/n");
      fclose(TextFp);
      free(TextFileBuf);
      return(MallocError);
      }
      MidiFp=fopen(MidiFileName,"wb");
      if (MidiFp==NULL)
       { sprintf(ErrorMsg,
      "Midi文件[%s]不能建立。/n",MidiFileName);
       fclose(TextFp);
       free(MidiFileBuf);
       free(TextFileBuf);
       return(MidiFileCanNotCreate);
       }
      MidiFileOldBuf=MidiFileBuf;
      TextFileOldBuf=TextFileBuf;
      fseek(TextFp,0,SEEK_SET);
      fread(TextFileBuf,FileSize,1,TextFp);
      fclose(TextFp);
      JumpNullChar(TextFileBuf);
      c=strnicmp(TextFileBuf,"[MIDI]",6);
      if (c)
      {sprintf(ErrorMsg,
      "文本文件[%s]不是MIDI文本文件。/n",MidiFileName);
      fcloseall();
      free(TextFileOldBuf);
      free(MidiFileOldBuf);
      return(NotMIDITextFile);
      }
      TextFileBuf+=6;
      JumpNullChar(TextFileBuf);
      sscanf(TextFileBuf,"%c,%d/%d,%d,%d", //取调号等信息
      c,nn,dd,speed,tracks);
      buf[0]=c;buf[1]=0; SetOneVal(buf); //设置该调1的键值
      if (nn<1 || nn> 7) nn=4;
      if (dd<2 || dd>16) dd=4;
      while(*TextFileBuf!='/n') TextfileBuf++;
      JumpNullChar(TextFileBuf);
      if (speed<60 || speed >200) speed=120;
      JumpNullChar(TextFileBuf);
      if (tracks<1 || tracks>16) tracks=1;
      JumpNullChar(TextFileBuf);
      ntrack=1;
      WriteMHToFile(6,1,tracks,speed,MidiFp);
      WriteTimeSignature(nn,dd); //设置时间记录格式
      SetPaiNum(nn);
      WriteSpeed(speed); //设置演奏速度
      while(ntrack<=tracks *TextFileBuf!=0)
      {sprintf(buf,"[%d]",ntrack);
      TextFileBuf=strstr(TextFileBuf,buf);//查找该磁道起始位置
      if (TextFileBuf==NULL) //没有找到
      { sprintf(ErrorMsg,
      "在文件[%s]中,第%d磁道音乐信息没找到。/n.",
       TextFileName,ntrack);
       free(MidiFileOldBuf);
       free(TextFileOldBuf);
       fcloseall();
       return(NotFoundTrack);
      }
      if (ntrack!=1) MidiFileBuf=MidiFileOldBuf;
      SpeedVal=0;
      TextFileBuf+=strlen(buf);
      IsFirst=1;
      while(*TextFileBuf!=0 *TextFileBuf!='[')
      { JumpNullChar(TextFileBuf);
      c=*(TextFileBuf++);
      if ( (c>='0' c<='7')
      || (c>='a' c<='g')
      || (c>='A' c<='G')
      )
      {JumpNullChar(TextFileBuf);
       if (*TextFileBuf=='b' || *TextFileBuf=='#')
       { c=GetToneNum(c,*TextFileBuf);/*取出实际的音符*/
       TextFileBuf++;
       JumpNullChar(TextFileBuf);
       }
       else c=GetToneNum(c,' ');
      switch(*(TextFileBuf++))
       { case '-': //延长一拍
       delaytime=2*FOURPAINUM;
       JumpNullChar(TextFileBuf);
       while(*TextFileBuf=='-')
       { TextFileBuf++;
       delaytime+=FOURPAINUM;
       JumpNullChar(TextFileBuf);
       }
       break;
       case '_': //8分音符
       delaytime=FOURPAINUM/2;
       JumpNullChar(TextFileBuf);
       if(*TextFileBuf=='.')
       {TextFileBuf++;
       delaytime=delaytime*3/2;
       }
       break;
       case '=': //16分音符
       delaytime=FOURPAINUM/4;
       JumpNullChar(TextFileBuf);
       if(*TextFileBuf=='.')
       {delaytime=delaytime*3/2;
       TextFileBuf++;}
       break;
       case '.': //附点音符
       delaytime=FOURPAINUM*3/2;
       break;
       case ':': //32分音符
       delaytime=FOURPAINUM/16;
       JumpNullChar(TextFileBuf);
       if(*TextFileBuf=='.')
       {delaytime=delaytime*3/2;
       TextFileBuf++;}
       break;
       case ';': //64分音符
       delaytime=FOURPAINUM/32;
       if(*TextFileBuf=='.')
       { delaytime=delaytime*3/2;
       TextFileBuf++;}
       break;
       default:
       delaytime=FOURPAINUM;
       TextFileBuf--;
       break;
       }
    
    if (IsFirst)
       {WriteNoteOn(ntrack,c,
      GetCurPaiSpeed(SpeedVal/(FOURPAINUM*4/dd)+1),
      delaytime);
       IsFirst=0;}
       else
       NoteOn(c,
      GetCurPaiSpeed(SpeedVal/(FOURPAINUM*4/dd)+1),
      delaytime);
       SpeedVal=(SpeedVal+delaytime) //下一音符所处的节拍
      %(PaiNum*FOURPAINUM*4/dd);
      }
      else
      {switch(c)
      { case 'S':
      case 's':
      case 'p':
      case 'P': /*设置音色*/
       sscanf(TextFileBuf,"%d",IsFirst);
       while(*TextFileBuf>='0' *TextFileBuf<='9')
      TextFileBuf++;
      if (c=='P'||c=='p') //若为P,表示改变音色
       ChangePrommgram(ntrack,(char)IsFirst);
       else //否则,表示设置音量大小
       WriteSoundSize(ntrack,(unsigned int)IsFirst);
       IsFirst=1;
       break;
      case '{': /*写歌词*/
       msgbuf=buf;
       while(*TextFileBuf!='}'
       *TextFileBuf!='/n'
       *TextFileBuf!=0
       *TextFileBuf!='[')
       *(msgbuf++)=*(TextFileBuf++);
       *msgbuf=0;
       IsFirst=1;
       WriteTextMsg(buf);
       if (*TextFileBuf=='}') TextFileBuf++;
       break;
      case '//': //降八度
       OneVal-=12;
       break;
      case '/': //升八度
       OneVal+=12;
       break;
      case '[':
      case 0:
       TextFileBuf--;
       break;
      default:
       sprintf(ErrorMsg,"文本文件[%s]出现非法字符(%c)。",
       TextFileName,c);
       free(MidiFileOldBuf);
       free(TextFileOldBuf);
       fcloseall();
       return(InvalideChar);
       }
      }
      }
      WriteTrackEndMsg(); //设置磁道结束信息
      WriteTrackMsgToFile(MidiFp); //将磁道音乐信息定入文件中
      ntrack++;
      }
      free(MidiFileOldBuf);
      free(TextFileOldBuf);
      fclose(MidiFp);
      sprintf(ErrorMsg,"MIDI文件[%s]转换成功。",MidiFileName);
      return(ChangeOK);
      }
     /*****************************************************/
      /*作用:将长整型数据变成可变长度,存入buf处 */
      /*入口参数:n 数据 buf 结果保存入 */
      /****************************************************/
      void MIDI::WriteLenghtToBuf(unsigned long n,char *buf)
      { unsigned char b[4]={0};
      int i;
      b[3]=(unsigned char)(n0x7f);
      i=2;
      while(n>>7)
      { n>>=7;
       b[i--]=(char)( (n0x7f)|0x80);
       }
      for (i=0;i<4;i++)
      if (b[i]) *(buf++)=b[i];
      *buf=0;
      }
      long MIDI::NewLong(long n) //将长整型数据改成高位在前
      { union LENGHT l={0};
      char i;
      l.length=n;
      SWAP(l.b[3],l.b[0]);
      SWAP(l.b[2],l.b[1]);
      return(l.length);
      }
      //开始演奏音乐
      void MIDI::WriteNoteOn(char channel, //通道号
      char note, //音符值
      char speed, //按键速度
      unsigned long delaytime) //延时数
      { unsigned char buf[5];
      int i;
      channel--;
      *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0x90|channel0x7f;//Write Channel
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=speed;
      WriteLenghtToBuf(delaytime*MIDICLOCK,buf);
      i=0;
      while(buf[i]>=0x80) //Write Delay Time
       *(MidiFileBuf++)=buf[i++];
      *(MidiFileBuf++)=buf[i];
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=0;
      }
      void MIDI::NoteOn(char note,
      char speed,
      unsigned long delaytime) //发音
      { unsigned char buf[5];
      int i;
      *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=speed;
      WriteLenghtToBuf(delaytime*MIDICLOCK,buf);
      i=0;
      while(buf[i]>0x80)
       *(MidiFileBuf++)=buf[i++];
      *(MidiFileBuf++)=buf[i];
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=0;
      }
      void MIDI::ChangePrommgram(char channel,char n) //改变音色
      { *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0xc0|(channel-1)0x7f;
      *(MidiFileBuf++)=n;
      }
      void MIDI::WriteTextMsg(char *msg) //向内存写入一文本信息
      { char bufmsg[100]={0xff,5,0,0,0};
      int len;
      *(MidiFileBuf++)=0;
      bufmsg[2]=(char)strlen(msg);
      strcpy(bufmsg[3],msg);
      strcpy(MidiFileBuf,bufmsg);
      MidiFileBuf+=strlen(bufmsg)+3;
      }
      void MIDI::WriteTrackEndMsg() //磁道结束信息
      { *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0xff;
      *(MidiFileBuf++)=0x2f;
      *(MidiFileBuf++)=0;
      }
      char MIDI::GetToneNum(char n,char flag)
      /*入口参数: n 音高
       flag 升降记号
      返回值: 该乐音的实际标号值*/
      { static char val[7]={9 ,11,0,2,4,5,7};
      static char one[7]={0,2,4,5,7,9,11};
      int i;
      i=OneVal;
      if (n<='7' n>='1') i=i+one[n-'1'];
      else
       if (n>='a' n<='g')
      i=i+val[n-'a']-12; //低音,降12个半音
       else
       if (n>='A' n<='G') //高音,升12个半音
       i=i+val[n-'A']+12;
       else //否则,识为休止符
       i=0;
      if (flag=='b') i--;
      else if (flag=='#') i++;
      return(i);
      }
    
       if (IsFirst)
       {WriteNoteOn(ntrack,c,
      GetCurPaiSpeed(SpeedVal/(FOURPAINUM*4/dd)+1),
      delaytime);
       IsFirst=0;}
       else
       NoteOn(c,
      GetCurPaiSpeed(SpeedVal/(FOURPAINUM*4/dd)+1),
      delaytime);
       SpeedVal=(SpeedVal+delaytime) //下一音符所处的节拍
      %(PaiNum*FOURPAINUM*4/dd);
      }
      else
      {switch(c)
      { case 'S':
      case 's':
      case 'p':
      case 'P': /*设置音色*/
       sscanf(TextFileBuf,"%d",IsFirst);
       while(*TextFileBuf>='0' *TextFileBuf<='9')
      TextFileBuf++;
      if (c=='P'||c=='p') //若为P,表示改变音色
       ChangePrommgram(ntrack,(char)IsFirst);
       else //否则,表示设置音量大小
       WriteSoundSize(ntrack,(unsigned int)IsFirst);
       IsFirst=1;
       break;
      case '{': /*写歌词*/
       msgbuf=buf;
       while(*TextFileBuf!='}'
       *TextFileBuf!='/n'
       *TextFileBuf!=0
       *TextFileBuf!='[')
       *(msgbuf++)=*(TextFileBuf++);
       *msgbuf=0;
       IsFirst=1;
       WriteTextMsg(buf);
       if (*TextFileBuf=='}') TextFileBuf++;
       break;
      case '//': //降八度
       OneVal-=12;
       break;
      case '/': //升八度
       OneVal+=12;
       break;
      case '[':
      case 0:
       TextFileBuf--;
       break;
      default:
       sprintf(ErrorMsg,"文本文件[%s]出现非法字符(%c)。",
       TextFileName,c);
       free(MidiFileOldBuf);
       free(TextFileOldBuf);
       fcloseall();
       return(InvalideChar);
       }
      }
      }
      WriteTrackEndMsg(); //设置磁道结束信息
      WriteTrackMsgToFile(MidiFp); //将磁道音乐信息定入文件中
      ntrack++;
      }
      free(MidiFileOldBuf);
      free(TextFileOldBuf);
      fclose(MidiFp);
      sprintf(ErrorMsg,"MIDI文件[%s]转换成功。",MidiFileName);
      return(ChangeOK);
      }
     /*****************************************************/
      /*作用:将长整型数据变成可变长度,存入buf处 */
      /*入口参数:n 数据 buf 结果保存入 */
      /****************************************************/
      void MIDI::WriteLenghtToBuf(unsigned long n,char *buf)
      { unsigned char b[4]={0};
      int i;
      b[3]=(unsigned char)(n0x7f);
      i=2;
      while(n>>7)
      { n>>=7;
       b[i--]=(char)( (n0x7f)|0x80);
       }
      for (i=0;i<4;i++)
      if (b[i]) *(buf++)=b[i];
      *buf=0;
      }
      long MIDI::NewLong(long n) //将长整型数据改成高位在前
      { union LENGHT l={0};
      char i;
      l.length=n;
      SWAP(l.b[3],l.b[0]);
      SWAP(l.b[2],l.b[1]);
      return(l.length);
      }
      //开始演奏音乐
      void MIDI::WriteNoteOn(char channel, //通道号
      char note, //音符值
      char speed, //按键速度
      unsigned long delaytime) //延时数
      { unsigned char buf[5];
      int i;
      channel--;
      *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0x90|channel0x7f;//Write Channel
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=speed;
      WriteLenghtToBuf(delaytime*MIDICLOCK,buf);
      i=0;
      while(buf[i]>=0x80) //Write Delay Time
       *(MidiFileBuf++)=buf[i++];
      *(MidiFileBuf++)=buf[i];
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=0;
      }
      void MIDI::NoteOn(char note,
      char speed,
      unsigned long delaytime) //发音
      { unsigned char buf[5];
      int i;
      *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=speed;
      WriteLenghtToBuf(delaytime*MIDICLOCK,buf);
      i=0;
      while(buf[i]>0x80)
       *(MidiFileBuf++)=buf[i++];
      *(MidiFileBuf++)=buf[i];
      *(MidiFileBuf++)=note;
      *(MidiFileBuf++)=0;
      }
      void MIDI::ChangePrommgram(char channel,char n) //改变音色
      { *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0xc0|(channel-1)0x7f;
      *(MidiFileBuf++)=n;
      }
      void MIDI::WriteTextMsg(char *msg) //向内存写入一文本信息
      { char bufmsg[100]={0xff,5,0,0,0};
      int len;
      *(MidiFileBuf++)=0;
      bufmsg[2]=(char)strlen(msg);
      strcpy(bufmsg[3],msg);
      strcpy(MidiFileBuf,bufmsg);
      MidiFileBuf+=strlen(bufmsg)+3;
      }
      void MIDI::WriteTrackEndMsg() //磁道结束信息
      { *(MidiFileBuf++)=0;
      *(MidiFileBuf++)=0xff;
      *(MidiFileBuf++)=0x2f;
      *(MidiFileBuf++)=0;
      }
      char MIDI::GetToneNum(char n,char flag)
      /*入口参数: n 音高
       flag 升降记号
      返回值: 该乐音的实际标号值*/
      { static char val[7]={9 ,11,0,2,4,5,7};
      static char one[7]={0,2,4,5,7,9,11};
      int i;
      i=OneVal;
      if (n<='7' n>='1') i=i+one[n-'1'];
      else
       if (n>='a' n<='g')
      i=i+val[n-'a']-12; //低音,降12个半音
       else
       if (n>='A' n<='G') //高音,升12个半音
       i=i+val[n-'A']+12;
       else //否则,识为休止符
       i=0;
      if (flag=='b') i--;
      else if (flag=='#') i++;
      return(i);
      }

    转载于:https://www.cnblogs.com/liangzid/p/10910026.html

    展开全文
  • MIDI格式

    2012-01-15 21:33:00
    朋友的公司准备做的一个内容,我负责其中一个模块,该模块需要解析MIDI文件,然后生成另外一种格式。虽然也有开源的包可以用,不过那个包bug微多,而且已经停止维护很久了。(开发那个包的好像是个搞乐队,估计专心...

    朋友的公司准备做的一个内容,我负责其中一个模块,该模块需要解析MIDI文件,然后生成另外一种格式。虽然也有开源的包可以用,不过那个包bug微多,而且已经停止维护很久了。(开发那个包的好像是个搞乐队,估计专心玩音乐去了吧)

    花了1天多才写完,上点翻译内容,表示斯坦福大学的内容真心好理解啊

     

    标准MIDI文件结构(译)

    原文地址:http://www.ccarh.org/courses/253/handout/smf/

     

    标准MIDI文件(Standard MIDI File 简称SMF)是由MIDI块(chunks)构成的。第一个MIDI块是Header块,接下来是一个或多个Track块。Header块包含整个MIDI文件的全局数据。每一个Track块都定义了一个逻辑音轨(track)

    SMF = <header_chunk> + <track_chunk> [+ <track_chunk> ...]

    一个块由三部分构成,与微软的RIFF文件类似(不同之处在于SMF是使用大端法存储(Big-endian),而RIFF是使用小端法(little-endian)),这三部分定义如下:

     1、  前四个字节是块IDHeader块是:”MThd”Track块是:”MTrk”

    2、  下面四字节是无符号值,用来定义块中数据部分的长度

    3、  最后则是块数据

    Header

    Header块包括块ID,长度,MIDI文件的格式信息,MIDI音轨(指逻辑音轨,即Track块个数)数量和MIDI最小时间单位长度信息。 

    header_chunk = "MThd" + <header_length> + <format> + <n> + <division>

     “MThd” 4字节

    标志Header块的字符,16进制表示为:0x4D546864。这4个字符出现在MIDI文件的开头,标志这是一个MIDI文件。

    <header_length> 4字节

    指示Header块中数据部分的长度(永远为6字节长,因为数据部分的三个字段均为2字节)。

    <format> 2字节

    0 = 单一音轨文件格式

    1 = 多音轨文件格式

    2 = 多歌曲文件格式(一组单一音轨的文件)

    <n> 2字节

    Header块后的Track块的数量。

    <division> 2字节

    间隔时间所对应的单位时间数(tick)。如果这个值为正,那么它标志着每一拍所对应的单位时间数。比如说,+96表示每拍对应96 ticks。如果这个值为负,间隔时间则对应SMPTE单位。

     

    Track

    Track块包括块ID,长度和事件信息(event data)

    track_chunk = "MTrk" + <length> + <track_event> [+ <track_event> ...]

     “MTrk” 4字节

    标志Track块开始

    <length> 4字节

    标志数据部分的长度

    <track_event>

    序列化的音轨事件

     

    音轨事件(Track Event)

    一个音轨事件由与上一事件的间隔时间和三种事件之一构成

     track_event = <v_time> + <midi_event> | <meta_event> | <sysex_event>

     <v_time>

    一个变长值,用来表示与前一事件的间隔时间

    <midi_event>

    MIDI的通道事件,比如说音符开始(note-on)与音符结束(note-off)。其播放方法在MIDI装置中都相同。

    <meta_event>

    元事件

    <sysex_event>

    系统独有事件

     

    元事件(Meta Event)

    元事件不是MIDI数据(即不是用来控制MIDI播放的),包括前缀,类型标识,长度和数据部分

     meta_event = 0xFF + <meta_type> + <v_length> + <event_data_bytes>

     <meta_type> 1 字节

    Type

    Event

    Type

    Event

    0x00

    Sequence number

    0x20

    MIDI channel prefix assignment

    0x01

    Text event

    0x2F

    End of track

    0x02

    Copyright notice

    0x51

    Tempo setting

    0x03

    Sequence or track name

    0x54

    SMPTE offset

    0x04

    Instrument name

    0x58

    Time signature

    0x05

    Lyric text

    0x59

    Key signature

    0x06

    Marker text

    0x7F

    Sequencer specific event

    0x07

    Cue point

     <v_length>

    变长值,表示数据部分长度

    <event_data_bytes>

    具体数据信息

    系统高级事件(System Exclusive Event)

    系统高级事件包括两种:

     sysex_event = 0xF0 + <data_bytes> 0xF7 or sysex_event = 0xF7 + <data_bytes> 0xF7

    第一种中MIDI数据流应包含0xF0,第二种则可以省略。

     

    可变长值:

    SMF中,有一些值被表达为可变长的。这种可变长值是一种被压缩的格式:

    一个可变长值使用每一个字节的低7位存储数据或者数据的一部分,最高位表示是否继续。只有可变长值的最后一字节的最高位为,其他均为1

     

    例如:

       Variable Length Value        Real Value 

       0x7F                         127 (0x7F)

       0x81 0x7F                    255 (0xFF)

       0x82 0x80 0x00               32768 (0x8000)

    转载于:https://my.oschina.net/Jeky/blog/39134

    展开全文
  • MIDI数字音乐

    2011-05-28 10:34:00
     MIDI(Musical Instrument Digital Interface,乐器数字接口)是为音乐制造业制定的一个标准,其主要功能是通过单一声音频率的合成来模拟各种...  在计算机的应用中,MIDI也作为一种标准的文件存储格式(.
  • mod音乐格式,mo3,midi 转换器,均为破解版。这些软件可以转换比较怪异的音频文件,但软件比较古老,而且网上也没别的了,大家将就用吧。
  • 22.3 MIDI音乐

    千次阅读 2016-02-29 18:04:08
     乐器数字接口(Musical Instrument Digital Interface, MIDI) 是在 20 世纪 80 年代初期由电子音乐合成器制造商的一个合作组织开发的。MIDI 是各种电子乐器之间及其和计算机之间相互连接的一个协议。它在电子音乐...
  • 大家都知道,HTML5 Audio標簽能夠支持wav, webm, mp3, ogg, acc等格式,但是有個很重要的音樂文件格式midi(擴展名mid)卻在各大瀏覽器中都沒有內置的支持,因為mid文件並不像其他聲音文件那樣記錄聲音的采樣信息,...
  • 7000首MIDI格式手机铃声,海量铃声供你选择
  • midi格式文件解析代码

    2021-05-23 15:26:28
    var midiSrc='/res/25469pm201.mid'//修改此处的midi音乐文件的地址为自己资源的地址 /** *加载二进制文件 */ var buffer; var bufferLen; function loadMidi(src="/res/baga.mid"){ var req = new ...
  • Midi音乐文件转MP3

    2018-06-25 16:30:22
    Midi音乐文件转MP3工具,不只能转换MP3,wav,ogg等格式均支持。
  • BASS播放MIDI例子,这个是我搬运其他大佬的代码,只是在里面稍微修改了下。搬运地址: https://www.eyuyan.la/post/14666.html 用这些API可以完美解决播放MID音乐没有声音的问题。
  • Sweet MIDI Player是一款免费好用的MIDI音乐播放器软件。软件可以播各种MIDI音乐文件,还可以通过类似混音的接口来修改 MIDI 音乐,能够实现改变控制讯号、调换音乐、修改拍子等诸多功能,。Sweet MIDI Player界面...
  • android midi 格式开发总结(1)

    千次阅读 2018-05-18 10:36:16
    总结来说midi格式是一种为了统一电子音乐之间的联系而进行规范的一种记录格式。mid文件并不录制声音的具体波形或者内容,它只是记录某些具体声音出现的时间顺序力度等信息。然后根据解析出来的文件进行相应的演奏。...
  • MIDI音乐的产生过程? 通过合成器产生MIDI音乐的方式有两种:FM(Frequency Modulation)合成和波形表(Wavetable)合成:FM频率调制合成: 通过硬件产生正弦信号,再经处理合成音乐。合成的方式是将波形组合在一起,...
  • 卷积神经网络,可将钢琴音频转换为简化的MIDI格式。 最终模型将音频文件(单音或多音)作为输入,并输出带有相应音符和音符持续时间的简化MIDI输出。 然后可以将该输出重构为标准MIDI文件格式。 主要目标 CNN执行的...
  • midi-dump-tools 是一组能够将 MIDI 音乐标准格式转换成各种音乐格式的工具。 分享 window._bd_share_config = { "common": { "bdSnsKey": {}...
  • 在本篇文章中,我们将主要介绍如何基于ATtiny85制作数字音乐盒,该设备可以播放以MIDI格式存储在内存卡中的音乐: 音符听起来像一个破破的音乐盒或大键琴,有四个通道,所以最多可以同时播放四个音符。我的示范音乐...
  • 标准MIDI文件格式.wps

    2011-11-25 14:20:43
    标准的MIDI文件格式就像奇异的兽。总体看来,它是那样的让你无法抗拒。当然,你怎样看它无关紧要,可是用足够多的描述符描述一段音乐并使它能够重现,可不是很少的工作就可以完成的。然而,它虽然复杂,但是真正理解...
  • 携您一起进入这美妙而又复杂的音乐世界隋顺意,公众号:萝卜大杂烩Python 播放音乐:使用 mido 编写,播放多声轨 MIDI 文件音乐“ 原文地址:...
  • MidiKlavar是从MidiXml到其他文件格式MIDI文件转换器。 MidiXml是由MusicXml.com(MusicXml文件格式背后的组织)管理的文件格式规范。 它与midi.org定义的MIDI二进制文件标准结合使用。 本质上,MidiXml使MIDI二...
  • midi音乐历史

    千次阅读 2013-04-07 16:08:38
    这节课,我们要开始讲MIDI技术了。但是看到这个标题可能读者会大吃一惊!学MIDI,不是在学最先进的高端技术么?你怎么说…… 哈哈!你错了。我告诉你,MIDI是老掉牙的技术了。可能你要问,有多老?难道比486电脑...
  • midi 格式转换为mp3或者wav工具,喜欢和弦的朋友可以在 http://www.mobile3g.cn/ring/152/137177.asp 现在mid格式的和弦铃音,然后去移动彩铃DIY ,制作上传,审核通过后就可以做彩铃了。。
  • MIDI音频格式解析

    千次阅读 2018-10-25 17:30:17
    由于网上关于MIDI音频格式的实例解析较少, 而本人这段时间刚好有做相关的应用, 所以,特别分享MIDI的解析实例, 希望对大家有所帮助。   0x4D , 0x54 , 0x68 , 0x64 , // "MThd" 0x00 , 0x00 , ...
  • MIDI 文件格式分析

    2018-10-26 11:18:47
    文件头一般包括文件的类型,因为 Midi 文件仅以.mid 为扩展名的就有 0 类和 1 类两种,而大家熟悉的位 图文件的格式就更多了,所以才会出现文件头这种东西。 而数据描述部份是主体,我们现在来一起分析它的结构: 在每...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,398
精华内容 3,359
关键字:

midi格式音乐