[Scummvm-cvs-logs] CVS: scummvm/backends/midi emumidi.h,NONE,1.1 adlib.cpp,1.60,1.61 ym2612.cpp,1.26,1.27

Max Horn fingolfin at users.sourceforge.net
Sun Oct 17 10:50:04 CEST 2004


Update of /cvsroot/scummvm/scummvm/backends/midi
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24057

Modified Files:
	adlib.cpp ym2612.cpp 
Added Files:
	emumidi.h 
Log Message:
added MidiDriver_Emulated base class used by the adlib & ym2612 midi 'drivers'

--- NEW FILE: emumidi.h ---
/* 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: /cvsroot/scummvm/scummvm/backends/midi/emumidi.h,v 1.1 2004/10/17 17:49:45 fingolfin Exp $
 */

#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; }
};

Index: adlib.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/adlib.cpp,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- adlib.cpp	17 Oct 2004 17:12:35 -0000	1.60
+++ adlib.cpp	17 Oct 2004 17:49:45 -0000	1.61
@@ -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 @@
 //
 ////////////////////////////////////////
 
-class MidiDriver_ADLIB : public AudioStream, public MidiDriver {
+class MidiDriver_ADLIB : public MidiDriver_Emulated {
 	friend class AdlibPart;
 	friend class AdlibPercussionChannel;
 
@@ -554,51 +548,30 @@
 	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 @@
 // 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 @@
 int MidiDriver_ADLIB::open() {
 	if (_isOpen)
 		return MERR_ALREADY_OPEN;
-	_isOpen = true;
+
+	MidiDriver_Emulated::open();
 
 	int i;
 	AdlibVoice *voice;
@@ -869,8 +838,6 @@
 	adlib_write(0xBD, 0x00);
 	create_lookup_table();
 
-	_samples_per_tick = (getRate() << FIXP_SHIFT) / BASE_FREQ;
-
 	_mixer->setupPremix(this);
 
 	return 0;
@@ -879,6 +846,10 @@
 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 @@
 			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 @@
 	_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::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() {

Index: ym2612.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/ym2612.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- ym2612.cpp	17 Oct 2004 17:12:35 -0000	1.26
+++ ym2612.cpp	17 Oct 2004 17:49:45 -0000	1.27
@@ -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 @@
 	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 @@
 	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 @@
 //
 ////////////////////////////////////////
 
-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 @@
 int MidiDriver_YM2612::open() {
 	if (_isOpen)
 		return MERR_ALREADY_OPEN;
+
+	MidiDriver_Emulated::open();
+
 	_mixer->setupPremix(this);
-	_isOpen = true;
 	return 0;
 }
 
@@ -783,11 +753,6 @@
 	_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::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) {





More information about the Scummvm-git-logs mailing list