//------------------------------------------------------------------------- // Filename: midiio.cc // Version: $Id: midiio.cc,v 1.1.4.1 1999/05/24 22:54:50 erik Exp $ // Copyright: Copyright (C) 1999, Erik Mouw (J.A.K.Mouw@its.tudelft.nl) // Author: Erik Mouw // Description: Linux MIDI device handling functions // Created at: Sun Feb 28 17:25:17 1999 // Modified by: Erik Mouw // Modified at: Mon May 24 18:44:06 1999 //------------------------------------------------------------------------- // // 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 // #ident "$Id: midiio.cc,v 1.1.4.1 1999/05/24 22:54:50 erik Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_UNISTD_H # include #endif #ifdef STDC_HEADERS # include # include #endif #include #include #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_LINUX_SOUNDCARD_H # include #endif #ifdef HAVE_SYS_IOCTL_H # include #endif #include "midiio.hh" #ifndef HAVE_STRERROR extern "C" char *strerror(int errnum); #endif #ifndef HAVE_STRDUP extern "C" char *strdup(const char *s); #endif SEQ_DEFINEBUF(129); int midiIo::defaultChannel = 0; void midiIo::init(void) { fd = -1; midi_dev = -1; deviceName = NULL; defaultChannel = 0; } void midiIo::destroy(void) { // do stuff if(deviceName != NULL) { free(deviceName); deviceName = NULL; } } void midiIo::seqbuf_dump() { if (_seqbufptr) if (write(fd, _seqbuf, _seqbufptr) == -1) { perror("write "); exit(-1); } _seqbufptr = 0; } midiIo::midiIo(void) { init(); } midiIo::midiIo(const char *device) { init(); if(device != NULL) { deviceName = strdup(device); } } midiIo::~midiIo(void) { destroy(); } bool midiIo::open(void) { int nrsynths, nrmidis; int i; struct synth_info synthInfo; struct midi_info midiInfo; if(fd != -1) { cerr<< __PRETTY_FUNCTION__<< ": already open"<< endl; return(false); } if(deviceName == NULL) { cerr<< __PRETTY_FUNCTION__<< ": NULL device name"<< endl; return(false); } // fd = ::open(deviceName, O_RDWR | O_SYNC); fd = ::open(deviceName, O_RDWR); if(fd == -1) { cerr<< __PRETTY_FUNCTION__<< ": can't open device '"<< deviceName<< "': "<< strerror(errno)<< endl; return(false); } if(ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) { cerr<< __PRETTY_FUNCTION__<< ": can't get number of synth devices: "<< strerror(errno)<< endl; return(false); } for(i = 0; i < nrsynths; i++) { synthInfo.device = i; if (ioctl(fd, SNDCTL_SYNTH_INFO, &synthInfo) == -1) { cerr<< __PRETTY_FUNCTION__<< ": can't get synth info: "<< strerror(errno)<< endl; return(false); } cerr<< __PRETTY_FUNCTION__<< ": synth device found: "<< synthInfo.name<< endl; } if(ioctl(fd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1) { cerr<< __PRETTY_FUNCTION__<< ": can't get number of MIDI devices: "<< strerror(errno)<< endl; return(false); } for(i = 0; i < nrmidis; i++) { midiInfo.device = i; if (ioctl(fd, SNDCTL_MIDI_INFO, &midiInfo) == -1) { cerr<< __PRETTY_FUNCTION__<< ": can't get midi info: "<< strerror(errno)<< endl; return(false); } cerr<< __PRETTY_FUNCTION__<< ": MIDI device found: "<< midiInfo.name<< endl; } // My stuff: // 0 --> external MIDI port: Roland HP-330 // 1 --> internal device : SoundBlaster AWE 64 Gold EMU-8000 synthesiser midi_dev = 0; SEQ_MIDIOUT(midi_dev, MIDI_CTL_CHANGE + defaultChannel); SEQ_MIDIOUT(midi_dev, CTL_BANK_SELECT); SEQ_MIDIOUT(midi_dev, 0); SEQ_MIDIOUT(midi_dev, MIDI_CTL_CHANGE | defaultChannel); SEQ_MIDIOUT(midi_dev, CTL_MAIN_VOLUME); SEQ_MIDIOUT(midi_dev, 127); SEQ_DUMPBUF(); return(true); } bool midiIo::close(void) { if(fd == -1) { cerr<< __PRETTY_FUNCTION__<< ": device already closed"<< endl; return(false); } SEQ_DUMPBUF(); if(::close(fd) < 0) { cerr<< __PRETTY_FUNCTION__<< ": can't close device '"<< deviceName<< "':"<< strerror(errno)<< endl; return(false); } fd = -1; return(true); } void midiIo::noteOn(int key, int velocity, int channel=defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_NOTEON | channel); SEQ_MIDIOUT(midi_dev, key); SEQ_MIDIOUT(midi_dev, velocity); SEQ_DUMPBUF(); } void midiIo::noteOff(int key, int velocity, int channel=defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_NOTEOFF | channel); SEQ_MIDIOUT(midi_dev, key); SEQ_MIDIOUT(midi_dev, velocity); SEQ_DUMPBUF(); } void midiIo::keyPressure(int key, int pressure, int channel = defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_KEY_PRESSURE | channel); SEQ_MIDIOUT(midi_dev, key); SEQ_MIDIOUT(midi_dev, pressure); SEQ_DUMPBUF(); } void midiIo::channelPressure(int pressure, int channel = defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_CHN_PRESSURE | channel); SEQ_MIDIOUT(midi_dev, pressure); SEQ_DUMPBUF(); } void midiIo::pitchBend(int fine, int coarse, int channel = defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_PITCH_BEND | channel); SEQ_MIDIOUT(midi_dev, fine); SEQ_MIDIOUT(midi_dev, coarse); SEQ_DUMPBUF(); } void midiIo::controlChange(int controller, int value, int channel = defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_CTL_CHANGE | channel); SEQ_MIDIOUT(midi_dev, controller); SEQ_MIDIOUT(midi_dev, value); SEQ_DUMPBUF(); } void midiIo::programChange(int program, int channel = defaultChannel) { SEQ_MIDIOUT(midi_dev, MIDI_PGM_CHANGE | channel); SEQ_MIDIOUT(midi_dev, program); SEQ_DUMPBUF(); }