diff options
| -rw-r--r-- | backends/midi/ym2612.cpp | 141 | ||||
| -rw-r--r-- | scumm/midiparser_eup.cpp | 26 | 
2 files changed, 68 insertions, 99 deletions
diff --git a/backends/midi/ym2612.cpp b/backends/midi/ym2612.cpp index fcdfa26f25..69bfef8cc9 100644 --- a/backends/midi/ym2612.cpp +++ b/backends/midi/ym2612.cpp @@ -97,9 +97,7 @@ public:  class Voice2612 {  public: -	MidiChannel_YM2612 *_owner; -	Voice2612 *prev, *next; -	bool _in_use; +	Voice2612 *next;  	uint16 _rate;  protected: @@ -129,18 +127,17 @@ public:  class MidiChannel_YM2612 : public MidiChannel {  protected: -	MidiDriver_YM2612 *_owner;  	uint16 _rate; -	byte _instrument[48];  	Voice2612 *_voices; +	Voice2612 *_next_voice;  public: -	void removeVoice (Voice2612 *voice); +	void removeAllVoices();  	void nextTick(int *outbuf, int buflen);  	void rate(uint16 r);  public: -	MidiChannel_YM2612 (MidiDriver_YM2612 *owner); +	MidiChannel_YM2612();  	virtual ~MidiChannel_YM2612();  	// MidiChannel interface @@ -160,7 +157,6 @@ public:  class MidiDriver_YM2612 : public MidiDriver {  protected:  	MidiChannel_YM2612 *_channel[16]; -	Voice2612 *_voices[32];  	int _next_voice;  	int _volume; @@ -183,9 +179,6 @@ protected:  	static void premix_proc(void *param, int16 *buf, uint len);  public: -	Voice2612 *allocateVoice(); - -public:  	MidiDriver_YM2612(SoundMixer *mixer);  	virtual ~MidiDriver_YM2612(); @@ -318,7 +311,7 @@ void Operator2612::frequency(int freq) {  	r = _specifiedReleaseRate;  	if (r != 0) { -		r = r * 2 + 1;		// このタイミングで良いのかわからん +		r = r * 2 + 1;		// (Translated) I cannot know whether the timing is a good choice or not  		r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale));  		// KS による補正はあるらしい。赤p.206 では記述されてないけど。  		if (r >= 64) @@ -435,9 +428,7 @@ void Operator2612::nextTick(const int *phasebuf, int *outbuf, int buflen) {  ////////////////////////////////////////  Voice2612::Voice2612() { -	_owner = 0; -	prev = next = 0; -	_in_use = false; +	next = 0;  	_control7 = 127;  	_note = 40;  	_frequency = 440; @@ -513,16 +504,8 @@ void Voice2612::setInstrument(byte const *instrument) {  }  void Voice2612::nextTick(int *outbuf, int buflen) { -	if (!_in_use || _velocity == 0) +	if (_velocity == 0)  		return; -	if (!_opr[0]->inUse() && !_opr[1]->inUse() && -	    !_opr[2]->inUse() && !_opr[3]->inUse()) -	{ -		_in_use = false; -		if (_owner) -			_owner->removeVoice (this); -		return; -	}  	if (_buflen < buflen) {  		free(_buffer); @@ -593,7 +576,6 @@ void Voice2612::noteOn(int n, int onVelo) {  	_note = n;  	velocity(onVelo);  	recalculateFrequency(); -	_in_use = true;  	int i;  	for (i = 0; i < ARRAYSIZE(_opr); i++)  		_opr[i]->keyOn(); @@ -645,64 +627,71 @@ void Voice2612::recalculateFrequency() {  //  //////////////////////////////////////// -MidiChannel_YM2612::MidiChannel_YM2612 (MidiDriver_YM2612 *owner) { -//	_voice = new Voice2612(); -	_owner = owner; +MidiChannel_YM2612::MidiChannel_YM2612() {  	_voices = 0; +	_next_voice = 0;  }  MidiChannel_YM2612::~MidiChannel_YM2612() { -//	delete _voice; +	removeAllVoices();  } -void MidiChannel_YM2612::noteOn(byte note, byte onVelo) { -	Voice2612 *voice = _owner->allocateVoice(); -	if (!voice) +void MidiChannel_YM2612::removeAllVoices() { +	if (!_voices)  		return; -	voice->_owner = this; -	voice->_rate = _rate; -	voice->next = _voices; -	voice->prev = 0; -	if (_voices) -		_voices->prev = voice; -	_voices = voice; -	voice->setInstrument (_instrument); -	voice->noteOn(note, onVelo); +	Voice2612 *last, *voice = _voices; +	for (; voice; voice = last) { +		last = voice->next; +		delete voice; +	} +	_voices = _next_voice = 0;  } -void MidiChannel_YM2612::noteOff(byte note) { -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) { -		if (voice->noteOff(note)) -			removeVoice(voice); -	} +void MidiChannel_YM2612::noteOn(byte note, byte onVelo) { +	if (!_voices) +		return; +	_next_voice = _next_voice ? _next_voice : _voices; +	_next_voice->noteOn(note, onVelo); +	_next_voice = _next_voice->next;  } -void MidiChannel_YM2612::removeVoice(Voice2612 *voice) { -	// We ASSUME that the voice belongs to us. -	voice->_owner = 0; -	if (voice->next) -		voice->next->prev = voice->prev; -	if (voice->prev) -		voice->prev->next = voice->next; -	else -		_voices = voice->next; +void MidiChannel_YM2612::noteOff(byte note) { +	if (!_voices) +		return; +	if (_next_voice == _voices) +		_next_voice = 0; +	Voice2612 *voice = _next_voice; +	do { +		if (!voice) +			voice = _voices; +		if (voice->noteOff(note)) { +			_next_voice = voice; +			break; +		} +		voice = voice->next; +	} while (voice != _next_voice);  }  void MidiChannel_YM2612::controlChange(byte control, byte value) { -  // いいのかこれで? -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) -		voice->setControlParameter(control, value); +	// いいのかこれで? +	if (control == 121) { +		// Reset controller +		removeAllVoices(); +	} else { +		Voice2612 *voice = _voices; +		for (; voice; voice = voice->next) +			voice->setControlParameter(control, value); +	}  }  void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, byte *fmInst) {  	if (type != 'EUP ')  		return; -	memcpy (_instrument, fmInst, 48); -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) -		voice->setInstrument(fmInst); +	Voice2612 *voice = new Voice2612; +	voice->next = _voices; +	_voices = voice; +	voice->_rate = _rate; +	voice->setInstrument(fmInst);  }  void MidiChannel_YM2612::pitchBend(int16 value) { @@ -744,10 +733,8 @@ _mixer(mixer)  	createLookupTables();  	_volume = 256;  	int i; -	for (i = 0; i < ARRAYSIZE(_voices); i++) -		_voices[i] = new Voice2612;  	for (i = 0; i < ARRAYSIZE(_channel); i++) -		_channel[i] = new MidiChannel_YM2612 (this); +		_channel[i] = new MidiChannel_YM2612;  	rate(_mixer->getOutputRate());  } @@ -755,8 +742,6 @@ MidiDriver_YM2612::~MidiDriver_YM2612() {  	int i;  	for (i = 0; i < ARRAYSIZE(_channel); i++)  		delete _channel[i]; -	for (i = 0; i < ARRAYSIZE(_voices); i++) -		delete _voices[i];  	delete sintbl;  	delete powtbl;  	delete frequencyTable; @@ -865,8 +850,8 @@ void MidiDriver_YM2612::nextTick(int16 *buf1, int buflen) {  	int *buf0 = (int *)buf1;  	int i; -	for (i = 0; i < ARRAYSIZE(_voices); i++) -		_voices[i]->nextTick(buf0, buflen); +	for (i = 0; i < ARRAYSIZE(_channel); i++) +		_channel[i]->nextTick(buf0, buflen);  	for (i = 0; i < buflen; ++i)  		buf1[i*2+1] = buf1[i*2] = ((buf0[i] * volume()) >> 10) & 0xffff; @@ -951,20 +936,6 @@ void MidiDriver_YM2612::createLookupTables() {  	}  } -Voice2612 *MidiDriver_YM2612::allocateVoice() { -	_next_voice %= ARRAYSIZE(_voices); -	int oldStart = _next_voice; -	do { -		if (!_voices[_next_voice++]->_in_use) -			return _voices[_next_voice-1]; -		_next_voice %= ARRAYSIZE(_voices); -	} while (_next_voice != oldStart); -	Voice2612 *voice = _voices[_next_voice++]; -	if (voice->_owner) -		voice->_owner->removeVoice (voice); -	return voice; -} -  ////////////////////////////////////////  //  // MidiDriver_YM2612 factory diff --git a/scumm/midiparser_eup.cpp b/scumm/midiparser_eup.cpp index eeca9fbb6d..c8c6f95fdc 100644 --- a/scumm/midiparser_eup.cpp +++ b/scumm/midiparser_eup.cpp @@ -33,7 +33,7 @@ namespace Scumm {  class MidiParser_EUP : public MidiParser {  protected:  	byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel # -	byte _channel_instr[16]; +	byte *_instr_to_channel;  	struct {  		byte *enable;  		int8 *channel; @@ -71,20 +71,21 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) {  	// program changes to get a reasonable "one-size-  	// fits-all" sound until we actually support the  	// FM synthesis capabilities of FM Towns. -	for (; _presend < 32; ++_presend) { -		if (_channel_instr[_presend >> 1] == 0xFF) continue; +	for (; _presend < 12; ++_presend) { +		if (_instr_to_channel[_presend>>1] >= 16) +			continue;  		info.start = pos;  		info.delta = 0;  		if (_presend & 1) { -			info.event = 0xB0; -			info.basic.param1 = 7; -			info.basic.param2 = 127; -		} else { -			byte *data = &_instruments[_channel_instr[_presend >> 1]][0]; -			data[1] = _presend >> 1; +			byte *data = &_instruments[_presend>>1][0]; +			data[1] = _instr_to_channel[_presend>>1];  			info.event = 0xF0;  			info.ext.data = data;  			info.length = 48; +		} else { +			info.event = 0xB0 | (_presend >> 1); +			info.basic.param1 = 121; +			info.basic.param2 = 0;  		}  		++_presend;  		return; @@ -186,11 +187,8 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {  	pos += 32;  	pos += 8; // Unknown bytes -	for (i = 0; i < 16; ++i) -		_channel_instr[i] = 0xFF; -	for (i = 0; i < 6; ++i) -		_channel_instr[pos[i]] = i; -	pos += 6; // Instrument-to-channel mapping (not supported yet) +	_instr_to_channel = pos; // Instrument-to-channel mapping +	pos += 6;  	pos += 4; // Skip the music size for now.  	pos++;    // Unknown byte  	byte tempo = *pos++;  | 
