[Scummvm-git-logs] scummvm master -> 2e68867e98f5b0e9d8521523efae1b5030dc7c60

sev- noreply at scummvm.org
Sun Aug 6 12:10:55 UTC 2023


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

Summary:
37764d86fc AUDIO: Support building the EAS MIDI driver on non-Android platforms
2e68867e98 AUDIO: Remove dynamic load of EAS for Android and fix DLS loading


Commit: 37764d86fc8802785f81439d3f1ccd74dc7a00a7
    https://github.com/scummvm/scummvm/commit/37764d86fc8802785f81439d3f1ccd74dc7a00a7
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-08-06T14:10:50+02:00

Commit Message:
AUDIO: Support building the EAS MIDI driver on non-Android platforms

Changed paths:
    audio/softsynth/eas.cpp
    base/plugins.cpp
    base/version.cpp
    configure


diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index 31449ac6328..84e8745ba37 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -21,9 +21,18 @@
 
 #include "common/scummsys.h"
 
-#if defined(__ANDROID__)
+#if defined(USE_SONIVOX) || defined(__ANDROID__)
 
+#ifdef USE_SONIVOX
+#include <sonivox/eas.h>
+#include <sonivox/eas_reverb.h>
+#else
+#define EAS_DLOPEN
+#endif
+
+#ifdef EAS_DLOPEN
 #include <dlfcn.h>
+#endif
 
 #include "common/debug.h"
 #include "common/endian.h"
@@ -51,14 +60,18 @@
 // from rate_arm.cpp
 #define INTERMEDIATE_BUFFER_SIZE 512
 
+#ifdef EAS_DLOPEN
 // so far all android versions have the very same library version
 #define EAS_LIBRARY "libsonivox.so"
 #define EAS_KNOWNVERSION 0x03060a0e
+#endif
 
-#define EAS_REVERB 2
-#define EAS_REVERB_BYPASS 0
-#define EAS_REVERB_PRESET 1
-#define EAS_REVERB_CHAMBER 2
+#ifndef USE_SONIVOX
+#define EAS_MODULE_REVERB 2
+#define EAS_PARAM_REVERB_BYPASS 0
+#define EAS_PARAM_REVERB_PRESET 1
+#define EAS_PARAM_REVERB_CHAMBER 2
+#endif
 
 class MidiDriver_EAS : public MidiDriver_MPU401, Audio::AudioStream {
 public:
@@ -67,7 +80,7 @@ public:
 
 	// MidiDriver
 	int open() override;
-	bool isOpen() const override { return _dlHandle != 0; }
+	bool isOpen() const override { return _isOpen; }
 
 	void close() override;
 	void send(uint32 b) override;
@@ -83,39 +96,62 @@ public:
 	bool endOfData() const override;
 
 private:
-	struct EASLibConfig {
-		uint32 version;
-		uint32 debug;
-		int32 voices;
-		int32 channels;
-		int32 rate;
-		int32 bufSize;
-		uint32 filter;
-		uint32 timeStamp;
-		char *GUID;
+#ifndef USE_SONIVOX
+	typedef long EAS_RESULT;
+
+	typedef unsigned EAS_BOOL;
+
+	typedef unsigned char EAS_U8;
+	typedef signed char EAS_I8;
+	typedef char EAS_CHAR;
+
+	typedef unsigned short EAS_U16;
+	typedef short EAS_I16;
+
+	typedef unsigned long EAS_U32;
+	typedef long EAS_I32;
+
+	typedef short EAS_PCM;
+
+	struct S_EAS_LIB_CONFIG {
+		EAS_U32 libVersion;
+		EAS_BOOL checkedVersion;
+		EAS_I32 maxVoices;
+		EAS_I32 numChannels;
+		EAS_I32 sampleRate;
+		EAS_I32 mixBufferSize;
+		EAS_BOOL filterEnabled;
+		EAS_U32 buildTimeStamp;
+		EAS_CHAR *buildGUID;
 	};
 
-	struct EASFile {
+#ifdef DLS_SYNTHESIZER
+	struct EAS_FILE_LOCATOR {
 		const char *path;
 		int fd;
 		long long offset;
 		long long length;
 	};
+#endif
 
-	typedef void * EASDataHandle;
-	typedef void * EASHandle;
+	typedef void * EAS_DATA_HANDLE;
+	typedef void * EAS_HANDLE;
+#endif
 
-	typedef EASLibConfig *(*ConfigFunc)();
-	typedef int32 (*InitFunc)(EASDataHandle *);
-	typedef int32 (*ShutdownFunc)(EASDataHandle);
-	typedef int32 (*LoadDLSFunc)(EASDataHandle, EASHandle, EASFile *);
-	typedef int32 (*SetParameterFunc)(EASDataHandle, int32, int32, int32);
-	typedef int32 (*SetVolumeFunc)(EASDataHandle, EASHandle, int32);
-	typedef int32 (*OpenStreamFunc)(EASDataHandle, EASHandle *, EASHandle);
-	typedef int32 (*WriteStreamFunc)(EASDataHandle, EASHandle, byte *, int32);
-	typedef int32 (*CloseStreamFunc)(EASDataHandle, EASHandle);
-	typedef int32 (*RenderFunc)(EASDataHandle, int16 *, int32, int32 *);
+	typedef const S_EAS_LIB_CONFIG *(*ConfigFunc)();
+	typedef EAS_RESULT (*InitFunc)(EAS_DATA_HANDLE *);
+	typedef EAS_RESULT (*ShutdownFunc)(EAS_DATA_HANDLE);
+	typedef EAS_RESULT (*SetParameterFunc)(EAS_DATA_HANDLE, EAS_I32, EAS_I32, EAS_I32);
+	typedef EAS_RESULT (*SetVolumeFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_I32);
+	typedef EAS_RESULT (*OpenStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE *, EAS_HANDLE);
+	typedef EAS_RESULT (*WriteStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_U8 *, EAS_I32);
+	typedef EAS_RESULT (*CloseStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE);
+	typedef EAS_RESULT (*RenderFunc)(EAS_DATA_HANDLE, EAS_PCM *, EAS_I32, EAS_I32 *);
+#ifdef DLS_SYNTHESIZER
+	typedef EAS_RESULT (*LoadDLSFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_FILE_LOCATOR *);
+#endif
 
+#ifdef EAS_DLOPEN
 	template<typename T>
 	void sym(T &t, const char *symbol) {
 		union {
@@ -134,21 +170,26 @@ private:
 	}
 
 	void *_dlHandle;
+#endif
+
+	bool _isOpen;
 
 	ConfigFunc _configFunc;
 	InitFunc _initFunc;
 	ShutdownFunc _shutdownFunc;
-	LoadDLSFunc _loadDLSFunc;
 	SetParameterFunc _setParameterFunc;
 	SetVolumeFunc _setVolumeFunc;
 	OpenStreamFunc _openStreamFunc;
 	WriteStreamFunc _writeStreamFunc;
 	CloseStreamFunc _closeStreamFunc;
 	RenderFunc _renderFunc;
+#ifdef DLS_SYNTHESIZER
+	LoadDLSFunc _loadDLSFunc;
+#endif
 
-	const EASLibConfig *_config;
-	EASDataHandle _EASHandle;
-	EASHandle _midiStream;
+	const S_EAS_LIB_CONFIG *_config;
+	EAS_DATA_HANDLE _EASHandle;
+	EAS_HANDLE _midiStream;
 
 	Common::TimerManager::TimerProc _timerProc;
 	void *_timerParam;
@@ -161,14 +202,19 @@ private:
 
 MidiDriver_EAS::MidiDriver_EAS() :
 	MidiDriver_MPU401(),
+#ifdef USE_DLOPEN
 	_dlHandle(0),
+#endif
 	_configFunc(0),
 	_initFunc(0),
 	_shutdownFunc(0),
-	_loadDLSFunc(0),
 	_setParameterFunc(0),
 	_setVolumeFunc(0),
 	_openStreamFunc(0),
+#ifdef DLS_SYNTHESIZER
+	_loadDLSFunc(0),
+#endif
+	_isOpen(false),
 	_writeStreamFunc(0),
 	_closeStreamFunc(0),
 	_renderFunc(0),
@@ -190,6 +236,7 @@ int MidiDriver_EAS::open() {
 	if (isOpen())
 		return MERR_ALREADY_OPEN;
 
+#ifdef EAS_DLOPEN
 	_dlHandle = dlopen(EAS_LIBRARY, RTLD_LAZY);
 	if (!_dlHandle) {
 		warning("error opening " EAS_LIBRARY ": %s", dlerror());
@@ -201,6 +248,9 @@ int MidiDriver_EAS::open() {
 		close();
 		return -1;
 	}
+#else
+	_configFunc = EAS_Config;
+#endif
 
 	_config = _configFunc();
 	if (!_config) {
@@ -209,28 +259,30 @@ int MidiDriver_EAS::open() {
 		return -1;
 	}
 
-	if (_config->version != EAS_KNOWNVERSION) {
+#ifdef EAS_DLOPEN
+	if (_config->libVersion != EAS_KNOWNVERSION) {
 		close();
-		warning("unknown EAS library version: 0x%08x", _config->version);
+		warning("unknown EAS library version: 0x%08x", (int32)_config->libVersion);
 		return -1;
 	}
+#endif
 
-	if (_config->channels > 2) {
+	if (_config->numChannels > 2) {
 		close();
-		warning("unsupported number of EAS channels: %d", _config->channels);
+		warning("unsupported number of EAS channels: %d", (int32)_config->numChannels);
 		return -1;
 	}
 
 	// see note at top of this file
-	if (INTERMEDIATE_BUFFER_SIZE % (_config->bufSize * _config->channels)) {
+	if (INTERMEDIATE_BUFFER_SIZE % (_config->mixBufferSize * _config->numChannels)) {
 		close();
-		warning("unsupported EAS buffer size: %d", _config->bufSize);
+		warning("unsupported EAS buffer size: %d", (int32)_config->mixBufferSize);
 		return -1;
 	}
 
+#ifdef EAS_DLOPEN
 	sym(_initFunc, "EAS_Init");
 	sym(_shutdownFunc, "EAS_Shutdown");
-	sym(_loadDLSFunc, "EAS_LoadDLSCollection");
 	sym(_setParameterFunc, "EAS_SetParameter");
 	sym(_setVolumeFunc, "EAS_SetVolume");
 	sym(_openStreamFunc, "EAS_OpenMIDIStream");
@@ -238,68 +290,91 @@ int MidiDriver_EAS::open() {
 	sym(_closeStreamFunc, "EAS_CloseMIDIStream");
 	sym(_renderFunc, "EAS_Render");
 
-	if (!_initFunc || !_shutdownFunc || !_loadDLSFunc || !_setParameterFunc ||
+	if (!_initFunc || !_shutdownFunc || !_setParameterFunc ||
 			!_openStreamFunc || !_writeStreamFunc || !_closeStreamFunc ||
 			!_renderFunc) {
 		close();
 		return -1;
 	}
 
-	int32 res = _initFunc(&_EASHandle);
+#ifdef DLS_SYNTHESIZER
+	sym(_loadDLSFunc, "EAS_LoadDLSCollection");
+
+	if (!_loadDLSFunc) {
+		close();
+		return -1;
+	}
+#endif
+#else
+	_initFunc = EAS_Init;
+	_shutdownFunc = EAS_Shutdown;
+	_setParameterFunc = EAS_SetParameter;
+	_setVolumeFunc = EAS_SetVolume;
+	_openStreamFunc = EAS_OpenMIDIStream;
+	_writeStreamFunc = EAS_WriteMIDIStream;
+	_closeStreamFunc = EAS_CloseMIDIStream;
+	_renderFunc = EAS_Render;
+#ifdef DLS_SYNTHESIZER
+	_loadDLSFunc = EAS_LoadDLSCollection;
+#endif
+#endif
+
+	EAS_RESULT res = _initFunc(&_EASHandle);
 	if (res) {
 		close();
-		warning("error initializing the EAS library: %d", res);
+		warning("error initializing the EAS library: %d", (int32)res);
 		return -1;
 	}
 
-	res = _setParameterFunc(_EASHandle, EAS_REVERB, EAS_REVERB_PRESET,
-							EAS_REVERB_CHAMBER);
+	res = _setParameterFunc(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
 	if (res)
-		warning("error setting reverb preset: %d", res);
+		warning("error setting reverb preset: %d", (int32)res);
 
-	res = _setParameterFunc(_EASHandle, EAS_REVERB, EAS_REVERB_BYPASS, 0);
+	res = _setParameterFunc(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, 0);
 	if (res)
-		warning("error disabling reverb bypass: %d", res);
+		warning("error disabling reverb bypass: %d", (int32)res);
 
 	// 90 is EAS's default, max is 100
 	// so the option slider will only work from 0.1 to 1.1
 	res = _setVolumeFunc(_EASHandle, 0, ConfMan.getInt("midi_gain") - 10);
 	if (res)
-		warning("error setting EAS master volume: %d", res);
+		warning("error setting EAS master volume: %d", (int32)res);
 
 	res = _openStreamFunc(_EASHandle, &_midiStream, 0);
 	if (res) {
 		close();
-		warning("error opening EAS MIDI stream: %d", res);
+		warning("error opening EAS MIDI stream: %d", (int32)res);
 		return -1;
 	}
 
 	// set the timer frequency to match a single buffer size
-	_baseTempo = (1000000 * _config->bufSize) / _config->rate;
+	_baseTempo = (1000000 * _config->mixBufferSize) / _config->sampleRate;
 
 	// number of buffer fills per readBuffer()
-	_rounds = INTERMEDIATE_BUFFER_SIZE / (_config->bufSize * _config->channels);
+	_rounds = INTERMEDIATE_BUFFER_SIZE / (_config->mixBufferSize * _config->numChannels);
 
 	debug("EAS initialized (voices:%d channels:%d rate:%d buffer:%d) "
-			"tempo:%u rounds:%u", _config->voices, _config->channels,
-			_config->rate, _config->bufSize, _baseTempo, _rounds);
+			"tempo:%u rounds:%u", (int32)_config->maxVoices, (int32)_config->numChannels,
+			(int32)_config->sampleRate, (int32)_config->mixBufferSize, _baseTempo, _rounds);
 
+#ifdef DLS_SYNTHESIZER
 	// TODO doesn't seem to work with midi streams?
 	if (ConfMan.hasKey("soundfont")) {
 		const Common::String dls = ConfMan.get("soundfont");
 
 		debug("loading DLS file '%s'", dls.c_str());
 
-		EASFile f;
-		memset(&f, 0, sizeof(EASFile));
+		EAS_FILE_LOCATOR f;
+		memset(&f, 0, sizeof(EAS_FILE_LOCATOR));
 		f.path = dls.c_str();
 
 		res = _loadDLSFunc(_EASHandle, 0, &f);
 		if (res)
-			warning("error loading DLS file '%s': %d", dls.c_str(), res);
+			warning("error loading DLS file '%s': %d", dls.c_str(), (int32)res);
 		else
 			debug("DLS file loaded");
 	}
+#endif
 
 #ifdef EAS_DUMPSTREAM
 	if (!_dump.open("/sdcard/eas.dump"))
@@ -311,6 +386,7 @@ int MidiDriver_EAS::open() {
 										Audio::Mixer::kMaxChannelVolume, 0,
 										DisposeAfterUse::NO, true);
 
+	_isOpen = true;
 	return 0;
 }
 
@@ -331,25 +407,29 @@ void MidiDriver_EAS::close() {
 	g_system->delayMillis((_baseTempo * _rounds) / 1000);
 
 	if (_midiStream) {
-		int32 res = _closeStreamFunc(_EASHandle, _midiStream);
+		EAS_RESULT res = _closeStreamFunc(_EASHandle, _midiStream);
 		if (res)
-			warning("error closing EAS MIDI stream: %d", res);
+			warning("error closing EAS MIDI stream: %d", (int32)res);
 
 		_midiStream = 0;
 	}
 
 	if (_EASHandle) {
-		int32 res = _shutdownFunc(_EASHandle);
+		EAS_RESULT res = _shutdownFunc(_EASHandle);
 		if (res)
-			warning("error shutting down the EAS library: %d", res);
+			warning("error shutting down the EAS library: %d", (int32)res);
 
 		_EASHandle = 0;
 	}
 
+#ifdef EAS_DLOPEN
 	if (dlclose(_dlHandle))
 		warning("error closing " EAS_LIBRARY ": %s", dlerror());
 
 	_dlHandle = 0;
+#endif
+
+	_isOpen = false;
 }
 
 void MidiDriver_EAS::send(uint32 b) {
@@ -366,7 +446,7 @@ void MidiDriver_EAS::send(uint32 b) {
 
 	int32 res = _writeStreamFunc(_EASHandle, _midiStream, buf, len);
 	if (res)
-		warning("error writing to EAS MIDI stream: %d", res);
+		warning("error writing to EAS MIDI stream: %d", (int32)res);
 }
 
 void MidiDriver_EAS::sysEx(const byte *msg, uint16 length) {
@@ -381,9 +461,9 @@ void MidiDriver_EAS::sysEx(const byte *msg, uint16 length) {
 	memcpy(buf + 1, msg, length);
 	buf[length + 1] = 0xF7;
 
-	int32 res = _writeStreamFunc(_EASHandle, _midiStream, buf, length + 2);
+	EAS_RESULT res = _writeStreamFunc(_EASHandle, _midiStream, buf, length + 2);
 	if (res)
-		warning("error writing to EAS MIDI stream: %d", res);
+		warning("error writing to EAS MIDI stream: %d", (int32)res);
 }
 
 void MidiDriver_EAS::setTimerCallback(void *timerParam,
@@ -403,7 +483,8 @@ int MidiDriver_EAS::readBuffer(int16 *buffer, const int numSamples) {
 	if (!isOpen())
 		return -1;
 
-	int32 res, c;
+	EAS_RESULT res;
+	EAS_I32 c;
 
 	for (uint i = 0; i < _rounds; ++i) {
 		// pull in MIDI events for exactly one buffer size
@@ -411,29 +492,29 @@ int MidiDriver_EAS::readBuffer(int16 *buffer, const int numSamples) {
 			(*_timerProc)(_timerParam);
 
 		// if there are no MIDI events, this just renders silence
-		res = _renderFunc(_EASHandle, buffer, _config->bufSize, &c);
+		res = _renderFunc(_EASHandle, buffer, _config->mixBufferSize, &c);
 		if (res) {
-			warning("error rendering EAS samples: %d", res);
+			warning("error rendering EAS samples: %d", (int32)res);
 			return -1;
 		}
 
 #ifdef EAS_DUMPSTREAM
 		if (_dump.isOpen())
-			_dump.write(buffer, c * _config->channels * 2);
+			_dump.write(buffer, c * _config->numChannels * 2);
 #endif
 
-		buffer += c * _config->channels;
+		buffer += c * _config->numChannels;
 	}
 
 	return numSamples;
 }
 
 bool MidiDriver_EAS::isStereo() const {
-	return _config->channels == 2;
+	return _config->numChannels == 2;
 }
 
 int MidiDriver_EAS::getRate() const {
-	return _config->rate;
+	return _config->sampleRate;
 }
 
 bool MidiDriver_EAS::endOfData() const {
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 246b843072a..47a5320b401 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -135,7 +135,7 @@ public:
 		#ifdef USE_MT32EMU
 		LINK_PLUGIN(MT32)
 		#endif
-		#if defined(__ANDROID__)
+		#if defined(USE_SONIVOX) || defined(__ANDROID__)
 		LINK_PLUGIN(EAS)
 		#endif
 		LINK_PLUGIN(ADLIB)
diff --git a/base/version.cpp b/base/version.cpp
index 18003142168..f995f9dc36d 100644
--- a/base/version.cpp
+++ b/base/version.cpp
@@ -137,6 +137,10 @@ const char gScummVMFeatures[] = ""
 	"FluidSynth "
 #endif
 
+#ifdef USE_SONIVOX
+	"EAS "
+#endif
+
 #ifdef USE_MIKMOD
 	"MikMod "
 #endif
diff --git a/configure b/configure
index 9afd6cd3333..d5559372305 100755
--- a/configure
+++ b/configure
@@ -162,6 +162,7 @@ _vpx=auto
 _faad=auto
 _fluidsynth=auto
 _fluidlite=auto
+_sonivox=auto
 _opengl_mode=auto
 _opengl_game_classic=auto
 _opengl_game_shaders=auto
@@ -1048,6 +1049,10 @@ Optional Libraries:
                            installed (optional)
   --disable-fluidlite      disable fluidlite MIDI driver [autodetect]
 
+  --with-sonivox-prefix=DIR prefix where libsonivox is
+                           installed (optional)
+  --disable-sonivox        disable EAS MIDI driver [autodetect]
+
   --with-ieee1284-prefix=DIR prefix where libieee1284 is installed (optional)
   --enable-opl2lpt         enable OPL2LPT support
 
@@ -1222,6 +1227,8 @@ for ac_option in $@; do
 	--enable-fluidsynth)          _fluidsynth=yes        ;;
 	--disable-fluidlite)          _fluidlite=no          ;;
 	--enable-fluidlite)           _fluidlite=yes         ;;
+	--disable-sonivox)            _sonivox=no            ;;
+	--enable-sonivox)             _sonivox=yes           ;;
 	--enable-readline)            _readline=yes          ;;
 	--disable-readline)           _readline=no           ;;
 	--enable-freetype2)           _freetype2=yes         ;;
@@ -1295,6 +1302,11 @@ for ac_option in $@; do
 		FLUIDLITE_CFLAGS="-I$arg/include"
 		FLUIDLITE_LIBS="-L$arg/lib"
 		;;
+	--with-sonivox-prefix=*)
+		arg=`echo $ac_option | cut -d '=' -f 2`
+		SONIVOX_CFLAGS="-I$arg/include"
+		SONIVOX_LIBS="-L$arg/lib"
+		;;
 	--with-mpeg2-prefix=*)
 		arg=`echo $ac_option | cut -d '=' -f 2`
 		MPEG2_CFLAGS="-I$arg/include"
@@ -5909,6 +5921,36 @@ else
 fi
 echo "$_fluidlite"
 
+#
+# Check for Sonivox
+#
+echocheck "Sonivox"
+
+append_var SONIVOX_LIBS "-lsonivox"
+if test "$_sonivox" = auto; then
+	_sonivox=no
+	cat > $TMPC << EOF
+#include <sonivox/eas.h>
+int main(void) { /* delete_fluid_settings(new_fluid_settings()); */ return 0; }
+EOF
+	cc_check_no_clean $SONIVOX_CFLAGS $SONIVOX_LIBS && _sonivox=yes
+	if test "$_sonivox" != yes && test "$_pkg_config" = "yes" && $_pkgconfig --exists sonivox; then
+		SONIVOX_LIBS="`$_pkgconfig --static --libs sonivox`"
+		cc_check_no_clean $SONIVOX_CFLAGS $SONIVOX_LIBS && _sonivox=yes
+	fi
+	if test "$_sonivox" != yes && test "$_pkg_config" = "yes" && $_pkgconfig --exists sonivox-static; then
+		SONIVOX_LIBS="`$_pkgconfig --static --libs sonivox-static`"
+		cc_check_no_clean $SONIVOX_CFLAGS $SONIVOX_LIBS && _sonivox=yes
+	fi
+	cc_check_clean
+fi
+if test "$_sonivox" = yes; then
+	append_var LIBS "$SONIVOX_LIBS"
+	append_var INCLUDES "$SONIVOX_CFLAGS"
+fi
+define_in_config_if_yes "$_sonivox" 'USE_SONIVOX'
+echo "$_sonivox"
+
 #
 # Check for readline if text_console is enabled
 #


Commit: 2e68867e98f5b0e9d8521523efae1b5030dc7c60
    https://github.com/scummvm/scummvm/commit/2e68867e98f5b0e9d8521523efae1b5030dc7c60
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-06T14:10:50+02:00

Commit Message:
AUDIO: Remove dynamic load of EAS for Android and fix DLS loading

Android 7 prevents loading of private libraries like AES.
DLS support was also broken because of a change in API.

Changed paths:
    audio/softsynth/eas.cpp


diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index 84e8745ba37..7b6cfe2d8a2 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -21,18 +21,10 @@
 
 #include "common/scummsys.h"
 
-#if defined(USE_SONIVOX) || defined(__ANDROID__)
+#if defined(USE_SONIVOX)
 
-#ifdef USE_SONIVOX
 #include <sonivox/eas.h>
 #include <sonivox/eas_reverb.h>
-#else
-#define EAS_DLOPEN
-#endif
-
-#ifdef EAS_DLOPEN
-#include <dlfcn.h>
-#endif
 
 #include "common/debug.h"
 #include "common/endian.h"
@@ -46,7 +38,7 @@
 #include "audio/musicplugin.h"
 #include "audio/mixer.h"
 
-//#define EAS_DUMPSTREAM
+//#define EAS_DUMPSTREAM "/sdcard/eas.dump"
 
 // NOTE:
 // EAS's render function *only* accepts one mix buffer size. it's defined at
@@ -60,18 +52,35 @@
 // from rate_arm.cpp
 #define INTERMEDIATE_BUFFER_SIZE 512
 
-#ifdef EAS_DLOPEN
-// so far all android versions have the very same library version
-#define EAS_LIBRARY "libsonivox.so"
-#define EAS_KNOWNVERSION 0x03060a0e
-#endif
+// EAS does many 1 byte reads, avoid seeking by caching values
+struct EAS_FileHandle {
+	Common::SeekableReadStream *stream;
+	int64 size;
+	int64 pos;
+};
 
-#ifndef USE_SONIVOX
-#define EAS_MODULE_REVERB 2
-#define EAS_PARAM_REVERB_BYPASS 0
-#define EAS_PARAM_REVERB_PRESET 1
-#define EAS_PARAM_REVERB_CHAMBER 2
-#endif
+static int EAS_DLS_read(void *handle, void *buf, int offset, int size) {
+	EAS_FileHandle *fh = (EAS_FileHandle *)handle;
+	if (fh->pos != offset) {
+		if (!fh->stream->seek(offset)) {
+			fh->pos = -1;
+			return 0;
+		}
+		fh->pos = offset;
+	}
+	int ret = fh->stream->read(buf, size);
+	fh->pos += ret;
+
+	return ret;
+}
+
+static int EAS_DLS_size(void *handle) {
+	EAS_FileHandle *fh = (EAS_FileHandle *)handle;
+	if (fh->size < 0) {
+		fh->size = fh->stream->size();
+	}
+	return fh->size;
+}
 
 class MidiDriver_EAS : public MidiDriver_MPU401, Audio::AudioStream {
 public:
@@ -80,7 +89,7 @@ public:
 
 	// MidiDriver
 	int open() override;
-	bool isOpen() const override { return _isOpen; }
+	bool isOpen() const override { return _EASHandle; }
 
 	void close() override;
 	void send(uint32 b) override;
@@ -96,97 +105,6 @@ public:
 	bool endOfData() const override;
 
 private:
-#ifndef USE_SONIVOX
-	typedef long EAS_RESULT;
-
-	typedef unsigned EAS_BOOL;
-
-	typedef unsigned char EAS_U8;
-	typedef signed char EAS_I8;
-	typedef char EAS_CHAR;
-
-	typedef unsigned short EAS_U16;
-	typedef short EAS_I16;
-
-	typedef unsigned long EAS_U32;
-	typedef long EAS_I32;
-
-	typedef short EAS_PCM;
-
-	struct S_EAS_LIB_CONFIG {
-		EAS_U32 libVersion;
-		EAS_BOOL checkedVersion;
-		EAS_I32 maxVoices;
-		EAS_I32 numChannels;
-		EAS_I32 sampleRate;
-		EAS_I32 mixBufferSize;
-		EAS_BOOL filterEnabled;
-		EAS_U32 buildTimeStamp;
-		EAS_CHAR *buildGUID;
-	};
-
-#ifdef DLS_SYNTHESIZER
-	struct EAS_FILE_LOCATOR {
-		const char *path;
-		int fd;
-		long long offset;
-		long long length;
-	};
-#endif
-
-	typedef void * EAS_DATA_HANDLE;
-	typedef void * EAS_HANDLE;
-#endif
-
-	typedef const S_EAS_LIB_CONFIG *(*ConfigFunc)();
-	typedef EAS_RESULT (*InitFunc)(EAS_DATA_HANDLE *);
-	typedef EAS_RESULT (*ShutdownFunc)(EAS_DATA_HANDLE);
-	typedef EAS_RESULT (*SetParameterFunc)(EAS_DATA_HANDLE, EAS_I32, EAS_I32, EAS_I32);
-	typedef EAS_RESULT (*SetVolumeFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_I32);
-	typedef EAS_RESULT (*OpenStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE *, EAS_HANDLE);
-	typedef EAS_RESULT (*WriteStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_U8 *, EAS_I32);
-	typedef EAS_RESULT (*CloseStreamFunc)(EAS_DATA_HANDLE, EAS_HANDLE);
-	typedef EAS_RESULT (*RenderFunc)(EAS_DATA_HANDLE, EAS_PCM *, EAS_I32, EAS_I32 *);
-#ifdef DLS_SYNTHESIZER
-	typedef EAS_RESULT (*LoadDLSFunc)(EAS_DATA_HANDLE, EAS_HANDLE, EAS_FILE_LOCATOR *);
-#endif
-
-#ifdef EAS_DLOPEN
-	template<typename T>
-	void sym(T &t, const char *symbol) {
-		union {
-			void *v;
-			T t;
-		} u;
-
-		assert(sizeof(u.v) == sizeof(u.t));
-
-		u.v = dlsym(_dlHandle, symbol);
-
-		if (!u.v)
-			warning("couldn't resolve %s from " EAS_LIBRARY, symbol);
-
-		t = u.t;
-	}
-
-	void *_dlHandle;
-#endif
-
-	bool _isOpen;
-
-	ConfigFunc _configFunc;
-	InitFunc _initFunc;
-	ShutdownFunc _shutdownFunc;
-	SetParameterFunc _setParameterFunc;
-	SetVolumeFunc _setVolumeFunc;
-	OpenStreamFunc _openStreamFunc;
-	WriteStreamFunc _writeStreamFunc;
-	CloseStreamFunc _closeStreamFunc;
-	RenderFunc _renderFunc;
-#ifdef DLS_SYNTHESIZER
-	LoadDLSFunc _loadDLSFunc;
-#endif
-
 	const S_EAS_LIB_CONFIG *_config;
 	EAS_DATA_HANDLE _EASHandle;
 	EAS_HANDLE _midiStream;
@@ -202,22 +120,6 @@ private:
 
 MidiDriver_EAS::MidiDriver_EAS() :
 	MidiDriver_MPU401(),
-#ifdef USE_DLOPEN
-	_dlHandle(0),
-#endif
-	_configFunc(0),
-	_initFunc(0),
-	_shutdownFunc(0),
-	_setParameterFunc(0),
-	_setVolumeFunc(0),
-	_openStreamFunc(0),
-#ifdef DLS_SYNTHESIZER
-	_loadDLSFunc(0),
-#endif
-	_isOpen(false),
-	_writeStreamFunc(0),
-	_closeStreamFunc(0),
-	_renderFunc(0),
 	_config(0),
 	_EASHandle(0),
 	_midiStream(0),
@@ -236,37 +138,13 @@ int MidiDriver_EAS::open() {
 	if (isOpen())
 		return MERR_ALREADY_OPEN;
 
-#ifdef EAS_DLOPEN
-	_dlHandle = dlopen(EAS_LIBRARY, RTLD_LAZY);
-	if (!_dlHandle) {
-		warning("error opening " EAS_LIBRARY ": %s", dlerror());
-		return MERR_DEVICE_NOT_AVAILABLE;
-	}
-
-	sym(_configFunc, "EAS_Config");
-	if (!_configFunc) {
-		close();
-		return -1;
-	}
-#else
-	_configFunc = EAS_Config;
-#endif
-
-	_config = _configFunc();
+	_config = EAS_Config();
 	if (!_config) {
 		close();
 		warning("error retrieving EAS library configuration");
 		return -1;
 	}
 
-#ifdef EAS_DLOPEN
-	if (_config->libVersion != EAS_KNOWNVERSION) {
-		close();
-		warning("unknown EAS library version: 0x%08x", (int32)_config->libVersion);
-		return -1;
-	}
-#endif
-
 	if (_config->numChannels > 2) {
 		close();
 		warning("unsupported number of EAS channels: %d", (int32)_config->numChannels);
@@ -280,67 +158,59 @@ int MidiDriver_EAS::open() {
 		return -1;
 	}
 
-#ifdef EAS_DLOPEN
-	sym(_initFunc, "EAS_Init");
-	sym(_shutdownFunc, "EAS_Shutdown");
-	sym(_setParameterFunc, "EAS_SetParameter");
-	sym(_setVolumeFunc, "EAS_SetVolume");
-	sym(_openStreamFunc, "EAS_OpenMIDIStream");
-	sym(_writeStreamFunc, "EAS_WriteMIDIStream");
-	sym(_closeStreamFunc, "EAS_CloseMIDIStream");
-	sym(_renderFunc, "EAS_Render");
-
-	if (!_initFunc || !_shutdownFunc || !_setParameterFunc ||
-			!_openStreamFunc || !_writeStreamFunc || !_closeStreamFunc ||
-			!_renderFunc) {
-		close();
-		return -1;
-	}
-
-#ifdef DLS_SYNTHESIZER
-	sym(_loadDLSFunc, "EAS_LoadDLSCollection");
-
-	if (!_loadDLSFunc) {
-		close();
-		return -1;
-	}
-#endif
-#else
-	_initFunc = EAS_Init;
-	_shutdownFunc = EAS_Shutdown;
-	_setParameterFunc = EAS_SetParameter;
-	_setVolumeFunc = EAS_SetVolume;
-	_openStreamFunc = EAS_OpenMIDIStream;
-	_writeStreamFunc = EAS_WriteMIDIStream;
-	_closeStreamFunc = EAS_CloseMIDIStream;
-	_renderFunc = EAS_Render;
-#ifdef DLS_SYNTHESIZER
-	_loadDLSFunc = EAS_LoadDLSCollection;
-#endif
-#endif
-
-	EAS_RESULT res = _initFunc(&_EASHandle);
+	EAS_RESULT res = EAS_Init(&_EASHandle);
 	if (res) {
 		close();
 		warning("error initializing the EAS library: %d", (int32)res);
 		return -1;
 	}
 
-	res = _setParameterFunc(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
+	res = EAS_SetParameter(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
 	if (res)
 		warning("error setting reverb preset: %d", (int32)res);
 
-	res = _setParameterFunc(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, 0);
+	res = EAS_SetParameter(_EASHandle, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, 0);
 	if (res)
 		warning("error disabling reverb bypass: %d", (int32)res);
 
 	// 90 is EAS's default, max is 100
 	// so the option slider will only work from 0.1 to 1.1
-	res = _setVolumeFunc(_EASHandle, 0, ConfMan.getInt("midi_gain") - 10);
+	res = EAS_SetVolume(_EASHandle, 0, ConfMan.getInt("midi_gain") - 10);
 	if (res)
 		warning("error setting EAS master volume: %d", (int32)res);
 
-	res = _openStreamFunc(_EASHandle, &_midiStream, 0);
+	if (ConfMan.hasKey("soundfont")) {
+		const Common::String dls = ConfMan.get("soundfont");
+
+		debug("loading DLS file '%s'", dls.c_str());
+		Common::FSNode fsnode(dls);
+		Common::SeekableReadStream *stream = fsnode.createReadStream();
+
+		if (stream) {
+			EAS_FileHandle h;
+			h.stream = stream;
+			h.size = -1;
+			h.pos = -1;
+
+			EAS_FILE f;
+			memset(&f, 0, sizeof(EAS_FILE));
+			f.handle = &h;
+			f.readAt = EAS_DLS_read;
+			f.size = EAS_DLS_size;
+
+			res = EAS_LoadDLSCollection(_EASHandle, 0, &f);
+			if (res)
+				warning("error loading DLS file '%s': %d", dls.c_str(), (int32)res);
+			else
+				debug("DLS file loaded");
+
+			delete stream;
+		} else {
+			warning("error loading DLS file '%s': can't be opened", dls.c_str());
+		}
+	}
+
+	res = EAS_OpenMIDIStream(_EASHandle, &_midiStream, 0);
 	if (res) {
 		close();
 		warning("error opening EAS MIDI stream: %d", (int32)res);
@@ -357,43 +227,23 @@ int MidiDriver_EAS::open() {
 			"tempo:%u rounds:%u", (int32)_config->maxVoices, (int32)_config->numChannels,
 			(int32)_config->sampleRate, (int32)_config->mixBufferSize, _baseTempo, _rounds);
 
-#ifdef DLS_SYNTHESIZER
-	// TODO doesn't seem to work with midi streams?
-	if (ConfMan.hasKey("soundfont")) {
-		const Common::String dls = ConfMan.get("soundfont");
-
-		debug("loading DLS file '%s'", dls.c_str());
-
-		EAS_FILE_LOCATOR f;
-		memset(&f, 0, sizeof(EAS_FILE_LOCATOR));
-		f.path = dls.c_str();
-
-		res = _loadDLSFunc(_EASHandle, 0, &f);
-		if (res)
-			warning("error loading DLS file '%s': %d", dls.c_str(), (int32)res);
-		else
-			debug("DLS file loaded");
-	}
-#endif
-
 #ifdef EAS_DUMPSTREAM
-	if (!_dump.open("/sdcard/eas.dump"))
+	if (!_dump.open(EAS_DUMPSTREAM))
 		warning("error opening EAS dump file");
 #endif
 
 	g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType,
-										&_soundHandle, this, -1,
-										Audio::Mixer::kMaxChannelVolume, 0,
-										DisposeAfterUse::NO, true);
+	                                 &_soundHandle, this, -1,
+	                                 Audio::Mixer::kMaxChannelVolume, 0,
+	                                 DisposeAfterUse::NO, true);
 
-	_isOpen = true;
 	return 0;
 }
 
 void MidiDriver_EAS::close() {
 	MidiDriver_MPU401::close();
 
-	if (!isOpen())
+	if (!_EASHandle)
 		return;
 
 	g_system->getMixer()->stopHandle(_soundHandle);
@@ -407,29 +257,18 @@ void MidiDriver_EAS::close() {
 	g_system->delayMillis((_baseTempo * _rounds) / 1000);
 
 	if (_midiStream) {
-		EAS_RESULT res = _closeStreamFunc(_EASHandle, _midiStream);
+		EAS_RESULT res = EAS_CloseMIDIStream(_EASHandle, _midiStream);
 		if (res)
 			warning("error closing EAS MIDI stream: %d", (int32)res);
 
 		_midiStream = 0;
 	}
 
-	if (_EASHandle) {
-		EAS_RESULT res = _shutdownFunc(_EASHandle);
-		if (res)
-			warning("error shutting down the EAS library: %d", (int32)res);
-
-		_EASHandle = 0;
-	}
-
-#ifdef EAS_DLOPEN
-	if (dlclose(_dlHandle))
-		warning("error closing " EAS_LIBRARY ": %s", dlerror());
-
-	_dlHandle = 0;
-#endif
+	EAS_RESULT res = EAS_Shutdown(_EASHandle);
+	if (res)
+		warning("error shutting down the EAS library: %d", (int32)res);
 
-	_isOpen = false;
+	_EASHandle = 0;
 }
 
 void MidiDriver_EAS::send(uint32 b) {
@@ -444,7 +283,7 @@ void MidiDriver_EAS::send(uint32 b) {
 	if ((buf[0] >> 4) == 0xC || (buf[0] >> 4) == 0xD)
 		len = 2;
 
-	int32 res = _writeStreamFunc(_EASHandle, _midiStream, buf, len);
+	int32 res = EAS_WriteMIDIStream(_EASHandle, _midiStream, buf, len);
 	if (res)
 		warning("error writing to EAS MIDI stream: %d", (int32)res);
 }
@@ -461,7 +300,7 @@ void MidiDriver_EAS::sysEx(const byte *msg, uint16 length) {
 	memcpy(buf + 1, msg, length);
 	buf[length + 1] = 0xF7;
 
-	EAS_RESULT res = _writeStreamFunc(_EASHandle, _midiStream, buf, length + 2);
+	EAS_RESULT res = EAS_WriteMIDIStream(_EASHandle, _midiStream, buf, length + 2);
 	if (res)
 		warning("error writing to EAS MIDI stream: %d", (int32)res);
 }
@@ -492,7 +331,7 @@ int MidiDriver_EAS::readBuffer(int16 *buffer, const int numSamples) {
 			(*_timerProc)(_timerParam);
 
 		// if there are no MIDI events, this just renders silence
-		res = _renderFunc(_EASHandle, buffer, _config->mixBufferSize, &c);
+		res = EAS_Render(_EASHandle, buffer, _config->mixBufferSize, &c);
 		if (res) {
 			warning("error rendering EAS samples: %d", (int32)res);
 			return -1;
@@ -560,10 +399,6 @@ Common::Error EASMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver
 	return Common::kNoError;
 }
 
-//#if PLUGIN_ENABLED_DYNAMIC(EAS)
-	//REGISTER_PLUGIN_DYNAMIC(EAS, PLUGIN_TYPE_MUSIC, EASMusicPlugin);
-//#else
-	REGISTER_PLUGIN_STATIC(EAS, PLUGIN_TYPE_MUSIC, EASMusicPlugin);
-//#endif
+REGISTER_PLUGIN_STATIC(EAS, PLUGIN_TYPE_MUSIC, EASMusicPlugin);
 
 #endif




More information about the Scummvm-git-logs mailing list