⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sequencer.c

📁 一个很好的c++ midi解码算法,不依赖于任何平台.
💻 C
字号:
/* *  sequencer.cc *  Copyright (C) 1998-2000 SAKAI Katsuya * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h> // #include <iostream.h>#include <stdlib.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include "defines.h"#include "config.h"#ifndef NO_OSS#include SOUNDCARD_HEADER#else#include "midievdefs.h"#endif#include "sequencer.h"#include "extern.h"int Sequencer::open(char *seqdev, int buflen){  if(flagOpen == TRUE) return -1;  if((seqfd = ::open(seqdev, O_WRONLY, 0))<0)    {      perror("cannot open device");      return -2;    }  _seqbuf = new u_char [buflen];  if(!_seqbuf)    {      printf("allocation error\n"); //cerr << "allocation error" << endl;      return -3;    }  _seqbuflen = buflen;  _seqbufptr = 0;  flagOpen = TRUE;  return 0;}int Sequencer::close(){  if(flagOpen != TRUE) return -1;  if (seqstart==TRUE)    stopTimer();  delete [] _seqbuf;  flagOpen = FALSE;  ::close(seqfd);  return 0;}int Sequencer::checkMidiDevice(){#ifndef NO_OSS  int nrmidis;    if (ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1)    {      printf("can't get info about midi ports\n"); // cerr << "can't get info about midi ports\n";      return -1;    }# ifdef SHOW_INFO  cout << "detect " << nrmidis << " midis." << endl;# endif  numberOfDevice = nrmidis;#endif  // NO_OSS  return numberOfDevice;}void Sequencer::reset(){#ifndef NO_OSS  ioctl(seqfd, SNDCTL_SEQ_RESET);#endif}void Sequencer::sync(){#ifndef NO_OSS  ioctl(seqfd, SNDCTL_SEQ_SYNC);#endif}int Sequencer::getCtrlRate(){  int rate=0;#ifndef NO_OSS  ioctl(seqfd, SNDCTL_SEQ_CTRLRATE, &rate);#endif  ctrlrate = rate;  return rate;}void Sequencer::startTimer(){  seqstart = TRUE;#ifdef RUNNING_ST  for(int n=0;n<16;n++)    LastStatus[n] = 0;#endif#ifndef NO_OSS  SEQ_START_TIMER();#endif  LastOutputPort = 6;  LastTick = 0;  CurrentTime = 0.;  getCtrlRate();}void Sequencer::stopTimer(){#ifndef NO_OSS  if(opt.useSerial==TRUE)    {      seq_midiout(port2dev[0], 0xF5);      seq_midiout(port2dev[0], 1);      LastOutputPort = 0;    }  SEQ_STOP_TIMER();  seqbuf_dump();  Sequencer::sync();#endif  seqstart = FALSE;}void Sequencer::waitTime(u_long tick){  if (tick>LastTick)    {      double DeltaTime;      DeltaTime =	(double)(tick-LastTick)	*(double)aSequencer->show_tempo ()	/(double)aSequencer->show_timebase ()	/1000000.	*(double)ctrlrate	/ (double)opt.tempo * 100.;            if((int)(DeltaTime+CurrentTime)>(int)(CurrentTime))	{	  seq_waittime((int)(CurrentTime+DeltaTime));	}      CurrentTime += DeltaTime;      LastTick = tick;    }}void Sequencer::MidiOut(u_char port, char ch){  u_char dev;  if(opt.useSerial==TRUE)    {      dev = port2dev[0];      if(port!=LastOutputPort)	{	  changePort(port2dev[0], port);	  LastOutputPort = port;	}    }  else    dev = port2dev[port];  if (dev&0x80) return;  seq_midiout(dev, ch);  /*    #ifdef RUNNING_ST    LastStatus[dev]=0;    #endif  */}void Sequencer::seqbuf_dump(){  if (_seqbufptr)    if (write (seqfd, _seqbuf, _seqbufptr) == -1)      {	perror ("write error");	exit(-1);      }  _seqbufptr=0;}void Sequencer::seqbuf_clear(){  _seqbufptr=0;}void Sequencer::midiEvent1(u_char port, u_char ev, u_char para1){  u_char dev;    if(opt.useSerial==TRUE)    {      dev = port2dev[0];      if(port!=LastOutputPort)	{	  changePort(port2dev[0], port);	  LastOutputPort = port;	}    }  else    dev = port2dev[port];    if (dev&0x80) return;  # ifdef RUNNING_ST  if(LastStatus[dev]!=ev)    {# endif      seq_midiout(dev, ev);# ifdef RUNNING_ST      LastStatus[dev]=ev;    }# endif  seq_midiout(dev, para1);}void Sequencer::midiEvent2(u_char port, u_char ev, u_char para1, u_char para2){  if (ev == MIDI_CTL_CHANGE || para1 == 32)    {      if (opt.changeBank32==128) return;      if (opt.changeBank32<128)	{	  para2 = opt.changeBank32;	}    }    u_char dev;  if(opt.useSerial==TRUE)    {      dev = port2dev[0];      if(port!=LastOutputPort)	{	  changePort(port2dev[0], port);	  LastOutputPort = port;	}    }  else    dev = port2dev[port];    if (dev&0x80) return;  #ifdef RUNNING_ST  if(LastStatus[dev]!=ev)    {#endif      seq_midiout(dev, ev);#ifdef RUNNING_ST      LastStatus[dev]=ev;    }#endif  seq_midiout(dev, para1);  seq_midiout(dev, para2);}#ifdef RUNNING_STvoid Sequencer::clearStatus(u_char port){  LastStatus[port2dev[port]]=0;}#endifvoid Sequencer::changePort(u_char dev, u_char port){  if (dev&0x80) return;  seq_midiout(dev, 0xF5);  seq_midiout(dev, port+1);# ifdef SHOW_PORTCHANGE  cout << "change port:" << port+1 << endl;# endif# ifdef RUNNING_ST  LastStatus[dev]=0;# endif}int Sequencer::NumOfDevice(){  return numberOfDevice;}void Sequencer::AllNoteOff(u_char dev){  int n;  if (dev&0x80) return;  for(n=0;n<16;n++)    {      seq_midiout(dev, 0xB0|n);      seq_midiout(dev, 64);      seq_midiout(dev, 0);      seq_midiout(dev, 0xB0|n);      seq_midiout(dev, 66);      seq_midiout(dev, 0);      seq_midiout(dev, 0xB0|n);      seq_midiout(dev, 123);      seq_midiout(dev, 0);      seqbuf_dump();    }}void Sequencer::send_exclusive(u_char port, u_char *ex, int len){  u_char dev;  if(opt.useSerial==TRUE)    {      dev = port2dev[0];      if(port!=LastOutputPort)	{	  changePort(port2dev[0], port);	  LastOutputPort = port;	}    }  else    dev = port2dev[port];  if (dev&0x80) return;    for (int i=0;i<len;i++)    seq_midiout(dev, ex[i]);    /*    #ifdef RUNNING_ST    LastStatus[dev]=0;    #endif  */}u_long Sequencer::show_tempo(){  return tempo;}void Sequencer::set_tempo(u_long val){  tempo = val;}int Sequencer::show_timebase(){  return timebase;}void Sequencer::set_timebase(int val){  timebase = val;}void Sequencer::seq_waittime(u_long time){#ifndef NO_OSS  SEQ_WAIT_TIME(time);#endif}void Sequencer::seq_midiout(u_char dev, u_char dat){#ifndef NO_OSS  SEQ_MIDIOUT(dev, dat);#endif}#ifdef SHOW_METAEVENTvoid Sequencer::metaEvent(u_char type, int len, char *data){  cout << "type:" << (int)type << endl;  if (type>0 && type<16)    {      cout << "  text:";      for (int i=0;i<len;i++)	cout << data[i];       cout << endl;    }}#elsevoid Sequencer::metaEvent(u_char, int, char *){}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -