[Scummvm-git-logs] scummvm master -> 2c7d70ac105884c90a035226db2e78a20d2daea4
sev-
noreply at scummvm.org
Tue Jun 30 23:13:27 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
b0728503c6 AUDIO: Add HMI Infinite Audio DSP library reimplementation
1759d44803 AUDIO: HMI: Infinite Audio clean-up
2c7d70ac10 AUDIO: HMI: Turn it into an optional component
Commit: b0728503c6482f4a7eae5716f51eb3b8af97236e
https://github.com/scummvm/scummvm/commit/b0728503c6482f4a7eae5716f51eb3b8af97236e
Author: AndywinXp (andywinxp at gmail.com)
Date: 2026-07-01T01:13:22+02:00
Commit Message:
AUDIO: Add HMI Infinite Audio DSP library reimplementation
Changed paths:
A audio/effects/hmi/hmi_interface.h
A audio/effects/hmi/hmi_types.h
A audio/effects/hmi/hmifxfp.cpp
A audio/effects/hmi/hmifxfp.h
A audio/effects/hmi/hmifxlib.cpp
A audio/effects/hmi/hmifxlib.h
A audio/effects/hmi/interfaces/envelope.cpp
A audio/effects/hmi/interfaces/envelope.h
A audio/effects/hmi/interfaces/filter1.cpp
A audio/effects/hmi/interfaces/filter1.h
A audio/effects/hmi/interfaces/mono_delay.cpp
A audio/effects/hmi/interfaces/mono_delay.h
A audio/effects/hmi/interfaces/phasor.cpp
A audio/effects/hmi/interfaces/phasor.h
A audio/effects/hmi/interfaces/resonator.cpp
A audio/effects/hmi/interfaces/resonator.h
A audio/effects/hmi/interfaces/reverb1.cpp
A audio/effects/hmi/interfaces/reverb1.h
A audio/effects/hmi/interfaces/reverb2.cpp
A audio/effects/hmi/interfaces/reverb2.h
A audio/effects/hmi/interfaces/ring_modulator.cpp
A audio/effects/hmi/interfaces/ring_modulator.h
A audio/effects/hmi/interfaces/stereo_delay.cpp
A audio/effects/hmi/interfaces/stereo_delay.h
audio/module.mk
diff --git a/audio/effects/hmi/hmi_interface.h b/audio/effects/hmi/hmi_interface.h
new file mode 100644
index 00000000000..e3f0fdc9f4f
--- /dev/null
+++ b/audio/effects/hmi/hmi_interface.h
@@ -0,0 +1,79 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACE_H
+#define AUDIO_EFFECTS_HMI_INTERFACE_H
+
+#include "audio/effects/hmi/hmi_types.h"
+
+namespace Audio {
+
+typedef const char *const *HMIParamNames;
+
+class HMIInterface {
+public:
+ virtual ~HMIInterface() {}
+
+ virtual int init(HMIPreset *, HMIEffectNode *) = 0;
+ virtual int uninit(HMIPreset *, HMIEffectNode *) = 0;
+ virtual int getMinDuration(HMIEffectNode *, uint32 *);
+ virtual int processBlock(HMIPreset *, HMIEffectNode *) = 0;
+ virtual int initEffect(HMIPreset *, HMIEffectNode *) = 0;
+ virtual int getEffectParam(HMIEffectNode *, int, float *, int *) = 0;
+ virtual int setEffectParam(HMIEffectNode *, int, float) = 0;
+
+ int effectStructSize() const { return _effectStructSize; }
+ int outChannels() const { return _outChannels; }
+ const char *interfaceName() const { return _interfaceName; }
+ HMIParamNames effectParams() const { return _effectParams; }
+ const float *paramMinValues() const { return _paramMinValues; }
+ const float *paramMaxValues() const { return _paramMaxValues; }
+ const float *paramDefaultValues() const { return _paramDefaultValues; }
+ const char *presetName() const { return _presetName; }
+ int presetId() const { return _presetId; }
+ int paramCount() const { return _paramCount; }
+
+protected:
+ static const double kHmiPi;
+ static const double kHmiTwoPi;
+ static const double kHmiMillis;
+
+ HMIInterface(int size, int channels,
+ const char *dialogName, HMIParamNames params, const float *mins,
+ const float *maxs, const float *defaults, const char *name, int id,
+ int paramCount);
+
+private:
+ int _effectStructSize;
+ int _outChannels;
+ const char *_interfaceName;
+ HMIParamNames _effectParams;
+ const float *_paramMinValues;
+ const float *_paramMaxValues;
+ const float *_paramDefaultValues;
+ char _presetName[64];
+ int _presetId;
+ int _paramCount;
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/hmi_types.h b/audio/effects/hmi/hmi_types.h
new file mode 100644
index 00000000000..0368330cc64
--- /dev/null
+++ b/audio/effects/hmi/hmi_types.h
@@ -0,0 +1,287 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_TYPES_H
+#define AUDIO_EFFECTS_HMI_TYPES_H
+
+#include "common/scummsys.h"
+
+namespace Audio {
+
+/* HMIPreset::flags */
+#define HMI_PRESET_FLAG_UNKNOWN_28 0x10000000U
+#define HMI_PRESET_FLAG_EFFECTS_INITIALIZED 0x20000000U
+#define HMI_PRESET_FLAG_USE_MALLOC 0x80000000U
+
+/* HMIProcessRequest::flags */
+#define HMI_PROCESS_USE_PRESET 0x00000001U
+#define HMI_PROCESS_FIND_PRESET_BY_NAME 0x00000002U
+#define HMI_PROCESS_ALLOCATE_OUTPUT 0x00000004U
+#define HMI_PROCESS_OVERRIDE_INPUT_FORMAT 0x00000008U
+#define HMI_PROCESS_OVERRIDE_OUTPUT_FORMAT 0x00000010U
+#define HMI_PROCESS_LOOKUP_ONLY 0x00000020U
+#define HMI_PROCESS_QUERY_OUTPUT_SIZE 0x00000040U
+#define HMI_PROCESS_INCLUDE_TAIL 0x00000080U
+#define HMI_PROCESS_DERIVE_OUTPUT_FORMAT 0x00000200U
+#define HMI_PROCESS_DISABLE_CLAMPING 0x00000400U
+
+/* HMIEffectNode::channelMode */
+#define HMI_EFFECT_CHANNEL_MONO 0x00000001U
+#define HMI_EFFECT_CHANNEL_STEREO 0x00000002U
+#define HMI_EFFECT_STEREO_ROUTING_MASK 0x0000000AU
+
+/* HMIFileDescriptor::fileFlags */
+#define HMI_FILE_FLAG_DIRTY 0x00008000U
+
+class HMIInterface;
+
+struct HMIFormat;
+struct HMIEffectNode;
+struct HMIPreset;
+
+struct HMIFormat {
+ uint16 fmtBeginSection;
+ uint16 numChannels;
+ uint32 sampleRate;
+ uint32 byteRate;
+ uint16 blockAlign;
+ uint16 bitsPerSample;
+ uint16 fmtEndSection;
+};
+
+struct HMIEffectNode {
+ uint32 flags;
+ int outputBus;
+ int sendChannel;
+ uint32 channelMode;
+ int outputBufSize;
+ HMIInterface *interface;
+ HMIEffectNode *next;
+};
+
+#define HMI_EFFECT_NODE_HEADER \
+ uint32 flags; \
+ int outputBus; \
+ int sendChannel; \
+ uint32 channelMode; \
+ int outputBufSize; \
+ HMIInterface *interface; \
+ HMIEffectNode *next
+
+struct HMIPreset {
+ uint32 flags;
+ char name[64];
+ int chunkSizeInMs;
+ float *floatBufLeftActive;
+ float *floatBufRightActive;
+ float *floatBufLeftAlt;
+ float *floatBufRightAlt;
+ float *floatBufLeft0;
+ float *floatBufLeft1;
+ float *floatBufRight0;
+ float *floatBufRight1;
+ int pingPongIndex;
+ uint32 chunkSizeInSamples;
+ uint32 chunkSize;
+ int lockLevel;
+ int allocatedHeapSize;
+ uint8 reserved[980];
+ HMIEffectNode *effectChain;
+ HMIFormat *outputFmt;
+ HMIFormat *inputFmt;
+ HMIPreset *next;
+};
+
+struct HMIInitData {
+ uint32 *a;
+ uint32 *b;
+ int heapSize;
+ void *heapPtr;
+ void *(*mallocFunc)(size_t);
+ void (*freeFunc)(void *);
+};
+
+struct HMILibrary {
+ char description[64];
+ char authorName[64];
+ uint8 data[20];
+ HMIPreset *effectPtr;
+ HMIFormat inputFmt;
+ HMIFormat outputFmt;
+};
+
+struct HMIProcessRequest {
+ uint32 flags;
+ HMIPreset *presetPtr;
+ char *effectName;
+ uint8 *dstBuf;
+ uint32 dstLen;
+ uint8 *srcBuf;
+ uint32 srcLen;
+ HMIFormat *inputFmt;
+ HMIFormat *outputFmt;
+};
+
+struct HMIFileDescriptor {
+ int fileFlags;
+ char filename[128];
+ uint8 *fileBuffer;
+ int fileSize;
+ int fileSizeExp;
+ uint8 *ptrToDescription;
+ int firstPresetPos;
+ uint8 *ptrToFirstPresetSection;
+ uint8 *ptrToFirstEffectSection;
+ uint8 *ptrToEffectParams;
+ uint8 *currentPos;
+ uint8 *anotherPtrToDescription;
+};
+
+struct HMIFilter1Node {
+ HMI_EFFECT_NODE_HEADER;
+ int filterType;
+ float cutoffFrequency;
+ float centerFrequency;
+ float bandWidth;
+ float coeff_b0, coeff_b1, coeff_b2, coeff_a1, coeff_a2;
+ float state_x1, state_x2, state_x3, state_y1;
+ float state_x1b, state_x2b, state_x3b, state_y1b;
+};
+
+struct HMIRingModulatorNode {
+ HMI_EFFECT_NODE_HEADER;
+ float frequency;
+ float modulatorType;
+ float modulateOutOfPhase;
+ float dryOut;
+ float wetOut;
+ float phase;
+};
+
+struct HMIResonatorNode {
+ HMI_EFFECT_NODE_HEADER;
+ float cutoffFrequency;
+ float bandWidth;
+ float resonance;
+ float coeff1;
+ float coeff2;
+ float stateX1;
+ float stateX2;
+};
+
+struct HMIReverbEchoStage {
+ float *buffer;
+ int writeHead;
+ int readHead;
+ int bufSizeInSamples;
+ float lastOutput;
+ float decayCoeff;
+};
+
+struct HMIReverb1Node {
+ HMI_EFFECT_NODE_HEADER;
+ float reverbMax;
+ float reverbTime;
+ float preDelay;
+ int preDelaySamples;
+ int bufSizeBytes;
+ HMIReverbEchoStage echoStages[4];
+ float dryOut;
+ float wetOut;
+};
+
+struct HMIReverb2Node {
+ HMI_EFFECT_NODE_HEADER;
+ float reverbMax;
+ float reverbTime;
+ float preDelay;
+ int preDelaySamples;
+ int bufSizeBytes;
+ HMIReverbEchoStage echoStages[6];
+ float dryOut;
+ float wetOut;
+};
+
+struct HMIPhasorNode {
+ HMI_EFFECT_NODE_HEADER;
+ float rate;
+ float depth;
+ float centerFrequency;
+ float feedback;
+ float dryOut;
+ float wetOut;
+ float phase;
+ float b0, b1, a1;
+ float state_x1L, state_y1L, state_x1R, state_y1R;
+ float state_x2L, state_y2L, state_x2R, state_y2R;
+ float coeff;
+ float modPhase;
+};
+
+struct HMIEnvelopeNode {
+ HMI_EFFECT_NODE_HEADER;
+ float envPoints;
+ float pointTime[8];
+ float pointAmp[8];
+ float initGuard;
+ int segRemaining[8];
+ int currentSegment;
+ float currentAmp;
+ float segSlopes[8];
+};
+
+struct HMIMonoDelayNode {
+ HMI_EFFECT_NODE_HEADER;
+ float maxDelayTime;
+ float delayTime;
+ float unused0;
+ float feedback;
+ float dryOut;
+ float wetOut;
+ float *delayBuf;
+ int unused1;
+ int bufSizeBytes;
+ int unused2;
+ int writeIndex;
+ int pad;
+};
+
+struct HMIStereoDelayNode {
+ HMI_EFFECT_NODE_HEADER;
+ float maxDelayTime;
+ float delayTimeL;
+ float delayTimeR;
+ float feedback;
+ float dryOut;
+ float wetOut;
+ float *delayBufL;
+ float *delayBufR;
+ int bufSizeBytesL;
+ int bufSizeBytesR;
+ int writeIndexL;
+ int writeIndexR;
+};
+
+#undef HMI_EFFECT_NODE_HEADER
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/hmifxfp.cpp b/audio/effects/hmi/hmifxfp.cpp
new file mode 100644
index 00000000000..d4719bdc139
--- /dev/null
+++ b/audio/effects/hmi/hmifxfp.cpp
@@ -0,0 +1,79 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/hmifxfp.h"
+
+namespace Audio {
+
+const double HMIInterface::kHmiPi = 3.14159265;
+const double HMIInterface::kHmiTwoPi = 6.2831853;
+const double HMIInterface::kHmiMillis = 0.001;
+
+static void copyName(char *dst, const char *src) {
+ int i = 0;
+ while (i != 63 && src[i]) {
+ dst[i] = src[i];
+ ++i;
+ }
+
+ dst[i] = 0;
+ while (++i != 64)
+ dst[i] = 0;
+}
+
+HMIInterface::HMIInterface(int size, int channels,
+ const char *dialogName, HMIParamNames params, const float *mins,
+ const float *maxs, const float *defaults, const char *name, int id,
+ int paramCount)
+ : _effectStructSize(size), _outChannels(channels),
+ _interfaceName(dialogName), _effectParams(params), _paramMinValues(mins),
+ _paramMaxValues(maxs), _paramDefaultValues(defaults),
+ _presetId(id), _paramCount(paramCount) {
+ copyName(_presetName, name);
+}
+
+int HMIInterface::getMinDuration(HMIEffectNode *, uint32 *duration) {
+ *duration = 0;
+ return 0;
+}
+
+HMIFxFp::HMIFxFp() { initializeInterfaces(); }
+
+void HMIFxFp::initializeInterfaces() {
+ /* Original interface-list order at 0x10012A70. */
+ _interfaceList[0] = &_monoDelay;
+ _interfaceList[1] = &_stereoDelay;
+ _interfaceList[2] = &_reverb1;
+ _interfaceList[3] = &_filter1;
+ _interfaceList[4] = &_ringModulator;
+ _interfaceList[5] = &_envelope;
+ _interfaceList[6] = &_resonator;
+ _interfaceList[7] = &_phasor;
+ _interfaceList[8] = &_reverb2;
+ _interfaceList[9] = nullptr;
+}
+
+int HMIFxFp::hmiFXGetInterfaceList(HMIInterface ***outList) {
+ *outList = _interfaceList;
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/hmifxfp.h b/audio/effects/hmi/hmifxfp.h
new file mode 100644
index 00000000000..8e7d200388a
--- /dev/null
+++ b/audio/effects/hmi/hmifxfp.h
@@ -0,0 +1,59 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_HMIFXFP_H
+#define AUDIO_EFFECTS_HMI_HMIFXFP_H
+
+#include "audio/effects/hmi/interfaces/envelope.h"
+#include "audio/effects/hmi/interfaces/filter1.h"
+#include "audio/effects/hmi/interfaces/mono_delay.h"
+#include "audio/effects/hmi/interfaces/phasor.h"
+#include "audio/effects/hmi/interfaces/resonator.h"
+#include "audio/effects/hmi/interfaces/reverb1.h"
+#include "audio/effects/hmi/interfaces/reverb2.h"
+#include "audio/effects/hmi/interfaces/ring_modulator.h"
+#include "audio/effects/hmi/interfaces/stereo_delay.h"
+
+namespace Audio {
+
+class HMIFxFp {
+public:
+ HMIFxFp();
+ int hmiFXGetInterfaceList(HMIInterface ***outList);
+
+private:
+ void initializeInterfaces();
+
+ HMIMonoDelay _monoDelay;
+ HMIStereoDelay _stereoDelay;
+ HMIReverb1 _reverb1;
+ HMIFilter1 _filter1;
+ HMIRingModulator _ringModulator;
+ HMIEnvelope _envelope;
+ HMIResonator _resonator;
+ HMIPhasor _phasor;
+ HMIReverb2 _reverb2;
+ HMIInterface *_interfaceList[10];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/hmifxlib.cpp b/audio/effects/hmi/hmifxlib.cpp
new file mode 100644
index 00000000000..d89385c4e69
--- /dev/null
+++ b/audio/effects/hmi/hmifxlib.cpp
@@ -0,0 +1,959 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/hmifxlib.h"
+
+#include "common/file.h"
+#include "common/str.h"
+#include "common/stream.h"
+
+namespace Audio {
+
+/*
+ * This deliberately is not a plain integer cast. With the DLL's default x87
+ * control word, FISTP rounds to nearest with ties going to the even integer:
+ * 1.6 becomes 2, 2.5 stays 2, and 3.5 becomes 4. A C++ cast would instead
+ * truncate toward zero. FISTP also produces its integer-indefinite value for
+ * NaN and out-of-range inputs, so preserve that behavior here as well.
+ * AFAIK, we have no rounding helper that provides this exact combination of
+ * nearest-even rounding and fixed-width x87 overflow behavior. AFAIK.
+ */
+static int32 hmiFistp32(float value) {
+ if (value != value || value < -2147483648.0f || value >= 2147483648.0f)
+ return -2147483647 - 1;
+
+ int32 result = (int32)value;
+ float fraction = value - (float)result;
+
+ if (fraction > 0.5f || (fraction == 0.5f && (result % 2))) {
+ ++result;
+ } else if (fraction < -0.5f || (fraction == -0.5f && (result % 2))) {
+ --result;
+ }
+
+ return result;
+}
+
+static int16 hmiFistp16(float value) {
+ int32 result = hmiFistp32(value);
+ if (result < -32768 || result > 32767)
+ return -32768;
+
+ return (int16)result;
+}
+
+HMIFxLib::HMIFxLib()
+ : _numLoadedInterfaces(0), _curInterfaceIndex(0), _systemHeap(0),
+ _heapCursor(0), _heapEnd(0), _mallocFunc(malloc), _freeFunc(free) {
+ memset(_loadedInterfaces, 0, sizeof(_loadedInterfaces));
+ HMIInterface **list = nullptr;
+ _fxFp.hmiFXGetInterfaceList(&list);
+
+ while (_numLoadedInterfaces != 1024 && list[_numLoadedInterfaces]) {
+ _loadedInterfaces[_numLoadedInterfaces] = list[_numLoadedInterfaces];
+ ++_numLoadedInterfaces;
+ }
+
+ if (_numLoadedInterfaces != 1024)
+ _loadedInterfaces[_numLoadedInterfaces] = nullptr;
+}
+
+HMIFxLib::~HMIFxLib() {}
+
+HMIFxFp *HMIFxLib::effects() {
+ return &_fxFp;
+}
+
+int HMIFxLib::hmiFXInitSystem(HMIInitData *initData) {
+ if (initData->mallocFunc && initData->freeFunc) {
+ _mallocFunc = initData->mallocFunc;
+ _freeFunc = initData->freeFunc;
+ } else {
+ _mallocFunc = malloc;
+ _freeFunc = free;
+ }
+
+ initData->heapPtr = hmiFXMalloc((size_t)initData->heapSize);
+ if (!initData->heapPtr)
+ return 1;
+
+ hmiFXHeapInit(initData);
+ return 0;
+}
+
+int HMIFxLib::hmiFXUnInitSystem(HMIInitData *initData) {
+ if (initData->heapPtr)
+ hmiFXFree(initData->heapPtr);
+
+ initData->heapPtr = nullptr;
+ _systemHeap = _heapCursor = _heapEnd = nullptr;
+ return 0;
+}
+
+int HMIFxLib::hmiFXGetInterface(int interfaceId, HMIInterface **outInterface) {
+ for (unsigned int i = 0; i != _numLoadedInterfaces; ++i) {
+ if (_loadedInterfaces[i]->presetId() == interfaceId) {
+ *outInterface = _loadedInterfaces[i];
+ return 0;
+ }
+ }
+
+ return 7;
+}
+
+unsigned int HMIFxLib::hmiFXGenerateQueryString(char *buffer, const char *prefix, unsigned int id) {
+ if (id < 10)
+ return (unsigned int)snprintf(buffer, 32, "%s000%d", prefix, id);
+
+ if (id < 100)
+ return (unsigned int)snprintf(buffer, 32, "%s00%d", prefix, id);
+
+ if (id < 1000)
+ return (unsigned int)snprintf(buffer, 32, "%s0%d", prefix, id);
+
+ if (id < 10000)
+ return (unsigned int)snprintf(buffer, 32, "%s%d", prefix, id);
+
+ return id;
+}
+
+int HMIFxLib::hmiFXGetFirstInterface(HMIInterface **outInterface) {
+ if (!_numLoadedInterfaces)
+ return 7;
+
+ _curInterfaceIndex = 1;
+ *outInterface = _loadedInterfaces[0];
+ return 0;
+}
+
+int HMIFxLib::hmiFXGetNextInterface(HMIInterface **outInterface) {
+ if (_curInterfaceIndex == _numLoadedInterfaces)
+ return 7;
+
+ *outInterface = _loadedInterfaces[_curInterfaceIndex++];
+ return 0;
+}
+
+void *HMIFxLib::hmiFXHeapAlloc(int size) {
+ uint8 *result = _heapCursor;
+ if (!result || result + size > _heapEnd)
+ return nullptr;
+ _heapCursor += size;
+ return result;
+}
+
+void HMIFxLib::hmiFXHeapFree(void *) {}
+
+int HMIFxLib::hmiFXHeapInit(HMIInitData *data) {
+ _systemHeap = (uint8 *)data->heapPtr;
+ _heapCursor = _systemHeap;
+ _heapEnd = _systemHeap + data->heapSize;
+ return 0;
+}
+
+void *HMIFxLib::hmiFXHeapReset() {
+ _heapCursor = _systemHeap;
+ return _systemHeap;
+}
+
+void *HMIFxLib::hmiFXMalloc(size_t size) {
+ return _mallocFunc(size);
+}
+
+void HMIFxLib::hmiFXFree(void *ptr) {
+ _freeFunc(ptr);
+}
+
+int HMIFxLib::convertPCMToFloat(HMIPreset *preset, const uint8 *buffer, int samples) {
+ float *left = preset->floatBufLeftActive;
+ float *right = preset->floatBufRightActive;
+
+ if (preset->inputFmt->bitsPerSample == 8) {
+ if (preset->inputFmt->numChannels == 1) {
+ for (int i = 0; i != samples; ++i) {
+ left[i] = (float)((double)buffer[i] - 127.0);
+ }
+ } else {
+ for (int i = 0; i != samples; ++i) {
+ left[i] = (float)((double)buffer[i * 2] - 127.0);
+ right[i] = (float)((double)buffer[i * 2 + 1] - 127.0);
+ }
+ }
+ } else if (preset->inputFmt->bitsPerSample == 16) {
+ const int16 *input = (const int16 *)buffer;
+ if (preset->inputFmt->numChannels == 1) {
+ for (int i = 0; i != samples; ++i) {
+ left[i] = (float)input[i];
+ }
+ } else {
+ for (int i = 0; i != samples; ++i) {
+ left[i] = (float)input[i * 2];
+ right[i] = (float)input[i * 2 + 1];
+ }
+ }
+ }
+
+ return 0;
+}
+
+int HMIFxLib::convertFloatToPCM(HMIPreset *preset, uint8 *buffer, int samples, int clampOutput) {
+ float *left = preset->floatBufLeftAlt;
+ float *right = preset->floatBufRightAlt;
+
+ if (preset->outputFmt->bitsPerSample == 8) {
+ if (preset->outputFmt->numChannels == 1) {
+ for (int i = 0; i != samples; ++i) {
+ if (left[i] > 127.0f) {
+ buffer[i] = 255;
+ } else if (left[i] <= -128.0f) {
+ buffer[i] = 0;
+ } else {
+ buffer[i] = (uint8)((int64)((double)left[i] + 128.0));
+ }
+ }
+ } else {
+ for (int i = 0; i != samples; ++i) {
+ float values[2] = {left[i], right[i]};
+ for (int c = 0; c != 2; ++c) {
+ if (values[c] > 127.0f) {
+ buffer[i * 2 + c] = 255;
+ } else if (values[c] <= -128.0f) {
+ buffer[i * 2 + c] = 0;
+ } else {
+ buffer[i * 2 + c] = (uint8)(((int64)values[c]) ^ 0x80);
+ }
+ }
+ }
+ }
+ } else if (preset->outputFmt->bitsPerSample == 16) {
+ int16 *output = (int16 *)buffer;
+ int channels = preset->outputFmt->numChannels == 1 ? 1 : 2;
+ for (int i = 0; i != samples; ++i) {
+ for (int c = 0; c != channels; ++c) {
+ float value = c ? right[i] : left[i];
+ if (!clampOutput) {
+ output[i * channels + c] = hmiFistp16(value);
+ continue;
+ }
+
+ int converted = hmiFistp32(value);
+ if (converted > 32767) {
+ converted = 32767;
+ } else if (converted < -32767) {
+ converted = -32767;
+ }
+
+ output[i * channels + c] = (int16)converted;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetCreate(HMIPreset *preset) {
+ hmiFXHeapReset();
+
+ uint32 samples = preset->inputFmt->sampleRate * preset->chunkSizeInMs / 1000U;
+ int segmentBytes = 4 * (int)samples + 1024;
+ preset->chunkSizeInSamples = samples;
+ float *block = (float *)((preset->flags & HMI_PRESET_FLAG_USE_MALLOC) ? hmiFXMalloc(4 * segmentBytes)
+ : hmiFXHeapAlloc(4 * segmentBytes));
+ if (!block)
+ return 1;
+
+ preset->floatBufLeft0 = block;
+ preset->floatBufLeft1 = (float *)((uint8 *)block + segmentBytes);
+ preset->floatBufRight0 = (float *)((uint8 *)block + segmentBytes * 2);
+ preset->floatBufRight1 = (float *)((uint8 *)block + segmentBytes * 3);
+
+ resetMixBuffers(preset);
+ preset->effectChain = nullptr;
+ return 0;
+}
+
+void HMIFxLib::resetMixBuffers(HMIPreset *preset) {
+ preset->floatBufLeftActive = preset->floatBufLeft0;
+ preset->floatBufRightActive = preset->floatBufRight0;
+ preset->floatBufLeftAlt = preset->floatBufLeft1;
+ preset->floatBufRightAlt = preset->floatBufRight1;
+ preset->pingPongIndex = 0;
+}
+
+int HMIFxLib::hmiFXPresetDestroy(HMIPreset *preset) {
+ for (HMIEffectNode *node = preset->effectChain; node; node = node->next)
+ node->interface->uninit(preset, node);
+
+ if (preset->flags & HMI_PRESET_FLAG_USE_MALLOC)
+ hmiFXFree(preset->floatBufLeft0);
+
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetAddEffect(HMIPreset *preset, HMIEffectNode *newNode) {
+ int result = newNode->interface->init(preset, newNode);
+ if (result)
+ return result;
+
+ HMIEffectNode *tail = preset->effectChain;
+ if (!tail) {
+ preset->effectChain = newNode;
+ } else {
+ while (tail->next)
+ tail = tail->next;
+
+ tail->next = newNode;
+ }
+
+ newNode->next = nullptr;
+ preset->allocatedHeapSize = _systemHeap ? (int)(_heapCursor - _systemHeap) : 0;
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetGetByName(HMILibrary *library, const char *name, HMIPreset **outPreset) {
+ HMIPreset *preset = library->effectPtr;
+ if (!preset)
+ return 12;
+
+ *outPreset = nullptr;
+ while (preset && scumm_stricmp(preset->name, name)) {
+ preset = preset->next;
+ }
+
+ if (!preset)
+ return 13;
+
+ *outPreset = preset;
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetLock(HMIPreset *preset) {
+ if (!preset)
+ return 15;
+
+ if (preset->lockLevel) {
+ ++preset->lockLevel;
+ return 0;
+ }
+
+ preset->lockLevel = 1;
+
+ preset->flags &= ~(HMI_PRESET_FLAG_USE_MALLOC | HMI_PRESET_FLAG_EFFECTS_INITIALIZED);
+ for (HMIEffectNode *n = preset->effectChain; n; n = n->next)
+ n->interface->uninit(preset, n);
+
+ preset->flags |= HMI_PRESET_FLAG_USE_MALLOC;
+ for (HMIEffectNode *n = preset->effectChain; n; n = n->next)
+ n->interface->init(preset, n);
+
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetRelease(HMIPreset *preset) {
+ if (!preset)
+ return 15;
+
+ if (--preset->lockLevel == 0) {
+ for (HMIEffectNode *n = preset->effectChain; n; n = n->next)
+ n->interface->uninit(preset, n);
+
+ HMIEffectNode *chain = preset->effectChain;
+ preset->flags &= ~HMI_PRESET_FLAG_USE_MALLOC;
+ hmiFXPresetCreate(preset);
+ preset->effectChain = chain;
+
+ for (HMIEffectNode *n = chain; n; n = n->next)
+ n->interface->init(preset, n);
+ }
+
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetGetRouting(HMIPreset *preset, uint32 *routingOut) {
+ if (!preset)
+ return 15;
+
+ if (!preset->effectChain)
+ return 6;
+
+ HMIEffectNode *n = preset->effectChain;
+ while (n->next)
+ n = n->next;
+
+ *routingOut = (n->channelMode & HMI_EFFECT_STEREO_ROUTING_MASK) ? 2 : 1;
+ return 0;
+}
+
+void HMIFxLib::hmiFXSetWaveFmtEx(HMIFormat *f, int rate, uint16 bits, uint16 channels) {
+ f->numChannels = channels;
+ f->bitsPerSample = bits;
+ f->sampleRate = rate;
+ f->blockAlign = (uint16)(bits * channels / 8);
+ f->byteRate = f->blockAlign * rate;
+ f->fmtBeginSection = 1;
+ f->fmtEndSection = 0;
+}
+
+int HMIFxLib::hmiFXPresetCreateInstance(HMIPreset *source, HMIPreset **outInstance) {
+ if (!source)
+ return 15;
+
+ HMIPreset *copy = (HMIPreset *)hmiFXMalloc(sizeof(HMIPreset));
+ if (!copy) {
+ *outInstance = nullptr;
+ return 1;
+ }
+
+ memcpy(copy, source, sizeof(HMIPreset));
+ copy->effectChain = nullptr;
+ copy->flags = (copy->flags & ~(HMI_PRESET_FLAG_USE_MALLOC | HMI_PRESET_FLAG_EFFECTS_INITIALIZED | HMI_PRESET_FLAG_UNKNOWN_28)) | HMI_PRESET_FLAG_USE_MALLOC;
+
+ HMIEffectNode *previous = nullptr;
+ for (HMIEffectNode *src = source->effectChain; src; src = src->next) {
+ HMIEffectNode *node = (HMIEffectNode *)hmiFXMalloc(src->interface->effectStructSize());
+ if (!node) {
+ hmiFXPresetDestroyInstance(copy);
+ *outInstance = nullptr;
+ return 1;
+ }
+
+ memcpy(node, src, src->interface->effectStructSize());
+ node->next = nullptr;
+ node->interface->init(copy, node);
+
+ if (previous) {
+ previous->next = node;
+ } else {
+ copy->effectChain = node;
+ }
+
+ previous = node;
+ }
+
+ *outInstance = copy;
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetDestroyInstance(HMIPreset *preset) {
+ if (!preset)
+ return 15;
+
+ HMIEffectNode *node = preset->effectChain;
+ while (node) {
+ node->interface->uninit(preset, node);
+ HMIEffectNode *next = node->next;
+ hmiFXFree(node);
+ node = next;
+ }
+
+ hmiFXFree(preset);
+ return 0;
+}
+
+void HMIFxLib::processEffectChain(HMIPreset *preset) {
+ HMIEffectNode *node = preset->effectChain;
+ while (node) {
+ node->interface->processBlock(preset, node);
+ node = node->next;
+
+ if (node) {
+ preset->pingPongIndex ^= 1;
+ int active = preset->pingPongIndex;
+ preset->floatBufLeftActive = active ? preset->floatBufLeft1 : preset->floatBufLeft0;
+ preset->floatBufRightActive = active ? preset->floatBufRight1 : preset->floatBufRight0;
+ preset->floatBufLeftAlt = active ? preset->floatBufLeft0 : preset->floatBufLeft1;
+ preset->floatBufRightAlt = active ? preset->floatBufRight0 : preset->floatBufRight1;
+ }
+ }
+}
+
+int HMIFxLib::processPreset(HMIPreset *preset, HMIProcessRequest *req) {
+ if (!preset->effectChain)
+ return 6;
+
+ HMIFormat *savedInput = preset->inputFmt;
+ HMIFormat *savedOutput = preset->outputFmt;
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_INPUT_FORMAT)
+ preset->inputFmt = req->inputFmt;
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_OUTPUT_FORMAT)
+ preset->outputFmt = req->outputFmt;
+
+ if (req->flags & HMI_PROCESS_DERIVE_OUTPUT_FORMAT) {
+ uint32 routing;
+ hmiFXPresetGetRouting(preset, &routing);
+ hmiFXSetWaveFmtEx(req->outputFmt, preset->inputFmt->sampleRate,
+ preset->inputFmt->bitsPerSample, (uint16)routing);
+ preset->outputFmt = req->outputFmt;
+ }
+
+ preset->chunkSizeInSamples = preset->inputFmt->sampleRate * preset->chunkSizeInMs / 1000U;
+ uint32 sourceSamples = req->srcLen / preset->inputFmt->blockAlign;
+ uint32 tailMs = 0;
+
+ for (HMIEffectNode *n = preset->effectChain; n; n = n->next) {
+ uint32 value = 0;
+ n->interface->getMinDuration(n, &value);
+ if (tailMs <= value)
+ tailMs = value;
+ }
+
+ uint32 tailSamples = 0;
+ if (!(preset->flags & HMI_PRESET_FLAG_USE_MALLOC) || (req->flags & HMI_PROCESS_INCLUDE_TAIL))
+ tailSamples = (uint32)((double)preset->inputFmt->sampleRate * tailMs * 0.001);
+
+ uint32 outputBytes = (sourceSamples + tailSamples) * preset->outputFmt->blockAlign;
+ if (req->flags & HMI_PROCESS_QUERY_OUTPUT_SIZE) {
+ req->dstLen = outputBytes;
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_INPUT_FORMAT)
+ preset->inputFmt = savedInput;
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_OUTPUT_FORMAT)
+ preset->outputFmt = savedOutput;
+
+ if (req->flags & HMI_PROCESS_DERIVE_OUTPUT_FORMAT)
+ preset->outputFmt = savedOutput;
+
+ return 0;
+ }
+
+ if (req->flags & HMI_PROCESS_ALLOCATE_OUTPUT) {
+ req->dstBuf = (uint8 *)hmiFXMalloc(outputBytes);
+ if (!req->dstBuf)
+ return 1;
+
+ req->dstLen = outputBytes;
+ }
+
+ resetMixBuffers(preset);
+
+ if (!(preset->flags & HMI_PRESET_FLAG_USE_MALLOC) ||
+ !(preset->flags & HMI_PRESET_FLAG_EFFECTS_INITIALIZED)) {
+ for (HMIEffectNode *n = preset->effectChain; n; n = n->next) {
+ n->outputBufSize = (int)(sourceSamples + tailSamples + preset->chunkSizeInSamples);
+ n->interface->initEffect(preset, n);
+ }
+
+ if (preset->flags & HMI_PRESET_FLAG_USE_MALLOC)
+ preset->flags |= HMI_PRESET_FLAG_EFFECTS_INITIALIZED;
+ }
+
+ uint8 *src = req->srcBuf;
+ uint8 *dst = req->dstBuf;
+ uint32 remaining = sourceSamples;
+ int clamp = (req->flags & HMI_PROCESS_DISABLE_CLAMPING) == 0;
+
+ while (remaining) {
+ uint32 count = remaining < preset->chunkSizeInSamples ? remaining : preset->chunkSizeInSamples;
+ preset->chunkSize = count;
+ convertPCMToFloat(preset, src, count);
+ processEffectChain(preset);
+ convertFloatToPCM(preset, dst, count, clamp);
+ src += count * preset->inputFmt->blockAlign;
+ dst += count * preset->outputFmt->blockAlign;
+ remaining -= count;
+ }
+
+ remaining = tailSamples;
+ while (remaining) {
+ uint32 count = remaining < preset->chunkSizeInSamples ? remaining : preset->chunkSizeInSamples;
+ preset->chunkSize = count;
+ memset(preset->floatBufLeftActive, 0, count * sizeof(float));
+ memset(preset->floatBufRightActive, 0, count * sizeof(float));
+ processEffectChain(preset);
+ convertFloatToPCM(preset, dst, count, clamp);
+ dst += count * preset->outputFmt->blockAlign;
+ remaining -= count;
+ }
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_INPUT_FORMAT)
+ preset->inputFmt = savedInput;
+
+ if (req->flags & HMI_PROCESS_OVERRIDE_OUTPUT_FORMAT)
+ preset->outputFmt = savedOutput;
+
+ if (req->flags & HMI_PROCESS_DERIVE_OUTPUT_FORMAT)
+ preset->outputFmt = savedOutput;
+
+ return 0;
+}
+
+int HMIFxLib::hmiFXPresetProcess(HMILibrary *library, HMIProcessRequest *req) {
+ if (req->flags & HMI_PROCESS_LOOKUP_ONLY) {
+ req->presetPtr = nullptr;
+ return hmiFXPresetGetByName(library, req->effectName, &req->presetPtr);
+ }
+
+ HMIPreset *preset = nullptr;
+ if (req->flags & HMI_PROCESS_USE_PRESET) {
+ preset = req->presetPtr;
+ } else if (req->flags & HMI_PROCESS_FIND_PRESET_BY_NAME) {
+ int result = hmiFXPresetGetByName(library, req->effectName, &preset);
+ if (result)
+ return result;
+
+ } else {
+ return 14;
+ }
+
+ return processPreset(preset, req);
+}
+
+int HMIFxLib::hmiFXPresetProcessEx(HMIProcessRequest *req) {
+ if (req->flags & HMI_PROCESS_LOOKUP_ONLY)
+ return 15;
+
+ if (!(req->flags & HMI_PROCESS_USE_PRESET))
+ return 14;
+
+ return processPreset(req->presetPtr, req);
+}
+
+int HMIFxLib::readFile(HMIFileDescriptor *d, Common::SeekableReadStream &stream) {
+ memset(d, 0, sizeof(*d));
+ const int64 streamSize = stream.size();
+ if (streamSize < 0 || streamSize > 0x7FFFFBFF)
+ return 0;
+
+ d->fileSize = (int)streamSize;
+ d->fileSizeExp = d->fileSize + 1024;
+ if (!stream.seek(0))
+ return 0;
+
+ d->fileBuffer = (uint8 *)malloc(d->fileSizeExp);
+ if (!d->fileBuffer)
+ return 0;
+
+ if ((int)stream.read(d->fileBuffer, d->fileSize) != d->fileSize) {
+ free(d->fileBuffer);
+ d->fileBuffer = nullptr;
+ return 0;
+ }
+
+ d->ptrToDescription = d->fileBuffer;
+ return 1;
+}
+
+int HMIFxLib::flushFile(HMIFileDescriptor *d) {
+ free(d->fileBuffer);
+ d->fileBuffer = nullptr;
+ return 1;
+}
+
+int HMIFxLib::findSection(HMIFileDescriptor *d, const char *section) {
+ uint8 *end = d->fileBuffer + d->fileSize;
+ for (uint8 *p = d->fileBuffer; p < end; ++p) {
+ if (*p != '[')
+ continue;
+
+ uint8 *name = p + 1;
+ const char *s = section;
+ while (name < end && *s && *name == (uint8)*s) {
+ ++name;
+ ++s;
+ }
+
+ if (!*s && name < end && *name == ']') {
+ while (name < end && *name != '\n')
+ ++name;
+
+ if (name < end)
+ ++name;
+
+ d->firstPresetPos = (int)(name - d->fileBuffer);
+ d->ptrToDescription = name;
+ d->anotherPtrToDescription = name;
+ d->ptrToFirstPresetSection = p;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int HMIFxLib::findKey(HMIFileDescriptor *d, const char *key) {
+ uint8 *p = d->ptrToDescription;
+ uint8 *end = d->fileBuffer + d->fileSize;
+
+ while (p < end && *p != '[') {
+ if (*p == (uint8)*key) {
+ uint8 *start = p;
+ const char *s = key;
+
+ while (p < end && *s && *p == (uint8)*s) {
+ ++p;
+ ++s;
+ }
+
+ if (!*s) {
+ while (p < end && *p != '=' && *p != '\r') {
+ ++p;
+ }
+
+ d->ptrToEffectParams = p < end && *p == '=' ? p + 1 : nullptr;
+ d->currentPos = nullptr;
+ d->ptrToFirstEffectSection = start;
+ return 1;
+ }
+
+ p = start;
+ }
+
+ ++p;
+ }
+
+ return 0;
+}
+
+int HMIFxLib::readInt(HMIFileDescriptor *d, int *value) {
+ uint8 *p = d->currentPos ? d->currentPos : d->ptrToEffectParams;
+ if (!p)
+ return 0;
+
+ while (*p == ' ')
+ ++p;
+
+ if (*p == '\r' || *p == '\n' || !*p)
+ return 0;
+
+ char token[32];
+ int n = 0;
+ while (*p != ',' && *p != ' ' && *p != '\r' && *p != '\n' && n != 31)
+ token[n++] = (char)*p++;
+
+ token[n] = 0;
+
+ while (*p == ' ')
+ ++p;
+
+ if (*p == ',')
+ ++p;
+
+ d->currentPos = p;
+
+ if (!n)
+ return 0;
+
+ *value = (int)strtol(token, 0, token[0] == '0' && (token[1] == 'x' || token[1] == 'X') ? 16 : 10);
+ return 1;
+}
+
+int HMIFxLib::readCSV(HMIFileDescriptor *d, char *buffer, int size) {
+ uint8 *p = d->currentPos ? d->currentPos : d->ptrToEffectParams;
+ if (!p)
+ return 0;
+
+ while (*p == ' ')
+ ++p;
+
+ int n = 0;
+ if (*p == '"') {
+ ++p;
+ while (*p != '\r' && *p != '\n' && n != size - 1) {
+ if (*p == '"') {
+ if (p[1] != '"') {
+ ++p;
+ break;
+ }
+
+ ++p;
+ }
+
+ buffer[n++] = (char)*p++;
+ }
+ } else {
+ while (*p != ',' && *p != '\r' && *p != '\n' && n != size - 1)
+ buffer[n++] = (char)*p++;
+ }
+
+ buffer[n] = 0;
+
+ while (*p != ',' && *p != '\r' && *p != '\n')
+ ++p;
+
+ if (*p == ',')
+ ++p;
+
+ d->currentPos = p;
+ return 1;
+}
+
+int HMIFxLib::readSectionInt(HMIFileDescriptor *d, const char *key, int *value) {
+ return findKey(d, key) && readInt(d, value);
+}
+int HMIFxLib::readSectionString(HMIFileDescriptor *d, const char *key, char *value, int size) {
+ return findKey(d, key) && readCSV(d, value, size);
+}
+
+int HMIFxLib::hmiFXPresetLoadLibrary(HMILibrary **outLib, const char *fileName) {
+ Common::File file;
+
+ if (!file.open(fileName))
+ return 10;
+
+ return hmiFXPresetLoadLibrary(outLib, file);
+}
+
+int HMIFxLib::hmiFXPresetLoadLibrary(HMILibrary **outLib, Common::SeekableReadStream &stream) {
+ HMIFileDescriptor d;
+ if (!readFile(&d, stream))
+ return 10;
+
+ HMILibrary *library = (HMILibrary *)hmiFXMalloc(sizeof(HMILibrary));
+ if (!library) {
+ flushFile(&d);
+ return 1;
+ }
+
+ memset(library, 0, sizeof(*library));
+ *outLib = library;
+ if (findSection(&d, "LIBRARY")) {
+ readSectionString(&d, "Description", library->description, 64);
+ readSectionString(&d, "Author", library->authorName, 64);
+ }
+
+ int value;
+ if (findSection(&d, "INPUTFMT")) {
+ readSectionInt(&d, "Rate", &value);
+ library->inputFmt.sampleRate = value;
+ readSectionInt(&d, "BitsPerSample", &value);
+ library->inputFmt.bitsPerSample = (uint16)value;
+ readSectionInt(&d, "Channels", &value);
+ library->inputFmt.numChannels = (uint16)value;
+ hmiFXSetWaveFmtEx(&library->inputFmt, library->inputFmt.sampleRate,
+ library->inputFmt.bitsPerSample, library->inputFmt.numChannels);
+ }
+
+ if (findSection(&d, "OUTPUTFMT")) {
+ readSectionInt(&d, "Rate", &value);
+ library->outputFmt.sampleRate = value;
+ readSectionInt(&d, "BitsPerSample", &value);
+ library->outputFmt.bitsPerSample = (uint16)value;
+ readSectionInt(&d, "Channels", &value);
+ library->outputFmt.numChannels = (uint16)value;
+ hmiFXSetWaveFmtEx(&library->outputFmt, library->outputFmt.sampleRate,
+ library->outputFmt.bitsPerSample, library->outputFmt.numChannels);
+ }
+
+ HMIPreset *head = nullptr;
+ char query[64];
+
+ for (unsigned int presetId = 0;; ++presetId) {
+ hmiFXGenerateQueryString(query, "PRESET", presetId);
+ if (!findSection(&d, query))
+ break;
+
+ HMIPreset *preset = (HMIPreset *)hmiFXMalloc(sizeof(HMIPreset));
+ if (!preset) {
+ flushFile(&d);
+ return 1;
+ }
+
+ memset(preset, 0, sizeof(*preset));
+ preset->next = head;
+ readSectionString(&d, "Description", preset->name, 64);
+ readSectionInt(&d, "Flags", (int *)&preset->flags);
+ preset->inputFmt = &library->inputFmt;
+ preset->outputFmt = &library->outputFmt;
+ preset->chunkSizeInMs = 200;
+
+ if (hmiFXPresetCreate(preset)) {
+ flushFile(&d);
+ return 1;
+ }
+
+ for (unsigned int effectId = 0;; ++effectId) {
+ hmiFXGenerateQueryString(query, "Effect", effectId);
+ if (!findKey(&d, query))
+ break;
+
+ int interfaceId;
+ if (!readInt(&d, &interfaceId))
+ break;
+
+ HMIInterface *interface;
+ if (hmiFXGetInterface(interfaceId, &interface)) {
+ flushFile(&d);
+ return 7;
+ }
+
+ HMIEffectNode *node = (HMIEffectNode *)hmiFXMalloc(interface->effectStructSize());
+ if (!node) {
+ flushFile(&d);
+ return 1;
+ }
+
+ memset(node, 0, interface->effectStructSize());
+ node->interface = interface;
+ readInt(&d, &node->outputBus);
+ readInt(&d, (int *)&node->channelMode);
+ readInt(&d, &node->sendChannel);
+
+ char token[64];
+ int param = 0;
+
+ while (readCSV(&d, token, 64) && token[0])
+ interface->setEffectParam(node, param++, (float)atof(token));
+
+ int result = hmiFXPresetAddEffect(preset, node);
+ if (result) {
+ flushFile(&d);
+ return result;
+ }
+ }
+
+ head = preset;
+ }
+
+ library->effectPtr = head;
+ flushFile(&d);
+ return head ? 0 : 12;
+}
+
+int HMIFxLib::hmiFXPresetFreeLibrary(HMILibrary *library) {
+ if (!library)
+ return 12;
+
+ HMIPreset *preset = library->effectPtr;
+ while (preset) {
+ HMIEffectNode *node = preset->effectChain;
+ while (node) {
+ node->interface->uninit(preset, node);
+ HMIEffectNode *next = node->next;
+ hmiFXFree(node);
+ node = next;
+ }
+
+ if (preset->flags & HMI_PRESET_FLAG_USE_MALLOC)
+ hmiFXFree(preset->floatBufLeft0);
+
+ HMIPreset *next = preset->next;
+ hmiFXFree(preset);
+ preset = next;
+ }
+
+ hmiFXFree(library);
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/hmifxlib.h b/audio/effects/hmi/hmifxlib.h
new file mode 100644
index 00000000000..97674363f8b
--- /dev/null
+++ b/audio/effects/hmi/hmifxlib.h
@@ -0,0 +1,100 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_HMIFXLIB_H
+#define AUDIO_EFFECTS_HMI_HMIFXLIB_H
+
+#include "audio/effects/hmi/hmifxfp.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Audio {
+
+class HMIFxLib {
+public:
+ HMIFxLib();
+ ~HMIFxLib();
+
+ HMIFxFp *effects();
+
+ int hmiFXInitSystem(HMIInitData *initData);
+ int hmiFXUnInitSystem(HMIInitData *initData);
+ int hmiFXGetInterface(int interfaceId, HMIInterface **outInterface);
+ unsigned int hmiFXGenerateQueryString(char *buffer, const char *prefix, unsigned int id);
+ int hmiFXGetFirstInterface(HMIInterface **outInterface);
+ int hmiFXGetNextInterface(HMIInterface **outInterface);
+
+ int hmiFXPresetCreate(HMIPreset *preset);
+ int hmiFXPresetDestroy(HMIPreset *preset);
+ int hmiFXPresetAddEffect(HMIPreset *preset, HMIEffectNode *newNode);
+ int hmiFXPresetLoadLibrary(HMILibrary **outLib, const char *fileName);
+ int hmiFXPresetLoadLibrary(HMILibrary **outLib, Common::SeekableReadStream &stream);
+ int hmiFXPresetFreeLibrary(HMILibrary *library);
+ int hmiFXPresetProcess(HMILibrary *library, HMIProcessRequest *request);
+ int hmiFXPresetGetByName(HMILibrary *library, const char *name, HMIPreset **outPreset);
+ int hmiFXPresetLock(HMIPreset *preset);
+ int hmiFXPresetRelease(HMIPreset *preset);
+ int hmiFXPresetGetRouting(HMIPreset *preset, uint32 *routingOut);
+ void hmiFXSetWaveFmtEx(HMIFormat *format, int sampleRate, uint16 bitsPerSample, uint16 channels);
+ int hmiFXPresetCreateInstance(HMIPreset *source, HMIPreset **outInstance);
+ int hmiFXPresetDestroyInstance(HMIPreset *instance);
+ int hmiFXPresetProcessEx(HMIProcessRequest *request);
+
+ void *hmiFXHeapAlloc(int size);
+ void hmiFXHeapFree(void *ptr);
+ int hmiFXHeapInit(HMIInitData *initData);
+ void *hmiFXHeapReset();
+ void *hmiFXMalloc(size_t size);
+ void hmiFXFree(void *ptr);
+
+private:
+ int convertPCMToFloat(HMIPreset *preset, const uint8 *buffer, int samples);
+ int convertFloatToPCM(HMIPreset *preset, uint8 *buffer, int samples, int clampOutput);
+ int processPreset(HMIPreset *preset, HMIProcessRequest *request);
+ void resetMixBuffers(HMIPreset *preset);
+ void processEffectChain(HMIPreset *preset);
+
+ int readFile(HMIFileDescriptor *desc, Common::SeekableReadStream &stream);
+ int flushFile(HMIFileDescriptor *desc);
+ int findSection(HMIFileDescriptor *desc, const char *section);
+ int findKey(HMIFileDescriptor *desc, const char *key);
+ int readInt(HMIFileDescriptor *desc, int *value);
+ int readCSV(HMIFileDescriptor *desc, char *buffer, int size);
+ int readSectionInt(HMIFileDescriptor *desc, const char *key, int *value);
+ int readSectionString(HMIFileDescriptor *desc, const char *key, char *value, int size);
+
+ HMIFxFp _fxFp;
+ HMIInterface *_loadedInterfaces[1024];
+ unsigned int _numLoadedInterfaces;
+ unsigned int _curInterfaceIndex;
+
+ uint8 *_systemHeap;
+ uint8 *_heapCursor;
+ uint8 *_heapEnd;
+ void *(*_mallocFunc)(size_t);
+ void (*_freeFunc)(void *);
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/envelope.cpp b/audio/effects/hmi/interfaces/envelope.cpp
new file mode 100644
index 00000000000..7537a10e827
--- /dev/null
+++ b/audio/effects/hmi/interfaces/envelope.cpp
@@ -0,0 +1,132 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/envelope.h"
+
+namespace Audio {
+
+const char *const HMIEnvelope::kEnvelopeParams[] = {"Envelope Points", "Envelope Duration"};
+const float HMIEnvelope::kEnvelopeMin[] = {2.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.5f, -1.0f, 0.0f};
+const float HMIEnvelope::kEnvelopeMax[] = {2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+const float HMIEnvelope::kEnvelopeDefault[] = {8.0f, 1000.0f, 1.0f, 1.0f, 1.0f, 1.0f};
+
+HMIEnvelope::HMIEnvelope()
+ : HMIInterface(sizeof(HMIEnvelopeNode), 1, "DLGEnvelope",
+ kEnvelopeParams, kEnvelopeMin, kEnvelopeMax, kEnvelopeDefault,
+ "Envelope", 2910, 18) {}
+
+int HMIEnvelope::init(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIEnvelope::uninit(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIEnvelope::initEffect(HMIPreset *, HMIEffectNode *base) {
+ HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
+
+ if (n->initGuard == 0.0f) {
+ n->currentAmp = n->pointAmp[0];
+ n->currentSegment = 0;
+
+ for (int i = 1; (double)(uint32)i < n->envPoints; ++i) {
+ int samples = (int)((double)n->pointTime[i] * (uint32)n->outputBufSize - (double)n->pointTime[i - 1] * (uint32)n->outputBufSize);
+ n->segRemaining[i] = samples;
+ n->segSlopes[i] = (float)(((double)n->pointAmp[i] - n->pointAmp[i - 1]) / (uint32)samples);
+ }
+ }
+
+ return 0;
+}
+
+int HMIEnvelope::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
+ float *in = preset->floatBufLeftActive;
+ float *out = preset->floatBufLeftAlt;
+ int remainingChunk = (int)preset->chunkSize;
+ int segment = n->currentSegment;
+ int remaining = n->segRemaining[segment];
+
+ for (;;) {
+ int left = remainingChunk;
+ while (left) {
+ if (!remaining--)
+ break;
+
+ *out++ = (float)((double)*in++ * n->currentAmp);
+ n->currentAmp = n->segSlopes[segment] + n->currentAmp;
+ --left;
+ }
+
+ if (!left)
+ break;
+
+ segment = ++n->currentSegment;
+ remainingChunk = left;
+ remaining = n->segRemaining[segment];
+ }
+
+ n->segRemaining[segment] = remaining;
+ return 0;
+}
+
+int HMIEnvelope::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
+ if (p == 0) {
+ *v = n->envPoints;
+ } else if (p == 1) {
+ *v = n->initGuard;
+ *type = 0;
+ return 0;
+ } else if (p >= 2 && p <= 17) {
+ int index = (p - 2) >> 1;
+ *v = (p & 1) ? n->pointAmp[index] : n->pointTime[index];
+ } else {
+ return 11;
+ }
+
+ *type = 3;
+ return 0;
+}
+
+int HMIEnvelope::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
+ if (p == 0) {
+ n->envPoints = v;
+ } else if (p == 1) {
+ n->initGuard = v;
+ } else if (p >= 2 && p <= 17) {
+ int index = (p - 2) >> 1;
+
+ if (p & 1) {
+ n->pointAmp[index] = v;
+ } else {
+ n->pointTime[index] = v;
+ }
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/envelope.h b/audio/effects/hmi/interfaces/envelope.h
new file mode 100644
index 00000000000..30498868a1f
--- /dev/null
+++ b/audio/effects/hmi/interfaces/envelope.h
@@ -0,0 +1,48 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_ENVELOPE_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_ENVELOPE_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIEnvelope : public HMIInterface {
+public:
+ HMIEnvelope();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kEnvelopeParams[];
+ static const float kEnvelopeMin[];
+ static const float kEnvelopeMax[];
+ static const float kEnvelopeDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/filter1.cpp b/audio/effects/hmi/interfaces/filter1.cpp
new file mode 100644
index 00000000000..84003c28f48
--- /dev/null
+++ b/audio/effects/hmi/interfaces/filter1.cpp
@@ -0,0 +1,158 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/filter1.h"
+
+namespace Audio {
+
+const char *const HMIFilter1::kFilter1Params[] = {"Filter Type", "Cutoff Frequency", "Center Frequency", "Band Width"};
+const float HMIFilter1::kFilter1Min[] = {1024.0f, 1000.0f, 0.0f, 0.0f, -1.0f, 0.0f};
+const float HMIFilter1::kFilter1Max[] = {1024.0f, 0.0f, 0.0f, 0.0f};
+const float HMIFilter1::kFilter1Default[] = {1026.0f, 10000.0f, 10000.0f, 2000.0f};
+
+HMIFilter1::HMIFilter1()
+ : HMIInterface(sizeof(HMIFilter1Node), 1, "DLGFilterMIMO",
+ kFilter1Params, kFilter1Min, kFilter1Max, kFilter1Default,
+ "Filter 1", 2300, 4) {}
+
+int HMIFilter1::init(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIFilter1::uninit(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIFilter1::initEffect(HMIPreset *preset, HMIEffectNode *base) {
+ HMIFilter1Node *node = (HMIFilter1Node *)base;
+
+ node->state_x1 = node->state_x2 = node->state_x3 = node->state_y1 = 0.0f;
+ node->state_x1b = node->state_x2b = node->state_x3b = node->state_y1b = 0.0f;
+ double sampleRate = (double)preset->inputFmt->sampleRate;
+
+ if (node->filterType == 1024 || node->filterType == 1025) {
+ double nyquist = (double)(preset->inputFmt->sampleRate >> 1);
+ double frequency = node->cutoffFrequency;
+
+ if (frequency >= nyquist)
+ frequency = nyquist;
+
+ double angle = frequency * kHmiPi / sampleRate;
+ double c = node->filterType == 1024 ? 1.0 / tan(angle) : tan(angle);
+ double c2 = c * c;
+ double root = sqrt(2.0) * c;
+
+ float gain = (float)(1.0 / (c2 + root + 1.0));
+ node->coeff_b0 = gain;
+ node->coeff_b1 = node->filterType == 1024 ? gain + gain : gain * -2.0f;
+ node->coeff_b2 = gain;
+
+ double a = node->filterType == 1024 ? 1.0 - c2 : c2 - 1.0;
+ node->coeff_a1 = (float)(a * gain + a * gain);
+ node->coeff_a2 = (float)((c2 - (root - 1.0)) * gain);
+ } else if (node->filterType == 1026) {
+ double c = 1.0 / tan((double)node->bandWidth * kHmiPi / sampleRate);
+ double cosine = cos((double)node->centerFrequency * kHmiTwoPi / sampleRate);
+ float gain = (float)(1.0 / (c + 1.0));
+
+ node->coeff_b0 = gain;
+ node->coeff_b1 = 0.0f;
+ node->coeff_b2 = -gain;
+ node->coeff_a1 = (float)(-((cosine + cosine) * c * gain));
+ node->coeff_a2 = (float)((c - 1.0) * gain);
+ } else if (node->filterType == 1027) {
+ float tangent = (float)tan((double)node->bandWidth * kHmiPi / sampleRate);
+ double twiceCosine = cos((double)node->centerFrequency * kHmiTwoPi / sampleRate) * 2.0;
+ float gain = (float)(1.0 / ((double)tangent + 1.0));
+ float a1 = (float)(-(twiceCosine * gain));
+
+ node->coeff_b0 = gain;
+ node->coeff_b1 = a1;
+ node->coeff_b2 = gain;
+ node->coeff_a1 = a1;
+ node->coeff_a2 = (1.0f - tangent) * gain;
+ }
+
+ return 0;
+}
+
+int HMIFilter1::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIFilter1Node *n = (HMIFilter1Node *)base;
+
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ double input = preset->floatBufLeftActive[i];
+ float output = (float)(input * n->coeff_b0 + (double)n->state_x1 * n->coeff_b1 + (double)n->state_x2 * n->coeff_b2 - (double)n->coeff_a1 * n->state_x3 - (double)n->state_y1 * n->coeff_a2);
+ preset->floatBufLeftAlt[i] = output;
+
+ float x1 = n->state_x1;
+ float y1 = n->state_x3;
+
+ n->state_x1 = (float)input;
+ n->state_x2 = x1;
+ n->state_y1 = y1;
+ n->state_x3 = output;
+ }
+
+ return 0;
+}
+
+int HMIFilter1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIFilter1Node *n = (HMIFilter1Node *)base;
+
+ if (p == 0) {
+ *v = (float)(uint32)n->filterType;
+ *type = 3;
+ return 0;
+ }
+
+ if (p == 1) {
+ *v = n->cutoffFrequency;
+ } else if (p == 2) {
+ *v = n->centerFrequency;
+ } else if (p == 3) {
+ *v = n->bandWidth;
+ } else {
+ return 11;
+ }
+
+ *type = 1;
+ return 0;
+}
+
+int HMIFilter1::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIFilter1Node *n = (HMIFilter1Node *)base;
+
+ if (p == 0) {
+ n->filterType = (int)(v);
+ } else if (p == 1) {
+ n->cutoffFrequency = v;
+ } else if (p == 2) {
+ n->centerFrequency = v;
+ } else if (p == 3) {
+ n->bandWidth = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/filter1.h b/audio/effects/hmi/interfaces/filter1.h
new file mode 100644
index 00000000000..c6dcf4b1427
--- /dev/null
+++ b/audio/effects/hmi/interfaces/filter1.h
@@ -0,0 +1,48 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_FILTER1_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_FILTER1_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIFilter1 : public HMIInterface {
+public:
+ HMIFilter1();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kFilter1Params[];
+ static const float kFilter1Min[];
+ static const float kFilter1Max[];
+ static const float kFilter1Default[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/mono_delay.cpp b/audio/effects/hmi/interfaces/mono_delay.cpp
new file mode 100644
index 00000000000..a06f5be5895
--- /dev/null
+++ b/audio/effects/hmi/interfaces/mono_delay.cpp
@@ -0,0 +1,133 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/mono_delay.h"
+
+namespace Audio {
+
+const char *const HMIMonoDelay::kMonoDelayParams[] = {"Delay Max", "Delay Time", "Feedback", "Dry Out", "Wet Out"};
+const float HMIMonoDelay::kMonoDelayMin[] = {1000.0f, 100.0f, 0.5f, 0.9f, 0.9f, -1.0f};
+const float HMIMonoDelay::kMonoDelayMax[] = {1000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+const float HMIMonoDelay::kMonoDelayDefault[] = {1000.0f, 1000.0f, 1.0f, 1.0f, 1.0f, 0.0f};
+
+HMIMonoDelay::HMIMonoDelay()
+ : HMIInterface(sizeof(HMIMonoDelayNode), 1, "DLGDelayMIMO",
+ kMonoDelayParams, kMonoDelayMin, kMonoDelayMax, kMonoDelayDefault,
+ "Mono Delay 1", 2000, 5) {}
+
+int HMIMonoDelay::init(HMIPreset *preset, HMIEffectNode *base) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+
+ int bytes = 4 * (int)((double)preset->inputFmt->sampleRate * n->maxDelayTime * kHmiMillis);
+ n->bufSizeBytes = bytes;
+ n->delayBuf = (float *)malloc(bytes);
+
+ if (!n->delayBuf)
+ return 1;
+
+ n->writeIndex = 0;
+ return 0;
+}
+
+int HMIMonoDelay::uninit(HMIPreset *, HMIEffectNode *base) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+ free(n->delayBuf);
+ return 0;
+}
+
+int HMIMonoDelay::initEffect(HMIPreset *, HMIEffectNode *base) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+ n->writeIndex = 0;
+ memset(n->delayBuf, 0, n->bufSizeBytes);
+ return 0;
+}
+
+int HMIMonoDelay::getMinDuration(HMIEffectNode *base, uint32 *out) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+ *out = (uint32)(log(kHmiMillis) / log(n->feedback) * n->delayTime);
+ return 0;
+}
+
+int HMIMonoDelay::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+
+ int delaySamples = (int)((double)preset->inputFmt->sampleRate * n->delayTime * kHmiMillis);
+ int index = n->writeIndex;
+
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ double input = preset->floatBufLeftActive[i];
+ float delayed = n->delayBuf[index];
+ preset->floatBufLeftAlt[i] = (float)(input * n->dryOut + (double)delayed * n->wetOut);
+ n->delayBuf[index] = (float)((double)delayed * n->feedback + input);
+
+ if (++index == delaySamples)
+ index = 0;
+ }
+
+ n->writeIndex = index;
+ return 0;
+}
+
+int HMIMonoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+
+ if (p == 0) {
+ *v = n->maxDelayTime;
+ *type = 0;
+ } else if (p == 1) {
+ *v = n->delayTime;
+ *type = 0;
+ } else if (p == 2) {
+ *v = n->feedback;
+ *type = 2;
+ } else if (p == 3) {
+ *v = n->dryOut;
+ *type = 2;
+ } else if (p == 4) {
+ *v = n->wetOut;
+ *type = 2;
+ } else {
+ return 11;
+ }
+ return 0;
+}
+
+int HMIMonoDelay::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
+
+ if (p == 0) {
+ n->maxDelayTime = v;
+ } else if (p == 1) {
+ n->delayTime = v;
+ } else if (p == 2) {
+ n->feedback = v;
+ } else if (p == 3) {
+ n->dryOut = v;
+ } else if (p == 4) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/mono_delay.h b/audio/effects/hmi/interfaces/mono_delay.h
new file mode 100644
index 00000000000..ce16bf68247
--- /dev/null
+++ b/audio/effects/hmi/interfaces/mono_delay.h
@@ -0,0 +1,49 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_MONO_DELAY_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_MONO_DELAY_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIMonoDelay : public HMIInterface {
+public:
+ HMIMonoDelay();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int getMinDuration(HMIEffectNode *, uint32 *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kMonoDelayParams[];
+ static const float kMonoDelayMin[];
+ static const float kMonoDelayMax[];
+ static const float kMonoDelayDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/phasor.cpp b/audio/effects/hmi/interfaces/phasor.cpp
new file mode 100644
index 00000000000..1360b63fd65
--- /dev/null
+++ b/audio/effects/hmi/interfaces/phasor.cpp
@@ -0,0 +1,148 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/phasor.h"
+
+namespace Audio {
+
+const char *const HMIPhasor::kPhasorParams[] = {
+ "Feedback", "Rate", "Range", "Base Frequency", "Dry Out", "Wet Out"};
+const float HMIPhasor::kPhasorMin[] = {0.8f, 2.0f, 1.0f, 100.0f, 0.5f, 0.9f, -1.0f, 0.0f};
+const float HMIPhasor::kPhasorMax[] = {0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000}; // Meaning: NaN
+const float HMIPhasor::kPhasorDefault[] = {1.0f, 32.0f, 12.0f, 1000.0f, 1.0f, 1.0f};
+
+HMIPhasor::HMIPhasor()
+ : HMIInterface(sizeof(HMIPhasorNode), 1, "DLGPhasor",
+ kPhasorParams, kPhasorMin, kPhasorMax, kPhasorDefault,
+ "Phasor", 2375, 6) {}
+
+int HMIPhasor::init(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIPhasor::uninit(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIPhasor::initEffect(HMIPreset *preset, HMIEffectNode *base) {
+ HMIPhasorNode *n = (HMIPhasorNode *)base;
+
+ double rate = preset->inputFmt->sampleRate;
+ float lower = (float)((double)n->feedback * kHmiPi / rate);
+ n->phase = lower;
+ n->coeff = lower;
+ float top = (float)pow(2.0, (double)n->centerFrequency);
+ n->state_x2R = top;
+ n->modPhase = (float)((double)n->feedback * top * kHmiPi / rate);
+ float multiplier = (float)pow((double)top,
+ (double)(n->depth / (double)(preset->inputFmt->sampleRate >> 1)));
+ n->state_y2R = multiplier;
+ n->state_y2L = multiplier;
+ n->b0 = n->b1 = n->a1 = 0.0f;
+ n->state_x1L = n->state_y1L = n->state_x1R = n->state_y1R = n->state_x2L = 0.0f;
+
+ return 0;
+}
+
+int HMIPhasor::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIPhasorNode *n = (HMIPhasorNode *)base;
+
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ float input = preset->floatBufLeftActive[i];
+ double k = (1.0 - n->phase) / ((double)n->phase + 1.0);
+ double feedbackState = (double)n->state_x2L * n->rate + input;
+
+ float stage1 = (float)((feedbackState + n->b1) * k - n->b0);
+ n->b0 = (float)feedbackState;
+ n->b1 = stage1;
+
+ float stage2 = (float)(((double)n->b1 + n->state_x1L) * k - n->a1);
+ n->a1 = n->b1;
+ n->state_x1L = stage2;
+
+ float stage3 = (float)(((double)n->state_x1R + n->state_x1L) * k - n->state_y1L);
+ n->state_y1L = n->state_x1L;
+ n->state_x1R = stage3;
+
+ float stage4 = (float)(((double)n->state_x2L + n->state_x1R) * k - n->state_y1R);
+ n->state_y1R = n->state_x1R;
+ n->state_x2L = stage4;
+
+ preset->floatBufLeftAlt[i] = (float)((double)input * n->dryOut + (double)n->wetOut * stage4);
+ double phase = (double)n->state_y2L * n->phase;
+ n->phase = (float)phase;
+
+ if (phase > n->modPhase) {
+ n->state_y2L = 1.0f / n->state_y2R;
+ } else if (phase < n->coeff) {
+ n->state_y2L = n->state_y2R;
+ }
+ }
+
+ return 0;
+}
+
+int HMIPhasor::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIPhasorNode *n = (HMIPhasorNode *)base;
+
+ if (p == 0) {
+ *v = n->rate;
+ } else if (p == 1) {
+ *v = n->depth;
+ } else if (p == 2) {
+ *v = n->centerFrequency;
+ } else if (p == 3) {
+ *v = n->feedback;
+ } else if (p == 4) {
+ *v = n->dryOut;
+ } else if (p == 5) {
+ *v = n->wetOut;
+ } else {
+ return 11;
+ }
+
+ *type = 1;
+ return 0;
+}
+
+int HMIPhasor::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIPhasorNode *n = (HMIPhasorNode *)base;
+
+ if (p == 0) {
+ n->rate = v;
+ } else if (p == 1) {
+ n->depth = v;
+ } else if (p == 2) {
+ n->centerFrequency = v;
+ } else if (p == 3) {
+ n->feedback = v;
+ } else if (p == 4) {
+ n->dryOut = v;
+ } else if (p == 5) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/phasor.h b/audio/effects/hmi/interfaces/phasor.h
new file mode 100644
index 00000000000..cc4b27c670b
--- /dev/null
+++ b/audio/effects/hmi/interfaces/phasor.h
@@ -0,0 +1,48 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_PHASOR_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_PHASOR_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIPhasor : public HMIInterface {
+public:
+ HMIPhasor();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kPhasorParams[];
+ static const float kPhasorMin[];
+ static const float kPhasorMax[];
+ static const float kPhasorDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/resonator.cpp b/audio/effects/hmi/interfaces/resonator.cpp
new file mode 100644
index 00000000000..8b32ba322f0
--- /dev/null
+++ b/audio/effects/hmi/interfaces/resonator.cpp
@@ -0,0 +1,104 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/resonator.h"
+
+namespace Audio {
+
+const char *const HMIResonator::kResonatorParams[] = {"Center Frequency", "Band Width"};
+const float HMIResonator::kResonatorMin[] = {1000.0f, 200.0f, -1.0f, 0.0f};
+const float HMIResonator::kResonatorMax[] = {1.0f, 1.0f};
+const float HMIResonator::kResonatorDefault[] = {10000.0f, 3000.0f};
+
+HMIResonator::HMIResonator()
+ : HMIInterface(sizeof(HMIResonatorNode), 1, "DLGResonator",
+ kResonatorParams, kResonatorMin, kResonatorMax, kResonatorDefault,
+ "Resonator", 2350, 2) {}
+
+int HMIResonator::init(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIResonator::uninit(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIResonator::initEffect(HMIPreset *preset, HMIEffectNode *base) {
+ HMIResonatorNode *n = (HMIResonatorNode *)base;
+
+ double rate = (double)preset->inputFmt->sampleRate;
+ double radius = pow(2.0, n->bandWidth / rate * -kHmiTwoPi * 1.442695040888963407);
+ n->coeff2 = (float)radius;
+ n->stateX1 = 0.0f;
+ n->stateX2 = 0.0f;
+
+ double c = cos(n->cutoffFrequency / rate * kHmiTwoPi) * (radius * -4.0 / (radius + 1.0));
+ n->coeff1 = (float)c;
+ n->resonance = (float)(sqrt(1.0 - c * c / ((double)n->coeff2 * 4.0)) * (1.0 - n->coeff2));
+
+ return 0;
+}
+
+int HMIResonator::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIResonatorNode *n = (HMIResonatorNode *)base;
+
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ double a = (double)preset->floatBufLeftActive[i] * n->resonance - (double)n->stateX1 * n->coeff1;
+ float output = (float)(a - (double)n->coeff2 * n->stateX2);
+ preset->floatBufLeftAlt[i] = output;
+ float previous = n->stateX1;
+ n->stateX1 = output;
+ n->stateX2 = previous;
+ }
+
+ return 0;
+}
+
+int HMIResonator::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIResonatorNode *n = (HMIResonatorNode *)base;
+
+ if (p == 0) {
+ *v = n->cutoffFrequency;
+ } else if (p == 1) {
+ *v = n->bandWidth;
+ } else {
+ return 11;
+ }
+
+ *type = 1;
+ return 0;
+}
+
+int HMIResonator::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIResonatorNode *n = (HMIResonatorNode *)base;
+
+ if (p == 0) {
+ n->cutoffFrequency = v;
+ } else if (p == 1) {
+ n->bandWidth = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/resonator.h b/audio/effects/hmi/interfaces/resonator.h
new file mode 100644
index 00000000000..faf4d0763c7
--- /dev/null
+++ b/audio/effects/hmi/interfaces/resonator.h
@@ -0,0 +1,48 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_RESONATOR_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_RESONATOR_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIResonator : public HMIInterface {
+public:
+ HMIResonator();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kResonatorParams[];
+ static const float kResonatorMin[];
+ static const float kResonatorMax[];
+ static const float kResonatorDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/reverb1.cpp b/audio/effects/hmi/interfaces/reverb1.cpp
new file mode 100644
index 00000000000..f4f7160d065
--- /dev/null
+++ b/audio/effects/hmi/interfaces/reverb1.cpp
@@ -0,0 +1,228 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/reverb1.h"
+
+namespace Audio {
+
+const char *const HMIReverb1::kReverb1Params[] = {"Reverb Max", "Reverb Pre-Delay", "Reverb Time", "Dry Out", "Wet Out"};
+const float HMIReverb1::kReverb1Min[] = {1000.0f, 0.0f, 100.0f, 0.9f, 0.3f, -1.0f};
+const float HMIReverb1::kReverb1Max[] = {1000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+const float HMIReverb1::kReverb1Default[] = {1000.0f, 250.0f, 100.0f, 1.0f, 1.0f, 0.0f};
+
+HMIReverb1::HMIReverb1()
+ : HMIInterface(sizeof(HMIReverb1Node), 3, "DLGReverbMISO",
+ kReverb1Params, kReverb1Min, kReverb1Max, kReverb1Default,
+ "Reverb 1", 2101, 5) {}
+
+const float HMIReverb1::kReverb1Delay[4] = {0.16463099420070648f, 0.5134339928627014f, 1.0f, 0.8304839730262756f};
+
+int HMIReverb1::init(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ int bytes = 4 * (int)((double)preset->inputFmt->sampleRate * n->reverbMax * kHmiMillis);
+ n->bufSizeBytes = bytes;
+
+ for (int i = 0; i != 4; ++i) {
+ n->echoStages[i].buffer = (float *)malloc(bytes);
+ if (!n->echoStages[i].buffer) {
+ while (i) {
+ free(n->echoStages[--i].buffer);
+ }
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int HMIReverb1::uninit(HMIPreset *, HMIEffectNode *base) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ for (int i = 0; i != 4; ++i) {
+ free(n->echoStages[i].buffer);
+ }
+
+ return 0;
+}
+
+int HMIReverb1::initEffect(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ double total = (double)preset->inputFmt->sampleRate * n->reverbTime * kHmiMillis;
+
+ for (int i = 0; i != 4; ++i) {
+ HMIReverbEchoStage *s = &n->echoStages[i];
+ memset(s->buffer, 0, n->bufSizeBytes);
+ double samples = total * kReverb1Delay[i];
+ s->bufSizeInSamples = (int)(samples)-2;
+ s->writeHead = 0;
+ s->readHead = (int)(samples * 0.5);
+ s->lastOutput = 0.0f;
+ }
+
+ n->preDelaySamples = (int)((double)preset->inputFmt->sampleRate * n->preDelay * kHmiMillis);
+ return 0;
+}
+
+int HMIReverb1::getMinDuration(HMIEffectNode *base, uint32 *out) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+ uint32 duration = (uint32)(log(kHmiMillis) / log(0.7) * n->reverbTime);
+ *out = duration / 3;
+ return 0;
+}
+
+static float reverb1Stage(HMIReverbEchoStage *s, double input, double coefficient) {
+ double previous = s->lastOutput;
+ float written = (float)(previous * coefficient + input);
+ s->buffer[s->writeHead] = written;
+
+ if (++s->writeHead == s->bufSizeInSamples)
+ s->writeHead = 0;
+
+ s->lastOutput = s->buffer[s->readHead];
+
+ if (++s->readHead == s->bufSizeInSamples)
+ s->readHead = 0;
+
+ return (float)((double)written * -coefficient + previous);
+}
+
+static float reverb1DelayStage(HMIReverbEchoStage *s, double input, double coefficient) {
+ s->buffer[s->writeHead] = (float)((double)s->lastOutput * coefficient + input);
+
+ if (++s->writeHead == s->bufSizeInSamples)
+ s->writeHead = 0;
+
+ s->lastOutput = s->buffer[s->readHead];
+
+ if (++s->readHead == s->bufSizeInSamples)
+ s->readHead = 0;
+
+ return s->lastOutput;
+}
+
+static int reverb1Mono(HMIPreset *preset, HMIReverb1Node *n) {
+ uint32 outIndex = 0;
+ while (n->preDelaySamples && outIndex != preset->chunkSize) {
+ // The mono DLL path advances only the destination during pre-delay...
+ preset->floatBufLeftAlt[outIndex] = (float)((double)n->wetOut * preset->floatBufLeftActive[0]);
+ --n->preDelaySamples;
+ ++outIndex;
+ }
+
+ uint32 inputIndex = 0;
+ for (; outIndex != preset->chunkSize; ++outIndex, ++inputIndex) {
+ float input = preset->floatBufLeftActive[inputIndex];
+ float a = reverb1Stage(&n->echoStages[0], input, 0.7);
+ float b = reverb1Stage(&n->echoStages[1], a, 0.7);
+ float wet = reverb1DelayStage(&n->echoStages[2], b, 0.62);
+ preset->floatBufLeftAlt[outIndex] = (float)((double)input * n->dryOut + (double)wet * n->wetOut);
+ }
+
+ return 0;
+}
+
+static int reverb1Stereo(HMIPreset *preset, HMIReverb1Node *n) {
+ uint32 i = 0;
+
+ while (n->preDelaySamples && i != preset->chunkSize) {
+ float output = (float)((double)preset->floatBufLeftActive[i] * n->wetOut);
+ preset->floatBufLeftAlt[i] = output;
+ preset->floatBufRightAlt[i] = output;
+ --n->preDelaySamples;
+ ++i;
+ }
+
+ for (; i != preset->chunkSize; ++i) {
+ float input = preset->floatBufLeftActive[i];
+ float a = reverb1Stage(&n->echoStages[0], input, 0.7);
+ float b = reverb1Stage(&n->echoStages[1], a, 0.7);
+ float rightInput = (float)((double)n->echoStages[3].lastOutput * -0.71 + b);
+ float leftWet = reverb1DelayStage(&n->echoStages[2], b, 0.62);
+ float rightWet = reverb1DelayStage(&n->echoStages[3], rightInput, 0.0);
+ double dry = (double)input * n->dryOut;
+ preset->floatBufLeftAlt[i] = (float)(dry + (double)leftWet * n->wetOut);
+ preset->floatBufRightAlt[i] = (float)(dry + (double)rightWet * n->wetOut);
+ }
+
+ return 0;
+}
+
+int HMIReverb1::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ if (n->channelMode & HMI_EFFECT_CHANNEL_MONO)
+ reverb1Mono(preset, n);
+
+ if (n->channelMode & HMI_EFFECT_CHANNEL_STEREO)
+ reverb1Stereo(preset, n);
+
+ return 0;
+}
+
+int HMIReverb1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ if (p == 0) {
+ *v = n->reverbMax;
+ } else if (p == 1) {
+ *v = n->preDelay;
+ } else if (p == 2) {
+ *v = n->reverbTime;
+ } else if (p == 3) {
+ *v = n->dryOut;
+ *type = 2;
+ return 0;
+ } else if (p == 4) {
+ *v = n->wetOut;
+ *type = 2;
+ return 0;
+ } else {
+ return 11;
+ }
+
+ *type = 0;
+ return 0;
+}
+
+int HMIReverb1::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIReverb1Node *n = (HMIReverb1Node *)base;
+
+ if (p == 0) {
+ n->reverbMax = v;
+ } else if (p == 1) {
+ n->preDelay = v;
+ } else if (p == 2) {
+ n->reverbTime = v;
+ } else if (p == 3) {
+ n->dryOut = v;
+ } else if (p == 4) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/reverb1.h b/audio/effects/hmi/interfaces/reverb1.h
new file mode 100644
index 00000000000..1db38c34fd6
--- /dev/null
+++ b/audio/effects/hmi/interfaces/reverb1.h
@@ -0,0 +1,50 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_REVERB1_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_REVERB1_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIReverb1 : public HMIInterface {
+public:
+ HMIReverb1();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int getMinDuration(HMIEffectNode *, uint32 *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kReverb1Params[];
+ static const float kReverb1Min[];
+ static const float kReverb1Max[];
+ static const float kReverb1Default[];
+ static const float kReverb1Delay[4];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/reverb2.cpp b/audio/effects/hmi/interfaces/reverb2.cpp
new file mode 100644
index 00000000000..3607ef5d1f1
--- /dev/null
+++ b/audio/effects/hmi/interfaces/reverb2.cpp
@@ -0,0 +1,207 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/reverb2.h"
+
+namespace Audio {
+
+const char *const HMIReverb2::kReverb2Params[] = {"Reverb Max", "Reverb Pre-Delay", "Reverb Time", "Dry Out", "Wet Out"};
+const float HMIReverb2::kReverb2Min[] = {5000.0f, 0.0f, 100.0f, 0.9f, 0.3f, -1.0f};
+const float HMIReverb2::kReverb2Max[] = {5000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+const float HMIReverb2::kReverb2Default[] = {5000.0f, 250.0f, 100.0f, 1.0f, 1.0f, 0.0f};
+
+HMIReverb2::HMIReverb2()
+ : HMIInterface(sizeof(HMIReverb2Node), 3, "DLGReverbMISO",
+ kReverb2Params, kReverb2Min, kReverb2Max, kReverb2Default,
+ "Reverb 2", 2103, 5) {}
+
+const float HMIReverb2::kReverb2Delay[6] = {
+ 0.02969999983906746f, 0.03709999844431877f, 0.041099999099969864f,
+ 0.043699998408555984f, 0.004999999888241291f, 0.0017000000225380063f
+};
+
+const float HMIReverb2::kReverb2Decay[6] = {
+ 0.041099999099969864f, 0.043699998408555984f, 0.004999999888241291f,
+ 0.0017000000225380063f, 0.09685350209474564f, 0.032924000173807144f
+};
+
+int HMIReverb2::init(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ double rate = preset->inputFmt->sampleRate;
+ n->bufSizeBytes = (int)(rate * 4.0);
+
+ for (int i = 0; i != 6; ++i) {
+ int bytes = 4 * (int)(rate * kReverb2Delay[i]);
+ n->echoStages[i].buffer = (float *)malloc(bytes);
+ if (!n->echoStages[i].buffer) {
+ while (i) {
+ free(n->echoStages[--i].buffer);
+ }
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int HMIReverb2::uninit(HMIPreset *, HMIEffectNode *base) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ for (int i = 0; i != 6; ++i) {
+ free(n->echoStages[i].buffer);
+ }
+
+ return 0;
+}
+
+int HMIReverb2::initEffect(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ float seconds = n->reverbTime * 0.001f;
+ float rate = (float)preset->inputFmt->sampleRate;
+
+ for (int i = 0; i != 6; ++i) {
+ int samples = (int)((double)rate * kReverb2Delay[i]);
+ n->echoStages[i].bufSizeInSamples = samples;
+ memset(n->echoStages[i].buffer, 0, 4 * samples);
+ n->echoStages[i].writeHead = 0;
+ double exponent = i >= 4 ? (double)kReverb2Delay[i] / kReverb2Decay[i]
+ : (double)kReverb2Delay[i] / seconds;
+ n->echoStages[i].decayCoeff = (float)pow(kHmiMillis, (double)exponent);
+ }
+
+ n->preDelaySamples = (int)((double)preset->inputFmt->sampleRate * n->preDelay * kHmiMillis);
+ return 0;
+}
+
+int HMIReverb2::getMinDuration(HMIEffectNode *base, uint32 *out) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ uint32 value = (uint32)(log(kHmiMillis) / log(0.7) * n->reverbTime);
+ *out = value / 3;
+ return 0;
+}
+
+static void advanceStage(HMIReverbEchoStage *s) {
+ if (++s->writeHead >= s->bufSizeInSamples)
+ s->writeHead = 0;
+}
+
+static void reverb2ProcessPath(HMIPreset *preset, HMIReverb2Node *n, int stereo) {
+ for (uint32 sample = 0; sample != preset->chunkSize; ++sample) {
+ double input = preset->floatBufLeftActive[sample];
+ double sum = 0.0;
+
+ for (int i = 0; i != 4; ++i) {
+ HMIReverbEchoStage *s = &n->echoStages[i];
+ float delayed = s->buffer[s->writeHead];
+ sum += delayed;
+ s->buffer[s->writeHead] = (float)((double)delayed * s->decayCoeff + input);
+ advanceStage(s);
+ }
+
+ HMIReverbEchoStage *a = &n->echoStages[4];
+ float oldA = a->buffer[a->writeHead];
+ float writtenA = (float)((double)oldA * a->decayCoeff + sum);
+ a->buffer[a->writeHead] = writtenA;
+ float first = (float)((double)oldA - (double)a->decayCoeff * writtenA);
+ advanceStage(a);
+
+ HMIReverbEchoStage *b = &n->echoStages[5];
+ float oldB = b->buffer[b->writeHead];
+ float monoIn = (float)((double)first * 0.25 + (double)oldB * b->decayCoeff);
+ float stereoIn = (float)((double)first * 0.35 + (double)oldB * b->decayCoeff);
+ float monoOut = (float)((double)oldB - (double)b->decayCoeff * monoIn);
+ float stereoOut = (float)((double)oldB - (double)b->decayCoeff * stereoIn);
+ b->buffer[b->writeHead] = monoIn;
+ advanceStage(b);
+
+ double dry = input * n->dryOut;
+
+ if (!stereo) {
+ preset->floatBufLeftAlt[sample] = (float)(dry + (double)monoOut * n->wetOut);
+ } else {
+ preset->floatBufLeftAlt[sample] = (float)(dry + (double)monoOut * n->wetOut);
+ preset->floatBufRightAlt[sample] = (float)(dry + (double)stereoOut * n->wetOut);
+ }
+ }
+}
+
+int HMIReverb2::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ if (n->channelMode & HMI_EFFECT_CHANNEL_MONO)
+ reverb2ProcessPath(preset, n, 0);
+
+ if (n->channelMode & HMI_EFFECT_CHANNEL_STEREO)
+ reverb2ProcessPath(preset, n, 1);
+
+ return 0;
+}
+
+int HMIReverb2::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ if (p == 0) {
+ *v = n->reverbMax;
+ } else if (p == 1) {
+ *v = n->preDelay;
+ } else if (p == 2) {
+ *v = n->reverbTime;
+ } else if (p == 3) {
+ *v = n->dryOut;
+ *type = 2;
+ return 0;
+ } else if (p == 4) {
+ *v = n->wetOut;
+ *type = 2;
+ return 0;
+ } else {
+ return 11;
+ }
+
+ *type = 0;
+ return 0;
+}
+
+int HMIReverb2::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIReverb2Node *n = (HMIReverb2Node *)base;
+
+ if (p == 0) {
+ n->reverbMax = v;
+ } else if (p == 1) {
+ n->preDelay = v;
+ } else if (p == 2) {
+ n->reverbTime = v;
+ } else if (p == 3) {
+ n->dryOut = v;
+ } else if (p == 4) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/reverb2.h b/audio/effects/hmi/interfaces/reverb2.h
new file mode 100644
index 00000000000..0b225fe0e06
--- /dev/null
+++ b/audio/effects/hmi/interfaces/reverb2.h
@@ -0,0 +1,51 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_REVERB2_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_REVERB2_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIReverb2 : public HMIInterface {
+public:
+ HMIReverb2();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int getMinDuration(HMIEffectNode *, uint32 *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kReverb2Params[];
+ static const float kReverb2Min[];
+ static const float kReverb2Max[];
+ static const float kReverb2Default[];
+ static const float kReverb2Delay[6];
+ static const float kReverb2Decay[6];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/ring_modulator.cpp b/audio/effects/hmi/interfaces/ring_modulator.cpp
new file mode 100644
index 00000000000..9e22b7d8d03
--- /dev/null
+++ b/audio/effects/hmi/interfaces/ring_modulator.cpp
@@ -0,0 +1,123 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/ring_modulator.h"
+
+namespace Audio {
+
+const char *const HMIRingModulator::kRingModulatorParams[] = {"Frequency", "Modulator Type", "Modulate Out Of Phase", "Dry Out", "Wet Out"};
+const float HMIRingModulator::kRingModulatorMin[] = {2.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f};
+const float HMIRingModulator::kRingModulatorMax[] = {0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000}; // Meaning: NaN
+const float HMIRingModulator::kRingModulatorDefault[] = {4000.0f, 0.0f, 1.0f, 1.0f, 1.0f};
+
+HMIRingModulator::HMIRingModulator()
+ : HMIInterface(sizeof(HMIRingModulatorNode), 3, "DLGRingMod",
+ kRingModulatorParams, kRingModulatorMin, kRingModulatorMax,
+ kRingModulatorDefault, "Ring Modulator", 2900, 5) {}
+
+int HMIRingModulator::init(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIRingModulator::uninit(HMIPreset *, HMIEffectNode *) {
+ return 0;
+}
+
+int HMIRingModulator::initEffect(HMIPreset *, HMIEffectNode *base) {
+ ((HMIRingModulatorNode *)base)->phase = 0.0f;
+ return 0;
+}
+
+int HMIRingModulator::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIRingModulatorNode *n = (HMIRingModulatorNode *)base;
+
+ float step = (float)((double)n->frequency * kHmiTwoPi / (double)preset->inputFmt->sampleRate);
+ if (n->channelMode & HMI_EFFECT_CHANNEL_MONO) {
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ double input = preset->floatBufLeftActive[i];
+ double dry = input * n->dryOut;
+ double wet = sin((double)step * n->phase) * input * n->wetOut;
+ n->phase = n->phase + 1.0f;
+ preset->floatBufLeftAlt[i] = (float)(wet + dry);
+ }
+ }
+
+ if (n->channelMode & HMI_EFFECT_CHANNEL_STEREO) {
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ float input = preset->floatBufLeftActive[i];
+ double phase = (double)step * n->phase;
+ preset->floatBufLeftAlt[i] = (float)(sin(phase) * input * n->wetOut + (double)input * n->dryOut);
+ double dry = (double)input * n->dryOut;
+ double right = cos(phase) * input;
+ n->phase = n->phase + 1.0f;
+ preset->floatBufRightAlt[i] = (float)(right * n->wetOut + dry);
+ }
+ }
+
+ return 0;
+}
+
+int HMIRingModulator::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIRingModulatorNode *n = (HMIRingModulatorNode *)base;
+
+ if (p == 0) {
+ *v = n->frequency;
+ *type = 1;
+ } else if (p == 1) {
+ *v = n->modulatorType;
+ *type = 3;
+ } else if (p == 2) {
+ *v = n->modulateOutOfPhase;
+ *type = 3;
+ } else if (p == 3) {
+ *v = n->dryOut;
+ *type = 2;
+ } else if (p == 4) {
+ *v = n->wetOut;
+ *type = 2;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+int HMIRingModulator::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIRingModulatorNode *n = (HMIRingModulatorNode *)base;
+
+ if (p == 0) {
+ n->frequency = v;
+ } else if (p == 1) {
+ n->modulatorType = v;
+ } else if (p == 2) {
+ n->modulateOutOfPhase = v;
+ } else if (p == 3) {
+ n->dryOut = v;
+ } else if (p == 4) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/ring_modulator.h b/audio/effects/hmi/interfaces/ring_modulator.h
new file mode 100644
index 00000000000..102328ff7f1
--- /dev/null
+++ b/audio/effects/hmi/interfaces/ring_modulator.h
@@ -0,0 +1,48 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_RING_MODULATOR_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_RING_MODULATOR_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIRingModulator : public HMIInterface {
+public:
+ HMIRingModulator();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kRingModulatorParams[];
+ static const float kRingModulatorMin[];
+ static const float kRingModulatorMax[];
+ static const float kRingModulatorDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/effects/hmi/interfaces/stereo_delay.cpp b/audio/effects/hmi/interfaces/stereo_delay.cpp
new file mode 100644
index 00000000000..d76fc4f74f4
--- /dev/null
+++ b/audio/effects/hmi/interfaces/stereo_delay.cpp
@@ -0,0 +1,163 @@
+/* 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/>.
+ *
+ */
+
+#include "audio/effects/hmi/interfaces/stereo_delay.h"
+
+namespace Audio {
+
+const char *const HMIStereoDelay::kStereoDelayParams[] = {"Delay Max", "Delay Time L", "Delay Time R", "Feedback", "Dry Out", "Wet Out"};
+const float HMIStereoDelay::kStereoDelayMin[] = {1000.0f, 100.0f, 100.0f, 0.5f, 0.9f, 0.9f, -1.0f, 0.0f};
+const float HMIStereoDelay::kStereoDelayMax[] = {1000.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+const float HMIStereoDelay::kStereoDelayDefault[] = {1000.0f, 1000.0f, 1000.0f, 1.0f, 1.0f, 1.0f};
+
+HMIStereoDelay::HMIStereoDelay()
+ : HMIInterface(sizeof(HMIStereoDelayNode), 2, "DLGDelayMISO",
+ kStereoDelayParams, kStereoDelayMin, kStereoDelayMax,
+ kStereoDelayDefault, "Stereo Delay", 2001, 6) {}
+
+int HMIStereoDelay::init(HMIPreset *preset, HMIEffectNode *base) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ int bytes = 4 * (int)((double)preset->inputFmt->sampleRate * n->maxDelayTime * kHmiMillis);
+ n->bufSizeBytesL = bytes;
+ n->bufSizeBytesR = bytes;
+
+ n->delayBufL = (float *)malloc(bytes);
+ if (!n->delayBufL)
+ return 1;
+
+ n->delayBufR = (float *)malloc(bytes);
+ if (!n->delayBufR) {
+ free(n->delayBufL);
+ n->delayBufL = 0;
+ return 1;
+ }
+
+ n->writeIndexL = n->writeIndexR = 0;
+ return 0;
+}
+
+int HMIStereoDelay::uninit(HMIPreset *, HMIEffectNode *base) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ free(n->delayBufL);
+ free(n->delayBufR);
+ return 0;
+}
+
+int HMIStereoDelay::initEffect(HMIPreset *, HMIEffectNode *base) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ n->writeIndexL = n->writeIndexR = 0;
+ memset(n->delayBufL, 0, n->bufSizeBytesL);
+ memset(n->delayBufR, 0, n->bufSizeBytesR);
+ return 0;
+}
+
+int HMIStereoDelay::getMinDuration(HMIEffectNode *base, uint32 *out) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ double delay = n->delayTimeL > n->delayTimeR ? n->delayTimeL : n->delayTimeR;
+ *out = (uint32)(log(kHmiMillis) / log(n->feedback) * delay);
+ return 0;
+}
+
+int HMIStereoDelay::processBlock(HMIPreset *preset, HMIEffectNode *base) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ double rate = preset->inputFmt->sampleRate;
+ int sizeL = (int)(n->delayTimeL * rate * kHmiMillis);
+ int sizeR = (int)(n->delayTimeR * rate * kHmiMillis);
+ int indexL = n->writeIndexL;
+ int indexR = n->writeIndexR;
+
+ for (uint32 i = 0; i != preset->chunkSize; ++i) {
+ double input = preset->floatBufLeftActive[i];
+ float delayedL = n->delayBufL[indexL];
+ float delayedR = n->delayBufR[indexR];
+ preset->floatBufLeftAlt[i] = (float)(input * n->dryOut + (double)n->wetOut * delayedL);
+ preset->floatBufRightAlt[i] = (float)(input * n->dryOut + (double)n->wetOut * delayedR);
+ n->delayBufL[indexL] = (float)((double)n->feedback * delayedL + input);
+ n->delayBufR[indexR] = (float)((double)n->feedback * delayedR + input);
+
+ if (++indexL == sizeL)
+ indexL = 0;
+
+ if (++indexR == sizeR)
+ indexR = 0;
+ }
+
+ n->writeIndexL = indexL;
+ n->writeIndexR = indexR;
+ return 0;
+}
+
+int HMIStereoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ if (p == 0) {
+ *v = n->maxDelayTime;
+ *type = 0;
+ } else if (p == 1) {
+ *v = n->delayTimeL;
+ *type = 0;
+ } else if (p == 2) {
+ *v = n->delayTimeR;
+ *type = 0;
+ } else if (p == 3) {
+ *v = n->feedback;
+ *type = 2;
+ } else if (p == 4) {
+ *v = n->dryOut;
+ *type = 2;
+ } else if (p == 5) {
+ *v = n->wetOut;
+ *type = 2;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+int HMIStereoDelay::setEffectParam(HMIEffectNode *base, int p, float v) {
+ HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
+
+ if (p == 0) {
+ n->maxDelayTime = v;
+ } else if (p == 1) {
+ n->delayTimeL = v;
+ } else if (p == 2) {
+ n->delayTimeR = v;
+ } else if (p == 3) {
+ n->feedback = v;
+ } else if (p == 4) {
+ n->dryOut = v;
+ } else if (p == 5) {
+ n->wetOut = v;
+ } else {
+ return 11;
+ }
+
+ return 0;
+}
+
+} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/stereo_delay.h b/audio/effects/hmi/interfaces/stereo_delay.h
new file mode 100644
index 00000000000..fda43379f65
--- /dev/null
+++ b/audio/effects/hmi/interfaces/stereo_delay.h
@@ -0,0 +1,49 @@
+/* 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/>.
+ *
+ */
+
+#ifndef AUDIO_EFFECTS_HMI_INTERFACES_STEREO_DELAY_H
+#define AUDIO_EFFECTS_HMI_INTERFACES_STEREO_DELAY_H
+
+#include "audio/effects/hmi/hmi_interface.h"
+
+namespace Audio {
+
+class HMIStereoDelay : public HMIInterface {
+public:
+ HMIStereoDelay();
+ int init(HMIPreset *, HMIEffectNode *) override;
+ int uninit(HMIPreset *, HMIEffectNode *) override;
+ int getMinDuration(HMIEffectNode *, uint32 *) override;
+ int processBlock(HMIPreset *, HMIEffectNode *) override;
+ int initEffect(HMIPreset *, HMIEffectNode *) override;
+ int getEffectParam(HMIEffectNode *, int, float *, int *) override;
+ int setEffectParam(HMIEffectNode *, int, float) override;
+
+private:
+ static const char *const kStereoDelayParams[];
+ static const float kStereoDelayMin[];
+ static const float kStereoDelayMax[];
+ static const float kStereoDelayDefault[];
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/audio/module.mk b/audio/module.mk
index 54633bd7bfa..a52ee375df5 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -30,6 +30,17 @@ MODULE_OBJS := \
sid.o \
ym2149.o \
timestamp.o \
+ effects/hmi/interfaces/envelope.o \
+ effects/hmi/interfaces/filter1.o \
+ effects/hmi/hmifxfp.o \
+ effects/hmi/hmifxlib.o \
+ effects/hmi/interfaces/mono_delay.o \
+ effects/hmi/interfaces/phasor.o \
+ effects/hmi/interfaces/resonator.o \
+ effects/hmi/interfaces/reverb1.o \
+ effects/hmi/interfaces/reverb2.o \
+ effects/hmi/interfaces/ring_modulator.o \
+ effects/hmi/interfaces/stereo_delay.o \
decoders/3do.o \
decoders/aac.o \
decoders/adpcm.o \
Commit: 1759d44803454e9c5e7078f6d33478af650ab4b6
https://github.com/scummvm/scummvm/commit/1759d44803454e9c5e7078f6d33478af650ab4b6
Author: AndywinXp (andywinxp at gmail.com)
Date: 2026-07-01T01:13:22+02:00
Commit Message:
AUDIO: HMI: Infinite Audio clean-up
Changed paths:
audio/effects/hmi/hmi_interface.h
audio/effects/hmi/hmi_types.h
audio/effects/hmi/hmifxfp.cpp
audio/effects/hmi/hmifxfp.h
audio/effects/hmi/hmifxlib.cpp
audio/effects/hmi/hmifxlib.h
audio/effects/hmi/interfaces/envelope.cpp
audio/effects/hmi/interfaces/envelope.h
audio/effects/hmi/interfaces/filter1.cpp
audio/effects/hmi/interfaces/filter1.h
audio/effects/hmi/interfaces/mono_delay.cpp
audio/effects/hmi/interfaces/mono_delay.h
audio/effects/hmi/interfaces/phasor.cpp
audio/effects/hmi/interfaces/phasor.h
audio/effects/hmi/interfaces/resonator.cpp
audio/effects/hmi/interfaces/resonator.h
audio/effects/hmi/interfaces/reverb1.cpp
audio/effects/hmi/interfaces/reverb1.h
audio/effects/hmi/interfaces/reverb2.cpp
audio/effects/hmi/interfaces/reverb2.h
audio/effects/hmi/interfaces/ring_modulator.cpp
audio/effects/hmi/interfaces/ring_modulator.h
audio/effects/hmi/interfaces/stereo_delay.cpp
audio/effects/hmi/interfaces/stereo_delay.h
diff --git a/audio/effects/hmi/hmi_interface.h b/audio/effects/hmi/hmi_interface.h
index e3f0fdc9f4f..cca4cc3120d 100644
--- a/audio/effects/hmi/hmi_interface.h
+++ b/audio/effects/hmi/hmi_interface.h
@@ -32,13 +32,13 @@ class HMIInterface {
public:
virtual ~HMIInterface() {}
- virtual int init(HMIPreset *, HMIEffectNode *) = 0;
- virtual int uninit(HMIPreset *, HMIEffectNode *) = 0;
- virtual int getMinDuration(HMIEffectNode *, uint32 *);
- virtual int processBlock(HMIPreset *, HMIEffectNode *) = 0;
- virtual int initEffect(HMIPreset *, HMIEffectNode *) = 0;
- virtual int getEffectParam(HMIEffectNode *, int, float *, int *) = 0;
- virtual int setEffectParam(HMIEffectNode *, int, float) = 0;
+ virtual int init(HMIPreset *preset, HMIEffectNode *base) = 0;
+ virtual int uninit(HMIPreset *preset, HMIEffectNode *base) = 0;
+ virtual int getMinDuration(HMIEffectNode *n, uint32 *out);
+ virtual int processBlock(HMIPreset *preset, HMIEffectNode *base) = 0;
+ virtual int initEffect(HMIPreset *preset, HMIEffectNode *base) = 0;
+ virtual int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) = 0;
+ virtual int setEffectParam(HMIEffectNode *base, int param, float value) = 0;
int effectStructSize() const { return _effectStructSize; }
int outChannels() const { return _outChannels; }
@@ -62,16 +62,16 @@ protected:
int paramCount);
private:
- int _effectStructSize;
- int _outChannels;
- const char *_interfaceName;
- HMIParamNames _effectParams;
- const float *_paramMinValues;
- const float *_paramMaxValues;
- const float *_paramDefaultValues;
- char _presetName[64];
- int _presetId;
- int _paramCount;
+ int _effectStructSize = 0;
+ int _outChannels = 0;
+ const char *_interfaceName = nullptr;
+ HMIParamNames _effectParams = nullptr;
+ const float *_paramMinValues = nullptr;
+ const float *_paramMaxValues = nullptr;
+ const float *_paramDefaultValues = nullptr;
+ char _presetName[64] = {0};
+ int _presetId = 0;
+ int _paramCount = 0;
};
} // End of namespace Audio
diff --git a/audio/effects/hmi/hmi_types.h b/audio/effects/hmi/hmi_types.h
index 0368330cc64..db45f7120db 100644
--- a/audio/effects/hmi/hmi_types.h
+++ b/audio/effects/hmi/hmi_types.h
@@ -103,7 +103,6 @@ struct HMIPreset {
uint32 chunkSize;
int lockLevel;
int allocatedHeapSize;
- uint8 reserved[980];
HMIEffectNode *effectChain;
HMIFormat *outputFmt;
HMIFormat *inputFmt;
@@ -111,12 +110,8 @@ struct HMIPreset {
};
struct HMIInitData {
- uint32 *a;
- uint32 *b;
int heapSize;
void *heapPtr;
- void *(*mallocFunc)(size_t);
- void (*freeFunc)(void *);
};
struct HMILibrary {
diff --git a/audio/effects/hmi/hmifxfp.cpp b/audio/effects/hmi/hmifxfp.cpp
index d4719bdc139..75dc4d35e7e 100644
--- a/audio/effects/hmi/hmifxfp.cpp
+++ b/audio/effects/hmi/hmifxfp.cpp
@@ -50,15 +50,16 @@ HMIInterface::HMIInterface(int size, int channels,
copyName(_presetName, name);
}
-int HMIInterface::getMinDuration(HMIEffectNode *, uint32 *duration) {
+int HMIInterface::getMinDuration(HMIEffectNode *n, uint32 *duration) {
*duration = 0;
return 0;
}
-HMIFxFp::HMIFxFp() { initializeInterfaces(); }
+HMIFxFp::HMIFxFp() {
+ initializeInterfaces();
+}
void HMIFxFp::initializeInterfaces() {
- /* Original interface-list order at 0x10012A70. */
_interfaceList[0] = &_monoDelay;
_interfaceList[1] = &_stereoDelay;
_interfaceList[2] = &_reverb1;
diff --git a/audio/effects/hmi/hmifxfp.h b/audio/effects/hmi/hmifxfp.h
index 8e7d200388a..5dc09dbb62c 100644
--- a/audio/effects/hmi/hmifxfp.h
+++ b/audio/effects/hmi/hmifxfp.h
@@ -51,7 +51,7 @@ private:
HMIResonator _resonator;
HMIPhasor _phasor;
HMIReverb2 _reverb2;
- HMIInterface *_interfaceList[10];
+ HMIInterface *_interfaceList[10] = {nullptr};
};
} // End of namespace Audio
diff --git a/audio/effects/hmi/hmifxlib.cpp b/audio/effects/hmi/hmifxlib.cpp
index d89385c4e69..b50fa5db68a 100644
--- a/audio/effects/hmi/hmifxlib.cpp
+++ b/audio/effects/hmi/hmifxlib.cpp
@@ -61,11 +61,13 @@ static int16 hmiFistp16(float value) {
}
HMIFxLib::HMIFxLib()
- : _numLoadedInterfaces(0), _curInterfaceIndex(0), _systemHeap(0),
- _heapCursor(0), _heapEnd(0), _mallocFunc(malloc), _freeFunc(free) {
+ : _numLoadedInterfaces(0), _curInterfaceIndex(0), _systemHeap(nullptr), _heapCursor(nullptr), _heapEnd(nullptr) {
memset(_loadedInterfaces, 0, sizeof(_loadedInterfaces));
+
+ _fxFp = new HMIFxFp();
+
HMIInterface **list = nullptr;
- _fxFp.hmiFXGetInterfaceList(&list);
+ _fxFp->hmiFXGetInterfaceList(&list);
while (_numLoadedInterfaces != 1024 && list[_numLoadedInterfaces]) {
_loadedInterfaces[_numLoadedInterfaces] = list[_numLoadedInterfaces];
@@ -76,22 +78,16 @@ HMIFxLib::HMIFxLib()
_loadedInterfaces[_numLoadedInterfaces] = nullptr;
}
-HMIFxLib::~HMIFxLib() {}
+HMIFxLib::~HMIFxLib() {
+ delete _fxFp;
+}
HMIFxFp *HMIFxLib::effects() {
- return &_fxFp;
+ return _fxFp;
}
int HMIFxLib::hmiFXInitSystem(HMIInitData *initData) {
- if (initData->mallocFunc && initData->freeFunc) {
- _mallocFunc = initData->mallocFunc;
- _freeFunc = initData->freeFunc;
- } else {
- _mallocFunc = malloc;
- _freeFunc = free;
- }
-
- initData->heapPtr = hmiFXMalloc((size_t)initData->heapSize);
+ initData->heapPtr = malloc((size_t)initData->heapSize);
if (!initData->heapPtr)
return 1;
@@ -101,7 +97,7 @@ int HMIFxLib::hmiFXInitSystem(HMIInitData *initData) {
int HMIFxLib::hmiFXUnInitSystem(HMIInitData *initData) {
if (initData->heapPtr)
- hmiFXFree(initData->heapPtr);
+ free(initData->heapPtr);
initData->heapPtr = nullptr;
_systemHeap = _heapCursor = _heapEnd = nullptr;
@@ -156,6 +152,7 @@ void *HMIFxLib::hmiFXHeapAlloc(int size) {
uint8 *result = _heapCursor;
if (!result || result + size > _heapEnd)
return nullptr;
+
_heapCursor += size;
return result;
}
@@ -174,14 +171,6 @@ void *HMIFxLib::hmiFXHeapReset() {
return _systemHeap;
}
-void *HMIFxLib::hmiFXMalloc(size_t size) {
- return _mallocFunc(size);
-}
-
-void HMIFxLib::hmiFXFree(void *ptr) {
- _freeFunc(ptr);
-}
-
int HMIFxLib::convertPCMToFloat(HMIPreset *preset, const uint8 *buffer, int samples) {
float *left = preset->floatBufLeftActive;
float *right = preset->floatBufRightActive;
@@ -275,7 +264,7 @@ int HMIFxLib::hmiFXPresetCreate(HMIPreset *preset) {
uint32 samples = preset->inputFmt->sampleRate * preset->chunkSizeInMs / 1000U;
int segmentBytes = 4 * (int)samples + 1024;
preset->chunkSizeInSamples = samples;
- float *block = (float *)((preset->flags & HMI_PRESET_FLAG_USE_MALLOC) ? hmiFXMalloc(4 * segmentBytes)
+ float *block = (float *)((preset->flags & HMI_PRESET_FLAG_USE_MALLOC) ? malloc(4 * segmentBytes)
: hmiFXHeapAlloc(4 * segmentBytes));
if (!block)
return 1;
@@ -303,7 +292,7 @@ int HMIFxLib::hmiFXPresetDestroy(HMIPreset *preset) {
node->interface->uninit(preset, node);
if (preset->flags & HMI_PRESET_FLAG_USE_MALLOC)
- hmiFXFree(preset->floatBufLeft0);
+ free(preset->floatBufLeft0);
return 0;
}
@@ -416,7 +405,7 @@ int HMIFxLib::hmiFXPresetCreateInstance(HMIPreset *source, HMIPreset **outInstan
if (!source)
return 15;
- HMIPreset *copy = (HMIPreset *)hmiFXMalloc(sizeof(HMIPreset));
+ HMIPreset *copy = (HMIPreset *)malloc(sizeof(HMIPreset));
if (!copy) {
*outInstance = nullptr;
return 1;
@@ -428,7 +417,7 @@ int HMIFxLib::hmiFXPresetCreateInstance(HMIPreset *source, HMIPreset **outInstan
HMIEffectNode *previous = nullptr;
for (HMIEffectNode *src = source->effectChain; src; src = src->next) {
- HMIEffectNode *node = (HMIEffectNode *)hmiFXMalloc(src->interface->effectStructSize());
+ HMIEffectNode *node = (HMIEffectNode *)malloc(src->interface->effectStructSize());
if (!node) {
hmiFXPresetDestroyInstance(copy);
*outInstance = nullptr;
@@ -460,11 +449,11 @@ int HMIFxLib::hmiFXPresetDestroyInstance(HMIPreset *preset) {
while (node) {
node->interface->uninit(preset, node);
HMIEffectNode *next = node->next;
- hmiFXFree(node);
+ free(node);
node = next;
}
- hmiFXFree(preset);
+ free(preset);
return 0;
}
@@ -538,7 +527,7 @@ int HMIFxLib::processPreset(HMIPreset *preset, HMIProcessRequest *req) {
}
if (req->flags & HMI_PROCESS_ALLOCATE_OUTPUT) {
- req->dstBuf = (uint8 *)hmiFXMalloc(outputBytes);
+ req->dstBuf = (uint8 *)malloc(outputBytes);
if (!req->dstBuf)
return 1;
@@ -819,7 +808,7 @@ int HMIFxLib::hmiFXPresetLoadLibrary(HMILibrary **outLib, Common::SeekableReadSt
if (!readFile(&d, stream))
return 10;
- HMILibrary *library = (HMILibrary *)hmiFXMalloc(sizeof(HMILibrary));
+ HMILibrary *library = (HMILibrary *)malloc(sizeof(HMILibrary));
if (!library) {
flushFile(&d);
return 1;
@@ -863,7 +852,7 @@ int HMIFxLib::hmiFXPresetLoadLibrary(HMILibrary **outLib, Common::SeekableReadSt
if (!findSection(&d, query))
break;
- HMIPreset *preset = (HMIPreset *)hmiFXMalloc(sizeof(HMIPreset));
+ HMIPreset *preset = (HMIPreset *)malloc(sizeof(HMIPreset));
if (!preset) {
flushFile(&d);
return 1;
@@ -897,7 +886,7 @@ int HMIFxLib::hmiFXPresetLoadLibrary(HMILibrary **outLib, Common::SeekableReadSt
return 7;
}
- HMIEffectNode *node = (HMIEffectNode *)hmiFXMalloc(interface->effectStructSize());
+ HMIEffectNode *node = (HMIEffectNode *)malloc(interface->effectStructSize());
if (!node) {
flushFile(&d);
return 1;
@@ -940,19 +929,19 @@ int HMIFxLib::hmiFXPresetFreeLibrary(HMILibrary *library) {
while (node) {
node->interface->uninit(preset, node);
HMIEffectNode *next = node->next;
- hmiFXFree(node);
+ free(node);
node = next;
}
if (preset->flags & HMI_PRESET_FLAG_USE_MALLOC)
- hmiFXFree(preset->floatBufLeft0);
+ free(preset->floatBufLeft0);
HMIPreset *next = preset->next;
- hmiFXFree(preset);
+ free(preset);
preset = next;
}
- hmiFXFree(library);
+ free(library);
return 0;
}
diff --git a/audio/effects/hmi/hmifxlib.h b/audio/effects/hmi/hmifxlib.h
index 97674363f8b..c978669c77d 100644
--- a/audio/effects/hmi/hmifxlib.h
+++ b/audio/effects/hmi/hmifxlib.h
@@ -64,8 +64,6 @@ public:
void hmiFXHeapFree(void *ptr);
int hmiFXHeapInit(HMIInitData *initData);
void *hmiFXHeapReset();
- void *hmiFXMalloc(size_t size);
- void hmiFXFree(void *ptr);
private:
int convertPCMToFloat(HMIPreset *preset, const uint8 *buffer, int samples);
@@ -83,16 +81,14 @@ private:
int readSectionInt(HMIFileDescriptor *desc, const char *key, int *value);
int readSectionString(HMIFileDescriptor *desc, const char *key, char *value, int size);
- HMIFxFp _fxFp;
+ HMIFxFp *_fxFp = nullptr;
HMIInterface *_loadedInterfaces[1024];
- unsigned int _numLoadedInterfaces;
- unsigned int _curInterfaceIndex;
+ unsigned int _numLoadedInterfaces = 0;
+ unsigned int _curInterfaceIndex = 0;
- uint8 *_systemHeap;
- uint8 *_heapCursor;
- uint8 *_heapEnd;
- void *(*_mallocFunc)(size_t);
- void (*_freeFunc)(void *);
+ uint8 *_systemHeap = nullptr;
+ uint8 *_heapCursor = nullptr;
+ uint8 *_heapEnd = nullptr;
};
} // End of namespace Audio
diff --git a/audio/effects/hmi/interfaces/envelope.cpp b/audio/effects/hmi/interfaces/envelope.cpp
index 7537a10e827..cf7045116b2 100644
--- a/audio/effects/hmi/interfaces/envelope.cpp
+++ b/audio/effects/hmi/interfaces/envelope.cpp
@@ -33,15 +33,15 @@ HMIEnvelope::HMIEnvelope()
kEnvelopeParams, kEnvelopeMin, kEnvelopeMax, kEnvelopeDefault,
"Envelope", 2910, 18) {}
-int HMIEnvelope::init(HMIPreset *, HMIEffectNode *) {
+int HMIEnvelope::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIEnvelope::uninit(HMIPreset *, HMIEffectNode *) {
+int HMIEnvelope::uninit(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIEnvelope::initEffect(HMIPreset *, HMIEffectNode *base) {
+int HMIEnvelope::initEffect(HMIPreset *preset, HMIEffectNode *base) {
HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
if (n->initGuard == 0.0f) {
@@ -89,17 +89,17 @@ int HMIEnvelope::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIEnvelope::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIEnvelope::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
- if (p == 0) {
- *v = n->envPoints;
- } else if (p == 1) {
- *v = n->initGuard;
+ if (param == 0) {
+ *value = n->envPoints;
+ } else if (param == 1) {
+ *value = n->initGuard;
*type = 0;
return 0;
- } else if (p >= 2 && p <= 17) {
- int index = (p - 2) >> 1;
- *v = (p & 1) ? n->pointAmp[index] : n->pointTime[index];
+ } else if (param >= 2 && param <= 17) {
+ int index = (param - 2) >> 1;
+ *value = (param & 1) ? n->pointAmp[index] : n->pointTime[index];
} else {
return 11;
}
@@ -108,19 +108,19 @@ int HMIEnvelope::getEffectParam(HMIEffectNode *base, int p, float *v, int *type)
return 0;
}
-int HMIEnvelope::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIEnvelope::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIEnvelopeNode *n = (HMIEnvelopeNode *)base;
- if (p == 0) {
- n->envPoints = v;
- } else if (p == 1) {
- n->initGuard = v;
- } else if (p >= 2 && p <= 17) {
- int index = (p - 2) >> 1;
-
- if (p & 1) {
- n->pointAmp[index] = v;
+ if (param == 0) {
+ n->envPoints = value;
+ } else if (param == 1) {
+ n->initGuard = value;
+ } else if (param >= 2 && param <= 17) {
+ int index = (param - 2) >> 1;
+
+ if (param & 1) {
+ n->pointAmp[index] = value;
} else {
- n->pointTime[index] = v;
+ n->pointTime[index] = value;
}
} else {
return 11;
diff --git a/audio/effects/hmi/interfaces/envelope.h b/audio/effects/hmi/interfaces/envelope.h
index 30498868a1f..8c8a55e7e90 100644
--- a/audio/effects/hmi/interfaces/envelope.h
+++ b/audio/effects/hmi/interfaces/envelope.h
@@ -29,12 +29,12 @@ namespace Audio {
class HMIEnvelope : public HMIInterface {
public:
HMIEnvelope();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kEnvelopeParams[];
diff --git a/audio/effects/hmi/interfaces/filter1.cpp b/audio/effects/hmi/interfaces/filter1.cpp
index 84003c28f48..3fca14ab860 100644
--- a/audio/effects/hmi/interfaces/filter1.cpp
+++ b/audio/effects/hmi/interfaces/filter1.cpp
@@ -33,11 +33,11 @@ HMIFilter1::HMIFilter1()
kFilter1Params, kFilter1Min, kFilter1Max, kFilter1Default,
"Filter 1", 2300, 4) {}
-int HMIFilter1::init(HMIPreset *, HMIEffectNode *) {
+int HMIFilter1::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIFilter1::uninit(HMIPreset *, HMIEffectNode *) {
+int HMIFilter1::uninit(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
@@ -114,21 +114,21 @@ int HMIFilter1::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIFilter1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIFilter1::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIFilter1Node *n = (HMIFilter1Node *)base;
- if (p == 0) {
- *v = (float)(uint32)n->filterType;
+ if (param == 0) {
+ *value = (float)(uint32)n->filterType;
*type = 3;
return 0;
}
- if (p == 1) {
- *v = n->cutoffFrequency;
- } else if (p == 2) {
- *v = n->centerFrequency;
- } else if (p == 3) {
- *v = n->bandWidth;
+ if (param == 1) {
+ *value = n->cutoffFrequency;
+ } else if (param == 2) {
+ *value = n->centerFrequency;
+ } else if (param == 3) {
+ *value = n->bandWidth;
} else {
return 11;
}
@@ -137,17 +137,17 @@ int HMIFilter1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type)
return 0;
}
-int HMIFilter1::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIFilter1::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIFilter1Node *n = (HMIFilter1Node *)base;
- if (p == 0) {
- n->filterType = (int)(v);
- } else if (p == 1) {
- n->cutoffFrequency = v;
- } else if (p == 2) {
- n->centerFrequency = v;
- } else if (p == 3) {
- n->bandWidth = v;
+ if (param == 0) {
+ n->filterType = (int)(value);
+ } else if (param == 1) {
+ n->cutoffFrequency = value;
+ } else if (param == 2) {
+ n->centerFrequency = value;
+ } else if (param == 3) {
+ n->bandWidth = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/filter1.h b/audio/effects/hmi/interfaces/filter1.h
index c6dcf4b1427..caf73c1abea 100644
--- a/audio/effects/hmi/interfaces/filter1.h
+++ b/audio/effects/hmi/interfaces/filter1.h
@@ -29,12 +29,12 @@ namespace Audio {
class HMIFilter1 : public HMIInterface {
public:
HMIFilter1();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kFilter1Params[];
diff --git a/audio/effects/hmi/interfaces/mono_delay.cpp b/audio/effects/hmi/interfaces/mono_delay.cpp
index a06f5be5895..92671b96509 100644
--- a/audio/effects/hmi/interfaces/mono_delay.cpp
+++ b/audio/effects/hmi/interfaces/mono_delay.cpp
@@ -47,13 +47,13 @@ int HMIMonoDelay::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIMonoDelay::uninit(HMIPreset *, HMIEffectNode *base) {
+int HMIMonoDelay::uninit(HMIPreset *preset, HMIEffectNode *base) {
HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
free(n->delayBuf);
return 0;
}
-int HMIMonoDelay::initEffect(HMIPreset *, HMIEffectNode *base) {
+int HMIMonoDelay::initEffect(HMIPreset *preset, HMIEffectNode *base) {
HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
n->writeIndex = 0;
memset(n->delayBuf, 0, n->bufSizeBytes);
@@ -86,23 +86,23 @@ int HMIMonoDelay::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIMonoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIMonoDelay::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
- if (p == 0) {
- *v = n->maxDelayTime;
+ if (param == 0) {
+ *value = n->maxDelayTime;
*type = 0;
- } else if (p == 1) {
- *v = n->delayTime;
+ } else if (param == 1) {
+ *value = n->delayTime;
*type = 0;
- } else if (p == 2) {
- *v = n->feedback;
+ } else if (param == 2) {
+ *value = n->feedback;
*type = 2;
- } else if (p == 3) {
- *v = n->dryOut;
+ } else if (param == 3) {
+ *value = n->dryOut;
*type = 2;
- } else if (p == 4) {
- *v = n->wetOut;
+ } else if (param == 4) {
+ *value = n->wetOut;
*type = 2;
} else {
return 11;
@@ -110,19 +110,19 @@ int HMIMonoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *type
return 0;
}
-int HMIMonoDelay::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIMonoDelay::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIMonoDelayNode *n = (HMIMonoDelayNode *)base;
- if (p == 0) {
- n->maxDelayTime = v;
- } else if (p == 1) {
- n->delayTime = v;
- } else if (p == 2) {
- n->feedback = v;
- } else if (p == 3) {
- n->dryOut = v;
- } else if (p == 4) {
- n->wetOut = v;
+ if (param == 0) {
+ n->maxDelayTime = value;
+ } else if (param == 1) {
+ n->delayTime = value;
+ } else if (param == 2) {
+ n->feedback = value;
+ } else if (param == 3) {
+ n->dryOut = value;
+ } else if (param == 4) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/mono_delay.h b/audio/effects/hmi/interfaces/mono_delay.h
index ce16bf68247..7c6cafd56b7 100644
--- a/audio/effects/hmi/interfaces/mono_delay.h
+++ b/audio/effects/hmi/interfaces/mono_delay.h
@@ -29,13 +29,13 @@ namespace Audio {
class HMIMonoDelay : public HMIInterface {
public:
HMIMonoDelay();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int getMinDuration(HMIEffectNode *, uint32 *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int getMinDuration(HMIEffectNode *base, uint32 *out) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kMonoDelayParams[];
diff --git a/audio/effects/hmi/interfaces/phasor.cpp b/audio/effects/hmi/interfaces/phasor.cpp
index 1360b63fd65..fb83ae41df3 100644
--- a/audio/effects/hmi/interfaces/phasor.cpp
+++ b/audio/effects/hmi/interfaces/phasor.cpp
@@ -34,11 +34,11 @@ HMIPhasor::HMIPhasor()
kPhasorParams, kPhasorMin, kPhasorMax, kPhasorDefault,
"Phasor", 2375, 6) {}
-int HMIPhasor::init(HMIPreset *, HMIEffectNode *) {
+int HMIPhasor::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIPhasor::uninit(HMIPreset *, HMIEffectNode *) {
+int HMIPhasor::uninit(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
@@ -100,21 +100,21 @@ int HMIPhasor::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIPhasor::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIPhasor::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIPhasorNode *n = (HMIPhasorNode *)base;
- if (p == 0) {
- *v = n->rate;
- } else if (p == 1) {
- *v = n->depth;
- } else if (p == 2) {
- *v = n->centerFrequency;
- } else if (p == 3) {
- *v = n->feedback;
- } else if (p == 4) {
- *v = n->dryOut;
- } else if (p == 5) {
- *v = n->wetOut;
+ if (param == 0) {
+ *value = n->rate;
+ } else if (param == 1) {
+ *value = n->depth;
+ } else if (param == 2) {
+ *value = n->centerFrequency;
+ } else if (param == 3) {
+ *value = n->feedback;
+ } else if (param == 4) {
+ *value = n->dryOut;
+ } else if (param == 5) {
+ *value = n->wetOut;
} else {
return 11;
}
@@ -123,21 +123,21 @@ int HMIPhasor::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
return 0;
}
-int HMIPhasor::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIPhasor::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIPhasorNode *n = (HMIPhasorNode *)base;
- if (p == 0) {
- n->rate = v;
- } else if (p == 1) {
- n->depth = v;
- } else if (p == 2) {
- n->centerFrequency = v;
- } else if (p == 3) {
- n->feedback = v;
- } else if (p == 4) {
- n->dryOut = v;
- } else if (p == 5) {
- n->wetOut = v;
+ if (param == 0) {
+ n->rate = value;
+ } else if (param == 1) {
+ n->depth = value;
+ } else if (param == 2) {
+ n->centerFrequency = value;
+ } else if (param == 3) {
+ n->feedback = value;
+ } else if (param == 4) {
+ n->dryOut = value;
+ } else if (param == 5) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/phasor.h b/audio/effects/hmi/interfaces/phasor.h
index cc4b27c670b..37885777e3f 100644
--- a/audio/effects/hmi/interfaces/phasor.h
+++ b/audio/effects/hmi/interfaces/phasor.h
@@ -29,12 +29,12 @@ namespace Audio {
class HMIPhasor : public HMIInterface {
public:
HMIPhasor();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kPhasorParams[];
diff --git a/audio/effects/hmi/interfaces/resonator.cpp b/audio/effects/hmi/interfaces/resonator.cpp
index 8b32ba322f0..1ede966dc94 100644
--- a/audio/effects/hmi/interfaces/resonator.cpp
+++ b/audio/effects/hmi/interfaces/resonator.cpp
@@ -33,11 +33,11 @@ HMIResonator::HMIResonator()
kResonatorParams, kResonatorMin, kResonatorMax, kResonatorDefault,
"Resonator", 2350, 2) {}
-int HMIResonator::init(HMIPreset *, HMIEffectNode *) {
+int HMIResonator::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIResonator::uninit(HMIPreset *, HMIEffectNode *) {
+int HMIResonator::uninit(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
@@ -72,13 +72,13 @@ int HMIResonator::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIResonator::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIResonator::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIResonatorNode *n = (HMIResonatorNode *)base;
- if (p == 0) {
- *v = n->cutoffFrequency;
- } else if (p == 1) {
- *v = n->bandWidth;
+ if (param == 0) {
+ *value = n->cutoffFrequency;
+ } else if (param == 1) {
+ *value = n->bandWidth;
} else {
return 11;
}
@@ -87,13 +87,13 @@ int HMIResonator::getEffectParam(HMIEffectNode *base, int p, float *v, int *type
return 0;
}
-int HMIResonator::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIResonator::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIResonatorNode *n = (HMIResonatorNode *)base;
- if (p == 0) {
- n->cutoffFrequency = v;
- } else if (p == 1) {
- n->bandWidth = v;
+ if (param == 0) {
+ n->cutoffFrequency = value;
+ } else if (param == 1) {
+ n->bandWidth = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/resonator.h b/audio/effects/hmi/interfaces/resonator.h
index faf4d0763c7..4e3c8c42a02 100644
--- a/audio/effects/hmi/interfaces/resonator.h
+++ b/audio/effects/hmi/interfaces/resonator.h
@@ -29,12 +29,12 @@ namespace Audio {
class HMIResonator : public HMIInterface {
public:
HMIResonator();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kResonatorParams[];
diff --git a/audio/effects/hmi/interfaces/reverb1.cpp b/audio/effects/hmi/interfaces/reverb1.cpp
index f4f7160d065..14bd7e3787e 100644
--- a/audio/effects/hmi/interfaces/reverb1.cpp
+++ b/audio/effects/hmi/interfaces/reverb1.cpp
@@ -55,7 +55,7 @@ int HMIReverb1::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIReverb1::uninit(HMIPreset *, HMIEffectNode *base) {
+int HMIReverb1::uninit(HMIPreset *preset, HMIEffectNode *base) {
HMIReverb1Node *n = (HMIReverb1Node *)base;
for (int i = 0; i != 4; ++i) {
@@ -180,21 +180,21 @@ int HMIReverb1::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIReverb1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIReverb1::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIReverb1Node *n = (HMIReverb1Node *)base;
- if (p == 0) {
- *v = n->reverbMax;
- } else if (p == 1) {
- *v = n->preDelay;
- } else if (p == 2) {
- *v = n->reverbTime;
- } else if (p == 3) {
- *v = n->dryOut;
+ if (param == 0) {
+ *value = n->reverbMax;
+ } else if (param == 1) {
+ *value = n->preDelay;
+ } else if (param == 2) {
+ *value = n->reverbTime;
+ } else if (param == 3) {
+ *value = n->dryOut;
*type = 2;
return 0;
- } else if (p == 4) {
- *v = n->wetOut;
+ } else if (param == 4) {
+ *value = n->wetOut;
*type = 2;
return 0;
} else {
@@ -205,19 +205,19 @@ int HMIReverb1::getEffectParam(HMIEffectNode *base, int p, float *v, int *type)
return 0;
}
-int HMIReverb1::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIReverb1::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIReverb1Node *n = (HMIReverb1Node *)base;
- if (p == 0) {
- n->reverbMax = v;
- } else if (p == 1) {
- n->preDelay = v;
- } else if (p == 2) {
- n->reverbTime = v;
- } else if (p == 3) {
- n->dryOut = v;
- } else if (p == 4) {
- n->wetOut = v;
+ if (param == 0) {
+ n->reverbMax = value;
+ } else if (param == 1) {
+ n->preDelay = value;
+ } else if (param == 2) {
+ n->reverbTime = value;
+ } else if (param == 3) {
+ n->dryOut = value;
+ } else if (param == 4) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/reverb1.h b/audio/effects/hmi/interfaces/reverb1.h
index 1db38c34fd6..79079222086 100644
--- a/audio/effects/hmi/interfaces/reverb1.h
+++ b/audio/effects/hmi/interfaces/reverb1.h
@@ -29,13 +29,13 @@ namespace Audio {
class HMIReverb1 : public HMIInterface {
public:
HMIReverb1();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int getMinDuration(HMIEffectNode *, uint32 *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int getMinDuration(HMIEffectNode *base, uint32 *duration) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kReverb1Params[];
diff --git a/audio/effects/hmi/interfaces/reverb2.cpp b/audio/effects/hmi/interfaces/reverb2.cpp
index 3607ef5d1f1..22873ac0942 100644
--- a/audio/effects/hmi/interfaces/reverb2.cpp
+++ b/audio/effects/hmi/interfaces/reverb2.cpp
@@ -64,7 +64,7 @@ int HMIReverb2::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIReverb2::uninit(HMIPreset *, HMIEffectNode *base) {
+int HMIReverb2::uninit(HMIPreset *preset, HMIEffectNode *base) {
HMIReverb2Node *n = (HMIReverb2Node *)base;
for (int i = 0; i != 6; ++i) {
@@ -159,21 +159,21 @@ int HMIReverb2::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIReverb2::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIReverb2::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIReverb2Node *n = (HMIReverb2Node *)base;
- if (p == 0) {
- *v = n->reverbMax;
- } else if (p == 1) {
- *v = n->preDelay;
- } else if (p == 2) {
- *v = n->reverbTime;
- } else if (p == 3) {
- *v = n->dryOut;
+ if (param == 0) {
+ *value = n->reverbMax;
+ } else if (param == 1) {
+ *value = n->preDelay;
+ } else if (param == 2) {
+ *value = n->reverbTime;
+ } else if (param == 3) {
+ *value = n->dryOut;
*type = 2;
return 0;
- } else if (p == 4) {
- *v = n->wetOut;
+ } else if (param == 4) {
+ *value = n->wetOut;
*type = 2;
return 0;
} else {
@@ -184,19 +184,19 @@ int HMIReverb2::getEffectParam(HMIEffectNode *base, int p, float *v, int *type)
return 0;
}
-int HMIReverb2::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIReverb2::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIReverb2Node *n = (HMIReverb2Node *)base;
- if (p == 0) {
- n->reverbMax = v;
- } else if (p == 1) {
- n->preDelay = v;
- } else if (p == 2) {
- n->reverbTime = v;
- } else if (p == 3) {
- n->dryOut = v;
- } else if (p == 4) {
- n->wetOut = v;
+ if (param == 0) {
+ n->reverbMax = value;
+ } else if (param == 1) {
+ n->preDelay = value;
+ } else if (param == 2) {
+ n->reverbTime = value;
+ } else if (param == 3) {
+ n->dryOut = value;
+ } else if (param == 4) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/reverb2.h b/audio/effects/hmi/interfaces/reverb2.h
index 0b225fe0e06..0b7498263a8 100644
--- a/audio/effects/hmi/interfaces/reverb2.h
+++ b/audio/effects/hmi/interfaces/reverb2.h
@@ -29,13 +29,13 @@ namespace Audio {
class HMIReverb2 : public HMIInterface {
public:
HMIReverb2();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int getMinDuration(HMIEffectNode *, uint32 *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int getMinDuration(HMIEffectNode *base, uint32 *duration) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kReverb2Params[];
diff --git a/audio/effects/hmi/interfaces/ring_modulator.cpp b/audio/effects/hmi/interfaces/ring_modulator.cpp
index 9e22b7d8d03..cbbef02065c 100644
--- a/audio/effects/hmi/interfaces/ring_modulator.cpp
+++ b/audio/effects/hmi/interfaces/ring_modulator.cpp
@@ -33,15 +33,15 @@ HMIRingModulator::HMIRingModulator()
kRingModulatorParams, kRingModulatorMin, kRingModulatorMax,
kRingModulatorDefault, "Ring Modulator", 2900, 5) {}
-int HMIRingModulator::init(HMIPreset *, HMIEffectNode *) {
+int HMIRingModulator::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIRingModulator::uninit(HMIPreset *, HMIEffectNode *) {
+int HMIRingModulator::uninit(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIRingModulator::initEffect(HMIPreset *, HMIEffectNode *base) {
+int HMIRingModulator::initEffect(HMIPreset *preset, HMIEffectNode *base) {
((HMIRingModulatorNode *)base)->phase = 0.0f;
return 0;
}
@@ -75,23 +75,23 @@ int HMIRingModulator::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIRingModulator::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIRingModulator::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIRingModulatorNode *n = (HMIRingModulatorNode *)base;
- if (p == 0) {
- *v = n->frequency;
+ if (param == 0) {
+ *value = n->frequency;
*type = 1;
- } else if (p == 1) {
- *v = n->modulatorType;
+ } else if (param == 1) {
+ *value = n->modulatorType;
*type = 3;
- } else if (p == 2) {
- *v = n->modulateOutOfPhase;
+ } else if (param == 2) {
+ *value = n->modulateOutOfPhase;
*type = 3;
- } else if (p == 3) {
- *v = n->dryOut;
+ } else if (param == 3) {
+ *value = n->dryOut;
*type = 2;
- } else if (p == 4) {
- *v = n->wetOut;
+ } else if (param == 4) {
+ *value = n->wetOut;
*type = 2;
} else {
return 11;
@@ -100,19 +100,19 @@ int HMIRingModulator::getEffectParam(HMIEffectNode *base, int p, float *v, int *
return 0;
}
-int HMIRingModulator::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIRingModulator::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIRingModulatorNode *n = (HMIRingModulatorNode *)base;
- if (p == 0) {
- n->frequency = v;
- } else if (p == 1) {
- n->modulatorType = v;
- } else if (p == 2) {
- n->modulateOutOfPhase = v;
- } else if (p == 3) {
- n->dryOut = v;
- } else if (p == 4) {
- n->wetOut = v;
+ if (param == 0) {
+ n->frequency = value;
+ } else if (param == 1) {
+ n->modulatorType = value;
+ } else if (param == 2) {
+ n->modulateOutOfPhase = value;
+ } else if (param == 3) {
+ n->dryOut = value;
+ } else if (param == 4) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/ring_modulator.h b/audio/effects/hmi/interfaces/ring_modulator.h
index 102328ff7f1..b5704058565 100644
--- a/audio/effects/hmi/interfaces/ring_modulator.h
+++ b/audio/effects/hmi/interfaces/ring_modulator.h
@@ -29,12 +29,12 @@ namespace Audio {
class HMIRingModulator : public HMIInterface {
public:
HMIRingModulator();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kRingModulatorParams[];
diff --git a/audio/effects/hmi/interfaces/stereo_delay.cpp b/audio/effects/hmi/interfaces/stereo_delay.cpp
index d76fc4f74f4..5e66e25dbbc 100644
--- a/audio/effects/hmi/interfaces/stereo_delay.cpp
+++ b/audio/effects/hmi/interfaces/stereo_delay.cpp
@@ -55,7 +55,7 @@ int HMIStereoDelay::init(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIStereoDelay::uninit(HMIPreset *, HMIEffectNode *base) {
+int HMIStereoDelay::uninit(HMIPreset *preset, HMIEffectNode *base) {
HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
free(n->delayBufL);
@@ -63,7 +63,7 @@ int HMIStereoDelay::uninit(HMIPreset *, HMIEffectNode *base) {
return 0;
}
-int HMIStereoDelay::initEffect(HMIPreset *, HMIEffectNode *base) {
+int HMIStereoDelay::initEffect(HMIPreset *preset, HMIEffectNode *base) {
HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
n->writeIndexL = n->writeIndexR = 0;
@@ -110,26 +110,26 @@ int HMIStereoDelay::processBlock(HMIPreset *preset, HMIEffectNode *base) {
return 0;
}
-int HMIStereoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *type) {
+int HMIStereoDelay::getEffectParam(HMIEffectNode *base, int param, float *value, int *type) {
HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
- if (p == 0) {
- *v = n->maxDelayTime;
+ if (param == 0) {
+ *value = n->maxDelayTime;
*type = 0;
- } else if (p == 1) {
- *v = n->delayTimeL;
+ } else if (param == 1) {
+ *value = n->delayTimeL;
*type = 0;
- } else if (p == 2) {
- *v = n->delayTimeR;
+ } else if (param == 2) {
+ *value = n->delayTimeR;
*type = 0;
- } else if (p == 3) {
- *v = n->feedback;
+ } else if (param == 3) {
+ *value = n->feedback;
*type = 2;
- } else if (p == 4) {
- *v = n->dryOut;
+ } else if (param == 4) {
+ *value = n->dryOut;
*type = 2;
- } else if (p == 5) {
- *v = n->wetOut;
+ } else if (param == 5) {
+ *value = n->wetOut;
*type = 2;
} else {
return 11;
@@ -138,21 +138,21 @@ int HMIStereoDelay::getEffectParam(HMIEffectNode *base, int p, float *v, int *ty
return 0;
}
-int HMIStereoDelay::setEffectParam(HMIEffectNode *base, int p, float v) {
+int HMIStereoDelay::setEffectParam(HMIEffectNode *base, int param, float value) {
HMIStereoDelayNode *n = (HMIStereoDelayNode *)base;
- if (p == 0) {
- n->maxDelayTime = v;
- } else if (p == 1) {
- n->delayTimeL = v;
- } else if (p == 2) {
- n->delayTimeR = v;
- } else if (p == 3) {
- n->feedback = v;
- } else if (p == 4) {
- n->dryOut = v;
- } else if (p == 5) {
- n->wetOut = v;
+ if (param == 0) {
+ n->maxDelayTime = value;
+ } else if (param == 1) {
+ n->delayTimeL = value;
+ } else if (param == 2) {
+ n->delayTimeR = value;
+ } else if (param == 3) {
+ n->feedback = value;
+ } else if (param == 4) {
+ n->dryOut = value;
+ } else if (param == 5) {
+ n->wetOut = value;
} else {
return 11;
}
diff --git a/audio/effects/hmi/interfaces/stereo_delay.h b/audio/effects/hmi/interfaces/stereo_delay.h
index fda43379f65..62b382dcf6b 100644
--- a/audio/effects/hmi/interfaces/stereo_delay.h
+++ b/audio/effects/hmi/interfaces/stereo_delay.h
@@ -29,13 +29,13 @@ namespace Audio {
class HMIStereoDelay : public HMIInterface {
public:
HMIStereoDelay();
- int init(HMIPreset *, HMIEffectNode *) override;
- int uninit(HMIPreset *, HMIEffectNode *) override;
- int getMinDuration(HMIEffectNode *, uint32 *) override;
- int processBlock(HMIPreset *, HMIEffectNode *) override;
- int initEffect(HMIPreset *, HMIEffectNode *) override;
- int getEffectParam(HMIEffectNode *, int, float *, int *) override;
- int setEffectParam(HMIEffectNode *, int, float) override;
+ int init(HMIPreset *preset, HMIEffectNode *base) override;
+ int uninit(HMIPreset *preset, HMIEffectNode *base) override;
+ int getMinDuration(HMIEffectNode *base, uint32 *out) override;
+ int processBlock(HMIPreset *preset, HMIEffectNode *base) override;
+ int initEffect(HMIPreset *preset, HMIEffectNode *base) override;
+ int getEffectParam(HMIEffectNode *base, int param, float *value, int *type) override;
+ int setEffectParam(HMIEffectNode *base, int param, float value) override;
private:
static const char *const kStereoDelayParams[];
Commit: 2c7d70ac105884c90a035226db2e78a20d2daea4
https://github.com/scummvm/scummvm/commit/2c7d70ac105884c90a035226db2e78a20d2daea4
Author: AndywinXp (andywinxp at gmail.com)
Date: 2026-07-01T01:13:22+02:00
Commit Message:
AUDIO: HMI: Turn it into an optional component
Grim is the only engine which will have to use it AFAIK.
Changed paths:
audio/module.mk
configure
engines/grim/configure.engine
diff --git a/audio/module.mk b/audio/module.mk
index a52ee375df5..a5078213e6c 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -30,17 +30,6 @@ MODULE_OBJS := \
sid.o \
ym2149.o \
timestamp.o \
- effects/hmi/interfaces/envelope.o \
- effects/hmi/interfaces/filter1.o \
- effects/hmi/hmifxfp.o \
- effects/hmi/hmifxlib.o \
- effects/hmi/interfaces/mono_delay.o \
- effects/hmi/interfaces/phasor.o \
- effects/hmi/interfaces/resonator.o \
- effects/hmi/interfaces/reverb1.o \
- effects/hmi/interfaces/reverb2.o \
- effects/hmi/interfaces/ring_modulator.o \
- effects/hmi/interfaces/stereo_delay.o \
decoders/3do.o \
decoders/aac.o \
decoders/adpcm.o \
@@ -83,6 +72,21 @@ MODULE_OBJS := \
softsynth/pcspk.o \
softsynth/ay8912.o
+ifdef USE_HMI_AUDIO
+MODULE_OBJS += \
+ effects/hmi/interfaces/envelope.o \
+ effects/hmi/interfaces/filter1.o \
+ effects/hmi/hmifxfp.o \
+ effects/hmi/hmifxlib.o \
+ effects/hmi/interfaces/mono_delay.o \
+ effects/hmi/interfaces/phasor.o \
+ effects/hmi/interfaces/resonator.o \
+ effects/hmi/interfaces/reverb1.o \
+ effects/hmi/interfaces/reverb2.o \
+ effects/hmi/interfaces/ring_modulator.o \
+ effects/hmi/interfaces/stereo_delay.o
+endif
+
ifndef DISABLE_NUKED_OPL
MODULE_OBJS += \
softsynth/opl/nuked.o
diff --git a/configure b/configure
index 3c9e0ed8d92..dc7aec30e11 100755
--- a/configure
+++ b/configure
@@ -304,6 +304,7 @@ _imgui=yes
_cdtoons=auto
_indeo3=auto
_indeo45=auto
+_hmi_audio=auto
_hnm=auto
_jyv1=auto
_qdm2=auto
@@ -341,6 +342,7 @@ add_component cdtoons "CDTOONS" "_cdtoons" "USE_CDTOONS"
add_component enet "ENet" "_enet" "USE_ENET"
add_component fmtowns_pc98_audio "FM-TOWNS/PC98 audio" "_fmtowns_pc98_audio" "USE_FMTOWNS_PC98_AUDIO"
add_component gif "GIF" "_gif" "USE_GIF"
+add_component hmi_audio "HMI Infinite Audio" "_hmi_audio" "USE_HMI_AUDIO"
add_component hnm "HNM" "_hnm" "USE_HNM"
add_component imgui "Dear ImGui based debugger" "_imgui" "USE_IMGUI"
add_component indeo3 "Indeo 3" "_indeo3" "USE_INDEO3"
diff --git a/engines/grim/configure.engine b/engines/grim/configure.engine
index e8d6a206224..b2976f745e0 100644
--- a/engines/grim/configure.engine
+++ b/engines/grim/configure.engine
@@ -1,4 +1,4 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
-add_engine grim "Grim" yes "monkey4" "Grim Fandango" "16bit 3d highres" "theoradec tinygl mpeg2"
+add_engine grim "Grim" yes "monkey4" "Grim Fandango" "16bit 3d highres hmi_audio" "theoradec tinygl mpeg2"
add_engine monkey4 "Escape from Monkey Island" no "" "" "bink"
More information about the Scummvm-git-logs
mailing list