mirror of
https://github.com/AxioDL/amuse.git
synced 2025-12-08 13:14:58 +00:00
Compare commits
6 Commits
9c75aeccbe
...
40efdcc38c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40efdcc38c | ||
|
|
92f44407c6 | ||
|
|
99f00a7cba | ||
|
|
5b6d736cfb | ||
|
|
be754a44a4 | ||
|
|
5de0035adb |
@@ -2,8 +2,10 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17
|
|||||||
|
|
||||||
project(amuse)
|
project(amuse)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
if (NOT MSVC)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
add_compile_options(-Wno-narrowing)
|
add_compile_options(-Wno-narrowing)
|
||||||
@@ -98,20 +100,27 @@ endif()
|
|||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(amuse PRIVATE
|
target_compile_options(amuse PRIVATE
|
||||||
# Enforce various standards compliant behavior.
|
# Enforce various standards compliant behavior.
|
||||||
/permissive-
|
$<$<COMPILE_LANGUAGE:CXX>:/permissive->
|
||||||
|
|
||||||
# Enable standard volatile semantics.
|
# Enable standard volatile semantics.
|
||||||
/volatile:iso
|
$<$<COMPILE_LANGUAGE:CXX>:/volatile:iso>
|
||||||
|
|
||||||
# Reports the proper value for the __cplusplus preprocessor macro.
|
# Reports the proper value for the __cplusplus preprocessor macro.
|
||||||
/Zc:__cplusplus
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>
|
||||||
|
|
||||||
# Allow constexpr variables to have explicit external linkage.
|
# Use latest C++ standard.
|
||||||
/Zc:externConstexpr
|
$<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>
|
||||||
|
|
||||||
# Assume that new throws exceptions, allowing better code generation.
|
|
||||||
/Zc:throwingNew
|
|
||||||
)
|
)
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
# Flags for MSVC (not clang-cl)
|
||||||
|
target_compile_options(amuse PRIVATE
|
||||||
|
# Allow constexpr variables to have explicit external linkage.
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>
|
||||||
|
|
||||||
|
# Assume that new throws exceptions, allowing better code generation.
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:throwingNew>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
target_compile_options(amuse PRIVATE -Wno-unknown-pragmas)
|
target_compile_options(amuse PRIVATE -Wno-unknown-pragmas)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -84,20 +84,27 @@ target_compile_definitions(amuse-gui PRIVATE
|
|||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(amuse-gui PRIVATE
|
target_compile_options(amuse-gui PRIVATE
|
||||||
# Enforce various standards compliant behavior.
|
# Enforce various standards compliant behavior.
|
||||||
/permissive-
|
$<$<COMPILE_LANGUAGE:CXX>:/permissive->
|
||||||
|
|
||||||
# Enable standard volatile semantics.
|
# Enable standard volatile semantics.
|
||||||
/volatile:iso
|
$<$<COMPILE_LANGUAGE:CXX>:/volatile:iso>
|
||||||
|
|
||||||
# Reports the proper value for the __cplusplus preprocessor macro.
|
# Reports the proper value for the __cplusplus preprocessor macro.
|
||||||
/Zc:__cplusplus
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>
|
||||||
|
|
||||||
# Allow constexpr variables to have explicit external linkage.
|
# Use latest C++ standard.
|
||||||
/Zc:externConstexpr
|
$<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>
|
||||||
|
|
||||||
# Assume that new throws exceptions, allowing better code generation.
|
|
||||||
/Zc:throwingNew
|
|
||||||
)
|
)
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
# Flags for MSVC (not clang-cl)
|
||||||
|
target_compile_options(amuse-gui PRIVATE
|
||||||
|
# Allow constexpr variables to have explicit external linkage.
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>
|
||||||
|
|
||||||
|
# Assume that new throws exceptions, allowing better code generation.
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:/Zc:throwingNew>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "amuse/Common.hpp"
|
#include "amuse/Common.hpp"
|
||||||
#include "amuse/EffectBase.hpp"
|
#include "amuse/EffectBase.hpp"
|
||||||
|
#include "amuse/IBackendVoice.hpp"
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -68,10 +70,11 @@ public:
|
|||||||
/** Type-specific implementation of chorus effect */
|
/** Type-specific implementation of chorus effect */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class EffectChorusImp : public EffectBase<T>, public EffectChorus {
|
class EffectChorusImp : public EffectBase<T>, public EffectChorus {
|
||||||
T* x0_lastChans[8][AMUSE_CHORUS_NUM_BLOCKS] = {}; /**< Evenly-allocated pointer-table for each channel's delay */
|
/** Evenly-allocated pointer-table for each channel's delay */
|
||||||
|
std::array<std::array<T*, AMUSE_CHORUS_NUM_BLOCKS>, NumChannels> x0_lastChans{};
|
||||||
|
|
||||||
uint8_t x24_currentLast = 1; /**< Last 5ms block-idx to be processed */
|
uint8_t x24_currentLast = 1; /**< Last 5ms block-idx to be processed */
|
||||||
T x28_oldChans[8][4] = {}; /**< Unprocessed history of previous 4 samples */
|
std::array<std::array<T, 4>, NumChannels> x28_oldChans{}; /**< Unprocessed history of previous 4 samples */
|
||||||
|
|
||||||
uint32_t x58_currentPosLo = 0; /**< 16.7 fixed-point low-part of sample index */
|
uint32_t x58_currentPosLo = 0; /**< 16.7 fixed-point low-part of sample index */
|
||||||
uint32_t x5c_currentPosHi = 0; /**< 16.7 fixed-point high-part of sample index */
|
uint32_t x5c_currentPosHi = 0; /**< 16.7 fixed-point high-part of sample index */
|
||||||
@@ -93,7 +96,8 @@ class EffectChorusImp : public EffectBase<T>, public EffectChorus {
|
|||||||
|
|
||||||
void doSrc1(size_t blockSamples, size_t chanCount);
|
void doSrc1(size_t blockSamples, size_t chanCount);
|
||||||
void doSrc2(size_t blockSamples, size_t chanCount);
|
void doSrc2(size_t blockSamples, size_t chanCount);
|
||||||
} x6c_src;
|
};
|
||||||
|
SrcInfo x6c_src;
|
||||||
|
|
||||||
uint32_t m_sampsPerMs; /**< canonical count of samples per ms for the current backend */
|
uint32_t m_sampsPerMs; /**< canonical count of samples per ms for the current backend */
|
||||||
uint32_t m_blockSamples; /**< count of samples in a 5ms block */
|
uint32_t m_blockSamples; /**< count of samples in a 5ms block */
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -13,24 +15,24 @@ class EffectDelayImp;
|
|||||||
|
|
||||||
/** Parameters needed to create EffectDelay */
|
/** Parameters needed to create EffectDelay */
|
||||||
struct EffectDelayInfo {
|
struct EffectDelayInfo {
|
||||||
uint32_t delay[8]; /**< [10, 5000] time in ms of each channel's delay */
|
std::array<uint32_t, NumChannels> delay; /**< [10, 5000] time in ms of each channel's delay */
|
||||||
uint32_t feedback[8] = {}; /**< [0, 100] percent to mix delayed signal with input signal */
|
std::array<uint32_t, NumChannels> feedback{}; /**< [0, 100] percent to mix delayed signal with input signal */
|
||||||
uint32_t output[8] = {}; /**< [0, 100] total output percent */
|
std::array<uint32_t, NumChannels> output{}; /**< [0, 100] total output percent */
|
||||||
|
|
||||||
static uint32_t lerp(uint32_t v0, uint32_t v1, float t) { return (1.f - t) * v0 + t * v1; }
|
static uint32_t lerp(uint32_t v0, uint32_t v1, float t) { return (1.f - t) * v0 + t * v1; }
|
||||||
|
|
||||||
static void Interp3To8(uint32_t arr[8], uint32_t L, uint32_t R, uint32_t S) {
|
static void Interp3To8(std::array<uint32_t, 8>& arr, uint32_t L, uint32_t R, uint32_t S) {
|
||||||
arr[int(AudioChannel::FrontLeft)] = L;
|
arr[size_t(AudioChannel::FrontLeft)] = L;
|
||||||
arr[int(AudioChannel::FrontRight)] = R;
|
arr[size_t(AudioChannel::FrontRight)] = R;
|
||||||
arr[int(AudioChannel::RearLeft)] = lerp(L, S, 0.75f);
|
arr[size_t(AudioChannel::RearLeft)] = lerp(L, S, 0.75f);
|
||||||
arr[int(AudioChannel::RearRight)] = lerp(R, S, 0.75f);
|
arr[size_t(AudioChannel::RearRight)] = lerp(R, S, 0.75f);
|
||||||
arr[int(AudioChannel::FrontCenter)] = lerp(L, R, 0.5f);
|
arr[size_t(AudioChannel::FrontCenter)] = lerp(L, R, 0.5f);
|
||||||
arr[int(AudioChannel::LFE)] = arr[int(AudioChannel::FrontCenter)];
|
arr[size_t(AudioChannel::LFE)] = arr[size_t(AudioChannel::FrontCenter)];
|
||||||
arr[int(AudioChannel::SideLeft)] = lerp(L, S, 0.5f);
|
arr[size_t(AudioChannel::SideLeft)] = lerp(L, S, 0.5f);
|
||||||
arr[int(AudioChannel::SideRight)] = lerp(R, S, 0.5f);
|
arr[size_t(AudioChannel::SideRight)] = lerp(R, S, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectDelayInfo() { std::fill_n(delay, 8, 10); }
|
EffectDelayInfo() { delay.fill(10); }
|
||||||
EffectDelayInfo(uint32_t delayL, uint32_t delayR, uint32_t delayS, uint32_t feedbackL, uint32_t feedbackR,
|
EffectDelayInfo(uint32_t delayL, uint32_t delayR, uint32_t delayS, uint32_t feedbackL, uint32_t feedbackR,
|
||||||
uint32_t feedbackS, uint32_t outputL, uint32_t outputR, uint32_t outputS) {
|
uint32_t feedbackS, uint32_t outputL, uint32_t outputR, uint32_t outputS) {
|
||||||
Interp3To8(delay, delayL, delayR, delayS);
|
Interp3To8(delay, delayL, delayR, delayS);
|
||||||
@@ -42,18 +44,18 @@ struct EffectDelayInfo {
|
|||||||
/** Mixes the audio back into itself after specified delay */
|
/** Mixes the audio back into itself after specified delay */
|
||||||
class EffectDelay {
|
class EffectDelay {
|
||||||
protected:
|
protected:
|
||||||
uint32_t x3c_delay[8]; /**< [10, 5000] time in ms of each channel's delay */
|
std::array<uint32_t, NumChannels> x3c_delay; /**< [10, 5000] time in ms of each channel's delay */
|
||||||
uint32_t x48_feedback[8]; /**< [0, 100] percent to mix delayed signal with input signal */
|
std::array<uint32_t, NumChannels> x48_feedback; /**< [0, 100] percent to mix delayed signal with input signal */
|
||||||
uint32_t x54_output[8]; /**< [0, 100] total output percent */
|
std::array<uint32_t, NumChannels> x54_output; /**< [0, 100] total output percent */
|
||||||
bool m_dirty = true; /**< needs update of internal parameter data */
|
bool m_dirty = true; /**< needs update of internal parameter data */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using ImpType = EffectDelayImp<T>;
|
using ImpType = EffectDelayImp<T>;
|
||||||
|
|
||||||
void setDelay(uint32_t delay) {
|
void setDelay(uint32_t delay) {
|
||||||
delay = std::clamp(delay, 10u, 5000u);
|
delay = std::clamp(delay, 10u, 5000u);
|
||||||
for (int i = 0; i < 8; ++i)
|
x3c_delay.fill(delay);
|
||||||
x3c_delay[i] = delay;
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
void setChanDelay(int chanIdx, uint32_t delay) {
|
void setChanDelay(int chanIdx, uint32_t delay) {
|
||||||
@@ -65,8 +67,7 @@ public:
|
|||||||
|
|
||||||
void setFeedback(uint32_t feedback) {
|
void setFeedback(uint32_t feedback) {
|
||||||
feedback = std::clamp(feedback, 0u, 100u);
|
feedback = std::clamp(feedback, 0u, 100u);
|
||||||
for (int i = 0; i < 8; ++i)
|
x48_feedback.fill(feedback);
|
||||||
x48_feedback[i] = feedback;
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +80,7 @@ public:
|
|||||||
|
|
||||||
void setOutput(uint32_t output) {
|
void setOutput(uint32_t output) {
|
||||||
output = std::clamp(output, 0u, 100u);
|
output = std::clamp(output, 0u, 100u);
|
||||||
for (int i = 0; i < 8; ++i)
|
x54_output.fill(output);
|
||||||
x54_output[i] = output;
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
uint32_t getChanOutput(int chanIdx) const { return x54_output[chanIdx]; }
|
uint32_t getChanOutput(int chanIdx) const { return x54_output[chanIdx]; }
|
||||||
|
|
||||||
void setParams(const EffectDelayInfo& info) {
|
void setParams(const EffectDelayInfo& info) {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < NumChannels; ++i) {
|
||||||
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
||||||
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
||||||
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
||||||
@@ -104,12 +104,12 @@ public:
|
|||||||
/** Type-specific implementation of delay effect */
|
/** Type-specific implementation of delay effect */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class EffectDelayImp : public EffectBase<T>, public EffectDelay {
|
class EffectDelayImp : public EffectBase<T>, public EffectDelay {
|
||||||
uint32_t x0_currentSize[8]; /**< per-channel delay-line buffer sizes */
|
std::array<uint32_t, NumChannels> x0_currentSize; /**< per-channel delay-line buffer sizes */
|
||||||
uint32_t xc_currentPos[8]; /**< per-channel block-index */
|
std::array<uint32_t, NumChannels> xc_currentPos; /**< per-channel block-index */
|
||||||
uint32_t x18_currentFeedback[8]; /**< [0, 128] feedback attenuator */
|
std::array<uint32_t, NumChannels> x18_currentFeedback; /**< [0, 128] feedback attenuator */
|
||||||
uint32_t x24_currentOutput[8]; /**< [0, 128] total attenuator */
|
std::array<uint32_t, NumChannels> x24_currentOutput; /**< [0, 128] total attenuator */
|
||||||
|
|
||||||
std::unique_ptr<T[]> x30_chanLines[8]; /**< delay-line buffers for each channel */
|
std::array<std::unique_ptr<T[]>, NumChannels> x30_chanLines; /**< delay-line buffers for each channel */
|
||||||
|
|
||||||
uint32_t m_sampsPerMs; /**< canonical count of samples per ms for the current backend */
|
uint32_t m_sampsPerMs; /**< canonical count of samples per ms for the current backend */
|
||||||
uint32_t m_blockSamples; /**< count of samples in a 5ms block */
|
uint32_t m_blockSamples; /**< count of samples in a 5ms block */
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "amuse/Common.hpp"
|
#include "amuse/Common.hpp"
|
||||||
#include "amuse/EffectBase.hpp"
|
#include "amuse/EffectBase.hpp"
|
||||||
|
#include "amuse/IBackendVoice.hpp"
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
@@ -144,16 +146,20 @@ public:
|
|||||||
/** Standard-quality 2-stage reverb */
|
/** Standard-quality 2-stage reverb */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class EffectReverbStdImp : public EffectBase<T>, public EffectReverbStd {
|
class EffectReverbStdImp : public EffectBase<T>, public EffectReverbStd {
|
||||||
ReverbDelayLine x0_AP[8][2] = {}; /**< All-pass delay lines */
|
using CombCoeffArray = std::array<std::array<float, 2>, NumChannels>;
|
||||||
ReverbDelayLine x78_C[8][2] = {}; /**< Comb delay lines */
|
using ReverbDelayArray = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
||||||
float xf0_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
using PreDelayArray = std::array<std::unique_ptr<float[]>, NumChannels>;
|
||||||
float xf4_combCoef[8][2] = {}; /**< Comb mix coefficients */
|
|
||||||
float x10c_lpLastout[8] = {}; /**< Last low-pass results */
|
ReverbDelayArray x0_AP{}; /**< All-pass delay lines */
|
||||||
float x118_level = 0.f; /**< Internal wet/dry mix factor */
|
ReverbDelayArray x78_C{}; /**< Comb delay lines */
|
||||||
float x11c_damping = 0.f; /**< Low-pass damping */
|
float xf0_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
||||||
int32_t x120_preDelayTime = 0; /**< Sample count of pre-delay */
|
CombCoeffArray xf4_combCoef{}; /**< Comb mix coefficients */
|
||||||
std::unique_ptr<float[]> x124_preDelayLine[8]; /**< Dedicated pre-delay buffers */
|
std::array<float, NumChannels> x10c_lpLastout{}; /**< Last low-pass results */
|
||||||
float* x130_preDelayPtr[8] = {}; /**< Current pre-delay pointers */
|
float x118_level = 0.f; /**< Internal wet/dry mix factor */
|
||||||
|
float x11c_damping = 0.f; /**< Low-pass damping */
|
||||||
|
int32_t x120_preDelayTime = 0; /**< Sample count of pre-delay */
|
||||||
|
PreDelayArray x124_preDelayLine; /**< Dedicated pre-delay buffers */
|
||||||
|
std::array<float*, NumChannels> x130_preDelayPtr{}; /**< Current pre-delay pointers */
|
||||||
|
|
||||||
double m_sampleRate; /**< copy of sample rate */
|
double m_sampleRate; /**< copy of sample rate */
|
||||||
void _setup(double sampleRate);
|
void _setup(double sampleRate);
|
||||||
@@ -173,17 +179,23 @@ public:
|
|||||||
/** High-quality 3-stage reverb with per-channel low-pass and crosstalk */
|
/** High-quality 3-stage reverb with per-channel low-pass and crosstalk */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class EffectReverbHiImp : public EffectBase<T>, public EffectReverbHi {
|
class EffectReverbHiImp : public EffectBase<T>, public EffectReverbHi {
|
||||||
ReverbDelayLine x0_AP[8][2] = {}; /**< All-pass delay lines */
|
using AllPassDelayLines = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
||||||
ReverbDelayLine x78_LP[8] = {}; /**< Per-channel low-pass delay-lines */
|
using CombCoefficients = std::array<std::array<float, 3>, NumChannels>;
|
||||||
ReverbDelayLine xb4_C[8][3] = {}; /**< Comb delay lines */
|
using CombDelayLines = std::array<std::array<ReverbDelayLine, 3>, NumChannels>;
|
||||||
float x168_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
using LowPassDelayLines = std::array<ReverbDelayLine, 8>;
|
||||||
float x16c_combCoef[8][3] = {}; /**< Comb mix coefficients */
|
using PreDelayLines = std::array<std::unique_ptr<float[]>, 8>;
|
||||||
float x190_lpLastout[8] = {}; /**< Last low-pass results */
|
|
||||||
float x19c_level = 0.f; /**< Internal wet/dry mix factor */
|
AllPassDelayLines x0_AP{}; /**< All-pass delay lines */
|
||||||
float x1a0_damping = 0.f; /**< Low-pass damping */
|
LowPassDelayLines x78_LP{}; /**< Per-channel low-pass delay-lines */
|
||||||
int32_t x1a4_preDelayTime = 0; /**< Sample count of pre-delay */
|
CombDelayLines xb4_C{}; /**< Comb delay lines */
|
||||||
std::unique_ptr<float[]> x1ac_preDelayLine[8]; /**< Dedicated pre-delay buffers */
|
float x168_allPassCoef = 0.f; /**< All-pass mix coefficient */
|
||||||
float* x1b8_preDelayPtr[8] = {}; /**< Current pre-delay pointers */
|
CombCoefficients x16c_combCoef{}; /**< Comb mix coefficients */
|
||||||
|
std::array<float, 8> x190_lpLastout{}; /**< Last low-pass results */
|
||||||
|
float x19c_level = 0.f; /**< Internal wet/dry mix factor */
|
||||||
|
float x1a0_damping = 0.f; /**< Low-pass damping */
|
||||||
|
int32_t x1a4_preDelayTime = 0; /**< Sample count of pre-delay */
|
||||||
|
PreDelayLines x1ac_preDelayLine; /**< Dedicated pre-delay buffers */
|
||||||
|
std::array<float*, NumChannels> x1b8_preDelayPtr{}; /**< Current pre-delay pointers */
|
||||||
float x1a8_internalCrosstalk = 0.f;
|
float x1a8_internalCrosstalk = 0.f;
|
||||||
|
|
||||||
double m_sampleRate; /**< copy of sample rate */
|
double m_sampleRate; /**< copy of sample rate */
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
class IBackendSubmix;
|
class IBackendSubmix;
|
||||||
@@ -18,10 +19,12 @@ enum class AudioChannel {
|
|||||||
Unknown = 0xff
|
Unknown = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr size_t NumChannels = 8;
|
||||||
|
|
||||||
/** Same structure from boo, used to represent interleaved speaker layout */
|
/** Same structure from boo, used to represent interleaved speaker layout */
|
||||||
struct ChannelMap {
|
struct ChannelMap {
|
||||||
unsigned m_channelCount = 0;
|
unsigned m_channelCount = 0;
|
||||||
AudioChannel m_channels[8] = {};
|
AudioChannel m_channels[NumChannels] = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Client-implemented voice instance */
|
/** Client-implemented voice instance */
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "amuse/EffectChorus.hpp"
|
#include "amuse/EffectChorus.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "amuse/Common.hpp"
|
#include "amuse/Common.hpp"
|
||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
@@ -9,8 +8,7 @@
|
|||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static const float rsmpTab12khz[] =
|
constexpr std::array rsmpTab12khz{
|
||||||
{
|
|
||||||
0.097504f, 0.802216f, 0.101593f, -0.000977f,
|
0.097504f, 0.802216f, 0.101593f, -0.000977f,
|
||||||
0.093506f, 0.802032f, 0.105804f, -0.001038f,
|
0.093506f, 0.802032f, 0.105804f, -0.001038f,
|
||||||
0.089600f, 0.801697f, 0.110107f, -0.001160f,
|
0.089600f, 0.801697f, 0.110107f, -0.001160f,
|
||||||
@@ -160,13 +158,14 @@ void EffectChorusImp<T>::_setup(double sampleRate) {
|
|||||||
|
|
||||||
delete[] x0_lastChans[0][0];
|
delete[] x0_lastChans[0][0];
|
||||||
|
|
||||||
T* buf = new T[m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8];
|
const size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||||
memset(buf, 0, m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8 * sizeof(T));
|
T* buf = new T[chanPitch * NumChannels]();
|
||||||
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
|
||||||
|
|
||||||
for (int c = 0; c < 8; ++c)
|
for (size_t c = 0; c < NumChannels; ++c) {
|
||||||
for (int i = 0; i < AMUSE_CHORUS_NUM_BLOCKS; ++i)
|
for (size_t i = 0; i < AMUSE_CHORUS_NUM_BLOCKS; ++i) {
|
||||||
x0_lastChans[c][i] = buf + chanPitch * c + m_blockSamples * i;
|
x0_lastChans[c][i] = buf + chanPitch * c + m_blockSamples * i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
x6c_src.x88_trigger = chanPitch;
|
x6c_src.x88_trigger = chanPitch;
|
||||||
|
|
||||||
@@ -294,15 +293,17 @@ void EffectChorusImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelM
|
|||||||
for (size_t f = 0; f < frameCount;) {
|
for (size_t f = 0; f < frameCount;) {
|
||||||
uint8_t next = x24_currentLast + 1;
|
uint8_t next = x24_currentLast + 1;
|
||||||
uint8_t buf = next % 3;
|
uint8_t buf = next % 3;
|
||||||
T* bufs[8] = {
|
std::array<T*, 8> bufs{
|
||||||
x0_lastChans[0][buf], x0_lastChans[1][buf], x0_lastChans[2][buf], x0_lastChans[3][buf],
|
x0_lastChans[0][buf], x0_lastChans[1][buf], x0_lastChans[2][buf], x0_lastChans[3][buf],
|
||||||
x0_lastChans[4][buf], x0_lastChans[5][buf], x0_lastChans[6][buf], x0_lastChans[7][buf],
|
x0_lastChans[4][buf], x0_lastChans[5][buf], x0_lastChans[6][buf], x0_lastChans[7][buf],
|
||||||
};
|
};
|
||||||
|
|
||||||
T* inBuf = audio;
|
T* inBuf = audio;
|
||||||
for (size_t s = 0; f < frameCount && s < m_blockSamples; ++s, ++f)
|
for (size_t s = 0; f < frameCount && s < m_blockSamples; ++s, ++f) {
|
||||||
for (size_t c = 0; c < chanMap.m_channelCount && c < 8; ++c)
|
for (size_t c = 0; c < chanMap.m_channelCount && c < NumChannels; ++c) {
|
||||||
*bufs[c]++ = *inBuf++;
|
*bufs[c]++ = *inBuf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
x6c_src.x84_pitchHi = (x60_pitchOffset >> 16) + 1;
|
x6c_src.x84_pitchHi = (x60_pitchOffset >> 16) + 1;
|
||||||
x6c_src.x80_pitchLo = (x60_pitchOffset << 16);
|
x6c_src.x80_pitchLo = (x60_pitchOffset << 16);
|
||||||
@@ -315,13 +316,13 @@ void EffectChorusImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelM
|
|||||||
|
|
||||||
T* outBuf = audio;
|
T* outBuf = audio;
|
||||||
size_t bs = std::min(remFrames, size_t(m_blockSamples));
|
size_t bs = std::min(remFrames, size_t(m_blockSamples));
|
||||||
for (size_t c = 0; c < chanMap.m_channelCount && c < 8; ++c) {
|
for (size_t c = 0; c < chanMap.m_channelCount && c < NumChannels; ++c) {
|
||||||
x6c_src.x7c_posHi = x5c_currentPosHi;
|
x6c_src.x7c_posHi = x5c_currentPosHi;
|
||||||
x6c_src.x78_posLo = x58_currentPosLo;
|
x6c_src.x78_posLo = x58_currentPosLo;
|
||||||
|
|
||||||
x6c_src.x6c_dest = outBuf++;
|
x6c_src.x6c_dest = outBuf++;
|
||||||
x6c_src.x70_smpBase = x0_lastChans[c][0];
|
x6c_src.x70_smpBase = x0_lastChans[c][0];
|
||||||
x6c_src.x74_old = x28_oldChans[c];
|
x6c_src.x74_old = x28_oldChans[c].data();
|
||||||
|
|
||||||
switch (x6c_src.x84_pitchHi) {
|
switch (x6c_src.x84_pitchHi) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "amuse/EffectDelay.hpp"
|
#include "amuse/EffectDelay.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "amuse/Common.hpp"
|
#include "amuse/Common.hpp"
|
||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
@@ -14,18 +13,16 @@ EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uin
|
|||||||
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
||||||
initOutput = std::clamp(initOutput, 0u, 100u);
|
initOutput = std::clamp(initOutput, 0u, 100u);
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
x3c_delay.fill(initDelay);
|
||||||
x3c_delay[i] = initDelay;
|
x48_feedback.fill(initFeedback);
|
||||||
x48_feedback[i] = initFeedback;
|
x54_output.fill(initOutput);
|
||||||
x54_output[i] = initOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
EffectDelayImp<T>::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
EffectDelayImp<T>::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < NumChannels; ++i) {
|
||||||
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
||||||
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
||||||
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
||||||
@@ -44,14 +41,13 @@ void EffectDelayImp<T>::_setup(double sampleRate) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EffectDelayImp<T>::_update() {
|
void EffectDelayImp<T>::_update() {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < NumChannels; ++i) {
|
||||||
x0_currentSize[i] = ((x3c_delay[i] - 5) * m_sampsPerMs + 159) / 160;
|
x0_currentSize[i] = ((x3c_delay[i] - 5) * m_sampsPerMs + 159) / 160;
|
||||||
xc_currentPos[i] = 0;
|
xc_currentPos[i] = 0;
|
||||||
x18_currentFeedback[i] = x48_feedback[i] * 128 / 100;
|
x18_currentFeedback[i] = x48_feedback[i] * 128 / 100;
|
||||||
x24_currentOutput[i] = x54_output[i] * 128 / 100;
|
x24_currentOutput[i] = x54_output[i] * 128 / 100;
|
||||||
|
|
||||||
x30_chanLines[i].reset(new T[m_blockSamples * x0_currentSize[i]]);
|
x30_chanLines[i] = std::make_unique<T[]>(m_blockSamples * x0_currentSize[i]);
|
||||||
memset(x30_chanLines[i].get(), 0, m_blockSamples * x0_currentSize[i] * sizeof(T));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "amuse/EffectReverb.hpp"
|
#include "amuse/EffectReverb.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
|
|
||||||
@@ -10,23 +10,20 @@ namespace amuse {
|
|||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
/* Comb-filter delays */
|
/* Comb-filter delays */
|
||||||
static const size_t CTapDelays[] =
|
constexpr std::array<size_t, 3> CTapDelays{
|
||||||
{
|
|
||||||
1789,
|
1789,
|
||||||
1999,
|
1999,
|
||||||
2333
|
2333
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All-pass-filter delays */
|
/* All-pass-filter delays */
|
||||||
static const size_t APTapDelays[] =
|
constexpr std::array<size_t, 2> APTapDelays{
|
||||||
{
|
|
||||||
433,
|
433,
|
||||||
149
|
149,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Per-channel low-pass delays (Hi-quality reverb only) */
|
/* Per-channel low-pass delays (Hi-quality reverb only) */
|
||||||
static const size_t LPTapDelays[] =
|
constexpr std::array<size_t, 8> LPTapDelays{
|
||||||
{
|
|
||||||
47,
|
47,
|
||||||
73,
|
73,
|
||||||
67,
|
67,
|
||||||
@@ -42,8 +39,7 @@ static const size_t LPTapDelays[] =
|
|||||||
void ReverbDelayLine::allocate(int32_t delay) {
|
void ReverbDelayLine::allocate(int32_t delay) {
|
||||||
delay += 2;
|
delay += 2;
|
||||||
x8_length = delay;
|
x8_length = delay;
|
||||||
xc_inputs.reset(new float[delay]);
|
xc_inputs = std::make_unique<float[]>(delay);
|
||||||
memset(xc_inputs.get(), 0, x8_length * sizeof(float));
|
|
||||||
x10_lastInput = 0.f;
|
x10_lastInput = 0.f;
|
||||||
setdelay(delay / 2);
|
setdelay(delay / 2);
|
||||||
x0_inPoint = 0;
|
x0_inPoint = 0;
|
||||||
@@ -83,8 +79,8 @@ template <typename T>
|
|||||||
void EffectReverbStdImp<T>::_update() {
|
void EffectReverbStdImp<T>::_update() {
|
||||||
float timeSamples = x148_x1d0_time * m_sampleRate;
|
float timeSamples = x148_x1d0_time * m_sampleRate;
|
||||||
double rateRatio = m_sampleRate / NativeSampleRate;
|
double rateRatio = m_sampleRate / NativeSampleRate;
|
||||||
for (int c = 0; c < 8; ++c) {
|
for (size_t c = 0; c < NumChannels; ++c) {
|
||||||
for (int t = 0; t < 2; ++t) {
|
for (size_t t = 0; t < x78_C[c].size(); ++t) {
|
||||||
ReverbDelayLine& combLine = x78_C[c][t];
|
ReverbDelayLine& combLine = x78_C[c][t];
|
||||||
size_t tapDelay = CTapDelays[t] * rateRatio;
|
size_t tapDelay = CTapDelays[t] * rateRatio;
|
||||||
combLine.allocate(tapDelay);
|
combLine.allocate(tapDelay);
|
||||||
@@ -92,7 +88,7 @@ void EffectReverbStdImp<T>::_update() {
|
|||||||
xf4_combCoef[c][t] = std::pow(10.f, tapDelay * -3.f / timeSamples);
|
xf4_combCoef[c][t] = std::pow(10.f, tapDelay * -3.f / timeSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < 2; ++t) {
|
for (size_t t = 0; t < x0_AP[c].size(); ++t) {
|
||||||
ReverbDelayLine& allPassLine = x0_AP[c][t];
|
ReverbDelayLine& allPassLine = x0_AP[c][t];
|
||||||
size_t tapDelay = APTapDelays[t] * rateRatio;
|
size_t tapDelay = APTapDelays[t] * rateRatio;
|
||||||
allPassLine.allocate(tapDelay);
|
allPassLine.allocate(tapDelay);
|
||||||
@@ -111,17 +107,16 @@ void EffectReverbStdImp<T>::_update() {
|
|||||||
|
|
||||||
if (x150_x1d8_preDelay != 0.f) {
|
if (x150_x1d8_preDelay != 0.f) {
|
||||||
x120_preDelayTime = m_sampleRate * x150_x1d8_preDelay;
|
x120_preDelayTime = m_sampleRate * x150_x1d8_preDelay;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < NumChannels; ++i) {
|
||||||
x124_preDelayLine[i].reset(new float[x120_preDelayTime]);
|
x124_preDelayLine[i] = std::make_unique<float[]>(x120_preDelayTime);
|
||||||
memset(x124_preDelayLine[i].get(), 0, x120_preDelayTime * sizeof(float));
|
|
||||||
x130_preDelayPtr[i] = x124_preDelayLine[i].get();
|
x130_preDelayPtr[i] = x124_preDelayLine[i].get();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x120_preDelayTime = 0;
|
x120_preDelayTime = 0;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (auto& delayLine : x124_preDelayLine) {
|
||||||
x124_preDelayLine[i] = nullptr;
|
delayLine.reset();
|
||||||
x130_preDelayPtr[i] = nullptr;
|
|
||||||
}
|
}
|
||||||
|
x130_preDelayPtr.fill(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
@@ -132,23 +127,23 @@ void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const Chann
|
|||||||
if (m_dirty)
|
if (m_dirty)
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
float dampWet = x118_level * 0.6f;
|
const float dampWet = x118_level * 0.6f;
|
||||||
float dampDry = 0.6f - dampWet;
|
const float dampDry = 0.6f - dampWet;
|
||||||
|
|
||||||
for (size_t f = 0; f < frameCount; f += 160) {
|
for (size_t f = 0; f < frameCount; f += 160) {
|
||||||
for (unsigned c = 0; c < chanMap.m_channelCount; ++c) {
|
for (unsigned c = 0; c < chanMap.m_channelCount; ++c) {
|
||||||
float* combCoefs = xf4_combCoef[c];
|
const auto& combCoefs = xf4_combCoef[c];
|
||||||
float& lpLastOut = x10c_lpLastout[c];
|
float& lpLastOut = x10c_lpLastout[c];
|
||||||
float* preDelayLine = x124_preDelayLine[c].get();
|
float* preDelayLine = x124_preDelayLine[c].get();
|
||||||
float* preDelayPtr = x130_preDelayPtr[c];
|
float* preDelayPtr = x130_preDelayPtr[c];
|
||||||
float* lastPreDelaySamp = &preDelayLine[x120_preDelayTime - 1];
|
float* lastPreDelaySamp = &preDelayLine[x120_preDelayTime - 1];
|
||||||
|
|
||||||
ReverbDelayLine* linesC = x78_C[c];
|
auto& linesC = x78_C[c];
|
||||||
ReverbDelayLine* linesAP = x0_AP[c];
|
auto& linesAP = x0_AP[c];
|
||||||
|
|
||||||
int procSamples = std::min(size_t(160), frameCount - f);
|
const int procSamples = std::min(size_t(160), frameCount - f);
|
||||||
for (int s = 0; s < procSamples; ++s) {
|
for (int s = 0; s < procSamples; ++s) {
|
||||||
float sample = audio[s * chanMap.m_channelCount + c];
|
const float sample = audio[s * chanMap.m_channelCount + c];
|
||||||
|
|
||||||
/* Pre-delay stage */
|
/* Pre-delay stage */
|
||||||
float sample2 = sample;
|
float sample2 = sample;
|
||||||
@@ -188,7 +183,8 @@ void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const Chann
|
|||||||
/* All-pass filter stage */
|
/* All-pass filter stage */
|
||||||
linesAP[0].xc_inputs[linesAP[0].x0_inPoint] =
|
linesAP[0].xc_inputs[linesAP[0].x0_inPoint] =
|
||||||
xf0_allPassCoef * linesAP[0].x10_lastInput + linesC[0].x10_lastInput + linesC[1].x10_lastInput;
|
xf0_allPassCoef * linesAP[0].x10_lastInput + linesC[0].x10_lastInput + linesC[1].x10_lastInput;
|
||||||
float lowPass = -(xf0_allPassCoef * linesAP[0].xc_inputs[linesAP[0].x0_inPoint] - linesAP[0].x10_lastInput);
|
const float lowPass =
|
||||||
|
-(xf0_allPassCoef * linesAP[0].xc_inputs[linesAP[0].x0_inPoint] - linesAP[0].x10_lastInput);
|
||||||
linesAP[0].x0_inPoint += 1;
|
linesAP[0].x0_inPoint += 1;
|
||||||
|
|
||||||
linesAP[0].x10_lastInput = linesAP[0].xc_inputs[linesAP[0].x4_outPoint];
|
linesAP[0].x10_lastInput = linesAP[0].xc_inputs[linesAP[0].x4_outPoint];
|
||||||
@@ -202,7 +198,8 @@ void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const Chann
|
|||||||
|
|
||||||
lpLastOut = x11c_damping * lpLastOut + lowPass * 0.3f;
|
lpLastOut = x11c_damping * lpLastOut + lowPass * 0.3f;
|
||||||
linesAP[1].xc_inputs[linesAP[1].x0_inPoint] = xf0_allPassCoef * linesAP[1].x10_lastInput + lpLastOut;
|
linesAP[1].xc_inputs[linesAP[1].x0_inPoint] = xf0_allPassCoef * linesAP[1].x10_lastInput + lpLastOut;
|
||||||
float allPass = -(xf0_allPassCoef * linesAP[1].xc_inputs[linesAP[1].x0_inPoint] - linesAP[1].x10_lastInput);
|
const float allPass =
|
||||||
|
-(xf0_allPassCoef * linesAP[1].xc_inputs[linesAP[1].x0_inPoint] - linesAP[1].x10_lastInput);
|
||||||
linesAP[1].x0_inPoint += 1;
|
linesAP[1].x0_inPoint += 1;
|
||||||
|
|
||||||
linesAP[1].x10_lastInput = linesAP[1].xc_inputs[linesAP[1].x4_outPoint];
|
linesAP[1].x10_lastInput = linesAP[1].xc_inputs[linesAP[1].x4_outPoint];
|
||||||
@@ -238,26 +235,27 @@ void EffectReverbHiImp<T>::_setup(double sampleRate) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EffectReverbHiImp<T>::_update() {
|
void EffectReverbHiImp<T>::_update() {
|
||||||
float timeSamples = x148_x1d0_time * m_sampleRate;
|
const float timeSamples = x148_x1d0_time * m_sampleRate;
|
||||||
double rateRatio = m_sampleRate / NativeSampleRate;
|
const double rateRatio = m_sampleRate / NativeSampleRate;
|
||||||
for (int c = 0; c < 8; ++c) {
|
|
||||||
for (int t = 0; t < 3; ++t) {
|
for (size_t c = 0; c < NumChannels; ++c) {
|
||||||
|
for (size_t t = 0; t < xb4_C[c].size(); ++t) {
|
||||||
ReverbDelayLine& combLine = xb4_C[c][t];
|
ReverbDelayLine& combLine = xb4_C[c][t];
|
||||||
size_t tapDelay = CTapDelays[t] * rateRatio;
|
const size_t tapDelay = CTapDelays[t] * rateRatio;
|
||||||
combLine.allocate(tapDelay);
|
combLine.allocate(tapDelay);
|
||||||
combLine.setdelay(tapDelay);
|
combLine.setdelay(tapDelay);
|
||||||
x16c_combCoef[c][t] = std::pow(10.f, tapDelay * -3.f / timeSamples);
|
x16c_combCoef[c][t] = std::pow(10.f, tapDelay * -3.f / timeSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < 2; ++t) {
|
for (size_t t = 0; t < x0_AP[c].size(); ++t) {
|
||||||
ReverbDelayLine& allPassLine = x0_AP[c][t];
|
ReverbDelayLine& allPassLine = x0_AP[c][t];
|
||||||
size_t tapDelay = APTapDelays[t] * rateRatio;
|
const size_t tapDelay = APTapDelays[t] * rateRatio;
|
||||||
allPassLine.allocate(tapDelay);
|
allPassLine.allocate(tapDelay);
|
||||||
allPassLine.setdelay(tapDelay);
|
allPassLine.setdelay(tapDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReverbDelayLine& lpLine = x78_LP[c];
|
ReverbDelayLine& lpLine = x78_LP[c];
|
||||||
size_t tapDelay = LPTapDelays[c] * rateRatio;
|
const size_t tapDelay = LPTapDelays[c] * rateRatio;
|
||||||
lpLine.allocate(tapDelay);
|
lpLine.allocate(tapDelay);
|
||||||
lpLine.setdelay(tapDelay);
|
lpLine.setdelay(tapDelay);
|
||||||
}
|
}
|
||||||
@@ -273,17 +271,16 @@ void EffectReverbHiImp<T>::_update() {
|
|||||||
|
|
||||||
if (x150_x1d8_preDelay != 0.f) {
|
if (x150_x1d8_preDelay != 0.f) {
|
||||||
x1a4_preDelayTime = m_sampleRate * x150_x1d8_preDelay;
|
x1a4_preDelayTime = m_sampleRate * x150_x1d8_preDelay;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < NumChannels; ++i) {
|
||||||
x1ac_preDelayLine[i].reset(new float[x1a4_preDelayTime]);
|
x1ac_preDelayLine[i] = std::make_unique<float[]>(x1a4_preDelayTime);
|
||||||
memset(x1ac_preDelayLine[i].get(), 0, x1a4_preDelayTime * sizeof(float));
|
|
||||||
x1b8_preDelayPtr[i] = x1ac_preDelayLine[i].get();
|
x1b8_preDelayPtr[i] = x1ac_preDelayLine[i].get();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x1a4_preDelayTime = 0;
|
x1a4_preDelayTime = 0;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (auto& delayLine : x1ac_preDelayLine) {
|
||||||
x1ac_preDelayLine[i] = nullptr;
|
delayLine.reset();
|
||||||
x1b8_preDelayPtr[i] = nullptr;
|
|
||||||
}
|
}
|
||||||
|
x1b8_preDelayPtr.fill(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
x1a8_internalCrosstalk = x1dc_crosstalk;
|
x1a8_internalCrosstalk = x1dc_crosstalk;
|
||||||
@@ -292,25 +289,25 @@ void EffectReverbHiImp<T>::_update() {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sampleCount) {
|
void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sampleCount) {
|
||||||
float dampWet = x19c_level * 0.6f;
|
const float dampWet = x19c_level * 0.6f;
|
||||||
float dampDry = 0.6f - dampWet;
|
const float dampDry = 0.6f - dampWet;
|
||||||
|
|
||||||
float* combCoefs = x16c_combCoef[c];
|
const auto& combCoefs = x16c_combCoef[c];
|
||||||
float& lpLastOut = x190_lpLastout[c];
|
float& lpLastOut = x190_lpLastout[c];
|
||||||
float* preDelayLine = x1ac_preDelayLine[c].get();
|
float* preDelayLine = x1ac_preDelayLine[c].get();
|
||||||
float* preDelayPtr = x1b8_preDelayPtr[c];
|
float* preDelayPtr = x1b8_preDelayPtr[c];
|
||||||
float* lastPreDelaySamp = &preDelayLine[x1a4_preDelayTime - 1];
|
float* lastPreDelaySamp = &preDelayLine[x1a4_preDelayTime - 1];
|
||||||
|
|
||||||
ReverbDelayLine* linesC = xb4_C[c];
|
auto& linesC = xb4_C[c];
|
||||||
ReverbDelayLine* linesAP = x0_AP[c];
|
auto& linesAP = x0_AP[c];
|
||||||
ReverbDelayLine& lineLP = x78_LP[c];
|
ReverbDelayLine& lineLP = x78_LP[c];
|
||||||
|
|
||||||
float allPassCoef = x168_allPassCoef;
|
const float allPassCoef = x168_allPassCoef;
|
||||||
float damping = x1a0_damping;
|
const float damping = x1a0_damping;
|
||||||
int32_t preDelayTime = x1a4_preDelayTime;
|
const int32_t preDelayTime = x1a4_preDelayTime;
|
||||||
|
|
||||||
for (int s = 0; s < sampleCount; ++s) {
|
for (int s = 0; s < sampleCount; ++s) {
|
||||||
float sample = audio[s * chanCount + c];
|
const float sample = audio[s * chanCount + c];
|
||||||
|
|
||||||
/* Pre-delay stage */
|
/* Pre-delay stage */
|
||||||
float sample2 = sample;
|
float sample2 = sample;
|
||||||
@@ -367,7 +364,7 @@ void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sam
|
|||||||
allPassCoef * linesAP[1].x10_lastInput -
|
allPassCoef * linesAP[1].x10_lastInput -
|
||||||
(allPassCoef * linesAP[0].xc_inputs[linesAP[0].x0_inPoint] - linesAP[0].x10_lastInput);
|
(allPassCoef * linesAP[0].xc_inputs[linesAP[0].x0_inPoint] - linesAP[0].x10_lastInput);
|
||||||
|
|
||||||
float lowPass = -(allPassCoef * linesAP[1].xc_inputs[linesAP[1].x0_inPoint] - linesAP[1].x10_lastInput);
|
const float lowPass = -(allPassCoef * linesAP[1].xc_inputs[linesAP[1].x0_inPoint] - linesAP[1].x10_lastInput);
|
||||||
linesAP[0].x0_inPoint += 1;
|
linesAP[0].x0_inPoint += 1;
|
||||||
linesAP[1].x0_inPoint += 1;
|
linesAP[1].x0_inPoint += 1;
|
||||||
|
|
||||||
@@ -391,7 +388,7 @@ void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sam
|
|||||||
|
|
||||||
lpLastOut = damping * lpLastOut + lowPass * 0.3f;
|
lpLastOut = damping * lpLastOut + lowPass * 0.3f;
|
||||||
lineLP.xc_inputs[lineLP.x0_inPoint] = allPassCoef * lineLP.x10_lastInput + lpLastOut;
|
lineLP.xc_inputs[lineLP.x0_inPoint] = allPassCoef * lineLP.x10_lastInput + lpLastOut;
|
||||||
float allPass = -(allPassCoef * lineLP.xc_inputs[lineLP.x0_inPoint] - lineLP.x10_lastInput);
|
const float allPass = -(allPassCoef * lineLP.xc_inputs[lineLP.x0_inPoint] - lineLP.x10_lastInput);
|
||||||
lineLP.x0_inPoint += 1;
|
lineLP.x0_inPoint += 1;
|
||||||
|
|
||||||
lineLP.x10_lastInput = lineLP.xc_inputs[lineLP.x4_outPoint];
|
lineLP.x10_lastInput = lineLP.xc_inputs[lineLP.x4_outPoint];
|
||||||
|
|||||||
Reference in New Issue
Block a user