diff options
| author | Max Horn | 2004-10-17 17:49:45 +0000 | 
|---|---|---|
| committer | Max Horn | 2004-10-17 17:49:45 +0000 | 
| commit | 267144e69c09862c230506ec1550b6b1ac8437f3 (patch) | |
| tree | 0115f95a43c141541c2f05bf209a9d9cfe1db910 /backends/midi | |
| parent | 649eb19a3ed45dbea8b2796a57190ff18534fffe (diff) | |
| download | scummvm-rg350-267144e69c09862c230506ec1550b6b1ac8437f3.tar.gz scummvm-rg350-267144e69c09862c230506ec1550b6b1ac8437f3.tar.bz2 scummvm-rg350-267144e69c09862c230506ec1550b6b1ac8437f3.zip  | |
added MidiDriver_Emulated base class used by the adlib & ym2612 midi 'drivers'
svn-id: r15589
Diffstat (limited to 'backends/midi')
| -rw-r--r-- | backends/midi/adlib.cpp | 83 | ||||
| -rw-r--r-- | backends/midi/emumidi.h | 96 | ||||
| -rw-r--r-- | backends/midi/ym2612.cpp | 68 | 
3 files changed, 119 insertions, 128 deletions
diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp index f702ee6532..48c62e1f5d 100644 --- a/backends/midi/adlib.cpp +++ b/backends/midi/adlib.cpp @@ -18,15 +18,9 @@   * $Header$   */ -#include "stdafx.h" -#include "sound/audiostream.h" -#include "sound/mididrv.h" -#include "sound/fmopl.h" -#include "sound/mixer.h" +#include "emumidi.h"  #include "common/util.h" - -#define BASE_FREQ 250 -#define FIXP_SHIFT 16 +#include "sound/fmopl.h"  #ifdef DEBUG_ADLIB  static int tick; @@ -544,7 +538,7 @@ static void create_lookup_table() {  //  //////////////////////////////////////// -class MidiDriver_ADLIB : public AudioStream, public MidiDriver { +class MidiDriver_ADLIB : public MidiDriver_Emulated {  	friend class AdlibPart;  	friend class AdlibPercussionChannel; @@ -554,51 +548,30 @@ public:  	int open();  	void close();  	void send(uint32 b); -	void send (byte channel, uint32 b); // Supports higher than channel 15 +	void send(byte channel, uint32 b); // Supports higher than channel 15  	uint32 property(int prop, uint32 param);  	void setPitchBendRange(byte channel, uint range);   	void sysEx_customInstrument(byte channel, uint32 type, byte *instr); -	void setTimerCallback(void *timer_param, Timer::TimerProc timer_proc); -	uint32 getBaseTempo() { -		return 1000000 / BASE_FREQ; -	} -  	MidiChannel *allocateChannel();  	MidiChannel *getPercussionChannel() { return &_percussion; } // Percussion partially supported +  	// AudioStream API -	int readBuffer(int16 *buffer, const int numSamples) { -		memset(buffer, 0, 2 * numSamples);	// FIXME -		generate_samples(buffer, numSamples); -		return numSamples; -	} -	int16 read() { -		error("ProcInputStream::read not supported"); -	}  	bool isStereo() const { return false; } -	bool endOfData() const { return false; } -	  	int getRate() const { return _mixer->getOutputRate(); }  private: -	bool _isOpen;  	bool _game_SmallHeader;  	FM_OPL *_opl;  	byte *_adlib_reg_cache; -	SoundMixer *_mixer; - -	Timer::TimerProc _timer_proc; -	void *_timer_param;  	int _adlib_timer_counter;  	uint16 channel_table_2[9];  	int _voice_index; -	int _next_tick; -	int _samples_per_tick;  	int _timer_p;  	int _timer_q;  	uint16 curnote_table[9]; @@ -820,20 +793,15 @@ void AdlibPercussionChannel::noteOn(byte note, byte velocity) {  // MidiDriver method implementations  MidiDriver_ADLIB::MidiDriver_ADLIB(SoundMixer *mixer)  -	: _mixer(mixer) { +	: MidiDriver_Emulated(mixer) {  	uint i; -	_isOpen = false;  	_game_SmallHeader = false;  	_adlib_reg_cache = 0; -	_timer_proc = 0; -	_timer_param = 0; -  	_adlib_timer_counter = 0;  	_voice_index = 0; -	_next_tick = 0;  	for (i = 0; i < ARRAYSIZE(curnote_table); ++i) {  		curnote_table[i] = 0;  	} @@ -849,7 +817,8 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(SoundMixer *mixer)  int MidiDriver_ADLIB::open() {  	if (_isOpen)  		return MERR_ALREADY_OPEN; -	_isOpen = true; + +	MidiDriver_Emulated::open();  	int i;  	AdlibVoice *voice; @@ -869,8 +838,6 @@ int MidiDriver_ADLIB::open() {  	adlib_write(0xBD, 0x00);  	create_lookup_table(); -	_samples_per_tick = (getRate() << FIXP_SHIFT) / BASE_FREQ; -  	_mixer->setupPremix(this);  	return 0; @@ -879,6 +846,10 @@ int MidiDriver_ADLIB::open() {  void MidiDriver_ADLIB::close() {  	if (!_isOpen)  		return; +	_isOpen = false; + +	// Detach the premix callback handler +	_mixer->setupPremix(0);  	uint i;  	for (i = 0; i < ARRAYSIZE(_voices); ++i) { @@ -886,15 +857,10 @@ void MidiDriver_ADLIB::close() {  			mc_off(&_voices [i]);  	} -	// Detach the premix callback handler -	_mixer->setupPremix(0); -  	// Turn off the OPL emulation  //	YM3812Shutdown();  	free(_adlib_reg_cache); - -	_isOpen = false;  }  void MidiDriver_ADLIB::send (uint32 b) { @@ -976,11 +942,6 @@ void MidiDriver_ADLIB::sysEx_customInstrument(byte channel, uint32 type, byte *i  	_parts[channel].sysEx_customInstrument(type, instr);  } -void MidiDriver_ADLIB::setTimerCallback(void *timer_param, Timer::TimerProc timer_proc) { -	_timer_proc = timer_proc; -	_timer_param = timer_param; -} -  MidiChannel *MidiDriver_ADLIB::allocateChannel() {  	AdlibPart *part;  	uint i; @@ -1013,24 +974,8 @@ void MidiDriver_ADLIB::adlib_write(byte port, byte value) {  }  void MidiDriver_ADLIB::generate_samples(int16 *data, int len) { -	int step; - -	do { -		step = len; -		if (step > (_next_tick >> FIXP_SHIFT)) -			step = (_next_tick >> FIXP_SHIFT); -		YM3812UpdateOne(_opl, data, step); - -		_next_tick -= step << FIXP_SHIFT; -		if (!(_next_tick >> FIXP_SHIFT)) { -			if (_timer_proc) -				(*_timer_proc)(_timer_param); -			on_timer(); -			_next_tick += _samples_per_tick; -		} -		data += step; -		len -= step; -	} while (len); +	memset(data, 0, sizeof(int16) * len); +	YM3812UpdateOne(_opl, data, len);  }  void MidiDriver_ADLIB::on_timer() { diff --git a/backends/midi/emumidi.h b/backends/midi/emumidi.h new file mode 100644 index 0000000000..e5daa40647 --- /dev/null +++ b/backends/midi/emumidi.h @@ -0,0 +1,96 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2004 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + * $Header$ + */ + +#include "stdafx.h" +#include "sound/audiostream.h" +#include "sound/mididrv.h" +#include "sound/mixer.h" + +#define BASE_FREQ 250 +#define FIXP_SHIFT 16 + +class MidiDriver_Emulated : public AudioStream, public MidiDriver { +protected: +	bool _isOpen; +	SoundMixer *_mixer; + +private: +	Timer::TimerProc _timer_proc; +	void *_timer_param; + +	int _next_tick; +	int _samples_per_tick; + +protected: +	virtual void generate_samples(int16 *buf, int len) = 0; + +public: +	MidiDriver_Emulated(SoundMixer *mixer) : _mixer(mixer) { +		_isOpen = false; +	 +		_timer_proc = 0; +		_timer_param = 0; +	 +		_next_tick = 0; +		_samples_per_tick = 0; +	} + +	int open() { +		_isOpen = true; +		_samples_per_tick = (getRate() << FIXP_SHIFT) / BASE_FREQ; +	} + +	void setTimerCallback(void *timer_param, Timer::TimerProc timer_proc) { +		_timer_proc = timer_proc; +		_timer_param = timer_param; +	} + +	uint32 getBaseTempo() { return 1000000 / BASE_FREQ; } + + +	// AudioStream API +	int readBuffer(int16 *data, const int numSamples) { +		const int stereoFactor = isStereo() ? 2 : 1; +		int len = numSamples / stereoFactor; +		int step; +	 +		do { +			step = len; +			if (step > (_next_tick >> FIXP_SHIFT)) +				step = (_next_tick >> FIXP_SHIFT); +			generate_samples(data, step); +	 +			_next_tick -= step << FIXP_SHIFT; +			if (!(_next_tick >> FIXP_SHIFT)) { +				if (_timer_proc) +					(*_timer_proc)(_timer_param); +				_next_tick += _samples_per_tick; +			} +			data += step * stereoFactor; +			len -= step; +		} while (len); + +		return numSamples; +	} +	int16 read() { +		error("ProcInputStream::read not supported"); +	} +	bool endOfData() const { return false; } +}; diff --git a/backends/midi/ym2612.cpp b/backends/midi/ym2612.cpp index 50f786b011..6f0e6aeece 100644 --- a/backends/midi/ym2612.cpp +++ b/backends/midi/ym2612.cpp @@ -22,11 +22,7 @@   * $Header$   */ -#include "stdafx.h" -#include "common/util.h" -#include "sound/audiostream.h" -#include "sound/mididrv.h" -#include "sound/mixer.h" +#include "emumidi.h"  #include <math.h> @@ -37,9 +33,6 @@  //  //////////////////////////////////////// -#define BASE_FREQ 250 -#define FIXP_SHIFT  16 -  static int *sintbl = 0;  static int *powtbl = 0;  static int *frequencyTable = 0; @@ -158,20 +151,13 @@ public:  	void sysEx_customInstrument(uint32 type, byte *instr);  }; -class MidiDriver_YM2612 : public AudioStream, public MidiDriver { +class MidiDriver_YM2612 : public MidiDriver_Emulated {  protected:  	MidiChannel_YM2612 *_channel[16];  	int _next_voice;  	int _volume; -	bool _isOpen; -	SoundMixer *_mixer; -	Timer::TimerProc _timer_proc; -	void *_timer_param; -	int _next_tick; -	int _samples_per_tick; -  protected:  	static void createLookupTables();  	void nextTick(int16 *buf1, int buflen); @@ -193,25 +179,12 @@ public:  	void setPitchBendRange(byte channel, uint range) { }  	void sysEx(byte *msg, uint16 length); -	void setTimerCallback(void *timer_param, Timer::TimerProc timer_proc); -	uint32 getBaseTempo() { return 1000000 / BASE_FREQ; } -  	MidiChannel *allocateChannel() { return 0; }  	MidiChannel *getPercussionChannel() { return 0; }  	// AudioStream API -	int readBuffer(int16 *buffer, const int numSamples) { -		memset(buffer, 0, 2 * numSamples);	// FIXME -		generate_samples(buffer, numSamples / 2); -		return numSamples; -	} -	int16 read() { -		error("ProcInputStream::read not supported"); -	}  	bool isStereo() const { return true; } -	bool endOfData() const { return false; } -	  	int getRate() const { return _mixer->getOutputRate(); }  }; @@ -736,13 +709,8 @@ void MidiChannel_YM2612::rate(uint16 r) {  //  //////////////////////////////////////// -MidiDriver_YM2612::MidiDriver_YM2612(SoundMixer *mixer) : -_mixer(mixer) { -	_isOpen = false; -	_timer_proc = 0; -	_timer_param = 0; -	_next_tick = 0; -	_samples_per_tick = (getRate() << FIXP_SHIFT) / BASE_FREQ; +MidiDriver_YM2612::MidiDriver_YM2612(SoundMixer *mixer) +	: MidiDriver_Emulated(mixer) {  	_next_voice = 0;  	createLookupTables(); @@ -769,8 +737,10 @@ MidiDriver_YM2612::~MidiDriver_YM2612() {  int MidiDriver_YM2612::open() {  	if (_isOpen)  		return MERR_ALREADY_OPEN; + +	MidiDriver_Emulated::open(); +  	_mixer->setupPremix(this); -	_isOpen = true;  	return 0;  } @@ -783,11 +753,6 @@ void MidiDriver_YM2612::close() {  	_mixer->setupPremix(0);  } -void MidiDriver_YM2612::setTimerCallback(void *timer_param, Timer::TimerProc timer_proc) { -	_timer_proc = timer_proc; -	_timer_param = timer_param; -} -  void MidiDriver_YM2612::send(uint32 b) {  	send(b & 0xF, b & 0xFFFFFFF0);  } @@ -838,23 +803,8 @@ void MidiDriver_YM2612::sysEx(byte *msg, uint16 length) {  }  void MidiDriver_YM2612::generate_samples(int16 *data, int len) { -	int step; - -	do { -		step = len; -		if (step > (_next_tick >> FIXP_SHIFT)) -			step = (_next_tick >> FIXP_SHIFT); -		nextTick(data, step); - -		_next_tick -= step << FIXP_SHIFT; -		if (!(_next_tick >> FIXP_SHIFT)) { -			if (_timer_proc) -				(*_timer_proc)(_timer_param); -			_next_tick += _samples_per_tick; -		} -		data += step * 2; // Stereo means * 2 -		len -= step; -	} while (len); +	memset(data, 0, 2 * sizeof(int16) * len); +	nextTick(data, len);  }  void MidiDriver_YM2612::nextTick(int16 *buf1, int buflen) {  | 
