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

📄 seq_oss_sio.cc.1

📁 一个很好的c++ midi解码算法,不依赖于任何平台.
💻 1
字号:
#include <iostream.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <termios.h>#include "defines.h"#include "config.h"#include "seq_oss_sio.h"#include "extern.h"#ifndef NO_OSS#include SOUNDCARD_HEADER#endifint Seq_OSS_Serial::open(char *seqdev, int buflen){  if(flagOpen == TRUE) return -1;  // device open  checkMidiDevice();  char middevname[20] = MIDIDEVICE;  int num;  for (num=0;num<numberOfDevice-1;num++)	{	  if((midifd[num] = ::open(middevname, O_WRONLY | O_NDELAY))<0)		{		  cerr << "cannot open device ";		  perror(middevname);		  return -2;		}	}  if((midifd[num] = ::open(seqdev, O_RDWR | O_NDELAY))<0)	{	  perror("cannot open device");	  return -2;	}  struct termios tio;  seqfd = midifd[num];  if (tcgetattr (seqfd, &tio) < 0)	{	  return -1;	}  tio_orig = tio;  tio.c_iflag = 0;  tio.c_oflag = 0;  tio.c_cflag = CS8 | CREAD | CLOCAL;  tio.c_lflag = 0;  cfsetispeed(&tio, B38400);  cfsetospeed(&tio, B38400);  if (tcsetattr (seqfd, TCSANOW, &tio) < 0)	{	  perror(" ");	  return -3;	}  // buffer  _buf = new u_char *[numberOfDevice];  for (num=0;num<numberOfDevice;num++)	_buf[num] = new u_char [buflen];  _seqbuflen = buflen;  _bufptr = new int [numberOfDevice];  if(!_buf || !_bufptr)	{	  cerr << "allocation error" << endl;	  return -3;	}  for (num=0;num<numberOfDevice;num++)	{	  _bufptr[num] = 0;	}  flagOpen = TRUE;  u_char port=0;  for (num=0;num<16;num++)	{	  if (port2dev[num]==numberOfDevice-1)		{		  SIOPORT[num]=port;		  port++;		}	}  return 0;}int Seq_OSS_Serial::close(){  if(flagOpen != TRUE) return -1;  stopTimer();  flagOpen = FALSE;  if (tcsetattr (seqfd, TCSANOW, &tio_orig) < 0)    perror(" ");  for (int num=0;num<numberOfDevice;num++)	{	  ::close (midifd[num]);	}  delete [] _buf;  delete [] _bufptr;  return 0;}int Seq_OSS_Serial::checkMidiDevice(){#ifndef NO_OSS  int nrmidis, fd;  static flag=0;  if(flag==0)	{	  if ((fd = ::open(SEQUENCER, O_RDWR | O_NDELAY))<0)		{		  cerr << "can't open " << SEQUENCER << endl;		  return -1;		}	  	  if (ioctl(fd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1)		{		  cerr << "can't get info about midi ports\n";		  return -1;		}	  ::close (fd);# ifdef SHOW_INFO	  cout << "detect " << nrmidis << " midis." << endl;# endif	  numberOfDevice = 2;	  flag=1;	}#endif  return numberOfDevice;}void Seq_OSS_Serial::reset(){  seqbuf_dump();  for (int num=0;num<numberOfDevice;num++)	_bufptr[num] = 0;}void Seq_OSS_Serial::sync(){  seqbuf_dump();}int Seq_OSS_Serial::getCtrlRate(){  return 1000000;}void Seq_OSS_Serial::startTimer(){#ifdef RUNNING_ST  for(int n=0;n<16;n++) clearStatus(n);#endif  LastOutputPort = 0;  gettimeofday(&starttime, NULL);}void Seq_OSS_Serial::stopTimer(){  LastOutputPort = 0;  seqbuf_dump();}void Seq_OSS_Serial::waitTime(u_long tick){  static long waittime;  seqbuf_dump();  gettimeofday (&now, NULL);  waittime = (long)tick - (now.tv_usec-starttime.tv_usec)	- (now.tv_sec-starttime.tv_sec)*1000000;  if(waittime>999)	usleep (waittime);}void Seq_OSS_Serial::MidiOut(u_char port, char ch){  u_char dev;  dev = port2dev[port];  if (dev==numberOfDevice-1) // $B%7%j%"%k%G%P%$%9$X$N=PNO$@$C$?$i(B	{	  if (port!=LastOutputPort)		{		  changePort (dev, SIOPORT[port]);		  LastOutputPort = port;		}	}  serial_midiout (dev, ch);}void Seq_OSS_Serial::midiEvent1(u_char port, u_char ev, u_char para1){  u_char dev;  dev = port2dev[port];  if (dev==numberOfDevice-1)	{	  if (port!=LastOutputPort)		{		  changePort (dev, SIOPORT[port]);		  LastOutputPort = port;		}	}#ifdef RUNNING_ST  if(LastStatus[dev]!=ev)	{#endif	  serial_midiout (dev, ev);#ifdef RUNNING_ST	  LastStatus[dev]=ev;	}#endif  serial_midiout (dev, para1);}void Seq_OSS_Serial::midiEvent2(u_char port, u_char ev, u_char para1, u_char para2){  u_char dev;  dev = port2dev[port];  if (dev==numberOfDevice-1)	{	  if (port!=LastOutputPort)		{		  changePort (dev, SIOPORT[port]);		  LastOutputPort = port;		}	}#ifdef RUNNING_ST  if(LastStatus[dev]!=ev)	{#endif	  serial_midiout (dev, ev);#ifdef RUNNING_ST	  LastStatus[dev]=ev;	}#endif  serial_midiout (dev, para1);  serial_midiout (dev, para2);}#ifdef RUNNING_STvoid Seq_OSS_Serial::clearStatus(u_char port){  LastStatus[port2dev[port]]=0;}#endifvoid Seq_OSS_Serial::changePort(u_char dev, u_char port){  if (dev&0x80) return;  serial_midiout (dev, 0xF5);  serial_midiout (dev, port+1);#ifdef SHOW_PORTCHANGE  cout << "change port:" << port+1 << endl;#endif#ifdef RUNNING_ST  LastStatus[dev]=0;#endif}int Seq_OSS_Serial::NumOfDevice(){  return numberOfDevice;}void Seq_OSS_Serial::AllNoteOff(u_char dev){  int n;  changePort(dev, 0);  for(n=0;n<16;n++)	{	  serial_midiout (dev, 0xB0|n);	  serial_midiout (dev, 64);	  serial_midiout (dev, 0);	  serial_midiout (dev, 0xB0|n);	  serial_midiout (dev, 66);	  serial_midiout (dev, 0);	  serial_midiout (dev, 0xB0|n);	  serial_midiout (dev, 123);	  serial_midiout (dev, 0);	  seqbuf_dump();	}}void Seq_OSS_Serial::serial_midiout(u_char dev, u_char dat){  if (dev&0x80) return;  if (_bufptr[dev]>=_seqbuflen) seqbuf_dump();  _buf[dev][_bufptr[dev]] = dat;  _bufptr[dev]++;}void Seq_OSS_Serial::seqbuf_dump(){  for (int num=0;num<numberOfDevice;num++)	{	  if(_bufptr[num])        if(write(midifd[num], _buf[num], _bufptr[num]) < 0)          {			perror("write error");			exit(-1);          }	  _bufptr[num]=0;	}}

⌨️ 快捷键说明

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