mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-06 18:27:26 +00:00
PARALLACTION: Change MidiPlayer impls to derive from Audio::MidiPlayer
This commit is contained in:
parent
84d68f31e8
commit
7cc04f25ff
@ -27,8 +27,8 @@
|
||||
#include "common/util.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/midiparser.h"
|
||||
#include "audio/midiplayer.h"
|
||||
#include "audio/mods/protracker.h"
|
||||
#include "audio/decoders/raw.h"
|
||||
|
||||
@ -201,13 +201,9 @@ MidiParser *createParser_MSC() {
|
||||
}
|
||||
|
||||
|
||||
class MidiPlayer_MSC : public MidiDriver_BASE {
|
||||
class MidiPlayer_MSC : public Audio::MidiPlayer {
|
||||
public:
|
||||
|
||||
enum {
|
||||
NUM_CHANNELS = 16
|
||||
};
|
||||
|
||||
MidiPlayer_MSC(MidiDriver *driver);
|
||||
~MidiPlayer_MSC();
|
||||
|
||||
@ -215,42 +211,26 @@ public:
|
||||
void stop();
|
||||
void pause(bool p);
|
||||
void updateTimer();
|
||||
void adjustVolume(int diff);
|
||||
void setVolume(int volume);
|
||||
int getVolume() const { return _masterVolume; }
|
||||
void setLooping(bool loop) { _isLooping = loop; }
|
||||
|
||||
// MidiDriver_BASE interface
|
||||
virtual void send(uint32 b);
|
||||
virtual void metaEvent(byte type, byte *data, uint16 length);
|
||||
|
||||
private:
|
||||
|
||||
static void timerCallback(void *p);
|
||||
void setVolumeInternal(int volume);
|
||||
|
||||
Common::Mutex _mutex;
|
||||
MidiDriver *_driver;
|
||||
MidiParser *_parser;
|
||||
uint8 *_midiData;
|
||||
bool _isLooping;
|
||||
bool _isPlaying;
|
||||
bool _paused;
|
||||
|
||||
int _masterVolume;
|
||||
MidiChannel *_channels[NUM_CHANNELS];
|
||||
uint8 _volume[NUM_CHANNELS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
MidiPlayer_MSC::MidiPlayer_MSC(MidiDriver *driver)
|
||||
: _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _paused(false), _masterVolume(0) {
|
||||
: _midiData(0), _paused(false) {
|
||||
_driver = driver;
|
||||
assert(_driver);
|
||||
memset(_channels, 0, sizeof(_channels));
|
||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||
_volume[i] = 127;
|
||||
}
|
||||
|
||||
int ret = _driver->open();
|
||||
if (ret == 0) {
|
||||
@ -295,13 +275,9 @@ void MidiPlayer_MSC::play(Common::SeekableReadStream *stream) {
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::stop() {
|
||||
Common::StackLock lock(_mutex);
|
||||
if (_isPlaying) {
|
||||
_isPlaying = false;
|
||||
_parser->unloadMusic();
|
||||
free(_midiData);
|
||||
_midiData = 0;
|
||||
}
|
||||
Audio::MidiPlayer::stop();
|
||||
free(_midiData);
|
||||
_midiData = 0;
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::pause(bool p) {
|
||||
@ -320,10 +296,6 @@ void MidiPlayer_MSC::updateTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::adjustVolume(int diff) {
|
||||
setVolume(_masterVolume + diff);
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::setVolume(int volume) {
|
||||
_masterVolume = CLIP(volume, 0, 255);
|
||||
setVolumeInternal(_masterVolume);
|
||||
@ -331,43 +303,28 @@ void MidiPlayer_MSC::setVolume(int volume) {
|
||||
|
||||
void MidiPlayer_MSC::setVolumeInternal(int volume) {
|
||||
Common::StackLock lock(_mutex);
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
if (_channels[i]) {
|
||||
_channels[i]->volume(_volume[i] * volume / 255);
|
||||
for (int i = 0; i < kNumChannels; ++i) {
|
||||
if (_channelsTable[i]) {
|
||||
_channelsTable[i]->volume(_channelsVolume[i] * volume / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::send(uint32 b) {
|
||||
// FIXME/TODO: Unlike Audio::MidiPlayer::send(), this code
|
||||
// does not handle All Note Off. Is this on purpose?
|
||||
// If not, we could simply remove this method, and use the
|
||||
// inherited one.
|
||||
const byte ch = b & 0x0F;
|
||||
byte param2 = (b >> 16) & 0xFF;
|
||||
|
||||
switch (b & 0xFFF0) {
|
||||
case 0x07B0: // volume change
|
||||
_volume[ch] = param2;
|
||||
_channelsVolume[ch] = param2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_channels[ch]) {
|
||||
_channels[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
|
||||
}
|
||||
if (_channels[ch]) {
|
||||
_channels[ch]->send(b);
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::metaEvent(byte type, byte *data, uint16 length) {
|
||||
switch (type) {
|
||||
case 0x2F: // end of Track
|
||||
if (_isLooping) {
|
||||
_parser->jumpToTick(0);
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sendToChannel(ch, b);
|
||||
}
|
||||
|
||||
void MidiPlayer_MSC::timerCallback(void *p) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "audio/midiparser.h"
|
||||
#include "audio/midiplayer.h"
|
||||
#include "audio/mods/protracker.h"
|
||||
#include "audio/decoders/raw.h"
|
||||
|
||||
@ -38,13 +39,9 @@
|
||||
|
||||
namespace Parallaction {
|
||||
|
||||
class MidiPlayer : public MidiDriver_BASE {
|
||||
class MidiPlayer : public Audio::MidiPlayer {
|
||||
public:
|
||||
|
||||
enum {
|
||||
NUM_CHANNELS = 16
|
||||
};
|
||||
|
||||
MidiPlayer(MidiDriver *driver);
|
||||
~MidiPlayer();
|
||||
|
||||
@ -52,38 +49,18 @@ public:
|
||||
void stop();
|
||||
void pause(bool p);
|
||||
void updateTimer();
|
||||
void adjustVolume(int diff);
|
||||
void setVolume(int volume);
|
||||
int getVolume() const { return _masterVolume; }
|
||||
void setLooping(bool loop) { _isLooping = loop; }
|
||||
|
||||
// MidiDriver_BASE interface
|
||||
virtual void send(uint32 b);
|
||||
virtual void metaEvent(byte type, byte *data, uint16 length);
|
||||
|
||||
private:
|
||||
|
||||
static void timerCallback(void *p);
|
||||
|
||||
MidiDriver *_driver;
|
||||
MidiParser *_parser;
|
||||
uint8 *_midiData;
|
||||
bool _isLooping;
|
||||
bool _isPlaying;
|
||||
bool _paused;
|
||||
int _masterVolume;
|
||||
MidiChannel *_channelsTable[NUM_CHANNELS];
|
||||
uint8 _channelsVolume[NUM_CHANNELS];
|
||||
Common::Mutex _mutex;
|
||||
};
|
||||
|
||||
MidiPlayer::MidiPlayer(MidiDriver *driver)
|
||||
: _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _paused(false), _masterVolume(0) {
|
||||
assert(_driver);
|
||||
memset(_channelsTable, 0, sizeof(_channelsTable));
|
||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||
_channelsVolume[i] = 127;
|
||||
}
|
||||
: _midiData(0), _paused(false) {
|
||||
assert(driver);
|
||||
_driver = driver;
|
||||
|
||||
int ret = _driver->open();
|
||||
if (ret == 0) {
|
||||
@ -128,19 +105,15 @@ void MidiPlayer::play(Common::SeekableReadStream *stream) {
|
||||
}
|
||||
|
||||
void MidiPlayer::stop() {
|
||||
Common::StackLock lock(_mutex);
|
||||
if (_isPlaying) {
|
||||
_isPlaying = false;
|
||||
_parser->unloadMusic();
|
||||
free(_midiData);
|
||||
_midiData = 0;
|
||||
}
|
||||
Audio::MidiPlayer::stop();
|
||||
free(_midiData);
|
||||
_midiData = 0;
|
||||
}
|
||||
|
||||
void MidiPlayer::pause(bool p) {
|
||||
_paused = p;
|
||||
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
for (int i = 0; i < kNumChannels; ++i) {
|
||||
if (_channelsTable[i]) {
|
||||
_channelsTable[i]->volume(_paused ? 0 : _channelsVolume[i] * _masterVolume / 255);
|
||||
}
|
||||
@ -158,61 +131,6 @@ void MidiPlayer::updateTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer::adjustVolume(int diff) {
|
||||
setVolume(_masterVolume + diff);
|
||||
}
|
||||
|
||||
void MidiPlayer::setVolume(int volume) {
|
||||
_masterVolume = CLIP(volume, 0, 255);
|
||||
|
||||
Common::StackLock lock(_mutex);
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
if (_channelsTable[i]) {
|
||||
_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer::send(uint32 b) {
|
||||
byte volume, ch = (byte)(b & 0xF);
|
||||
switch (b & 0xFFF0) {
|
||||
case 0x07B0: // volume change
|
||||
volume = (byte)((b >> 16) & 0x7F);
|
||||
_channelsVolume[ch] = volume;
|
||||
volume = volume * _masterVolume / 255;
|
||||
b = (b & 0xFF00FFFF) | (volume << 16);
|
||||
break;
|
||||
case 0x7BB0: // all notes off
|
||||
if (!_channelsTable[ch]) {
|
||||
// channel not yet allocated, no need to send the event
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_channelsTable[ch]) {
|
||||
_channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
|
||||
}
|
||||
if (_channelsTable[ch]) {
|
||||
_channelsTable[ch]->send(b);
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
|
||||
switch (type) {
|
||||
case 0x2F: // end of Track
|
||||
if (_isLooping) {
|
||||
_parser->jumpToTick(0);
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// warning("Unhandled meta event: %02x", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MidiPlayer::timerCallback(void *p) {
|
||||
MidiPlayer *player = (MidiPlayer *)p;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user