[Scummvm-cvs-logs] SF.net SVN: scummvm: [24617] scummvm/trunk/engines/touche

cyx at users.sourceforge.net cyx at users.sourceforge.net
Sun Nov 5 01:29:46 CET 2006


Revision: 24617
          http://svn.sourceforge.net/scummvm/?rev=24617&view=rev
Author:   cyx
Date:     2006-11-04 16:29:34 -0800 (Sat, 04 Nov 2006)

Log Message:
-----------
added basic MIDI playback

Modified Paths:
--------------
    scummvm/trunk/engines/touche/module.mk
    scummvm/trunk/engines/touche/resource.cpp
    scummvm/trunk/engines/touche/touche.cpp
    scummvm/trunk/engines/touche/touche.h

Added Paths:
-----------
    scummvm/trunk/engines/touche/midi.cpp
    scummvm/trunk/engines/touche/midi.h

Added: scummvm/trunk/engines/touche/midi.cpp
===================================================================
--- scummvm/trunk/engines/touche/midi.cpp	                        (rev 0)
+++ scummvm/trunk/engines/touche/midi.cpp	2006-11-05 00:29:34 UTC (rev 24617)
@@ -0,0 +1,157 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/mutex.h"
+#include "common/stream.h"
+
+#include "sound/midiparser.h"
+
+#include "touche/midi.h"
+
+namespace Touche {
+
+MidiPlayer::MidiPlayer(MidiDriver *driver)
+	: _masterVolume(255), _isPlaying(false), _driver(driver), _parser(0), _midiData(0) {
+	assert(_driver);
+	memset(_channelsTable, 0, sizeof(_channelsTable));
+	memset(_channelsVolume, 0, sizeof(_channelsVolume));
+	open();
+}
+
+MidiPlayer::~MidiPlayer() {
+	close();
+}
+
+void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
+	stop();
+	_midiData = (uint8 *)malloc(size);
+	if (_midiData) {
+		stream.read(_midiData, size);
+		_mutex.lock();
+		_parser->loadMusic(_midiData, size);
+		_parser->setTrack(0);
+		_isLooping = loop;
+		_isPlaying = true;
+		_mutex.unlock();
+	}
+}
+
+void MidiPlayer::stop() {
+	_mutex.lock();
+	if (_isPlaying) {
+		_isPlaying = false;
+		_parser->unloadMusic();
+		free(_midiData);
+		_midiData = 0;
+	}
+	_mutex.unlock();
+}
+
+void MidiPlayer::updateTimer() {
+	_mutex.lock();
+	if (_isPlaying) {
+		_parser->onTimer();
+	}
+	_mutex.unlock();
+}
+
+void MidiPlayer::setVolume(int volume) {
+	if (volume < 0) {
+		volume = 0;
+	} else if (volume > 255) {
+		volume = 255;
+	}
+	for (int i = 0; i < NUM_CHANNELS; ++i) {
+		if (_channelsTable[i]) {
+			_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
+		}
+	}
+}
+
+int MidiPlayer::open() {
+	int ret = _driver->open();
+	if (ret == 0) {
+		_parser = MidiParser::createParser_SMF();
+		_parser->setMidiDriver(this);
+		_parser->setTimerRate(_driver->getBaseTempo());
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+	return ret;
+}
+
+void MidiPlayer::close() {
+	_mutex.lock();
+	_driver->setTimerCallback(NULL, NULL);
+	_mutex.unlock();
+	stop();
+	_parser->setMidiDriver(NULL);
+	delete _parser;
+	_driver->close();
+	_driver = 0;
+}
+
+void MidiPlayer::send(uint32 b) {
+	byte volume, ch = (byte)(b & 0xF);
+	switch (b & 0xFFF0) {
+	case 0x07B0: // volume change
+		volume = (byte)((b >> 16) & 0x7F);
+		_channelsVolume[ch] = volume;
+		volume = volume * _masterVolume / 255;
+		b = (b & 0xFF00FFFF) | (volume << 16);
+		break;
+	case 0x7BB0: // all notes off
+		if (!_channelsTable[ch]) {
+			// channel not yet allocated, no need to send the event
+			return;
+		}
+		break;
+	}
+	if (!_channelsTable[ch]) {
+		_channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+	}
+	if (_channelsTable[ch]) {
+		_channelsTable[ch]->send(b);
+	}
+}
+
+void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
+	switch (type) {
+	case 0x2F: // end of Track
+		if (_isLooping) {
+			_parser->jumpToTick(0);
+		} else {
+			stop();
+		}
+		break;
+	default:
+//		warning("Unhandled meta event: %02x", type);
+		break;
+	}
+}
+
+void MidiPlayer::timerCallback(void *p) {
+	MidiPlayer *player = (MidiPlayer *)p;
+	player->updateTimer();
+}
+
+} // Touche namespace


Property changes on: scummvm/trunk/engines/touche/midi.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/touche/midi.h
===================================================================
--- scummvm/trunk/engines/touche/midi.h	                        (rev 0)
+++ scummvm/trunk/engines/touche/midi.h	2006-11-05 00:29:34 UTC (rev 24617)
@@ -0,0 +1,80 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TOUCHE_MIDI_H
+#define TOUCHE_MIDI_H
+
+#include "common/util.h"
+#include "sound/mididrv.h"
+
+class MidiParser;
+
+namespace Common {
+	class ReadStream;
+	class Mutex;
+}
+
+namespace Touche {
+
+class MidiPlayer : public MidiDriver {
+public:
+
+	enum {
+		NUM_CHANNELS = 16
+	};
+
+	MidiPlayer(MidiDriver *driver);
+	~MidiPlayer();
+
+	void play(Common::ReadStream &stream, int size, bool loop = false);
+	void stop();
+	void updateTimer();
+	void setVolume(int volume);
+
+	// MidiDriver interface
+	int open();
+	void close();
+	void send(uint32 b);
+	void metaEvent(byte type, byte *data, uint16 length);
+	void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
+	uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; }
+	MidiChannel *allocateChannel() { return 0; }
+	MidiChannel *getPercussionChannel() { return 0; }
+
+private:
+
+	static void timerCallback(void *p);
+
+	int _masterVolume;
+	bool _isLooping;
+	bool _isPlaying;
+	MidiDriver *_driver;
+	MidiParser *_parser;
+	MidiChannel *_channelsTable[NUM_CHANNELS];
+	byte _channelsVolume[NUM_CHANNELS];
+	uint8 *_midiData;
+	Common::Mutex _mutex;
+};
+
+} // namespace Touche
+
+#endif


Property changes on: scummvm/trunk/engines/touche/midi.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/touche/module.mk
===================================================================
--- scummvm/trunk/engines/touche/module.mk	2006-11-05 00:22:46 UTC (rev 24616)
+++ scummvm/trunk/engines/touche/module.mk	2006-11-05 00:29:34 UTC (rev 24617)
@@ -2,6 +2,7 @@
 
 MODULE_OBJS := \
 	graphics.o \
+	midi.o \
 	plugin.o \
 	opcodes.o \
 	resource.o \

Modified: scummvm/trunk/engines/touche/resource.cpp
===================================================================
--- scummvm/trunk/engines/touche/resource.cpp	2006-11-05 00:22:46 UTC (rev 24616)
+++ scummvm/trunk/engines/touche/resource.cpp	2006-11-05 00:29:34 UTC (rev 24617)
@@ -28,6 +28,7 @@
 #include "sound/voc.h"
 #include "sound/vorbis.h"
 
+#include "touche/midi.h"
 #include "touche/touche.h"
 #include "touche/graphics.h"
 
@@ -564,7 +565,7 @@
 	uint32 size;
 	const uint32 offs = res_getDataOffset(kResourceTypeMusic, num, &size);
 	_fData.seek(offs);
-	// XXX start MIDI data playback
+	_midiPlayer->play(_fData, size);
 }
 
 void ToucheEngine::res_loadSpeech(int num) {

Modified: scummvm/trunk/engines/touche/touche.cpp
===================================================================
--- scummvm/trunk/engines/touche/touche.cpp	2006-11-05 00:22:46 UTC (rev 24616)
+++ scummvm/trunk/engines/touche/touche.cpp	2006-11-05 00:29:34 UTC (rev 24617)
@@ -24,6 +24,9 @@
 #include "common/config-manager.h"
 #include "common/system.h"
 
+#include "sound/mididrv.h"
+
+#include "touche/midi.h"
 #include "touche/touche.h"
 #include "touche/graphics.h"
 
@@ -74,10 +77,15 @@
 	Common::addSpecialDebugLevel(kDebugResource, "Resource", "Resource debug level");
 	Common::addSpecialDebugLevel(kDebugOpcodes,  "Opcodes",  "Opcodes debug level");
 	Common::addSpecialDebugLevel(kDebugUserIntf, "UserIntf", "UserInterface debug level");
+
+	int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
+	MidiDriver *driver = MidiDriver::createMidi(midiDriver);
+	_midiPlayer = new MidiPlayer(driver);
 }
 
 ToucheEngine::~ToucheEngine() {
 	Common::clearAllSpecialDebugLevels();
+	delete _midiPlayer;
 }
 
 int ToucheEngine::init() {
@@ -88,6 +96,9 @@
 
 	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
 	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
+
+	_midiPlayer->setVolume(ConfMan.getInt("music_volume"));
 	return 0;
 }
 

Modified: scummvm/trunk/engines/touche/touche.h
===================================================================
--- scummvm/trunk/engines/touche/touche.h	2006-11-05 00:22:46 UTC (rev 24616)
+++ scummvm/trunk/engines/touche/touche.h	2006-11-05 00:29:34 UTC (rev 24617)
@@ -299,6 +299,8 @@
 	kLoadGameState
 };
 
+class MidiPlayer;
+
 class ToucheEngine: public Engine {
 public:
 
@@ -595,6 +597,8 @@
 	void ui_displayTextMode(int str);
 
 
+	MidiPlayer *_midiPlayer;
+
 	Common::Language _language;
 	Common::RandomSource _rnd;
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list