1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef AUDIO_MIDIPLAYER_H
#define AUDIO_MIDIPLAYER_H
#include "common/scummsys.h"
#include "common/mutex.h"
#include "audio/mididrv.h"
class MidiParser;
namespace Audio {
/**
* Simple MIDI playback class.
*
* @note Currently incomplete, as it lacks play() methods. This is just a
* start of the real thing, which tries to include code replicated between
* several of our engines.
*
* Eventually, this should offer ways to start playback of SMF and XMIDI
* data (and possibly make it easy to add further playback methods),
* should be able to automatically instantiate _driver as needed,
* should perform memory management on the MidiParser object(s) being
* used, and possibly more.
*
* Also, pause/resume handling should be unified (we provide an implementation,
* but several subclasses use different ones).
*
* Also, care should be taken to ensure that mutex locking is done right.
*
* @todo Document origin of this class. It is based on code shared by
* several engines (e.g. DRACI says it copied it from MADE, which took
* it from SAGE).
*/
class MidiPlayer : public MidiDriver_BASE {
public:
MidiPlayer();
~MidiPlayer();
// TODO: Implement ways to actually play stuff
//virtual void play(TODO);
// TODO: Document these
virtual void stop();
virtual void pause();
virtual void resume();
/**
* Return whether there is currently any MIDI music playing.
*
* @todo There is a subtle difference between the semantics of this in
* various subclasses, related to paused music: Namely, should this
* function return true or false if a MIDI song is currently loaded,
* but paused? In the base implementation of pause/resume, "false"
* will be returned (that is, it is not possible to distinguish between
* nothing being played, and an active but paused MIDI tune).
* But in several subclasses (e.g. in HUGO), there is a separate _paused
* variable, which is used to pause playback, and for these, "true"
* will be returned.
* And in SAGA, isPlaying is overwritten to return the value
* of _parser->isPlaying() (which should amount to "true" in the
* described situation).
* We really should unify this and clearly define the desired
* semantics of this method.
*/
bool isPlaying() const { return _isPlaying; }
/**
* Return the currently active master volume, in the range 0-255.
*/
int getVolume() const { return _masterVolume; }
/**
* Set the master volume to the specified value in the range 0-255.
* (values outside this range are automatically clipped).
* This may cause suitable MIDI events to be sent to active channels.
*
* @todo This method currently does not do anything if the new volume
* matches the old volume. But some engines always update the
* volume (Parallaction, Tinsel, Touche, ...). This is why
* this method is currently virtual. We really should figure
* which way to do it, and then make this the default, and make
* this method non-virtual again.
*/
virtual void setVolume(int volume);
/**
* Update the volume according to the ConfMan's 'music_volume'
* setting. also respects the 'mute' setting.
*/
void syncVolume();
// TODO: Document this
bool hasNativeMT32() const { return _nativeMT32; }
// MidiDriver_BASE implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
protected:
/**
* This method is invoked by the default send() implementation,
* after suitably filtering the message b.
*/
virtual void sendToChannel(byte ch, uint32 b);
/**
* This method is invoked by metaEvent when an end-of-track
* event arrives. By default, this tells the parser
* to jump to the start (if looping is enabled) resp.
* invokes stope():
* Overload this to customize behavior.
*/
virtual void endOfTrack();
// TODO: Document this
virtual void onTimer();
static void timerCallback(void *data);
void createDriver(int flags = MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
protected:
enum {
/**
* The number of MIDI channels supported.
*/
kNumChannels = 16
};
Common::Mutex _mutex;
MidiDriver *_driver;
/**
* A MidiParser instances, to be created by methods of a MidiPlayer
* subclass.
* @note The stop() method (and hence the destructor) invoke the
* unloadMusic() method of _parser and then delete it.
*/
MidiParser *_parser;
/**
* This is an (optional) pointer to a malloc'ed buffer containing
* MIDI data used by _parser. The stop() method (and hence the
* destructor) will free this if set.
* Subclasses of this class may use _midiData, but don't have to
*/
byte *_midiData;
MidiChannel *_channelsTable[kNumChannels];
uint8 _channelsVolume[kNumChannels];
bool _isLooping;
bool _isPlaying;
/**
* The master volume, in the range 0-255.
*/
int _masterVolume; // FIXME: byte or int ?
bool _nativeMT32;
};
} // End of namespace Audio
#endif
|