~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmid/player/deviceman.h

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  deviceman.h  - The device manager, that hides the use of midiOut 
 
2
    Copyright (C) 1997,98  Antonio Larrosa Jimenez
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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.
 
17
 
 
18
    Send comments and bug fixes to antlarr@arrakis.es
 
19
    or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain
 
20
 
 
21
***************************************************************************/
 
22
#ifndef DEVICEMAN_H
 
23
#define DEVICEMAN_H
 
24
 
 
25
#include "dattypes.h"
 
26
#include "../version.h"
 
27
 
 
28
class MidiOut;
 
29
class MidiMapper;
 
30
 
 
31
/**
 
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.
 
34
 *
 
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.
 
40
 *
 
41
 * @short Manages all MIDI devices and redirects MIDI events to each one as 
 
42
 * configured. 
 
43
 * @author Antonio Larrosa <larrosa@kde.org>
 
44
 */
 
45
class DeviceManager
 
46
{
 
47
  protected:
 
48
 
 
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
 
56
 
 
57
#ifndef HANDLETIMEINDEVICES
 
58
 
 
59
    int                 rate;
 
60
    double              convertrate; // A "constant" used to convert from
 
61
    // milliseconds to the computer rate
 
62
 
 
63
#endif
 
64
    int timerstarted; // Newest kernels don't want me to stop a timer that
 
65
                // hasn't been started :-)
 
66
 
 
67
    double lastwaittime; // Last time waited for in wait(double)
 
68
 
 
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
 
72
 
 
73
    int initialized;
 
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
 
77
 
 
78
    int _ok;
 
79
    void seqbuf_dump (void);
 
80
    void seqbuf_clean (void);
 
81
 
 
82
  public:
 
83
/**
 
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.
 
89
 */
 
90
    DeviceManager(int def=0);
 
91
/**
 
92
 * Destructor. It closes the device (calling @ref closeDev) if it wasn't
 
93
 * closed before. 
 
94
 */
 
95
    ~DeviceManager(void);
 
96
 
 
97
/**
 
98
 * Initializes the MIDI Device Manager object.
 
99
 * 
 
100
 * The /dev/sequencer file is opened,  available devices are analyzed and
 
101
 * *Out objects are created. Then, the /dev/sequencer file is closed.
 
102
 *
 
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
 
105
 * file)
 
106
 */
 
107
    int initManager(void); 
 
108
 
 
109
/**
 
110
 * Checks if the device manager has been initialized (with @initManager),
 
111
 * and in case it wasn't, initializes it.
 
112
 * 
 
113
 * @return 0 if it was (or has just been) correctly initialized, and -1 if there
 
114
 * was an error.
 
115
 */
 
116
    int checkInit(void); 
 
117
 
 
118
/**
 
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.
 
122
 *
 
123
 * @return the device to which MIDI events goind to channel chn should be sent. 
 
124
 */
 
125
    MidiOut *chntodev(int chn) { return device[chn2dev[chn]]; };
 
126
 
 
127
/**
 
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.
 
130
 */
 
131
    int ok(void);
 
132
 
 
133
// The following funtion are here to emulate a midi, so that the DeviceManager
 
134
// sends the events to the appropiate devices.
 
135
 
 
136
/**
 
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) .
 
140
 *
 
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
 
144
 * @see #closeDev
 
145
 * @see #initDev
 
146
 */
 
147
    void openDev        (void);
 
148
 
 
149
/**
 
150
 * Closes the devices, and /dev/sequencer. 
 
151
 *
 
152
 * @see #openDev
 
153
 */
 
154
    void closeDev       (void);
 
155
 
 
156
/**
 
157
 * Calls @ref MidiOut::initDev in turn in each of the available devices.
 
158
 *
 
159
 * @see MidiOut::initDev
 
160
 */
 
161
    void initDev        (void);
 
162
 
 
163
/**
 
164
 * Sends a Note On MIDI event.
 
165
 *
 
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).
 
169
 *
 
170
 * @see #noteOff
 
171
 */
 
172
    void noteOn         ( uchar chn, uchar note, uchar vel );
 
173
 
 
174
/**
 
175
 * Sends a Note Off MIDI event. This is equivalent to send a Note On event with a 
 
176
 * vel value of 0.
 
177
 *
 
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).
 
181
 *
 
182
 * @see #noteOn
 
183
 */
 
184
    void noteOff        ( uchar chn, uchar note, uchar vel );
 
185
 
 
186
/**
 
187
 * Sends a Key Pressure (or Aftertouch) MIDI event.
 
188
 * This event changes the pressure over a key after this key has been played.
 
189
 *
 
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).
 
193
 */
 
194
    void keyPressure    ( uchar chn, uchar note, uchar vel );
 
195
 
 
196
 
 
197
/**
 
198
 * Changes the patch (instrument) on a MIDI channel.  
 
199
 * 
 
200
 * @see setPatchesToUse
 
201
 *
 
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.
 
204
 */
 
205
    void chnPatchChange ( uchar chn, uchar patch );
 
206
 
 
207
/**
 
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. 
 
210
 * 
 
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.
 
213
 */
 
214
    void chnPressure    ( uchar chn, uchar vel );
 
215
 
 
216
/**
 
217
 * Changes the Pitch Bender value on a MIDI channel. This bends the tone of
 
218
 * each note played on this channel.
 
219
 * 
 
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.
 
224
 */
 
225
    void chnPitchBender ( uchar chn, uchar lsb,  uchar msb );
 
226
 
 
227
/**
 
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.
 
231
 *
 
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.
 
234
 *
 
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.
 
238
 */
 
239
    void chnController  ( uchar chn, uchar ctl , uchar v );
 
240
 
 
241
/**
 
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)
 
244
 * 
 
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
 
247
 * exclusive message)
 
248
 * @param size the size in bytes of the data to send 
 
249
 *
 
250
 * @see setDefaultDevice
 
251
 */
 
252
    void sysEx          ( uchar *data,ulong size);
 
253
 
 
254
/**
 
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.
 
257
 */
 
258
    void wait (double ticks);
 
259
 
 
260
/**
 
261
 * Sets the tempo which will be used to convert between ticks and milliseconds.  
 
262
 */
 
263
    void tmrSetTempo(int v);
 
264
 
 
265
/**
 
266
 * Starts the timer. You should call tmrStart before using @ref #wait
 
267
 */
 
268
    void tmrStart(void);
 
269
 
 
270
/**
 
271
 * Stops the timer. This will be called by @ref #closeDev before closing the device
 
272
 */
 
273
    void tmrStop(void);
 
274
 
 
275
/**
 
276
 * Continue the stopped timer . It is the same than starting a new timer, but
 
277
 * without resetting it.
 
278
 */
 
279
    void tmrContinue(void);
 
280
 
 
281
/**
 
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.
 
284
 * 
 
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.
 
288
 */ 
 
289
    void sync(bool f=0);  
 
290
 
 
291
/**
 
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).
 
295
 * 
 
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.
 
298
 */
 
299
    void setVolumePercentage(int i);
 
300
 
 
301
/**
 
302
 * Returns the device to which the MIDI events will be sent.
 
303
 *
 
304
 * @see #setDefaultDevice
 
305
 */
 
306
    int defaultDevice(void);
 
307
 
 
308
/**
 
309
 * Sets the device to send the MIDI events to.
 
310
 * 
 
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)
 
314
 *
 
315
 * @see #defaultDevice
 
316
 */
 
317
    void setDefaultDevice(int i);
 
318
 
 
319
/**
 
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.
 
323
 *
 
324
 * The parameter is an int [256] array, which contain the following:
 
325
 * 
 
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.
 
328
 *
 
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.
 
331
 *
 
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
 
334
 * going to use most.
 
335
 *
 
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.
 
338
 * 
 
339
 * @see GUSOut::setPatchesToUse
 
340
 * @see GUSOut::loadPatch 
 
341
 * 
 
342
 * @return 0 if ok, and -1 if there wasn't enough memory to load the patches
 
343
 * in the card's memory.
 
344
 */
 
345
    int setPatchesToUse(int *patchesused);
 
346
 
 
347
/**
 
348
 * Returns the filename where the Midi Mapper was loaded from, or "" if no
 
349
 * MIDI Mapper is in use.
 
350
 *
 
351
 * @see #setMidiMap
 
352
 */
 
353
    char *midiMapFilename(void);
 
354
 
 
355
/**
 
356
 * Sets a @ref MidiMapper object to use. This object should already have
 
357
 * loaded the configuration. See the description of @ref MidiMapper for
 
358
 * more information.
 
359
 *
 
360
 * @see MidiMapper::MidiMapper
 
361
 * @see #midiMapFilename
 
362
 */
 
363
    void setMidiMap(MidiMapper *map);
 
364
 
 
365
/**
 
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.
 
370
 *
 
371
 * @see #synthDevices
 
372
 * @see #setDefaultDevice
 
373
 */
 
374
    int midiPorts(void) {return n_midi;};
 
375
/**
 
376
 * Returns the number of internal synthesizers available on the system. Some
 
377
 * of these devices will need special configuration, for example, to load
 
378
 * sound patches.
 
379
 *
 
380
 * @see #midiPorts
 
381
 * @see #setDefaultDevice
 
382
 * @see #setPatchesToUse
 
383
 */
 
384
    int synthDevices(void) {return n_synths;};
 
385
/**
 
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.
 
390
 */
 
391
 
 
392
    char *name(int i);
 
393
/**
 
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.
 
397
 */
 
398
    const char *type(int i);
 
399
 
 
400
};
 
401
 
 
402
#endif