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

📄 rtmidi.cpp

📁 Mobile STK for Symbian OS V0.1
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ){  int result;  AlsaMidiData *data = static_cast<AlsaMidiData *> (apiData_);  unsigned int nBytes = message->size();  if ( nBytes > data->bufferSize ) {    data->bufferSize = nBytes;    result = snd_midi_event_resize_buffer ( data->coder, nBytes);    if ( result != 0 ) {      errorString_ = "RtMidiOut::sendMessage: ALSA error resizing MIDI event buffer.";      error( RtError::DRIVER_ERROR );    }    free (data->buffer);    data->buffer = (unsigned char *) malloc( data->bufferSize );    if ( data->buffer == NULL ) {    errorString_ = "RtMidiOut::initialize: error allocating buffer memory!\n\n";    error( RtError::MEMORY_ERROR );    }  }  snd_seq_event_t ev;  snd_seq_ev_clear(&ev);  snd_seq_ev_set_source(&ev, data->vport);  snd_seq_ev_set_subs(&ev);  snd_seq_ev_set_direct(&ev);  for ( unsigned int i=0; i<nBytes; i++ ) data->buffer[i] = message->at(i);  result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev );  if ( result < (int)nBytes ) {    errorString_ = "RtMidiOut::sendMessage: event parsing error!";    error( RtError::WARNING );    return;  }  // Send the event.  result = snd_seq_event_output(data->seq, &ev);  if ( result < 0 ) {    errorString_ = "RtMidiOut::sendMessage: error sending MIDI message to port.";    error( RtError::WARNING );  }  snd_seq_drain_output(data->seq);}#endif // __LINUX_ALSA__//*********************************************************************////  API: IRIX MD//*********************************************************************//// API information gleamed from://   http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?cmd=getdoc&coll=0650&db=man&fname=3%20mdIntro// If the Makefile doesn't work, try the following:// CC -o midiinfo -LANG:std -D__IRIX_MD__ -I../ ../RtMidi.cpp midiinfo.cpp -lpthread -lmd// CC -o midiout -LANG:std -D__IRIX_MD__ -I../ ../RtMidi.cpp midiout.cpp -lpthread -lmd// CC -o qmidiin -LANG:std -D__IRIX_MD__ -I../ ../RtMidi.cpp qmidiin.cpp -lpthread -lmd// CC -o cmidiin -LANG:std -D__IRIX_MD__ -I../ ../RtMidi.cpp cmidiin.cpp -lpthread -lmd#if defined(__IRIX_MD__)#include <pthread.h>#include <sys/time.h>#include <unistd.h>// Irix MIDI header file.#include <dmedia/midi.h>// A structure to hold variables related to the IRIX API// implementation.struct IrixMidiData {  MDport port;  pthread_t thread;};//*********************************************************************////  API: IRIX//  Class Definitions: RtMidiIn//*********************************************************************//extern "C" void *irixMidiHandler( void *ptr ){  RtMidiIn::RtMidiInData *data = static_cast<RtMidiIn::RtMidiInData *> (ptr);  IrixMidiData *apiData = static_cast<IrixMidiData *> (data->apiData);  bool continueSysex = false;  unsigned char status;  unsigned short size;  MDevent event;  int fd = mdGetFd( apiData->port );  if ( fd < 0 ) {    data->doInput = false;    std::cerr << "\nRtMidiIn::irixMidiHandler: error getting port descriptor!\n\n";    return 0;  }  fd_set mask, rmask;  FD_ZERO( &mask );  FD_SET( fd, &mask );  struct timeval timeout = {0, 0};  RtMidiIn::MidiMessage message;  int result;  while ( data->doInput ) {    rmask = mask;    timeout.tv_sec = 0;    timeout.tv_usec = 0;    if ( select( fd+1, &rmask, NULL, NULL, &timeout ) <= 0 ) {      // No data pending ... sleep a bit.      usleep( 1000 );      continue;    }    // If here, there should be data.    result = mdReceive( apiData->port, &event, 1);    if ( result <= 0 ) {      std::cerr << "\nRtMidiIn::irixMidiHandler: MIDI input read error!\n\n";      continue;    }    message.timeStamp = event.stamp * 0.000000001;    size = 0;    status = event.msg[0];    if ( !(status & 0x80) ) continue;    if ( status == 0xF0 ) {      // Sysex message ... can be segmented across multiple messages.      if ( !(data->ignoreFlags & 0x01) ) {        if ( continueSysex ) {          // We have a continuing, segmented sysex message.  Append          // the new bytes to our existing message.          for ( int i=0; i<event.msglen; i++ )            message.bytes.push_back( event.sysexmsg[i] );          if ( event.sysexmsg[event.msglen-1] == 0xF7 ) continueSysex = false;          if ( !continueSysex ) {            // If not a continuing sysex message, invoke the user callback function or queue the message.            if ( data->usingCallback && message.bytes.size() > 0 ) {              RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;              callback( message.timeStamp, &message.bytes, data->userData );            }            else {              // As long as we haven't reached our queue size limit, push the message.              if ( data->queueLimit > data->queue.size() )                data->queue.push( message );              else                std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";            }            message.bytes.clear();          }        }      }      mdFree( NULL );      continue;    }    else if ( status < 0xC0 ) size = 3;    else if ( status < 0xE0 ) size = 2;    else if ( status < 0xF0 ) size = 3;    else if ( status < 0xF3 ) {      if ( status == 0xF1 && !(data->ignoreFlags & 0x02) ) {        // A MIDI time code message and we're not ignoring it.        size = 3;      }    }    else if ( status == 0xF3 ) size = 2;    else if ( status == 0xF8 ) {      if ( !(data->ignoreFlags & 0x02) ) {        // A MIDI timing tick message and we're not ignoring it.        size = 1;      }    }    else if ( status == 0xFE ) { // MIDI active sensing      if ( !(data->ignoreFlags & 0x04) )        size = 1;    }    else size = 1;    // Copy the MIDI data to our vector.    if ( size ) {      message.bytes.assign( &event.msg[0], &event.msg[size] );      // Invoke the user callback function or queue the message.      if ( data->usingCallback ) {        RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback;        callback( message.timeStamp, &message.bytes, data->userData );      }      else {        // As long as we haven't reached our queue size limit, push the message.        if ( data->queueLimit > data->queue.size() )          data->queue.push( message );        else          std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n";      }      message.bytes.clear();    }  }  return 0;}void RtMidiIn :: initialize( void ){  // Initialize the Irix MIDI system.  At the moment, we will not  // worry about a return value of zero (ports) because there is a  // chance the user could plug something in after instantiation.  int nPorts = mdInit();  // Create our api-specific connection information.  IrixMidiData *data = (IrixMidiData *) new IrixMidiData;  apiData_ = (void *) data;  inputData_.apiData = (void *) data;}void RtMidiIn :: openPort( unsigned int portNumber ){  if ( connected_ ) {    errorString_ = "RtMidiIn::openPort: a valid connection already exists!";    error( RtError::WARNING );    return;  }  int nPorts = mdInit();  if (nPorts < 1) {    errorString_ = "RtMidiIn::openPort: no Irix MIDI input sources found!";    error( RtError::NO_DEVICES_FOUND );  }  std::ostringstream ost;  if ( portNumber >= nPorts ) {    ost << "RtMidiIn::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";    errorString_ = ost.str();    error( RtError::INVALID_PARAMETER );  }  IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);  data->port = mdOpenInPort( mdGetName(portNumber) );  if ( data->port == NULL ) {    ost << "RtMidiIn::openPort: Irix error opening the port (" << portNumber << ").";    errorString_ = ost.str();    error( RtError::DRIVER_ERROR );  }  mdSetStampMode(data->port, MD_DELTASTAMP);  // Start our MIDI input thread.  pthread_attr_t attr;  pthread_attr_init(&attr);  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);  pthread_attr_setschedpolicy(&attr, SCHED_RR);  inputData_.doInput = true;  int err = pthread_create(&data->thread, &attr, irixMidiHandler, &inputData_);  pthread_attr_destroy(&attr);  if (err) {    mdClosePort( data->port );    inputData_.doInput = false;    errorString_ = "RtMidiIn::openPort: error starting MIDI input thread!";    error( RtError::THREAD_ERROR );  }  connected_ = true;}void RtMidiIn :: openVirtualPort(){  // This function cannot be implemented for the Irix MIDI API.  errorString_ = "RtMidiIn::openVirtualPort: cannot be implemented in Irix MIDI API!";  error( RtError::WARNING );}void RtMidiIn :: closePort( void ){  if ( connected_ ) {    IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);    mdClosePort( data->port );    connected_ = false;    // Shutdown the input thread.    inputData_.doInput = false;    pthread_join( data->thread, NULL );  }}RtMidiIn :: ~RtMidiIn(){  // Close a connection if it exists.  closePort();  // Cleanup.  IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);  delete data;}unsigned int RtMidiIn :: getPortCount(){  int nPorts = mdInit();  if ( nPorts >= 0 ) return nPorts;  else return 0;}std::string RtMidiIn :: getPortName( unsigned int portNumber ){  int nPorts = mdInit();  std::ostringstream ost;  if ( portNumber >= nPorts ) {    ost << "RtMidiIn::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";    errorString_ = ost.str();    error( RtError::INVALID_PARAMETER );  }  std::string stringName = std::string( mdGetName( portNumber ) );  return stringName;}//*********************************************************************////  API: IRIX MD//  Class Definitions: RtMidiOut//*********************************************************************//unsigned int RtMidiOut :: getPortCount(){  int nPorts = mdInit();  if ( nPorts >= 0 ) return nPorts;  else return 0;}std::string RtMidiOut :: getPortName( unsigned int portNumber ){  int nPorts = mdInit();  std::ostringstream ost;  if ( portNumber >= nPorts ) {    ost << "RtMidiIn::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid.";    errorString_ = ost.str();    error( RtError::INVALID_PARAMETER );  }  std::string stringName = std::string( mdGetName( portNumber ) );  return stringName;}void RtMidiOut :: initialize( void ){  // Initialize the Irix MIDI system.  At the moment, we will not  // worry about a return value of zero (ports) because there is a  // chance the user could plug something in after instantiation.  int nPorts = mdInit();  // Create our api-specific connection information.  IrixMidiData *data = (IrixMidiData *) new IrixMidiData;  apiData_ = (void *) data;}void RtMidiOut :: openPort( unsigned int portNumber ){  if ( connected_ ) {    errorString_ = "RtMidiOut::openPort: a valid connection already exists!";    error( RtError::WARNING );    return;  }  int nPorts = mdInit();  if (nPorts < 1) {    errorString_ = "RtMidiOut::openPort: no Irix MIDI output sources found!";    error( RtError::NO_DEVICES_FOUND );  }  std::ostringstream ost;  if ( portNumber >= nPorts ) {    ost << "RtMidiOut::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";    errorString_ = ost.str();    error( RtError::INVALID_PARAMETER );  }  IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);  data->port = mdOpenOutPort( mdGetName(portNumber) );  if ( data->port == NULL ) {    ost << "RtMidiOut::openPort: Irix error opening the port (" << portNumber << ").";    errorString_ = ost.str();    error( RtError::DRIVER_ERROR );  }  mdSetStampMode(data->port, MD_NOSTAMP);  connected_ = true;}void RtMidiOut :: closePort( void ){  if ( connected_ ) {    IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);    mdClosePort( data->port );    connected_ = false;  }}void RtMidiOut :: openVirtualPort(){  // This function cannot be implemented for the Irix MIDI API.  errorString_ = "RtMidiOut::openVirtualPort: cannot be implemented in Irix MIDI API!";  error( RtError::WARNING );}RtMidiOut :: ~RtMidiOut(){  // Close a connection if it exists.  closePort();  // Cleanup.  IrixMidiData *data = static_cast<IrixMidiData *> (apiData_);  delete data;

⌨️ 快捷键说明

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