libkmid Library API Documentation

midiout.cc

00001 /************************************************************************** 00002 00003 midiout.cc - class midiOut which handles external midi devices 00004 This file is part of LibKMid 0.9.5 00005 Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez 00006 LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00021 Boston, MA 02111-1307, USA. 00022 00023 Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org> 00024 00025 ***************************************************************************/ 00026 #include "midiout.h" 00027 #include <unistd.h> 00028 #include <fcntl.h> 00029 #include <stdio.h> 00030 #include "sndcard.h" 00031 #include <errno.h> 00032 #include <string.h> 00033 #include <stdlib.h> 00034 #include <sys/param.h> 00035 #include "midispec.h" 00036 #include "alsaout.h" 00037 00038 #ifdef HAVE_CONFIG_H 00039 #include <config.h> 00040 #endif 00041 00042 #include <sys/ioctl.h> 00043 00044 SEQ_USE_EXTBUF(); 00045 00046 MidiOut::MidiOut(int d) 00047 { 00048 seqfd = -1; 00049 devicetype=KMID_EXTERNAL_MIDI; 00050 device= d; 00051 volumepercentage=100; 00052 map=new MidiMapper(NULL); 00053 if (map==NULL) { printfdebug("ERROR : midiOut : Map is NULL\n"); return; }; 00054 _ok=1; 00055 } 00056 00057 MidiOut::~MidiOut() 00058 { 00059 delete map; 00060 closeDev(); 00061 } 00062 00063 void MidiOut::openDev (int sqfd) 00064 { 00065 #ifdef HAVE_OSS_SUPPORT 00066 _ok=1; 00067 seqfd=sqfd; 00068 if (seqfd==-1) 00069 { 00070 printfdebug("ERROR: Could not open /dev/sequencer\n"); 00071 _ok=0; 00072 return; 00073 } 00074 #endif 00075 } 00076 00077 void MidiOut::closeDev (void) 00078 { 00079 if (!ok()) return; 00080 // if (deviceType()!=KMID_ALSA) allNotesOff(); 00081 SEQ_STOP_TIMER(); 00082 SEQ_DUMPBUF(); 00083 seqfd=-1; 00084 } 00085 00086 void MidiOut::initDev (void) 00087 { 00088 #ifdef HAVE_OSS_SUPPORT 00089 int chn; 00090 if (!ok()) return; 00091 uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; 00092 sysex(gm_reset, sizeof(gm_reset)); 00093 for (chn=0;chn<16;chn++) 00094 { 00095 chnmute[chn]=0; 00096 chnPatchChange(chn,0); 00097 chnPressure(chn,127); 00098 chnPitchBender(chn, 0x00, 0x40); 00099 chnController(chn, CTL_MAIN_VOLUME,110*volumepercentage); 00100 chnController(chn, CTL_EXT_EFF_DEPTH, 0); 00101 chnController(chn, CTL_CHORUS_DEPTH, 0); 00102 chnController(chn, 0x4a, 127); 00103 } 00104 #endif 00105 } 00106 00107 void MidiOut::setMidiMapper(MidiMapper *_map) 00108 { 00109 delete map; 00110 map=_map; 00111 } 00112 00113 void MidiOut::noteOn (uchar chn, uchar note, uchar vel) 00114 { 00115 if (vel==0) 00116 { 00117 noteOff(chn,note,vel); 00118 } 00119 else 00120 { 00121 SEQ_MIDIOUT(device, MIDI_NOTEON + map->channel(chn)); 00122 SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); 00123 SEQ_MIDIOUT(device, vel); 00124 } 00125 #ifdef MIDIOUTDEBUG 00126 printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); 00127 #endif 00128 } 00129 00130 void MidiOut::noteOff (uchar chn, uchar note, uchar vel) 00131 { 00132 SEQ_MIDIOUT(device, MIDI_NOTEOFF + map->channel(chn)); 00133 SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); 00134 SEQ_MIDIOUT(device, vel); 00135 #ifdef MIDIOUTDEBUG 00136 printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); 00137 #endif 00138 } 00139 00140 void MidiOut::keyPressure (uchar chn, uchar note, uchar vel) 00141 { 00142 SEQ_MIDIOUT(device, MIDI_KEY_PRESSURE + map->channel(chn)); 00143 SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); 00144 SEQ_MIDIOUT(device, vel); 00145 } 00146 00147 void MidiOut::chnPatchChange (uchar chn, uchar patch) 00148 { 00149 #ifdef MIDIOUTDEBUG 00150 printfdebug("PATCHCHANGE [%d->%d] %d -> %d\n", 00151 chn,map->channel(chn),patch,map->patch(chn,patch)); 00152 #endif 00153 SEQ_MIDIOUT(device, MIDI_PGM_CHANGE + map->channel(chn)); 00154 SEQ_MIDIOUT(device, map->patch(chn,patch)); 00155 chnpatch[chn]=patch; 00156 } 00157 00158 void MidiOut::chnPressure (uchar chn, uchar vel) 00159 { 00160 SEQ_MIDIOUT(device, MIDI_CHN_PRESSURE + map->channel(chn)); 00161 SEQ_MIDIOUT(device, vel); 00162 00163 chnpressure[chn]=vel; 00164 } 00165 00166 void MidiOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) 00167 { 00168 SEQ_MIDIOUT(device, MIDI_PITCH_BEND + map->channel(chn)); 00169 /* 00170 #ifdef AT_HOME 00171 short pbs=((short)msb<<7) | (lsb & 0x7F); 00172 pbs=pbs-0x2000; 00173 short pbs2=(((long)pbs*672)/4096); 00174 printfdebug("Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2); 00175 pbs2=pbs2+0x2000; 00176 lsb=pbs2 & 0x7F; 00177 msb=(pbs2 >> 7)&0x7F; 00178 #endif 00179 */ 00180 map->pitchBender(chn,lsb,msb); 00181 SEQ_MIDIOUT(device, lsb); 00182 SEQ_MIDIOUT(device, msb); 00183 chnbender[chn]=(msb << 8) | (lsb & 0xFF); 00184 } 00185 00186 void MidiOut::chnController (uchar chn, uchar ctl, uchar v) 00187 { 00188 SEQ_MIDIOUT(device, MIDI_CTL_CHANGE + map->channel(chn)); 00189 #ifdef AT_HOME 00190 if (ctl==11) ctl=7; 00191 #endif 00192 map->controller(chn,ctl,v); 00193 if ((ctl==11)||(ctl==7)) 00194 { 00195 v=(v*volumepercentage)/100; 00196 if (v>127) v=127; 00197 } 00198 00199 SEQ_MIDIOUT(device, ctl); 00200 SEQ_MIDIOUT(device, v); 00201 00202 chncontroller[chn][ctl]=v; 00203 } 00204 00205 void MidiOut::sysex(uchar *data, ulong size) 00206 { 00207 ulong i=0; 00208 SEQ_MIDIOUT(device, MIDI_SYSTEM_PREFIX); 00209 while (i<size) 00210 { 00211 SEQ_MIDIOUT(device, *data); 00212 data++; 00213 i++; 00214 } 00215 #ifdef MIDIOUTDEBUG 00216 printfdebug("sysex\n"); 00217 #endif 00218 } 00219 00220 void MidiOut::allNotesOff (void) 00221 { 00222 for (int i=0; i<16; i++) 00223 { 00224 chnController(i, 0x78, 0); 00225 chnController(i, 0x79, 0); 00226 }; 00227 sync(1); 00228 } 00229 00230 void MidiOut::channelSilence (uchar chn) 00231 { 00232 uchar i; 00233 for ( i=0; i<127; i++) 00234 { 00235 noteOff(chn,i,0); 00236 }; 00237 sync(); 00238 } 00239 00240 void MidiOut::channelMute(uchar chn, int a) 00241 { 00242 if (a==1) 00243 { 00244 chnmute[chn]=a; 00245 channelSilence(chn); 00246 } 00247 else if (a==0) 00248 { 00249 chnmute[chn]=a; 00250 } 00251 /* else ignore the call to this function */ 00252 } 00253 00254 void MidiOut::seqbuf_dump (void) 00255 { 00256 #ifdef HAVE_OSS_SUPPORT 00257 if (_seqbufptr && seqfd!=-1 && seqfd!=0) 00258 if (write (seqfd, _seqbuf, _seqbufptr) == -1) 00259 { 00260 printfdebug("Error writing to /dev/sequencer in MidiOut::seq_buf_dump\n"); 00261 perror ("write /dev/sequencer in seqBufDump\n"); 00262 exit (-1); 00263 } 00264 _seqbufptr = 0; 00265 #endif 00266 } 00267 00268 void MidiOut::seqbuf_clean(void) 00269 { 00270 #ifdef HAVE_OSS_SUPPORT 00271 _seqbufptr=0; 00272 #endif 00273 } 00274 00275 const char *MidiOut::midiMapFilename(void) 00276 { 00277 return (map!=NULL) ? map->filename() : ""; 00278 } 00279 00280 const char * MidiOut::deviceName(void) const 00281 { 00282 switch (deviceType()) 00283 { 00284 case (KMID_EXTERNAL_MIDI) : return "External Midi"; 00285 case (KMID_SYNTH) : return "Synth"; 00286 case (KMID_FM) : return "FM"; 00287 case (KMID_GUS) : return "GUS"; 00288 case (KMID_AWE) : return "AWE"; 00289 case (KMID_ALSA) : return reinterpret_cast<const AlsaOut *>(this)->deviceName(); 00290 } 00291 return "Unknown"; 00292 } 00293 00294 void MidiOut::sync(int i) 00295 { 00296 if (deviceType()==KMID_ALSA) { // XXX : sync should be virtual after next bic 00297 reinterpret_cast<AlsaOut *>(this)->sync(i); 00298 return; 00299 } 00300 SEQ_DUMPBUF(); 00301 }
KDE Logo
This file is part of the documentation for libkmid Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 8 11:15:25 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003