[Scummvm-git-logs] scummvm master -> 68bae81aff950f04b1fdafccb6024834a90f61db

sev- noreply at scummvm.org
Fri Mar 24 22:59:58 UTC 2023


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
afa9ccbf62 AUDIO: Add support for Impulse Tracker using libmikmod
356957694f TESTBED: Support for impulse tracker in module playback testing
68bae81aff SLUDGE: Add support for impulse tracker mod files in sound


Commit: afa9ccbf62f789bdc3efc402761c3989632fff8f
    https://github.com/scummvm/scummvm/commit/afa9ccbf62f789bdc3efc402761c3989632fff8f
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-03-24T23:59:53+01:00

Commit Message:
AUDIO: Add support for Impulse Tracker using libmikmod

Changed paths:
  A audio/mods/impulsetracker.cpp
  A audio/mods/impulsetracker.h
    audio/module.mk
    configure


diff --git a/audio/mods/impulsetracker.cpp b/audio/mods/impulsetracker.cpp
new file mode 100644
index 00000000000..c9250ba4e73
--- /dev/null
+++ b/audio/mods/impulsetracker.cpp
@@ -0,0 +1,230 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Disable symbol overrides for FILE and fseek as those are used in the
+// mikmod headers.
+#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+
+#include "audio/mods/impulsetracker.h"
+
+#ifdef USE_MIKMOD
+
+#include <mikmod.h>
+
+#include "common/inttypes.h"
+#include "common/ptr.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+// Start memory wrapper
+// Extras, mikmod mreader struct to wrap readstream
+typedef struct MikMemoryReader {
+	MREADER core;
+	Common::SeekableReadStream *stream;
+} MikMemoryReader;
+
+static BOOL memoryReaderEof(MREADER *reader);
+static BOOL memoryReaderRead(MREADER *reader, void *ptr, size_t size);
+static int  memoryReaderGet(MREADER *reader);
+static int  memoryReaderSeek(MREADER *reader, long offset, int whence);
+static long memoryReaderTell(MREADER *reader);
+
+MREADER *createMikMemoryReader(Common::SeekableReadStream *stream) {
+	MikMemoryReader *reader = (MikMemoryReader *)calloc(1, sizeof(MikMemoryReader));
+
+	if (reader) {
+		reader->core.Eof = &memoryReaderEof;
+		reader->core.Read = &memoryReaderRead;
+		reader->core.Get = &memoryReaderGet;
+		reader->core.Seek = &memoryReaderSeek;
+		reader->core.Tell = &memoryReaderTell;
+		reader->stream = stream;
+	}
+
+	return (MREADER *)reader;
+}
+
+static BOOL memoryReaderEof(MREADER *reader) {
+	MikMemoryReader *mr = (MikMemoryReader *)reader;
+
+	if (!mr)
+		return 1;
+
+	if (mr->stream && mr->stream->eos() == true)
+		return 1;
+
+	return 0;
+}
+
+static BOOL memoryReaderRead(MREADER *reader, void *ptr, size_t size) {
+	MikMemoryReader *mr;
+	mr = (MikMemoryReader *)reader;
+
+	if (!mr && !mr->stream)
+		return 0;
+
+	uint32 receivedBytes = mr->stream->read(ptr, size);
+	
+	if (receivedBytes < size)
+		return 0; // not enough remaining bytes (or error)
+
+	return 1;
+}
+
+static int memoryReaderGet(MREADER *reader) {
+	MikMemoryReader *mr;
+	mr = (MikMemoryReader *)reader;
+
+	if (!mr->stream)
+		return -1;
+
+	return mr->stream->readByte();
+}
+
+static int memoryReaderSeek(MREADER *reader, long offset, int whence) {
+	MikMemoryReader *mr;
+	mr = (MikMemoryReader *)reader;
+	
+	if (!reader || !mr->stream)
+		return -1;
+
+	return mr->stream->seek(offset, whence);
+}
+
+static long memoryReaderTell(MREADER *reader) {
+	if (reader)
+		return ((MikMemoryReader *)reader)->stream->pos();
+
+	return 0;
+}
+// End memory wrappper
+
+namespace Audio {
+class ImpulseTrackerMod : public RewindableAudioStream {
+public:
+	ImpulseTrackerMod(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);
+	~ImpulseTrackerMod();
+
+	// ImpulseTrackerMod functions
+	bool isLoaded() {
+		return _mikmod_load_successful;
+	}
+
+	// AudioStream API
+	int readBuffer(int16 *buffer, const int numSamples) override {
+		// Multiplied by 2 as VC_WriteBytes function expects 8 byte integer arrays, whereas buffer needs 16 ones.
+		VC_WriteBytes((SBYTE *)buffer, numSamples * 2);
+
+		return numSamples;
+	}
+
+	bool isStereo() const override {
+		return true;
+	}
+	int getRate() const override {
+		return 44100;
+	}
+	bool endOfData() const override {
+		return !Player_Active();
+	}
+	bool endOfStream() const override {
+		return endOfData();
+	}
+
+	// RewindableAudioStream API
+	bool rewind() {
+		Player_SetPosition(0);
+		return true;
+	}
+
+private:
+	DisposeAfterUse::Flag _dispose;
+	bool _mikmod_load_successful = false;
+	Common::SeekableReadStream *_stream;
+	MREADER *_reader;
+	MODULE *_mod;
+};
+
+ImpulseTrackerMod::ImpulseTrackerMod(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
+	if (!stream) {
+		warning("ImpulseTrackerMod::ImpulseTrackerMod(): Input file/stream is invalid.");
+		return;
+	}
+
+	MikMod_InitThreads();
+	MikMod_RegisterDriver(&drv_nos);
+
+	// Set flags
+	md_mode |= DMODE_SOFT_MUSIC | DMODE_NOISEREDUCTION;
+	md_mixfreq = getRate();
+	
+	if (MikMod_Init("")) {
+		warning("ImpulseTrackerMod::ImpulseTrackerMod(): Could not initialize sound, reason: %s",
+		        MikMod_strerror(MikMod_errno));
+		return;
+	}
+
+	// Loading only impulse tracker loader!
+	MikMod_RegisterLoader(&load_it);
+
+	_stream = stream;
+	_dispose = disposeAfterUse;
+
+	// Load mod using custom loader class!
+	_reader = createMikMemoryReader(_stream);
+	_mod = Player_LoadGeneric(_reader, 64, 0);
+	if (!_mod) {
+		warning("ImpulseTrackerMod::ImpulseTrackerMod(): Parsing mod error: %s", MikMod_strerror(MikMod_errno));
+		return;
+	}
+
+	// Start mikmod playing, ie fill VC_Driver buffer with data
+	Player_Start(_mod);
+	_mikmod_load_successful = true;
+}
+
+ImpulseTrackerMod::~ImpulseTrackerMod() {
+	Player_Stop();
+	
+	if (_mod)
+		Player_Free(_mod);
+		
+	if (_reader)
+		free(_reader);
+
+	if (_dispose == DisposeAfterUse::Flag::YES)
+		delete _stream;
+
+	MikMod_Exit();
+}
+
+RewindableAudioStream *makeImpulseTrackerStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
+	ImpulseTrackerMod *impulseTrackerMod = new ImpulseTrackerMod(stream, disposeAfterUse);
+	return impulseTrackerMod;
+}
+
+} // End of namespace Audio
+
+#endif // #ifdef USE_MIKMOD
diff --git a/audio/mods/impulsetracker.h b/audio/mods/impulsetracker.h
new file mode 100644
index 00000000000..b07dea1c398
--- /dev/null
+++ b/audio/mods/impulsetracker.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * @file
+ * Sound decoder used in engines:
+ *  - sludge
+ */
+
+#ifndef AUDIO_IMPULSETRACKER_H
+#define AUDIO_IMPULSETRACKER_H
+
+#include "common/scummsys.h"
+#include "common/types.h"
+
+#ifdef USE_MIKMOD
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Audio {
+
+class RewindableAudioStream;
+/**
+ * Create a new AudioStream from the Impulse Tracker data in the given stream.
+ *
+ * @param stream            the SeekableReadStream from which to read the Ogg Vorbis data
+ * @param disposeAfterUse   whether to delete the stream after use
+ * @return  a new AudioStream, or NULL, if an error occurred
+ */
+RewindableAudioStream *makeImpulseTrackerStream(
+    Common::SeekableReadStream *stream,
+    DisposeAfterUse::Flag disposeAfterUse);
+} // End of namespace Audio
+
+#endif // #ifdef USE_MIKMOD
+#endif // #ifndef AUDIO_IMPULSETRACKER_H
diff --git a/audio/module.mk b/audio/module.mk
index 93af443687f..8d671571203 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -43,6 +43,7 @@ MODULE_OBJS := \
 	decoders/wma.o \
 	decoders/xa.o \
 	decoders/xan_dpcm.o \
+	mods/impulsetracker.o \
 	mods/infogrames.o \
 	mods/maxtrax.o \
 	mods/mod_xm_s3m.o \
diff --git a/configure b/configure
index 682b6971c6c..d66522d15a8 100755
--- a/configure
+++ b/configure
@@ -168,6 +168,7 @@ _opengl_game_shaders=auto
 _tinygl=yes
 _readline=auto
 _freetype2=auto
+_libmikmod=auto
 _taskbar=auto
 _updates=no
 _libunity=auto
@@ -240,11 +241,13 @@ _sparklepath=
 _pkgconfig=pkg-config
 _sdlconfig=sdl2-config
 _libcurlconfig=curl-config
+_libmikmodconfig=libmikmod-config
 _freetypeconfig=freetype-config
 _freetype_found="false"
 _sdlpath="$PATH"
 _freetypepath="$PATH"
 _libcurlpath="$PATH"
+_libmikmodpath="$PATH"
 _nasmpath="$PATH"
 NASMFLAGS=""
 NASM=""
@@ -546,6 +549,40 @@ find_libcurlconfig() {
 	fi
 }
 
+#
+# Determine libmikmod-config
+#
+find_libmikmodconfig() {
+	echo_n "Looking for mikmod-config... "
+	libmikmodconfigs="$_libmikmodconfig"
+	_libmikmodconfig=
+
+	IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS="$SEPARATOR"
+	for path_dir in $_libmikmodpath; do
+		#reset separator to parse mikmodconfig
+		IFS=":"
+		for libmikmodconfig in $libmikmodconfigs; do
+			if test -f "$path_dir/$libmikmodconfig" ; then
+				_libmikmodconfig="$path_dir/$libmikmodconfig"
+				echo $_libmikmodconfig
+				# Save the prefix
+				_libmikmodpath=$path_dir
+				if test `basename $path_dir` = bin ; then
+					_libmikmodpath=`dirname $path_dir`
+				fi
+				# break at first mikmod-config found in path
+				break 2
+			fi
+		done
+	done
+
+	IFS="$ac_save_ifs"
+
+	if test -z "$_libmikmodconfig"; then
+		echo "none found!"
+	fi
+}
+
 #
 # Determine extension used for executables
 #
@@ -974,6 +1011,9 @@ Optional Libraries:
   --with-mpeg2-prefix=DIR  prefix where libmpeg2 is installed (optional)
   --enable-mpeg2           enable mpeg2 codec for cutscenes [autodetect]
 
+  --with-mikmod-prefix=DIR    Prefix where libmikmod is installed (optional)
+  --enable-mikmod             enable mikmod module for playing various sound formats like impulsetracker [autodetect]
+
   --with-a52-prefix=DIR    Prefix where liba52 is installed (optional)
   --enable-a52             enable a52 codec for MPEG decoder [autodetect]
 
@@ -1162,6 +1202,8 @@ for ac_option in $@; do
 	--disable-nasm)               _nasm=no               ;;
 	--enable-mpeg2)               _mpeg2=yes             ;;
 	--disable-mpeg2)              _mpeg2=no              ;;
+	--enable-mikmod)              _libmikmod=yes         ;;
+	--disable-mikmod)             _libmikmod=no          ;;
 	--enable-a52)                 _a52=yes               ;;
 	--disable-a52)                _a52=no                ;;
 	--disable-jpeg)               _jpeg=no               ;;
@@ -1455,6 +1497,10 @@ for ac_option in $@; do
 		arg=`echo $ac_option | cut -d '=' -f 2`
 		_libcurlpath="$arg:$arg/bin"
 		;;
+	--with-mikmod-prefix=*)
+		arg=`echo $ac_option | cut -d '=' -f 2`
+		_libmikmodpath="$arg:$arg/bin"
+		;;
 	--with-nasm-prefix=*)
 		arg=`echo $ac_option | cut -d '=' -f 2`
 		_nasmpath="$arg:$arg/bin"
@@ -5682,6 +5728,51 @@ echo "$_libcurl"
 
 define_in_config_if_yes "$_libcurl" "USE_LIBCURL"
 
+#
+# Check for libmikmod to be present
+#
+echocheck "libmikmod"
+if test "$_libmikmod" != "no"; then
+
+	# Look for the mikmod-config script
+	find_libmikmodconfig
+
+	if test -z "$_libmikmodconfig"; then
+		_libmikmod=no
+	else
+		if test -n "$_staticlibpath"; then
+			LIBMIKMOD_LIBS=`$_libmikmodconfig --static-libs`
+		else
+			LIBMIKMOD_LIBS=`$_libmikmodconfig --libs`
+		fi
+		LIBMIKMOD_CFLAGS=`$_libmikmodconfig --cflags`
+
+		if test "$_libmikmod" = "auto"; then
+			_libmikmod=no
+
+			cat > $TMPC << EOF
+			#include <mikmod.h>
+			int main(void) {
+				SAMPLE *spl = Sample_Load("abcd");
+				Sample_Free(spl);
+				return 0;
+			}
+EOF
+		cc_check $LIBMIKMOD_CFLAGS $LIBMIKMOD_LIBS && _libmikmod=yes
+		fi
+
+		if test "$_libmikmod" = "yes"; then
+			append_var LIBS "$LIBMIKMOD_LIBS"
+			append_var INCLUDES "$LIBMIKMOD_CFLAGS"
+		fi
+	fi
+
+fi
+
+echo "$_libmikmod"
+
+define_in_config_if_yes "$_libmikmod" "USE_MIKMOD"
+
 #
 # Check whether to build cloud integration support
 #


Commit: 356957694fc67a45e94d99bfb019b57afa28eaf0
    https://github.com/scummvm/scummvm/commit/356957694fc67a45e94d99bfb019b57afa28eaf0
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-03-24T23:59:53+01:00

Commit Message:
TESTBED: Support for impulse tracker in module playback testing

Changed paths:
    engines/testbed/sound.cpp


diff --git a/engines/testbed/sound.cpp b/engines/testbed/sound.cpp
index 3f935768aea..514d329138b 100644
--- a/engines/testbed/sound.cpp
+++ b/engines/testbed/sound.cpp
@@ -21,6 +21,7 @@
 
 #include "audio/softsynth/pcspk.h"
 #include "audio/mods/mod_xm_s3m.h"
+#include "audio/mods/impulsetracker.h"
 
 #include "backends/audiocd/audiocd.h"
 
@@ -209,6 +210,12 @@ TestExitStatus SoundSubsystem::modPlayback() {
 			continue;
 
 		Audio::RewindableAudioStream *mod = Audio::makeModXmS3mStream(&f, DisposeAfterUse::NO);
+#ifdef USE_MIKMOD
+		if (!mod) {
+			// Try impulse tracker if failed!
+			mod = Audio::makeImpulseTrackerStream(&f, DisposeAfterUse::NO);
+		}
+#endif
 		if (!mod) {
 			Testsuite::displayMessage(Common::String::format("Could not load MOD file '%s'", music[i]));
 			f.close();


Commit: 68bae81aff950f04b1fdafccb6024834a90f61db
    https://github.com/scummvm/scummvm/commit/68bae81aff950f04b1fdafccb6024834a90f61db
Author: Harishankar Kumar (hari01584 at gmail.com)
Date: 2023-03-24T23:59:53+01:00

Commit Message:
SLUDGE: Add support for impulse tracker mod files in sound

Changed paths:
    engines/sludge/sound.cpp


diff --git a/engines/sludge/sound.cpp b/engines/sludge/sound.cpp
index 65f0a2bf3c5..929d532a239 100644
--- a/engines/sludge/sound.cpp
+++ b/engines/sludge/sound.cpp
@@ -23,6 +23,7 @@
 #include "audio/decoders/wave.h"
 #include "audio/decoders/vorbis.h"
 #include "audio/mods/mod_xm_s3m.h"
+#include "audio/mods/impulsetracker.h"
 
 #include "sludge/errors.h"
 #include "sludge/fileset.h"
@@ -224,7 +225,12 @@ bool SoundManager::playMOD(int f, int a, int fromTrack) {
 		return fatal("Sound reading failed");
 	}
 	Audio::RewindableAudioStream *mod = Audio::makeModXmS3mStream(memImage, DisposeAfterUse::NO, fromTrack);
-
+#ifdef USE_MIKMOD
+	if (!mod) {
+		// Try impulse tracker if failed!
+		mod = Audio::makeImpulseTrackerStream(memImage, DisposeAfterUse::NO);
+	}
+#endif
 	if (!mod) {
 		warning("Could not load MOD file");
 		g_sludge->_resMan->finishAccess();




More information about the Scummvm-git-logs mailing list