diff options
| author | athrxx | 2011-05-05 23:02:01 +0200 | 
|---|---|---|
| committer | Willem Jan Palenstijn | 2011-05-17 20:36:31 +0200 | 
| commit | 90a300d86cf25ddaa15b8080f3551076a4f6e3ee (patch) | |
| tree | 2ef888828fb8dbfed86816262ac3178b14bf8bd1 | |
| parent | 88896117da13a9222b7bf27bb2890705cf48d5ef (diff) | |
| download | scummvm-rg350-90a300d86cf25ddaa15b8080f3551076a4f6e3ee.tar.gz scummvm-rg350-90a300d86cf25ddaa15b8080f3551076a4f6e3ee.tar.bz2 scummvm-rg350-90a300d86cf25ddaa15b8080f3551076a4f6e3ee.zip | |
FM-TOWNS AUDIO: Improve thread safety
| -rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 13 | ||||
| -rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 32 | ||||
| -rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp | 10 | ||||
| -rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 30 | ||||
| -rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 8 | 
5 files changed, 59 insertions, 34 deletions
| diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp index 33606128bf..51c2000514 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp @@ -411,13 +411,13 @@ bool TownsAudioInterfaceIntern::checkPluginDriver(TownsAudioInterfacePluginDrive  	if (_refCount <= 1)  		return true; -	Common::StackLock lock(_mutex); -  	if (_drv) {  		if (driver && driver != _drv)  			return false;  	} else { +		lock();  		_drv = driver; +		unlock();  	}  	return true; @@ -467,8 +467,11 @@ int TownsAudioInterfaceIntern::processCommand(int command, va_list &args) {  	if (command < 0 || command > 81)  		return 4; -	Common::StackLock lock(_mutex); -	return (this->*_intfOpcodes[command])(args); +	lock(); +	int res = (this->*_intfOpcodes[command])(args); +	unlock(); + +	return res;  }  void TownsAudioInterfaceIntern::setMusicVolume(int volume) { @@ -539,13 +542,11 @@ void TownsAudioInterfaceIntern::nextTickEx(int32 *buffer, uint32 bufferSize) {  }  void TownsAudioInterfaceIntern::timerCallbackA() { -	Common::StackLock lock(_mutex);  	if (_drv && _ready)  		_drv->timerCallback(0);  }  void TownsAudioInterfaceIntern::timerCallbackB() { -	Common::StackLock lock(_mutex);  	if (_ready) {  		if (_drv)  			_drv->timerCallback(1); diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp index 7072149d2d..ff14bb158a 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -52,7 +52,7 @@ public:  private:  	struct StateA {  		uint8 numLoop; -		int32 fld_1; +		uint32 fld_1;  		int32 duration;  		int32 fld_9;  		int16 effectState; @@ -60,10 +60,10 @@ private:  		uint8 ar1[4];  		uint8 ar2[4];  		int8 modWheelSensitivity; -		uint8 modWheelState; +		int8 modWheelState;  		uint8 fld_1c;  		uint32 fld_1d; -		int32 fld_21; +		uint32 fld_21;  		uint32 fld_25;  		int8 dir;  		uint32 fld_2a; @@ -71,14 +71,14 @@ private:  	} *_stateA;  	struct StateB { -		int8 inc; +		int16 inc;  		uint8 type;  		uint8 useModWheel;  		uint8 fld_6;  		StateA *a;  	} *_stateB; -	uint16 getEffectState(uint8 type); +	int16 getEffectState(uint8 type);  	void initEffect(StateA *a, const uint8 *effectData);  	void updateEffectOuter3(StateA *a, StateB *b);  	int updateEffectOuter(StateA *a, StateB *b); @@ -159,7 +159,7 @@ private:  	int8 _transpose;  	uint8 _fld_1f;  	int8 _detune; -	uint8 _modWheel; +	int8 _modWheel;  	uint8 _sustain;  	uint8 _pitchBendFactor;  	int16 _pitchBend; @@ -392,7 +392,7 @@ int TownsMidiOutputChannel::checkPriority(int pri) {  	return kHighPriority;  } -uint16 TownsMidiOutputChannel::getEffectState(uint8 type) { +int16 TownsMidiOutputChannel::getEffectState(uint8 type) {  	uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan);  	if (type == 28) @@ -404,7 +404,7 @@ uint16 TownsMidiOutputChannel::getEffectState(uint8 type) {  	else if (type > 12)  		type -= 13; -	uint32 res = 0; +	int32 res = 0;  	uint8 cs = (_driver->_chanState[chan].get(_effectDefs[type * 4] >> 5) & _effectDefs[type * 4 + 2]) >> _effectDefs[type * 4 + 1];  	if (_effectDefs[type * 4 + 3])  		res = _effectDefs[type * 4 + 3] - cs; @@ -422,7 +422,7 @@ void TownsMidiOutputChannel::initEffect(StateA *a, const uint8 *effectData) {  	a->ar1[2] = effectData[5];  	a->ar1[3] = effectData[6];  	a->ar2[0] = effectData[2]; -	a->ar2[1] = effectData[3]; +	a->ar2[1] = effectData[4];  	a->ar2[2] = 0;  	a->ar2[3] = effectData[7];  	updateEffect(a); @@ -434,10 +434,10 @@ void TownsMidiOutputChannel::updateEffectOuter3(StateA *a, StateB *b) {  	if (f & 1) {  		switch (b->type) {  		case 0: -			_carrierTl = (a->effectState & 0xff) + b->inc; /*???*/ +			_carrierTl = a->effectState + b->inc; /*???*/  			break;  		case 13: -			_modulatorTl = (a->effectState & 0xff) + b->inc; /*???*/ +			_modulatorTl = a->effectState + b->inc; /*???*/  			break;  		case 30:  			b->a->modWheelState = b->inc; @@ -504,7 +504,7 @@ int TownsMidiOutputChannel::updateEffectOuter(StateA *a, StateB *b) {  void TownsMidiOutputChannel::updateEffect(StateA *a) {  	uint8 c = a->numLoop - 1;  	uint16 v = a->ar1[c]; -	int e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]]; +	int32 e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]];  	if (v & 0x80)  		e = _driver->randomValue(e); @@ -545,7 +545,7 @@ int TownsMidiOutputChannel::lookupVolume(int a, int b) {  	if (b == 31)  		return a; -	if (a > 63) +	if (a > 63 || a < -63)  		return ((a + 1) * b) >> 5;  	if (b < 0) { @@ -760,6 +760,10 @@ void TownsMidiInputChannel::controlChange(byte control, byte value) {  	case 64:  		controlSustain(value);  		break; +	case 123: +		while (_outChan) +			_outChan->disconnect(); +		break;  	default:  		break;  	} @@ -793,7 +797,7 @@ void TownsMidiInputChannel::controlVolume(byte value) {  	uint16 v2 = value;  	if (_chanIndex != 16) {  		_ctrlVolume = value; -		v2 = value; +		v2 = _player->getEffectiveVolume();  	}  	_tl = (v1 * v2) >> 7;*/ diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp index 289cc95863..e35da91cbb 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -1145,7 +1145,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) {  	reset(); -	Common::StackLock lock(_mutex); +	lock();  	uint8 *src_a = _trackPtr = _musicBuffer = data;  	for (uint8 i = 0; i < 3; i++) { @@ -1176,6 +1176,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) {  	_finishedChannelsFlag = _finishedSSGFlag = _finishedRhythmFlag = 0;  	_musicPlaying = (loadPaused ? false : true); +	unlock();  }  void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { @@ -1194,16 +1195,17 @@ void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) {  		return;  	} -	Common::StackLock lock(_mutex); +	lock();  	_sfxData = _sfxBuffer = data;  	_sfxOffsets[0] = READ_LE_UINT16(&_sfxData[(trackNum << 2)]);  	_sfxOffsets[1] = READ_LE_UINT16(&_sfxData[(trackNum << 2) + 2]);  	_sfxPlaying = true;  	_finishedSfxFlag = 0; +	unlock();  }  void TownsPC98_AudioDriver::reset() { -	Common::StackLock lock(_mutex); +	lock();  	_musicPlaying = false;  	_sfxPlaying = false; @@ -1230,13 +1232,13 @@ void TownsPC98_AudioDriver::reset() {  	if (_rhythmChannel)  		_rhythmChannel->reset();  #endif +	unlock();  }  void TownsPC98_AudioDriver::fadeStep() {  	if (!_musicPlaying)  		return; -	Common::StackLock lock(_mutex);  	for (int j = 0; j < _numChan; j++) {  		if (_updateChannelsFlag & _channels[j]->_idFlag)  			_channels[j]->fadeStep(); diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 57ab8d9e1f..9412538685 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -837,8 +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), _ready(false) { +	_volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _regProtectionFlag(false), _externLock(0), _ready(false) {  	memset(&_timers[0], 0, sizeof(ChipTimer));  	memset(&_timers[1], 0, sizeof(ChipTimer)); @@ -931,9 +930,9 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  	if (_regProtectionFlag || !_ready)  		return; -	static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; +	lock(); -	Common::StackLock lock(_mutex); +	static const uint8 oprOrdr[] = { 0, 2, 1, 3 };  	uint8 h = regAddress & 0xf0;  	uint8 l = (regAddress & 0x0f); @@ -1081,6 +1080,7 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  		if (l == 0) {  			c->frqTemp = (c->frqTemp & 0xff00) | value;  			c->updateEnvelopeParameters = true; +			c->fmIndex = (c->frqTemp >> 4 & 0x7f);  			for (int i = 0; i < 4; i++)  				co[i]->frequency(c->frqTemp);  		} else if (l == 4) { @@ -1112,18 +1112,17 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  	default:  		warning("TownsPC98_FmSynth: UNKNOWN ADDRESS %d", regAddress);  	} +	unlock();  }  int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { -	Common::StackLock lock(_mutex); -  	memset(buffer, 0, sizeof(int16) * numSamples);  	int32 *tmp = new int32[numSamples];  	int32 *tmpStart = tmp;  	memset(tmp, 0, sizeof(int32) * numSamples);  	int32 samplesLeft = numSamples >> 1; -	while (_ready && samplesLeft) { +	while (_ready && !_externLock && samplesLeft) {  		int32 render = samplesLeft;  		for (int i = 0; i < 2; i++) { @@ -1173,6 +1172,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {  	}  	delete[] tmpStart; +  	return numSamples;  } @@ -1187,7 +1187,7 @@ uint8 TownsPC98_FmSynth::readSSGStatus() {  }  void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { -	Common::StackLock lock(_mutex); +	lock();  	_volumeA = CLIP<uint16>(volA, 0, Audio::Mixer::kMaxMixerVolume);  	_volumeB = CLIP<uint16>(volB, 0, Audio::Mixer::kMaxMixerVolume);  	if (_ssg) @@ -1196,10 +1196,11 @@ void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) {  	if (_prc)  		_prc->setVolumeIntern(_volumeA, _volumeB);  #endif +	unlock();  }  void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { -	Common::StackLock lock(_mutex); +	lock();  	_volMaskA = channelMaskA;  	_volMaskB = channelMaskB;  	if (_ssg) @@ -1208,6 +1209,17 @@ void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB  	if (_prc)  		_prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG));  #endif +	unlock(); +} + +void TownsPC98_FmSynth::lock() { +	_mutex.lock(); +	_externLock++; +} + +void  TownsPC98_FmSynth::unlock() { +	_mutex.unlock(); +	_externLock--;  }  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 5edd1a3ab8..f1494b6ba7 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -102,11 +102,13 @@ protected:  	void setVolumeIntern(int volA, int volB);  	void setVolumeChannelMasks(int channelMaskA, int channelMaskB); +	void lock(); +	void unlock(); +  	const int _numChan;  	const int _numSSG;  	const bool _hasPercussion; -	Common::Mutex _mutex;  private:  	void generateTables();  	void nextTick(int32 *buffer, uint32 bufferSize); @@ -124,6 +126,7 @@ private:  		}  		uint16 frqTemp; +		uint8 fmIndex;  		bool enableLeft;  		bool enableRight;  		bool updateEnvelopeParameters; @@ -179,6 +182,9 @@ private:  	Audio::Mixer *_mixer;  	Audio::SoundHandle _soundHandle; +	int _externLock; +	Common::Mutex _mutex; +  #ifndef DISABLE_PC98_RHYTHM_CHANNEL  	static const uint8 _percussionData[];  #endif | 
