[Scummvm-cvs-logs] CVS: scummvm/sound midistreamer.cpp,1.1,1.2

Jamieson Christian jamieson630 at projects.sourceforge.net
Mon Nov 18 01:10:04 CET 2002


Update of /cvsroot/scummvm/scummvm/sound
In directory sc8-pr-cvs1:/tmp/cvs-serv467/scummvm/sound

Modified Files:
	midistreamer.cpp 
Log Message:
Added support for volume and pause control to Simon music.
Note that MidiStreamer is now used as a streaming wrapper
for ALL MidiDriver types, even those that natively support
streaming. This is because MidiStreamer supports a hybrid
of streamed and non-streamed MIDI, which is necessary to
support interactive events.

Index: midistreamer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sound/midistreamer.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- midistreamer.cpp	13 Nov 2002 00:24:48 -0000	1.1
+++ midistreamer.cpp	18 Nov 2002 09:08:42 -0000	1.2
@@ -1,181 +1,182 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001/2002 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 "mididrv.h"
-#include "engine.h"
-#include "common/util.h"
-
-class MidiStreamer : public MidiDriver {
-private:
-	MidiDriver *_target;
-	StreamCallback *_stream_proc;
-	void *_stream_param;
-	int _mode;
-	bool _paused;
-
-	MidiEvent _events [64];
-	int _event_count;
-	int _event_index;
-
-	long _tempo;
-	uint16 _ticks_per_beat;
-	long _delay;
-
-	volatile bool _active;
-
-	uint32 property(int prop, uint32 param);
-	static int timer_thread (void *param);
-	void on_timer (void);
-
-public:
-	MidiStreamer (MidiDriver *target);
-
-	int open(int mode);
-	void close();
-	void send(uint32 b) { _target->send (b); }
-	void pause(bool p) { _paused = p; }
-	void set_stream_callback(void *param, StreamCallback *sc);
-	void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); }
-};
-
-MidiStreamer::MidiStreamer (MidiDriver *target) :
-_target (target),
-_stream_proc (0),
-_stream_param (0),
-_mode (0),
-_paused (false),
-_event_count (0),
-_event_index (0),
-_tempo (500000), // 120 BPM = 500,000 microseconds between each beat
-_ticks_per_beat (96),
-_delay (0),
-_active (false)
-{ }
-
-void MidiStreamer::set_stream_callback (void *param, StreamCallback *sc)
-{
-	_stream_param = param;
-	_stream_proc = sc;
-
-	if (_mode) {
-		_event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events));
-		_event_index = 0;
-	}
-}
-
-int MidiStreamer::timer_thread (void *param) {
-	MidiStreamer *mid = (MidiStreamer *) param;
-	int old_time, cur_time;
-	while (mid->_mode) {
-		while (!mid->_stream_proc);
-		old_time = g_system->get_msecs();
-		while (!mid->_paused) {
-			g_system->delay_msecs(10);
-
-			cur_time = g_system->get_msecs();
-			while (old_time < cur_time) {
-				old_time += 10;
-				mid->on_timer();
-			}
-		}
-	}
-
-	// Turn off all notes on all channels,
-	// just to catch anything still playing.
-	int i;
-	for (i = 0; i < 16; ++i)
-		mid->send ((0x7B << 8) | 0xB0 | i);
-	mid->_active = false;
-	return 0;
-}
-
-void MidiStreamer::on_timer()
-{
-	_delay += 10000;
-	while (true) {
-		if (_event_index >= _event_count) {
-			_event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events));
-			_event_index = 0;
-		}
-
-		if (!_event_count)
-			return;
-
-		MidiEvent *ev = &_events [_event_index];
-		if (_delay < _tempo * (long) ev->delta / (long) _ticks_per_beat)
-			return;
-		_delay -= _tempo * ev->delta / _ticks_per_beat;
-		if ((ev->event >> 24) != ME_TEMPO) {
-			_target->send (ev->event);
-		} else {
-			_tempo = ev->event & 0xFFFFFF;
-		}
-
-		++_event_index;
-	} // end while
-}
-
-int MidiStreamer::open (int mode)
-{
-	if (_mode != 0)
-		close();
-
-	int res = _target->open (MidiDriver::MO_SIMPLE);
-	if (res && res != MERR_ALREADY_OPEN)
-		return res;
-
-	// Wait for existing timer thread to shut down.
-	while (_active);
-
-	_event_index = _event_count = _delay = 0;
-	_mode = mode;
-	_paused = false;
-	_active = true;
-
-	if (mode == MO_SIMPLE)
-		return 0;
-
-	g_system->create_thread (timer_thread, this);
-	return 0;
-}
-
-void MidiStreamer::close()
-{
-	if (!_mode)
-		return;
-	_mode = 0;
-	_paused = true;
-}
-
-uint32 MidiStreamer::property (int prop, uint32 param)
-{
-	switch (prop) {
-
-	// 16-bit time division according to standard midi specification
-	case PROP_TIMEDIV:
-		_ticks_per_beat = (uint16)param;
-		return 1;
-	}
-
-	return 0;
-}
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001/2002 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 "mididrv.h"
+#include "engine.h"
+#include "common/util.h"
+
+class MidiStreamer : public MidiDriver {
+private:
+	MidiDriver *_target;
+	StreamCallback *_stream_proc;
+	void *_stream_param;
+	volatile int _mode;
+	volatile bool _paused;
+
+	MidiEvent _events [64];
+	int _event_count;
+	int _event_index;
+
+	long _tempo;
+	uint16 _ticks_per_beat;
+	long _delay;
+
+	volatile bool _active;
+
+	uint32 property(int prop, uint32 param);
+	static int timer_thread (void *param);
+	void on_timer (void);
+
+public:
+	MidiStreamer (MidiDriver *target);
+
+	int open(int mode);
+	void close();
+	void send(uint32 b) { if (_mode) _target->send (b); }
+	void pause(bool p) { _paused = p; }
+	void set_stream_callback(void *param, StreamCallback *sc);
+	void setPitchBendRange (byte channel, uint range) { _target->setPitchBendRange (channel, range); }
+};
+
+MidiStreamer::MidiStreamer (MidiDriver *target) :
+_target (target),
+_stream_proc (0),
+_stream_param (0),
+_mode (0),
+_paused (false),
+_event_count (0),
+_event_index (0),
+_tempo (500000), // 120 BPM = 500,000 microseconds between each beat
+_ticks_per_beat (96),
+_delay (0),
+_active (false)
+{ }
+
+void MidiStreamer::set_stream_callback (void *param, StreamCallback *sc)
+{
+	_stream_param = param;
+	_stream_proc = sc;
+
+	if (_mode) {
+		_event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events));
+		_event_index = 0;
+	}
+}
+
+int MidiStreamer::timer_thread (void *param) {
+	MidiStreamer *mid = (MidiStreamer *) param;
+	int old_time, cur_time;
+	while (mid->_mode) {
+		g_system->delay_msecs (100);
+		while (!mid->_stream_proc);
+		old_time = g_system->get_msecs();
+		while (!mid->_paused) {
+			g_system->delay_msecs(10);
+
+			cur_time = g_system->get_msecs();
+			while (old_time < cur_time) {
+				old_time += 10;
+				mid->on_timer();
+			}
+		}
+	}
+
+	// Turn off all notes on all channels,
+	// just to catch anything still playing.
+	int i;
+	for (i = 0; i < 16; ++i)
+		mid->_target->send ((0x7B << 8) | 0xB0 | i);
+	mid->_active = false;
+	return 0;
+}
+
+void MidiStreamer::on_timer()
+{
+	_delay += 10000;
+	while (true) {
+		if (_event_index >= _event_count) {
+			_event_count = _stream_proc (_stream_param, _events, ARRAYSIZE (_events));
+			_event_index = 0;
+		}
+
+		if (!_event_count)
+			return;
+
+		MidiEvent *ev = &_events [_event_index];
+		if (_delay < _tempo * (long) ev->delta / (long) _ticks_per_beat)
+			return;
+		_delay -= _tempo * ev->delta / _ticks_per_beat;
+		if ((ev->event >> 24) != ME_TEMPO) {
+			_target->send (ev->event);
+		} else {
+			_tempo = ev->event & 0xFFFFFF;
+		}
+
+		++_event_index;
+	} // end while
+}
+
+int MidiStreamer::open (int mode)
+{
+	if (_mode != 0)
+		close();
+
+	int res = _target->open (MidiDriver::MO_SIMPLE);
+	if (res && res != MERR_ALREADY_OPEN)
+		return res;
+
+	// Wait for existing timer thread to shut down.
+	while (_active);
+
+	_event_index = _event_count = _delay = 0;
+	_mode = mode;
+	_paused = false;
+	_active = true;
+
+	if (mode == MO_SIMPLE)
+		return 0;
+
+	g_system->create_thread (timer_thread, this);
+	return 0;
+}
+
+void MidiStreamer::close()
+{
+	if (!_mode)
+		return;
+	_mode = 0;
+	_paused = true;
+}
+
+uint32 MidiStreamer::property (int prop, uint32 param)
+{
+	switch (prop) {
+
+	// 16-bit time division according to standard midi specification
+	case PROP_TIMEDIV:
+		_ticks_per_beat = (uint16)param;
+		return 1;
+	}
+
+	return 0;
+}





More information about the Scummvm-git-logs mailing list