1
/* deviceman.h - The device manager, that hides the use of midiOut
2
Copyright (C) 1997,98 Antonio Larrosa Jimenez
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
Send comments and bug fixes to antlarr@arrakis.es
19
or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain
21
***************************************************************************/
26
#include "../version.h"
32
* MIDI Device Manager class . This class is the one you should use to
33
* send MIDI events to any device, as it creates and manages the *Out classes.
35
* This class is usually used by creating a DeviceManager object, then call
36
* @ref #openDev and @ref #initDev . Then, use @ref #numberOfMidiPorts,
37
* @ref #numberOfSynthDevices, @ref #name and @ref #type to choose which
38
* device to play MIDI events to and then use @ref defaultDevice to set the
39
* MIDI device to play.
41
* @short Manages all MIDI devices and redirects MIDI events to each one as
43
* @author Antonio Larrosa <larrosa@kde.org>
49
MidiOut **device; // The midi devices objects
50
struct midi_info *midiinfo; // Midi info
51
struct synth_info *synthinfo; // Synth info
52
int chn2dev[16]; // Stores the device thru which a channel will be sent
53
int n_synths; // Number of synths devices
54
int n_midi; // Number of midi ports
55
int n_total; // n_midi+n_synths
57
#ifndef HANDLETIMEINDEVICES
60
double convertrate; // A "constant" used to convert from
61
// milliseconds to the computer rate
64
int timerstarted; // Newest kernels don't want me to stop a timer that
65
// hasn't been started :-)
67
double lastwaittime; // Last time waited for in wait(double)
69
MidiMapper *mapper_tmp; // Keeps a pointer to the mapper so that if devices
70
// weren't initialized when first called setMidiMap
71
// then, when they get initialized, they use the proper mapper
74
int seqfd; // The real file handler for /dev/sequencer,
75
// that is opened and closed.
76
int default_dev; // The device to which timer events will be sent
79
void seqbuf_dump (void);
80
void seqbuf_clean (void);
84
* Constructor. It just initializes internal variables, before playing any
85
* music, you should call @ref #initManager, @ref #setMidiMap (optional),
86
* @ref openDev, @ref initDev, @ref setPatchesToUse (optional, except if
87
* you're playing to a GUS device, which must load the patches),
88
* @ref tmrStart, and finally, play the music.
90
DeviceManager(int def=0);
92
* Destructor. It closes the device (calling @ref closeDev) if it wasn't
98
* Initializes the MIDI Device Manager object.
100
* The /dev/sequencer file is opened, available devices are analyzed and
101
* *Out objects are created. Then, the /dev/sequencer file is closed.
103
* @return 0 if everything was OK, or -1 if there was an error and it couldn't
104
* be initialized (for example, because it couldn't open the /dev/sequencer i
107
int initManager(void);
110
* Checks if the device manager has been initialized (with @initManager),
111
* and in case it wasn't, initializes it.
113
* @return 0 if it was (or has just been) correctly initialized, and -1 if there
119
* It's possible to send different MIDI channels to different MIDI devices,
120
* so that you can for example send channel 1 to an external synthesizer,
121
* channel 2 to a FM device and channel 10 to an AWE synth.
123
* @return the device to which MIDI events goind to channel chn should be sent.
125
MidiOut *chntodev(int chn) { return device[chn2dev[chn]]; };
128
* @return 0 if there was a problem and 1 if everything was OK. Note that the
129
* return value is changed after you check it, so you can only check it once.
133
// The following funtion are here to emulate a midi, so that the DeviceManager
134
// sends the events to the appropiate devices.
137
* Open the devices. It first initializes the manager it that wasn't done yet
138
* (you should do it yourself, to be able to choose the MIDI output device, as
139
* it will be set to an external synth by default, if available) .
141
* Then /dev/sequencer is opened and the MIDI devices are opened
142
* (calling @ref MidiOut::openDev ).
143
* @see #ok to check if there was any problem
150
* Closes the devices, and /dev/sequencer.
154
void closeDev (void);
157
* Calls @ref MidiOut::initDev in turn in each of the available devices.
159
* @see MidiOut::initDev
164
* Sends a Note On MIDI event.
166
* @param chn the MIDI channel (0 to 15) to play the note on.
167
* @param note the key of the note to play (0 to 127).
168
* @param vel the velocity of the note (0 to 127).
172
void noteOn ( uchar chn, uchar note, uchar vel );
175
* Sends a Note Off MIDI event. This is equivalent to send a Note On event with a
178
* @param chn the MIDI channel (0 to 15) to play the note on.
179
* @param note the key of the note to play (0 to 127).
180
* @param vel the velocity of the note (0 to 127).
184
void noteOff ( uchar chn, uchar note, uchar vel );
187
* Sends a Key Pressure (or Aftertouch) MIDI event.
188
* This event changes the pressure over a key after this key has been played.
190
* @param chn the MIDI channel (0 to 15) where the note is being played.
191
* @param note the key of the note (0 to 127).
192
* @param vel the new velocity (or pressure) of the note (0 to 127).
194
void keyPressure ( uchar chn, uchar note, uchar vel );
198
* Changes the patch (instrument) on a MIDI channel.
200
* @see setPatchesToUse
202
* @param chn the MIDI channel (0 to 15) .
203
* @param patch the General Midi patch (0 to 127) to use on the channel chn.
205
void chnPatchChange ( uchar chn, uchar patch );
208
* Changes the Pressure (Aftertouch) on a MIDI channel. Keep in mind that some
209
* synthesizers don't like this events, and it's better not to send it.
211
* @param chn the MIDI channel (0 to 15) to change.
212
* @param vel the velocity (0 to 127) to use on the channel chn.
214
void chnPressure ( uchar chn, uchar vel );
217
* Changes the Pitch Bender value on a MIDI channel. This bends the tone of
218
* each note played on this channel.
220
* @param chn the MIDI channel (0 to 15) to use.
221
* @param lsb @param msb the less significant byte and the most significant
222
* byte (0 to 127 each) of the number by which notes will be bend. a 0x4000
223
* value means not to bend.
225
void chnPitchBender ( uchar chn, uchar lsb, uchar msb );
228
* Sends a Controller event to a MIDI channel. This can be used for example to
229
* change the volume, set a XG patch, etc. Look for any General Midi resource
230
* page on the net for more information about the available controller events.
232
* For example, to set the tremolo value to a maximum on the MIDI channel
233
* number one, you should pass 1 to chn, 1 to ctl and 127 to v.
235
* @param chn the MIDI channel (0 to 15) to send the event to.
236
* @param ctl the controller (0 to 15) to send.
237
* @param v the value (data) of the controller.
239
void chnController ( uchar chn, uchar ctl , uchar v );
242
* Sends a SYStem EXclusive message to the default MIDI device (usually,
243
* external MIDI synths, as most internal synths do not support sysex messages)
245
* @param data the array of bytes that comform the system exclusive message.
246
* Without the initial 0xF0 char, and including the final 0xF7 char (end of
248
* @param size the size in bytes of the data to send
250
* @see setDefaultDevice
252
void sysEx ( uchar *data,ulong size);
255
* Sets the number of MIDI ticks to wait until the next event is sent. This way,
256
* you can schedule notes and events to send to the MIDI device.
258
void wait (double ticks);
261
* Sets the tempo which will be used to convert between ticks and milliseconds.
263
void tmrSetTempo(int v);
266
* Starts the timer. You should call tmrStart before using @ref #wait
271
* Stops the timer. This will be called by @ref #closeDev before closing the device
276
* Continue the stopped timer . It is the same than starting a new timer, but
277
* without resetting it.
279
void tmrContinue(void);
282
* Synchronizes with the MIDI buffer. Midi events are put into a buffer, along
283
* with timer delays (see @ref #wait). sync returns when the buffer is empty.
285
* @param f if false, it syncronizes by waiting for the buffer to be sent.
286
* If true, it forces the synchronization by clearing the buffer inmediately.
287
* The "force" method is, of course, not recommended, except in rare situations.
292
* Changes the "master" volume of the played events by altering next volume
293
* controller events. The parameter i should be in the range of 0 (nothing
294
* is heard) to 150 (music is played at a 150% of the original volume).
296
* Keep in mind that as most MIDI files already play music at near the maximumi
297
* volume, an i value greater than 100 is very probably ignored most of the times.
299
void setVolumePercentage(int i);
302
* Returns the device to which the MIDI events will be sent.
304
* @see #setDefaultDevice
306
int defaultDevice(void);
309
* Sets the device to send the MIDI events to.
311
* By using @ref #midiPorts, @ref #synthDevices, @ref #name and @ref #type, you
312
* should choose which device to use (note that they are numbered with midi
313
* ports being first and synth devices next)
315
* @see #defaultDevice
317
void setDefaultDevice(int i);
320
* Loads the patches you're going to use . This has effect only for GUS cards,
321
* although, if you use this function when @ref defaultDevice is not a GUS device,
322
* it will be ignored.
324
* The parameter is an int [256] array, which contain the following:
326
* The first 0..127 integers, are the number of times each General MIDI patch will be used,
327
* and -1 when the corresponding patch won't be used.
329
* The 128..255 integers are the number of times each drum voice (each note on the drum channel)
330
* will be used, and -1 when the corresponding percussion won't be used.
332
* This is done this way so that if the user has very little memory on his GUS card, and not
333
* all patches will be loaded, they are at least reordered, so that it first loads the one you're
336
* In case you don't worry about such users, or you don't know "a priori" the number of notes
337
* you're going to play, you can just use 1 for each patch you want to load and -1 in the rest.
339
* @see GUSOut::setPatchesToUse
340
* @see GUSOut::loadPatch
342
* @return 0 if ok, and -1 if there wasn't enough memory to load the patches
343
* in the card's memory.
345
int setPatchesToUse(int *patchesused);
348
* Returns the filename where the Midi Mapper was loaded from, or "" if no
349
* MIDI Mapper is in use.
353
char *midiMapFilename(void);
356
* Sets a @ref MidiMapper object to use. This object should already have
357
* loaded the configuration. See the description of @ref MidiMapper for
360
* @see MidiMapper::MidiMapper
361
* @see #midiMapFilename
363
void setMidiMap(MidiMapper *map);
366
* Returns the number of MIDI ports available on the system. It's common that
367
* users have MIDI ports available, but there are no external synthesizers
368
* connected to these ports, so sending MIDI events to these ports will not
369
* produce any music in this case.
372
* @see #setDefaultDevice
374
int midiPorts(void) {return n_midi;};
376
* Returns the number of internal synthesizers available on the system. Some
377
* of these devices will need special configuration, for example, to load
381
* @see #setDefaultDevice
382
* @see #setPatchesToUse
384
int synthDevices(void) {return n_synths;};
386
* Returns the name of the i-th device . In case the DeviceManager wasn't yet
387
* initialized ( see @ref #checkInit ), the return value is NULL, and in case
388
* the parameter has a value out of the valid range ( 0 to @ref midiPorts () +
389
* @ref synthDevices () ) it returns an empty string.
394
* Returns the type of device the i-th device is , in a user-friendly string.
395
* For example, "External Midi Port" for midi ports, "FM" for FM synthesizers,
396
* "GUS" for Gravis Ultrasound devices, etc.
398
const char *type(int i);