diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 20 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_euphony.cpp | 22 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_euphony.h | 6 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 185 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.h | 15 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 12 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 2 |
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 |