aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorathrxx2015-11-08 22:26:52 +0100
committerathrxx2015-11-09 18:41:10 +0100
commit8c046f4826be1d2d85d04b1e3f83dcc62ac55e5c (patch)
treefa1f0c8e5d2cac1bbb12e991041c560c4642d210 /audio
parent924b582ced24139b2e78a0a06d6ba5049089c8a5 (diff)
downloadscummvm-rg350-8c046f4826be1d2d85d04b1e3f83dcc62ac55e5c.tar.gz
scummvm-rg350-8c046f4826be1d2d85d04b1e3f83dcc62ac55e5c.tar.bz2
scummvm-rg350-8c046f4826be1d2d85d04b1e3f83dcc62ac55e5c.zip
AUDIO: (FM-TOWNS) - replace fixed hanging notes buffer with a dynamic chain
(This works around issues with some Indy 3 sound tracks. These tracks seem to be broken, since they have way too long duration values for some notes which would fill up the event buffer rather quickly. I tested with the UNZ emulator to be sure that this is an issue which also occurs with the original driver.)
Diffstat (limited to 'audio')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.cpp79
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.h9
2 files changed, 46 insertions, 42 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
index 79df54dbee..aea714f68f 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
@@ -26,7 +26,7 @@
#include "common/textconsole.h"
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), _timedEvents(0), _timedEventsCount(0),
+ _partConfig_transpose(0), _musicPos(0), _musicStart(0), _playing(false), _savedEventsChain(0),
_tempoControlMode(0), _timerSetting(0), _tempoMode1PulseCounter(0), _parseToBar(0), _tempoMode1UpdateF8(0), _loop(false),
_endOfTrack(false), _paused(false), _musicTrackSize(0) {
_drivers[0] = _eupDriver = new EuphonyDriver(mixer, this);
@@ -39,7 +39,12 @@ EuphonyPlayer::~EuphonyPlayer() {
for (int i = 0; i < 3; i++)
delete _drivers[i];
- delete[] _timedEvents;
+ while (_savedEventsChain) {
+ SavedEvent *evt = _savedEventsChain;
+ _savedEventsChain = _savedEventsChain->next;
+ delete evt;
+ }
+
delete[] _partConfig_enable;
delete[] _partConfig_type;
delete[] _partConfig_ordr;
@@ -61,15 +66,18 @@ bool EuphonyPlayer::init() {
if (!_drivers[0] || !_drivers[1])
return false;
- delete[] _timedEvents;
+ while (_savedEventsChain) {
+ SavedEvent *evt = _savedEventsChain;
+ _savedEventsChain = _savedEventsChain->next;
+ delete evt;
+ }
+
delete[] _partConfig_enable;
delete[] _partConfig_type;
delete[] _partConfig_ordr;
delete[] _partConfig_volume;
delete[] _partConfig_transpose;
- _timedEvents = new TimedEvent[64];
-
_partConfig_enable = new uint8[32];
_partConfig_type = new uint8[32];
_partConfig_ordr = new uint8[32];
@@ -195,8 +203,11 @@ void EuphonyPlayer::reset() {
resetPartConfig();
- memset(_timedEvents, 0, 64 * sizeof(TimedEvent));
- _timedEventsCount = 0;
+ while (_savedEventsChain) {
+ SavedEvent *evt = _savedEventsChain;
+ _savedEventsChain = _savedEventsChain->next;
+ delete evt;
+ }
_playing = _endOfTrack = _paused = _loop = false;
_tempoMode1UpdateF8 = 0;
@@ -297,7 +308,7 @@ void EuphonyPlayer::updateParser() {
}
void EuphonyPlayer::updateCheckEot() {
- if (!_endOfTrack || _timedEventsCount)
+ if (!_endOfTrack || _savedEventsChain)
return;
stop();
}
@@ -357,30 +368,35 @@ void EuphonyPlayer::proceedToNextEvent() {
}
void EuphonyPlayer::updateHangingNotes() {
- TimedEvent *e = _timedEvents;
- for (int i = _timedEventsCount; i; e++) {
- if (e->evt == 0)
- continue;
+ SavedEvent *l = 0;
+ SavedEvent *e = _savedEventsChain;
+
+ while (e) {
if (--e->len) {
- --i;
+ l = e;
+ e = e->next;
continue;
}
+
+ SavedEvent *n = e->next;
+ if (l)
+ l->next = n;
+ if (_savedEventsChain == e)
+ _savedEventsChain = n;
+
sendNoteEvent(e->type, e->evt, e->note, e->velo);
- e->evt = 0;
- --i;
- --_timedEventsCount;
+ delete e;
+
+ e = n;
}
}
void EuphonyPlayer::clearHangingNotes() {
- TimedEvent *e = _timedEvents;
- for (int i = _timedEventsCount; i; e++) {
- if (e->evt == 0)
- continue;
+ while (_savedEventsChain) {
+ SavedEvent *e = _savedEventsChain;
+ _savedEventsChain = _savedEventsChain->next;
sendNoteEvent(e->type, e->evt, e->note, e->velo);
- e->evt = 0;
- --i;
- --_timedEventsCount;
+ delete e;
}
}
@@ -439,22 +455,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);
- int i = 0;
- for (; i < 64; i++) {
- if (_timedEvents[i].evt == 0)
- break;
- }
-
- if (i == 64) {
- sendNoteEvent(type, evt, note, velo);
- } else {
- _timedEvents[i].evt = evt;
- _timedEvents[i].type = type;
- _timedEvents[i].note = note;
- _timedEvents[i].velo = velo;
- _timedEvents[i].len = len ? len : 1;
- _timedEventsCount++;
- }
+ _savedEventsChain = new SavedEvent(evt, type, note, velo, len ? len : 1, _savedEventsChain);
return false;
}
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h
index 68c5041117..76aa153a37 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.h
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h
@@ -181,14 +181,17 @@ private:
int8 *_partConfig_volume;
int8 *_partConfig_transpose;
- struct TimedEvent {
+ 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) {}
uint8 evt;
uint8 type;
uint8 note;
uint8 velo;
uint16 len;
- } *_timedEvents;
- int _timedEventsCount;
+ SavedEvent *next;
+ };
+
+ SavedEvent *_savedEventsChain;
uint8 _defaultBarLength;
uint8 _barLength;