aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorathrxx2011-05-07 16:44:43 +0200
committerWillem Jan Palenstijn2011-05-17 20:36:31 +0200
commit8fb5906117c67f4265e868b33aa343698bceac73 (patch)
tree2681724f8da5efa21092f89981431a1acf446ade /audio
parent90a300d86cf25ddaa15b8080f3551076a4f6e3ee (diff)
downloadscummvm-rg350-8fb5906117c67f4265e868b33aa343698bceac73.tar.gz
scummvm-rg350-8fb5906117c67f4265e868b33aa343698bceac73.tar.bz2
scummvm-rg350-8fb5906117c67f4265e868b33aa343698bceac73.zip
FM-TOWNS AUDIO: Some midi code fixes and some renaming
Diffstat (limited to 'audio')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.cpp20
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.cpp22
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.h6
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.cpp185
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.h15
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp12
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h2
7 files changed, 148 insertions, 114 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 51c2000514..6679e65cd2 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -163,8 +163,10 @@ private:
int intf_fmReset(va_list &args);
int intf_setOutputVolume(va_list &args);
int intf_resetOutputVolume(va_list &args);
- int intf_updateOutputVolume(va_list &args);
+ int intf_setOutputMute(va_list &args);
int intf_cdaToggle(va_list &args);
+ int intf_getOutputVolume(va_list &args);
+ int intf_getOutputMute(va_list &args);
int intf_pcmUpdateEnvelopeGenerator(va_list &args);
int intf_notImpl(va_list &args);
@@ -344,13 +346,13 @@ TownsAudioInterfaceIntern::TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsA
// 68
INTCB(resetOutputVolume),
INTCB(notImpl),
- INTCB(updateOutputVolume),
+ INTCB(setOutputMute),
INTCB(notImpl),
// 72
INTCB(notImpl),
INTCB(cdaToggle),
- INTCB(notImpl),
- INTCB(notImpl),
+ INTCB(getOutputVolume),
+ INTCB(getOutputMute),
// 76
INTCB(notImpl),
INTCB(notImpl),
@@ -947,7 +949,7 @@ int TownsAudioInterfaceIntern::intf_resetOutputVolume(va_list &args) {
return 0;
}
-int TownsAudioInterfaceIntern::intf_updateOutputVolume(va_list &args) {
+int TownsAudioInterfaceIntern::intf_setOutputMute(va_list &args) {
int flags = va_arg(args, int);
_outputMuteFlags = flags & 3;
updateOutputVolume();
@@ -960,6 +962,14 @@ int TownsAudioInterfaceIntern::intf_cdaToggle(va_list &args) {
return 0;
}
+int TownsAudioInterfaceIntern::intf_getOutputVolume (va_list &args) {
+ return 0;
+}
+
+int TownsAudioInterfaceIntern::intf_getOutputMute (va_list &args) {
+ return 0;
+}
+
int TownsAudioInterfaceIntern::intf_pcmUpdateEnvelopeGenerator(va_list &args) {
for (int i = 0; i < 8; i++)
pcmUpdateEnvelopeGenerator(i);
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
index cb6cfc53f3..f161228876 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp
@@ -27,7 +27,7 @@
TownsEuphonyDriver::TownsEuphonyDriver(Audio::Mixer *mixer) : _activeChannels(0), _sustainChannels(0),
_assignedChannels(0), _paraCount(0), _command(0), _tEnable(0), _tMode(0), _tOrdr(0), _tLevel(0),
- _tDetune(0), _musicPos(0), _musicStart(0), _playing(false), _eventBuffer(0), _bufferedEventsCount(0),
+ _tTranspose(0), _musicPos(0), _musicStart(0), _playing(false), _eventBuffer(0), _bufferedEventsCount(0),
_tempoControlMode(0) {
_para[0] = _para[1] = 0;
_intf = new TownsAudioInterface(mixer, this);
@@ -44,7 +44,7 @@ TownsEuphonyDriver::~TownsEuphonyDriver() {
delete[] _tMode;
delete[] _tOrdr;
delete[] _tLevel;
- delete[] _tDetune;
+ delete[] _tTranspose;
}
bool TownsEuphonyDriver::init() {
@@ -59,7 +59,7 @@ bool TownsEuphonyDriver::init() {
delete[] _tMode;
delete[] _tOrdr;
delete[] _tLevel;
- delete[] _tDetune;
+ delete[] _tTranspose;
_activeChannels = new int8[16];
_sustainChannels = new int8[16];
@@ -70,7 +70,7 @@ bool TownsEuphonyDriver::init() {
_tMode = new uint8[32];
_tOrdr = new uint8[32];
_tLevel = new int8[32];
- _tDetune = new int8[32];
+ _tTranspose = new int8[32];
reset();
@@ -250,11 +250,11 @@ int TownsEuphonyDriver::configChan_adjustVolume(int tableEntry, int val) {
return 0;
}
-int TownsEuphonyDriver::configChan_setDetune(int tableEntry, int val) {
+int TownsEuphonyDriver::configChan_setTranspose(int tableEntry, int val) {
if (tableEntry > 31)
return 3;
if (val <= 40)
- _tDetune[tableEntry] = (int8)(val & 0xff);
+ _tTranspose[tableEntry] = (int8)(val & 0xff);
return 0;
}
@@ -325,7 +325,7 @@ void TownsEuphonyDriver::resetTables() {
for (int i = 0; i < 32; i++)
_tOrdr[i] = i & 0x0f;
memset(_tLevel, 0, 32);
- memset(_tDetune, 0, 32);
+ memset(_tTranspose, 0, 32);
}
void TownsEuphonyDriver::resetTempo() {
@@ -672,7 +672,7 @@ bool TownsEuphonyDriver::evtSetupNote() {
uint8 velo = _musicPos[5];
sendEvent(mode, evt);
- sendEvent(mode, applyDetune(note));
+ sendEvent(mode, applyTranspose(note));
sendEvent(mode, applyVolumeAdjust(velo));
jumpNextLoop();
@@ -712,7 +712,7 @@ bool TownsEuphonyDriver::evtPolyphonicAftertouch() {
uint8 mode = _tMode[_musicPos[1]];
sendEvent(mode, evt);
- sendEvent(mode, applyDetune(_musicPos[4]));
+ sendEvent(mode, applyTranspose(_musicPos[4]));
sendEvent(mode, _musicPos[5]);
return false;
@@ -780,8 +780,8 @@ bool TownsEuphonyDriver::evtModeOrdrChange() {
return false;
}
-uint8 TownsEuphonyDriver::applyDetune(uint8 in) {
- int out = _tDetune[_musicPos[1]];
+uint8 TownsEuphonyDriver::applyTranspose(uint8 in) {
+ int out = _tTranspose[_musicPos[1]];
if (!out)
return in;
out += (in & 0x7f);
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h
index ae36d1232b..6b30bfb7f5 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.h
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h
@@ -59,7 +59,7 @@ public:
int configChan_setMode(int tableEntry, int val);
int configChan_remap(int tableEntry, int val);
int configChan_adjustVolume(int tableEntry, int val);
- int configChan_setDetune(int tableEntry, int val);
+ int configChan_setTranspose(int tableEntry, int val);
int assignChannel(int chan, int tableEntry);
@@ -111,7 +111,7 @@ private:
return false;
}
- uint8 applyDetune(uint8 in);
+ uint8 applyTranspose(uint8 in);
uint8 applyVolumeAdjust(uint8 in);
void sendNoteOff();
@@ -136,7 +136,7 @@ private:
uint8 *_tMode;
uint8 *_tOrdr;
int8 *_tLevel;
- int8 *_tDetune;
+ int8 *_tTranspose;
struct DlEvent {
uint8 evt;
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
index ff14bb158a..ac6a89fbc0 100644
--- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
@@ -24,6 +24,7 @@
#include "audio/softsynth/fmtowns_pc98/towns_midi.h"
#include "common/textconsole.h"
+#include "common/system.h"
class TownsMidiOutputChannel {
friend class TownsMidiInputChannel;
@@ -33,8 +34,8 @@ public:
void noteOn(uint8 msb, uint16 lsb);
void noteOnPitchBend(uint8 msb, uint16 lsb);
- void setupProgram(const uint8 *data, uint8 vol1, uint8 vol2);
- void setupEffects(int index, uint8 c, const uint8 *effectData);
+ void setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara);
+ void setupEffects(int index, uint8 flags, const uint8 *effectData);
void setModWheel(uint8 value);
void connect(TownsMidiInputChannel *chan);
@@ -52,26 +53,26 @@ public:
private:
struct StateA {
uint8 numLoop;
- uint32 fld_1;
+ int32 fld_1;
int32 duration;
- int32 fld_9;
- int16 effectState;
+ uint32 fld_9;
+ int32 effectState;
uint8 fld_11;
uint8 ar1[4];
uint8 ar2[4];
int8 modWheelSensitivity;
int8 modWheelState;
- uint8 fld_1c;
- uint32 fld_1d;
+ uint8 modWheelLast;
+ uint16 fld_1d;
uint32 fld_21;
- uint32 fld_25;
+ int32 fld_25;
int8 dir;
uint32 fld_2a;
uint32 fld_2e;
} *_stateA;
struct StateB {
- int16 inc;
+ int32 inc;
uint8 type;
uint8 useModWheel;
uint8 fld_6;
@@ -99,7 +100,7 @@ private:
uint8 _carrierTl;
uint8 _modulatorTl;
uint8 _sustainNoteOff;
- int32 _duration;
+ int16 _duration;
uint16 _freq;
int16 _freqAdjust;
@@ -237,7 +238,7 @@ void TownsMidiOutputChannel::noteOnPitchBend(uint8 msb, uint16 lsb) {
keyOnSetFreq(_freq + _freqAdjust);
}
-void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 vol1, uint8 vol2) {
+void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara) {
// This driver uses only 2 operators and 2 algorithms (algorithm 5 and 7),
// since it is just a modified AdLib driver. It also uses AdLib programs.
// There are no FM-TOWNS specific programs. This is the reason for the FM-TOWNS
@@ -248,10 +249,10 @@ void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 vol1, uint8 v
uint8 chan = _chanMap[_chan];
uint8 mulAmsFms1 = _driver->_chanState[chan].mulAmsFms = data[0];
- uint8 tl1 = _driver->_chanState[chan].tl = (data[1] | 0x3f) - vol1;
+ uint8 tl1 = _driver->_chanState[chan].tl = (data[1] | 0x3f) - mLevelPara;
uint8 attDec1 = _driver->_chanState[chan].attDec = ~data[2];
uint8 sus1 = _driver->_chanState[chan].sus = ~data[3];
- uint8 unk1 = _driver->_chanState[chan].unk2 = data[4];
+ _driver->_chanState[chan].unk2 = data[4];
chan += 3;
out(0x30, mul[mulAmsFms1 & 0x0f]);
@@ -262,10 +263,10 @@ void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 vol1, uint8 v
out(0x80, sus1);
uint8 mulAmsFms2 = _driver->_chanState[chan].mulAmsFms = data[5];
- uint8 tl2 = _driver->_chanState[chan].tl = (data[6] | 0x3f) - vol2;
+ uint8 tl2 = _driver->_chanState[chan].tl = (data[6] | 0x3f) - tLevelPara;
uint8 attDec2 = _driver->_chanState[chan].attDec = ~data[7];
uint8 sus2 = _driver->_chanState[chan].sus = ~data[8];
- uint8 unk2 = _driver->_chanState[chan].unk2 = data[9];
+ _driver->_chanState[chan].unk2 = data[9];
uint8 mul2 = mul[mulAmsFms2 & 0x0f];
tl2 = (tl2 & 0x3f) + 15;
@@ -290,7 +291,7 @@ void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 vol1, uint8 v
out(0xb4, 0xc0 | ((t & 0x80) >> 3) | ((t & 0x40) >> 5));
}
-void TownsMidiOutputChannel::setupEffects(int index, uint8 c, const uint8 *effectData) {
+void TownsMidiOutputChannel::setupEffects(int index, uint8 flags, const uint8 *effectData) {
uint16 maxVal[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F };
uint8 effectType[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 };
@@ -298,11 +299,11 @@ void TownsMidiOutputChannel::setupEffects(int index, uint8 c, const uint8 *effec
StateB *b = &_stateB[index];
b->inc = 0;
- b->useModWheel = c & 0x40;
- a->fld_11 = c & 0x20;
- b->fld_6 = c & 0x10;
- b->type = effectType[c & 0x0f];
- a->fld_9 = maxVal[c & 0x0f];
+ b->useModWheel = flags & 0x40;
+ a->fld_11 = flags & 0x20;
+ b->fld_6 = flags & 0x10;
+ b->type = effectType[flags & 0x0f];
+ a->fld_9 = maxVal[flags & 0x0f];
a->modWheelSensitivity = 31;
a->modWheelState = b->useModWheel ? _midi->_modWheel >> 2 : 31;
@@ -368,8 +369,9 @@ bool TownsMidiOutputChannel::update() {
if (_duration) {
_duration -= 17;
- if (_duration <=0) {
+ if (_duration <= 0) {
disconnect();
+ //_duration = 0;
return true;
}
}
@@ -415,7 +417,7 @@ int16 TownsMidiOutputChannel::getEffectState(uint8 type) {
void TownsMidiOutputChannel::initEffect(StateA *a, const uint8 *effectData) {
a->numLoop = 1;
a->fld_1 = 0;
- a->fld_1c = 31;
+ a->modWheelLast = 31;
a->duration = effectData[0] * 63;
a->ar1[0] = effectData[1];
a->ar1[1] = effectData[3];
@@ -475,16 +477,17 @@ int TownsMidiOutputChannel::updateEffectOuter(StateA *a, StateB *b) {
int retFlags = 0;
- if (t != a->fld_1 || a->modWheelState != a->fld_1c) {
+ if (t != a->fld_1 || a->modWheelState != a->modWheelLast) {
a->fld_1 = t;
- a->fld_1c = a->modWheelState;
+ a->modWheelLast = a->modWheelState;
t = lookupVolume(t, a->modWheelState);
if (t != b->inc)
b->inc = t;
retFlags |= 1;
}
- if (--a->fld_21 != 0)
+ --a->fld_21;/*???*/
+ if (a->fld_21 != 0)
return retFlags;
if (++a->numLoop > 4) {
@@ -504,7 +507,7 @@ int TownsMidiOutputChannel::updateEffectOuter(StateA *a, StateB *b) {
void TownsMidiOutputChannel::updateEffect(StateA *a) {
uint8 c = a->numLoop - 1;
uint16 v = a->ar1[c];
- int32 e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]];
+ int32 e = _effectData[_driver->_chanEffectLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]];
if (v & 0x80)
e = _driver->randomValue(e);
@@ -515,7 +518,7 @@ void TownsMidiOutputChannel::updateEffect(StateA *a) {
a->fld_1d = a->fld_21 = e;
int32 d = 0;
- if (c + 1 != 3) {
+ if (c != 2) {
v = a->ar2[c];
e = lookupVolume(a->fld_9, (v & 0x7f) - 31);
@@ -533,7 +536,8 @@ void TownsMidiOutputChannel::updateEffect(StateA *a) {
}
a->fld_25 = d / a->fld_1d;
- a->dir = d < 0 ? -1 : 1;
+ a->dir = (d < 0) ? -1 : 1;
+ d *= a->dir;
a->fld_2a = d % a->fld_1d;
a->fld_2e = 0;
}
@@ -550,14 +554,14 @@ int TownsMidiOutputChannel::lookupVolume(int a, int b) {
if (b < 0) {
if (a < 0)
- return _driver->_chanOutputLevel[(-a << 5) - b];
+ return _driver->_chanEffectLevel[((-a) << 5) - b];
else
- return -_driver->_chanOutputLevel[(a << 5) - b];
+ return -_driver->_chanEffectLevel[(a << 5) - b];
} else {
if (a < 0)
- return -_driver->_chanOutputLevel[(-a << 5) + b];
+ return -_driver->_chanEffectLevel[((-a) << 5) + b];
else
- return _driver->_chanOutputLevel[(-a << 5) + b];
+ return _driver->_chanEffectLevel[((-a) << 5) + b];
}
}
@@ -713,15 +717,15 @@ void TownsMidiInputChannel::noteOn(byte note, byte velocity) {
oc->_sustainNoteOff = 0;
oc->_duration = _instrument[29] * 63;
- oc->_modulatorTl = (_instrument[1] & 0x3f) + _driver->_chanOutputLevel[((velocity >> 1) << 5) + (_instrument[4] >> 2)];
+ oc->_modulatorTl = (_instrument[1] & 0x3f) + _driver->_chanEffectLevel[((velocity >> 1) << 5) + (_instrument[4] >> 2)];
if (oc->_modulatorTl > 63)
oc->_modulatorTl = 63;
- oc->_carrierTl = (_instrument[6] & 0x3f) + _driver->_chanOutputLevel[((velocity >> 1) << 5) + (_instrument[9] >> 2)];
+ oc->_carrierTl = (_instrument[6] & 0x3f) + _driver->_chanEffectLevel[((velocity >> 1) << 5) + (_instrument[9] >> 2)];
if (oc->_carrierTl > 63)
oc->_carrierTl = 63;
- oc->setupProgram(_instrument, oc->_fld_c == 1 ? _programAdjustLevel[_driver->_chanOutputLevel[(_tl >> 2) + (oc->_modulatorTl << 5)]] : oc->_modulatorTl, _programAdjustLevel[_driver->_chanOutputLevel[(_tl >> 2) + (oc->_carrierTl << 5)]]);
+ oc->setupProgram(_instrument, oc->_fld_c == 1 ? _programAdjustLevel[_driver->_chanEffectLevel[(_tl >> 2) + (oc->_modulatorTl << 5)]] : oc->_modulatorTl, _programAdjustLevel[_driver->_chanEffectLevel[(_tl >> 2) + (oc->_carrierTl << 5)]]);
oc->noteOn(note + _transpose, _freqLSB);
if (_instrument[11] & 0x80)
@@ -838,6 +842,19 @@ const uint8 TownsMidiInputChannel::_programAdjustLevel[] = {
MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerProcPara(0), _tickCounter1(0), _tickCounter2(0), _curChan(0), _rand(1), _open(false) {
_intf = new TownsAudioInterface(mixer, this);
+}
+
+MidiDriver_TOWNS::~MidiDriver_TOWNS() {
+ close();
+ delete _intf;
+}
+
+int MidiDriver_TOWNS::open() {
+ if (_open)
+ return MERR_ALREADY_OPEN;
+
+ if (!_intf->init())
+ return MERR_CANNOT_CONNECT;
_channels = new TownsMidiInputChannel*[32];
for (int i = 0; i < 32; i++)
@@ -849,38 +866,13 @@ MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerP
_chanState = new TownsMidiChanState[32];
- _chanOutputLevel = new uint8[2048];
+ _chanEffectLevel = new uint8[2048];
for (int i = 0; i < 64; i++) {
for (int ii = 0; ii < 32; ii++)
- _chanOutputLevel[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff;
+ _chanEffectLevel[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff;
}
for (int i = 0; i < 64; i++)
- _chanOutputLevel[i << 5] = 0;
-}
-
-MidiDriver_TOWNS::~MidiDriver_TOWNS() {
- close();
- delete _intf;
- setTimerCallback(0, 0);
-
- for (int i = 0; i < 32; i++)
- delete _channels[i];
- delete[] _channels;
-
- for (int i = 0; i < 6; i++)
- delete _out[i];
- delete[] _out;
-
- delete[] _chanState;
- delete[] _chanOutputLevel;
-}
-
-int MidiDriver_TOWNS::open() {
- if (_open)
- return MERR_ALREADY_OPEN;
-
- if (!_intf->init())
- return MERR_CANNOT_CONNECT;
+ _chanEffectLevel[i << 5] = 0;
_intf->callback(0);
@@ -897,10 +889,38 @@ int MidiDriver_TOWNS::open() {
}
void MidiDriver_TOWNS::close() {
+ if (!_open)
+ return;
+
_open = false;
+
+ setTimerCallback(0, 0);
+ g_system->delayMillis(20);
+
+ if (_channels) {
+ for (int i = 0; i < 32; i++)
+ delete _channels[i];
+ delete[] _channels;
+ }
+ _channels = 0;
+
+ if (_out) {
+ for (int i = 0; i < 6; i++)
+ delete _out[i];
+ delete[] _out;
+ }
+ _out = 0;
+
+ delete[] _chanState;
+ _chanState = 0;
+ delete[] _chanEffectLevel;
+ _chanEffectLevel = 0;
}
void MidiDriver_TOWNS::send(uint32 b) {
+ if (!_open)
+ return;
+
byte param2 = (b >> 16) & 0xFF;
byte param1 = (b >> 8) & 0xFF;
byte cmd = b & 0xF0;
@@ -945,6 +965,9 @@ uint32 MidiDriver_TOWNS::getBaseTempo() {
}
MidiChannel *MidiDriver_TOWNS::allocateChannel() {
+ if (!_open)
+ return 0;
+
for (int i = 0; i < 32; ++i) {
TownsMidiInputChannel *chan = _channels[i];
if (chan->allocate())
@@ -978,6 +1001,23 @@ void MidiDriver_TOWNS::timerCallback(int timerId) {
}
}
+void MidiDriver_TOWNS::updateParser() {
+ if (_timerProc)
+ _timerProc(_timerProcPara);
+}
+
+void MidiDriver_TOWNS::updateOutputChannels() {
+ _tickCounter2 += 10000;
+ while (_tickCounter2 >= 16667) {
+ _tickCounter2 -= 16667;
+ for (int i = 0; i < 6; i++) {
+ TownsMidiOutputChannel *oc = _out[i];
+ if (oc->update())
+ return;
+ }
+ }
+}
+
TownsMidiOutputChannel *MidiDriver_TOWNS::allocateOutputChannel(int pri) {
TownsMidiOutputChannel *res = 0;
@@ -1001,23 +1041,6 @@ TownsMidiOutputChannel *MidiDriver_TOWNS::allocateOutputChannel(int pri) {
return res;
}
-void MidiDriver_TOWNS::updateParser() {
- if (_timerProc)
- _timerProc(_timerProcPara);
-}
-
-void MidiDriver_TOWNS::updateOutputChannels() {
- _tickCounter2 += 10000;
- while (_tickCounter2 >= 16667) {
- _tickCounter2 -= 16667;
- for (int i = 0; i < 6; i++) {
- TownsMidiOutputChannel *oc = _out[i];
- if (oc->update())
- return;
- }
- }
-}
-
int MidiDriver_TOWNS::randomValue(int para) {
_rand = (_rand & 1) ? (_rand >> 1) ^ 0xb8 : (_rand >> 1);
return (_rand * para) >> 8;
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.h b/audio/softsynth/fmtowns_pc98/towns_midi.h
index a525226959..5164e04708 100644
--- a/audio/softsynth/fmtowns_pc98/towns_midi.h
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.h
@@ -43,25 +43,22 @@ public:
int open();
bool isOpen() const { return _open; }
void close();
+
void send(uint32 b);
- //virtual uint32 property(int prop, uint32 param) { return 0; }
- //virtual void sysEx(const byte *msg, uint16 length) { }
- //virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { }
- //virtual void metaEvent(byte type, byte *data, uint16 length) { }
+
void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
+
uint32 getBaseTempo();
MidiChannel *allocateChannel();
MidiChannel *getPercussionChannel();
void timerCallback(int timerId);
- TownsAudioInterface *intf() { return _intf; }
-
private:
- TownsMidiOutputChannel *allocateOutputChannel(int pri);
-
void updateParser();
void updateOutputChannels();
+
+ TownsMidiOutputChannel *allocateOutputChannel(int pri);
int randomValue(int para);
@@ -81,7 +78,7 @@ private:
bool _open;
- uint8 *_chanOutputLevel;
+ uint8 *_chanEffectLevel;
};
#endif
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 9412538685..263986ec0c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -837,7 +837,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :
_hasPercussion(type == kType86 ? true : false),
_oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0),
_rtt(type == kTypeTowns ? 0x514767 : 0x5B8D80), _baserate(55125.0f / (float)mixer->getOutputRate()),
- _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _regProtectionFlag(false), _externLock(0), _ready(false) {
+ _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _regProtectionFlag(false), _lock(0), _ready(false) {
memset(&_timers[0], 0, sizeof(ChipTimer));
memset(&_timers[1], 0, sizeof(ChipTimer));
@@ -1121,8 +1121,9 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
int32 *tmpStart = tmp;
memset(tmp, 0, sizeof(int32) * numSamples);
int32 samplesLeft = numSamples >> 1;
+ _lock |= 0x10000;
- while (_ready && !_externLock && samplesLeft) {
+ while (_ready && !(_lock & 0xffff) && samplesLeft) {
int32 render = samplesLeft;
for (int i = 0; i < 2; i++) {
@@ -1171,6 +1172,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
tmp += (render << 1);
}
+ _lock &= ~0x10000;
delete[] tmpStart;
return numSamples;
@@ -1178,6 +1180,8 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
void TownsPC98_FmSynth::deinit() {
_ready = false;
+ while (_lock)
+ g_system->delayMillis(20);
_mixer->stopHandle(_soundHandle);
_timers[0].cb = _timers[1].cb = &TownsPC98_FmSynth::idleTimerCallback;
}
@@ -1214,12 +1218,12 @@ void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB
void TownsPC98_FmSynth::lock() {
_mutex.lock();
- _externLock++;
+ _lock++;
}
void TownsPC98_FmSynth::unlock() {
_mutex.unlock();
- _externLock--;
+ _lock--;
}
void TownsPC98_FmSynth::generateTables() {
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
index f1494b6ba7..cbf856c78c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
@@ -182,7 +182,7 @@ private:
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
- int _externLock;
+ int _lock;
Common::Mutex _mutex;
#ifndef DISABLE_PC98_RHYTHM_CHANNEL