aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/fmtowns_pc98
diff options
context:
space:
mode:
Diffstat (limited to 'audio/softsynth/fmtowns_pc98')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.cpp148
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.h18
2 files changed, 86 insertions, 80 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
index e80d29bcec..e989db33d8 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
@@ -25,24 +25,43 @@
#include "common/util.h"
#include "common/textconsole.h"
+#define EUP_EVENT(x) _euphonyEvents.push_back(new EuphonyEvent(this, &EuphonyPlayer::event_##x))
+
EuphonyPlayer::EuphonyPlayer(Audio::Mixer *mixer) : _partConfig_enable(0), _partConfig_type(0), _partConfig_ordr(0), _partConfig_volume(0),
- _partConfig_transpose(0), _musicPos(0), _musicStart(0), _playing(false), _savedEventsChain(0), _tempoModifier(0), _bar(0),
+ _partConfig_transpose(0), _musicPos(0), _musicStart(0), _playing(false), _pendingEventsChain(0), _tempoModifier(0), _bar(0),
_beat(0), _defaultBarLength(0), _barLength(0), _playerUpdatesLeft(0), _updatesPerPulseRemainder(0), _updatesPerPulse(0),
_deltaTicks(0), _defaultTempo(0), _trackTempo(0), _tempoControlMode(0), _timerSetting(0), _tempoMode1PulseCounter(0),
_parseToBar(0), _tempoMode1UpdateF8(0), _loop(false), _endOfTrack(false), _paused(false), _musicTrackSize(0) {
+ EUP_EVENT(notImpl);
+ EUP_EVENT(noteOn);
+ EUP_EVENT(polyphonicAftertouch);
+ EUP_EVENT(controlChange_pitchWheel);
+ EUP_EVENT(programChange_channelAftertouch);
+ EUP_EVENT(programChange_channelAftertouch);
+ EUP_EVENT(controlChange_pitchWheel);
+ EUP_EVENT(sysex);
+ EUP_EVENT(advanceBar);
+ EUP_EVENT(notImpl);
+ EUP_EVENT(notImpl);
+ EUP_EVENT(setTempo);
+ EUP_EVENT(notImpl);
+ EUP_EVENT(typeOrdrChange);
+
_drivers[0] = _eupDriver = new EuphonyDriver(mixer, this);
_drivers[1] = new Type0Driver(this);
_drivers[2] = 0;
resetTempo();
}
+#undef EUP_EVENT
+
EuphonyPlayer::~EuphonyPlayer() {
for (int i = 0; i < 3; i++)
delete _drivers[i];
- while (_savedEventsChain) {
- SavedEvent *evt = _savedEventsChain;
- _savedEventsChain = _savedEventsChain->next;
+ while (_pendingEventsChain) {
+ PendingEvent *evt = _pendingEventsChain;
+ _pendingEventsChain = _pendingEventsChain->next;
delete evt;
}
@@ -51,6 +70,9 @@ EuphonyPlayer::~EuphonyPlayer() {
delete[] _partConfig_ordr;
delete[] _partConfig_volume;
delete[] _partConfig_transpose;
+
+ for (EuphonyEventsArray::iterator i = _euphonyEvents.begin(); i != _euphonyEvents.end(); ++i)
+ delete *i;
}
bool EuphonyPlayer::init() {
@@ -67,9 +89,9 @@ bool EuphonyPlayer::init() {
if (!_drivers[0] || !_drivers[1])
return false;
- while (_savedEventsChain) {
- SavedEvent *evt = _savedEventsChain;
- _savedEventsChain = _savedEventsChain->next;
+ while (_pendingEventsChain) {
+ PendingEvent *evt = _pendingEventsChain;
+ _pendingEventsChain = _pendingEventsChain->next;
delete evt;
}
@@ -204,9 +226,9 @@ void EuphonyPlayer::reset() {
resetPartConfig();
- while (_savedEventsChain) {
- SavedEvent *evt = _savedEventsChain;
- _savedEventsChain = _savedEventsChain->next;
+ while (_pendingEventsChain) {
+ PendingEvent *evt = _pendingEventsChain;
+ _pendingEventsChain = _pendingEventsChain->next;
delete evt;
}
@@ -309,35 +331,15 @@ void EuphonyPlayer::updateParser() {
}
void EuphonyPlayer::updateCheckEot() {
- if (!_endOfTrack || _savedEventsChain)
+ if (!_endOfTrack || _pendingEventsChain)
return;
stop();
}
bool EuphonyPlayer::parseEvent() {
-#define EVENT(x) &EuphonyPlayer::event_##x
- static const EuphonyEvent events[] = {
- EVENT(notImpl),
- EVENT(noteOn),
- EVENT(polyphonicAftertouch),
- EVENT(controlChange_pitchWheel),
- EVENT(programChange_channelAftertouch),
- EVENT(programChange_channelAftertouch),
- EVENT(controlChange_pitchWheel),
-
- EVENT(sysex),
- EVENT(advanceBar),
- EVENT(notImpl),
- EVENT(notImpl),
- EVENT(setTempo),
- EVENT(notImpl),
- EVENT(typeOrdrChange)
- };
-#undef EVENT
-
uint cmd = _musicPos[0];
if (cmd != 0xfe && cmd != 0xfd) {
- bool result = (cmd >= 0xf0) ? (this->*events[((cmd - 0xf0) >> 1) + 7])() : (this->*events[(cmd - 0x80) >> 4])();
+ bool result = (cmd >= 0xf0) ? (*_euphonyEvents[((cmd - 0xf0) >> 1) + 7])() : (*_euphonyEvents[(cmd - 0x80) >> 4])();
if (!result) {
proceedToNextEvent();
return false;
@@ -369,8 +371,8 @@ void EuphonyPlayer::proceedToNextEvent() {
}
void EuphonyPlayer::updateHangingNotes() {
- SavedEvent *l = 0;
- SavedEvent *e = _savedEventsChain;
+ PendingEvent *l = 0;
+ PendingEvent *e = _pendingEventsChain;
while (e) {
if (--e->len) {
@@ -379,13 +381,13 @@ void EuphonyPlayer::updateHangingNotes() {
continue;
}
- SavedEvent *n = e->next;
+ PendingEvent *n = e->next;
if (l)
l->next = n;
- if (_savedEventsChain == e)
- _savedEventsChain = n;
+ if (_pendingEventsChain == e)
+ _pendingEventsChain = n;
- sendNoteEvent(e->type, e->evt, e->note, e->velo);
+ sendPendingEvent(e->type, e->evt, e->note, e->velo);
delete e;
e = n;
@@ -393,10 +395,10 @@ void EuphonyPlayer::updateHangingNotes() {
}
void EuphonyPlayer::clearHangingNotes() {
- while (_savedEventsChain) {
- SavedEvent *e = _savedEventsChain;
- _savedEventsChain = _savedEventsChain->next;
- sendNoteEvent(e->type, e->evt, e->note, e->velo);
+ while (_pendingEventsChain) {
+ PendingEvent *e = _pendingEventsChain;
+ _pendingEventsChain = _pendingEventsChain->next;
+ sendPendingEvent(e->type, e->evt, e->note, e->velo);
delete e;
}
}
@@ -445,9 +447,9 @@ bool EuphonyPlayer::event_noteOn() {
uint8 note = _musicPos[4];
uint8 velo = _musicPos[5];
- sendEvent(type, evt);
- sendEvent(type, applyTranspose(note));
- sendEvent(type, applyVolumeAdjust(velo));
+ sendByte(type, evt);
+ sendByte(type, applyTranspose(note));
+ sendByte(type, applyVolumeAdjust(velo));
proceedToNextEvent();
if (_musicPos[0] == 0xfe || _musicPos[0] == 0xfd)
@@ -456,7 +458,7 @@ bool EuphonyPlayer::event_noteOn() {
velo = _musicPos[5];
uint16 len = (_musicPos[1] & 0x0f) | ((_musicPos[2] & 0x0f) << 4) | ((_musicPos[3] & 0x0f) << 8) | ((_musicPos[4] & 0x0f) << 12);
- _savedEventsChain = new SavedEvent(evt, type, note, velo, len ? len : 1, _savedEventsChain);
+ _pendingEventsChain = new PendingEvent(evt, type, note, velo, len ? len : 1, _pendingEventsChain);
return false;
}
@@ -470,9 +472,9 @@ bool EuphonyPlayer::event_polyphonicAftertouch() {
uint8 evt = appendEvent(_musicPos[0], _musicPos[1]);
uint8 type = _partConfig_type[_musicPos[1]];
- sendEvent(type, evt);
- sendEvent(type, applyTranspose(_musicPos[4]));
- sendEvent(type, _musicPos[5]);
+ sendByte(type, evt);
+ sendByte(type, applyTranspose(_musicPos[4]));
+ sendByte(type, _musicPos[5]);
return false;
}
@@ -486,9 +488,9 @@ bool EuphonyPlayer::event_controlChange_pitchWheel() {
uint8 evt = appendEvent(_musicPos[0], _musicPos[1]);
uint8 type = _partConfig_type[_musicPos[1]];
- sendEvent(type, evt);
- sendEvent(type, _musicPos[4]);
- sendEvent(type, _musicPos[5]);
+ sendByte(type, evt);
+ sendByte(type, _musicPos[4]);
+ sendByte(type, _musicPos[5]);
return false;
}
@@ -502,21 +504,21 @@ bool EuphonyPlayer::event_programChange_channelAftertouch() {
uint8 evt = appendEvent(_musicPos[0], _musicPos[1]);
uint8 type = _partConfig_type[_musicPos[1]];
- sendEvent(type, evt);
- sendEvent(type, _musicPos[4]);
+ sendByte(type, evt);
+ sendByte(type, _musicPos[4]);
return false;
}
bool EuphonyPlayer::event_sysex() {
uint8 type = _partConfig_type[_musicPos[1]];
- sendEvent(type, 0xF0);
+ sendByte(type, 0xF0);
proceedToNextEvent();
for (bool loop = true; loop; ) {
for (int i = 0; i < 6; i++) {
if (_musicPos[i] != 0xFF) {
- sendEvent(type, _musicPos[i]);
+ sendByte(type, _musicPos[i]);
if (_musicPos[i] >= 0x80) {
loop = false;
break;
@@ -579,36 +581,36 @@ uint8 EuphonyPlayer::applyVolumeAdjust(uint8 in) {
return out & 0xff;
}
-void EuphonyPlayer::sendEvent(uint8 type, uint8 command) {
+void EuphonyPlayer::sendByte(uint8 type, uint8 command) {
int drv = ((type >> 4) + 1) & 3;
if (_drivers[drv])
_drivers[drv]->send(command);
}
-void EuphonyPlayer::sendNoteEvent(int type, int evt, int note, int velo) {
+void EuphonyPlayer::sendPendingEvent(int type, int evt, int note, int velo) {
if (velo)
evt &= 0x8f;
- sendEvent(type, evt);
- sendEvent(type, note);
- sendEvent(type, velo);
+ sendByte(type, evt);
+ sendByte(type, note);
+ sendByte(type, velo);
}
void EuphonyPlayer::sendControllerReset(int type, int part) {
- sendEvent(type, 0xb0 | part);
- sendEvent(type, 0x40);
- sendEvent(type, 0);
- sendEvent(type, 0xb0 | part);
- sendEvent(type, 0x7b);
- sendEvent(type, 0);
- sendEvent(type, 0xb0 | part);
- sendEvent(type, 0x79);
- sendEvent(type, 0x40);
+ sendByte(type, 0xb0 | part);
+ sendByte(type, 0x40);
+ sendByte(type, 0);
+ sendByte(type, 0xb0 | part);
+ sendByte(type, 0x7b);
+ sendByte(type, 0);
+ sendByte(type, 0xb0 | part);
+ sendByte(type, 0x79);
+ sendByte(type, 0x40);
}
void EuphonyPlayer::sendAllNotesOff(int type, int part) {
- sendEvent(type, 0xb0 | part);
- sendEvent(type, 0x40);
- sendEvent(type, 0);
+ sendByte(type, 0xb0 | part);
+ sendByte(type, 0x40);
+ sendByte(type, 0);
}
void EuphonyPlayer::sendTempo(int tempo) {
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h
index 65e55fac40..6b9d94acf4 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.h
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h
@@ -25,6 +25,7 @@
#include "audio/softsynth/fmtowns_pc98/towns_audio.h"
#include "common/array.h"
+#include "common/func.h"
class EuphonyBaseDriver {
public:
@@ -154,7 +155,6 @@ private:
uint8 appendEvent(uint8 evt, uint8 chan);
- typedef bool(EuphonyPlayer::*EuphonyEvent)();
bool event_notImpl();
bool event_noteOn();
bool event_polyphonicAftertouch();
@@ -169,8 +169,8 @@ private:
uint8 applyTranspose(uint8 in);
uint8 applyVolumeAdjust(uint8 in);
- void sendEvent(uint8 type, uint8 command);
- void sendNoteEvent(int type, int evt, int note, int velo);
+ void sendByte(uint8 type, uint8 command);
+ void sendPendingEvent(int type, int evt, int note, int velo);
void sendControllerReset(int type, int part);
void sendAllNotesOff(int type, int part);
void sendTempo(int tempo);
@@ -181,17 +181,21 @@ private:
int8 *_partConfig_volume;
int8 *_partConfig_transpose;
- struct SavedEvent {
- SavedEvent(int ev, int tp, int nt, int vl, int ln, SavedEvent *chain) : evt(ev), type(tp), note(nt), velo(vl), len(ln), next(chain) {}
+ struct PendingEvent {
+ PendingEvent(int ev, int tp, int nt, int vl, int ln, PendingEvent *chain) : evt(ev), type(tp), note(nt), velo(vl), len(ln), next(chain) {}
uint8 evt;
uint8 type;
uint8 note;
uint8 velo;
uint16 len;
- SavedEvent *next;
+ PendingEvent *next;
};
- SavedEvent *_savedEventsChain;
+ PendingEvent *_pendingEventsChain;
+
+ typedef Common::Functor0Mem<bool, EuphonyPlayer> EuphonyEvent;
+ typedef Common::Array<const EuphonyEvent*> EuphonyEventsArray;
+ EuphonyEventsArray _euphonyEvents;
uint8 _defaultBarLength;
uint8 _barLength;