00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00171
00172
00173
00174
00175
00176
00177
00178
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
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) {
00297 reinterpret_cast<AlsaOut *>(
this)->sync(i);
00298
return;
00299 }
00300 SEQ_DUMPBUF();
00301 }