mirror of
https://github.com/AxioDL/amuse.git
synced 2025-08-09 05:29:07 +00:00
Make audio overload types float-only, initial boo2 switchover
This commit is contained in:
parent
5112228abd
commit
6da262355a
@ -77,12 +77,8 @@ add_library(amuse
|
|||||||
include/amuse/VolumeTable.hpp
|
include/amuse/VolumeTable.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_atdna(amuse atdna_AudioGroupPool.cpp include/amuse/AudioGroupPool.hpp)
|
|
||||||
target_atdna(amuse atdna_AudioGroupProject.cpp include/amuse/AudioGroupProject.hpp)
|
|
||||||
target_atdna(amuse atdna_AudioGroupSampleDirectory.cpp include/amuse/AudioGroupSampleDirectory.hpp)
|
|
||||||
|
|
||||||
target_include_directories(amuse PUBLIC include)
|
target_include_directories(amuse PUBLIC include)
|
||||||
target_link_libraries(amuse
|
target_link_libraries(amuse PUBLIC
|
||||||
athena-core
|
athena-core
|
||||||
lzokay
|
lzokay
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES}
|
||||||
@ -92,11 +88,15 @@ if(NX)
|
|||||||
target_sources(amuse PRIVATE include/switch_math.hpp)
|
target_sources(amuse PRIVATE include/switch_math.hpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TARGET boo)
|
if(TARGET boo2)
|
||||||
target_sources(amuse PRIVATE lib/BooBackend.cpp include/amuse/BooBackend.hpp)
|
target_sources(amuse PRIVATE lib/BooBackend.cpp include/amuse/BooBackend.hpp)
|
||||||
target_link_libraries(amuse boo)
|
target_link_libraries(amuse PUBLIC boo2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_atdna(amuse atdna_AudioGroupPool.cpp include/amuse/AudioGroupPool.hpp)
|
||||||
|
target_atdna(amuse atdna_AudioGroupProject.cpp include/amuse/AudioGroupProject.hpp)
|
||||||
|
target_atdna(amuse atdna_AudioGroupSampleDirectory.cpp include/amuse/AudioGroupSampleDirectory.hpp)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(amuse PRIVATE
|
target_compile_options(amuse PRIVATE
|
||||||
# Enforce various standards compliant behavior.
|
# Enforce various standards compliant behavior.
|
||||||
|
@ -27,7 +27,7 @@ namespace amuse {
|
|||||||
class Engine;
|
class Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace boo {
|
namespace boo2 {
|
||||||
struct IAudioVoiceEngine;
|
struct IAudioVoiceEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +854,7 @@ void EventCallback::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods,
|
|||||||
m_app.m_engine->setVolume(m_app.m_volume);
|
m_app.m_engine->setVolume(m_app.m_volume);
|
||||||
m_app.m_updateDisp = true;
|
m_app.m_updateDisp = true;
|
||||||
break;
|
break;
|
||||||
case boo::ESpecialKey::Esc:
|
case boo2::Keycode::ESC:
|
||||||
m_app.m_breakout = true;
|
m_app.m_breakout = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
#include "amuse/IBackendSubmix.hpp"
|
#include "amuse/IBackendSubmix.hpp"
|
||||||
#include "amuse/IBackendVoiceAllocator.hpp"
|
#include "amuse/IBackendVoiceAllocator.hpp"
|
||||||
|
|
||||||
#include <boo/audiodev/IAudioSubmix.hpp>
|
#include "boo2/audiodev/IAudioSubmix.hpp"
|
||||||
#include <boo/audiodev/IAudioVoiceEngine.hpp>
|
#include "boo2/audiodev/IAudioVoiceEngine.hpp"
|
||||||
#include <boo/audiodev/IMIDIReader.hpp>
|
#include "boo2/audiodev/IMIDIReader.hpp"
|
||||||
#include <boo/audiodev/MIDIDecoder.hpp>
|
#include "boo2/audiodev/MIDIDecoder.hpp"
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
@ -24,19 +24,19 @@ namespace amuse {
|
|||||||
class BooBackendVoice : public IBackendVoice {
|
class BooBackendVoice : public IBackendVoice {
|
||||||
friend class BooBackendVoiceAllocator;
|
friend class BooBackendVoiceAllocator;
|
||||||
Voice& m_clientVox;
|
Voice& m_clientVox;
|
||||||
struct VoiceCallback : boo::IAudioVoiceCallback {
|
struct VoiceCallback : boo2::IAudioVoiceCallback {
|
||||||
BooBackendVoice& m_parent;
|
BooBackendVoice& m_parent;
|
||||||
void preSupplyAudio(boo::IAudioVoice& voice, double dt) override;
|
void preSupplyAudio(boo2::IAudioVoice& voice, double dt) override;
|
||||||
size_t supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data) override;
|
size_t supplyAudio(boo2::IAudioVoice& voice, size_t frames, int16_t* data) override;
|
||||||
void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out) override;
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out) override;
|
||||||
void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out) override;
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out) override;
|
||||||
void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out) override;
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out) override;
|
||||||
VoiceCallback(BooBackendVoice& parent) : m_parent(parent) {}
|
VoiceCallback(BooBackendVoice& parent) : m_parent(parent) {}
|
||||||
} m_cb;
|
} m_cb;
|
||||||
boo::ObjToken<boo::IAudioVoice> m_booVoice;
|
boo2::ObjToken<boo2::IAudioVoice> m_booVoice;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BooBackendVoice(boo::IAudioVoiceEngine& engine, Voice& clientVox, double sampleRate, bool dynamicPitch);
|
BooBackendVoice(boo2::IAudioVoiceEngine& engine, Voice& clientVox, double sampleRate, bool dynamicPitch);
|
||||||
void resetSampleRate(double sampleRate) override;
|
void resetSampleRate(double sampleRate) override;
|
||||||
|
|
||||||
void resetChannelLevels() override;
|
void resetChannelLevels() override;
|
||||||
@ -51,35 +51,30 @@ class BooBackendSubmix : public IBackendSubmix {
|
|||||||
friend class BooBackendVoiceAllocator;
|
friend class BooBackendVoiceAllocator;
|
||||||
friend class BooBackendVoice;
|
friend class BooBackendVoice;
|
||||||
Submix& m_clientSmx;
|
Submix& m_clientSmx;
|
||||||
struct SubmixCallback : boo::IAudioSubmixCallback {
|
struct SubmixCallback : boo2::IAudioSubmixCallback {
|
||||||
BooBackendSubmix& m_parent;
|
BooBackendSubmix& m_parent;
|
||||||
bool canApplyEffect() const override;
|
bool canApplyEffect() const override;
|
||||||
void applyEffect(int16_t* audio, size_t frameCount, const boo::ChannelMap& chanMap,
|
void applyEffect(float* audio, size_t frameCount, const boo2::ChannelMap& chanMap, double sampleRate) const override;
|
||||||
double sampleRate) const override;
|
|
||||||
void applyEffect(int32_t* audio, size_t frameCount, const boo::ChannelMap& chanMap,
|
|
||||||
double sampleRate) const override;
|
|
||||||
void applyEffect(float* audio, size_t frameCount, const boo::ChannelMap& chanMap, double sampleRate) const override;
|
|
||||||
void resetOutputSampleRate(double sampleRate) override;
|
void resetOutputSampleRate(double sampleRate) override;
|
||||||
SubmixCallback(BooBackendSubmix& parent) : m_parent(parent) {}
|
SubmixCallback(BooBackendSubmix& parent) : m_parent(parent) {}
|
||||||
} m_cb;
|
} m_cb;
|
||||||
boo::ObjToken<boo::IAudioSubmix> m_booSubmix;
|
boo2::ObjToken<boo2::IAudioSubmix> m_booSubmix;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BooBackendSubmix(boo::IAudioVoiceEngine& engine, Submix& clientSmx, bool mainOut, int busId);
|
BooBackendSubmix(boo2::IAudioVoiceEngine& engine, Submix& clientSmx, bool mainOut, int busId);
|
||||||
void setSendLevel(IBackendSubmix* submix, float level, bool slew) override;
|
void setSendLevel(IBackendSubmix* submix, float level, bool slew) override;
|
||||||
double getSampleRate() const override;
|
double getSampleRate() const override;
|
||||||
SubmixFormat getSampleFormat() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Backend MIDI event reader for controlling sequencer with external hardware / software */
|
/** Backend MIDI event reader for controlling sequencer with external hardware / software */
|
||||||
class BooBackendMIDIReader : public IMIDIReader, public boo::IMIDIReader {
|
class BooBackendMIDIReader : public IMIDIReader, public boo2::IMIDIReader {
|
||||||
friend class BooBackendVoiceAllocator;
|
friend class BooBackendVoiceAllocator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Engine& m_engine;
|
Engine& m_engine;
|
||||||
std::unordered_map<std::string, std::unique_ptr<boo::IMIDIIn>> m_midiIns;
|
std::unordered_map<std::string, std::unique_ptr<boo2::IMIDIIn>> m_midiIns;
|
||||||
std::unique_ptr<boo::IMIDIIn> m_virtualIn;
|
std::unique_ptr<boo2::IMIDIIn> m_virtualIn;
|
||||||
boo::MIDIDecoder m_decoder;
|
boo2::MIDIDecoder m_decoder;
|
||||||
|
|
||||||
bool m_useLock;
|
bool m_useLock;
|
||||||
std::list<std::pair<double, std::vector<uint8_t>>> m_queue;
|
std::list<std::pair<double, std::vector<uint8_t>>> m_queue;
|
||||||
@ -127,15 +122,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Backend voice allocator implementation for boo mixer */
|
/** Backend voice allocator implementation for boo mixer */
|
||||||
class BooBackendVoiceAllocator : public IBackendVoiceAllocator, public boo::IAudioVoiceEngineCallback {
|
class BooBackendVoiceAllocator : public IBackendVoiceAllocator, public boo2::IAudioVoiceEngineCallback {
|
||||||
friend class BooBackendMIDIReader;
|
friend class BooBackendMIDIReader;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
boo::IAudioVoiceEngine& m_booEngine;
|
boo2::IAudioVoiceEngine& m_booEngine;
|
||||||
Engine* m_cbInterface = nullptr;
|
Engine* m_cbInterface = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine);
|
BooBackendVoiceAllocator(boo2::IAudioVoiceEngine& booEngine);
|
||||||
std::unique_ptr<IBackendVoice> allocateVoice(Voice& clientVox, double sampleRate, bool dynamicPitch) override;
|
std::unique_ptr<IBackendVoice> allocateVoice(Voice& clientVox, double sampleRate, bool dynamicPitch) override;
|
||||||
std::unique_ptr<IBackendSubmix> allocateSubmix(Submix& clientSmx, bool mainOut, int busId) override;
|
std::unique_ptr<IBackendSubmix> allocateSubmix(Submix& clientSmx, bool mainOut, int busId) override;
|
||||||
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices() override;
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices() override;
|
||||||
@ -143,7 +138,7 @@ public:
|
|||||||
void setCallbackInterface(Engine* engine) override;
|
void setCallbackInterface(Engine* engine) override;
|
||||||
AudioChannelSet getAvailableSet() override;
|
AudioChannelSet getAvailableSet() override;
|
||||||
void setVolume(float vol) override;
|
void setVolume(float vol) override;
|
||||||
void on5MsInterval(boo::IAudioVoiceEngine& engine, double dt) override;
|
void on5MsInterval(boo2::IAudioVoiceEngine& engine, double dt) override;
|
||||||
void onPumpCycleComplete(boo::IAudioVoiceEngine& engine) override;
|
void onPumpCycleComplete(boo2::IAudioVoiceEngine& engine) override;
|
||||||
};
|
};
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -368,23 +368,6 @@ inline int CompareCaseInsensitive(const SystemChar* a, const SystemChar* b) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr T ClampFull(float in) noexcept {
|
|
||||||
if (std::is_floating_point<T>()) {
|
|
||||||
return in;
|
|
||||||
} else {
|
|
||||||
constexpr T MAX = std::numeric_limits<T>::max();
|
|
||||||
constexpr T MIN = std::numeric_limits<T>::min();
|
|
||||||
|
|
||||||
if (in < MIN)
|
|
||||||
return MIN;
|
|
||||||
else if (in > MAX)
|
|
||||||
return MAX;
|
|
||||||
else
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef M_PIF
|
#ifndef M_PIF
|
||||||
#define M_PIF 3.14159265358979323846f /* pi */
|
#define M_PIF 3.14159265358979323846f /* pi */
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,16 +5,11 @@ struct ChannelMap;
|
|||||||
|
|
||||||
enum class EffectType { Invalid, ReverbStd, ReverbHi, Delay, Chorus, EffectTypeMAX };
|
enum class EffectType { Invalid, ReverbStd, ReverbHi, Delay, Chorus, EffectTypeMAX };
|
||||||
|
|
||||||
class EffectBaseTypeless {
|
class EffectBase {
|
||||||
public:
|
public:
|
||||||
virtual ~EffectBaseTypeless() = default;
|
virtual ~EffectBase() = default;
|
||||||
virtual void resetOutputSampleRate(double sampleRate) = 0;
|
virtual void resetOutputSampleRate(double sampleRate) = 0;
|
||||||
virtual EffectType Isa() const = 0;
|
virtual EffectType Isa() const = 0;
|
||||||
};
|
virtual void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) = 0;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class EffectBase : public EffectBaseTypeless {
|
|
||||||
public:
|
|
||||||
virtual void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) = 0;
|
|
||||||
};
|
};
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
template <typename T>
|
|
||||||
class EffectChorusImp;
|
class EffectChorusImp;
|
||||||
|
|
||||||
#define AMUSE_CHORUS_NUM_BLOCKS 3
|
#define AMUSE_CHORUS_NUM_BLOCKS 3
|
||||||
@ -31,13 +30,11 @@ class EffectChorus {
|
|||||||
uint32_t x98_period; /**< [500, 10000] time (in ms) of one delay-shift cycle */
|
uint32_t x98_period; /**< [500, 10000] time (in ms) of one delay-shift cycle */
|
||||||
bool m_dirty = true; /**< needs update of internal parameter data */
|
bool m_dirty = true; /**< needs update of internal parameter data */
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
friend class EffectChorusImp;
|
friend class EffectChorusImp;
|
||||||
EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t period);
|
EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t period);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
using ImpType = EffectChorusImp;
|
||||||
using ImpType = EffectChorusImp<T>;
|
|
||||||
|
|
||||||
void setBaseDelay(uint32_t baseDelay) {
|
void setBaseDelay(uint32_t baseDelay) {
|
||||||
baseDelay = std::clamp(baseDelay, 5u, 15u);
|
baseDelay = std::clamp(baseDelay, 5u, 15u);
|
||||||
@ -68,13 +65,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Type-specific implementation of chorus effect */
|
/** Type-specific implementation of chorus effect */
|
||||||
template <typename T>
|
class EffectChorusImp : public EffectBase, public EffectChorus {
|
||||||
class EffectChorusImp : public EffectBase<T>, public EffectChorus {
|
|
||||||
/** 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{};
|
std::array<std::array<float*, 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 */
|
||||||
std::array<std::array<T, 4>, NumChannels> x28_oldChans{}; /**< Unprocessed history of previous 4 samples */
|
std::array<std::array<float, 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 */
|
||||||
@ -84,9 +80,9 @@ class EffectChorusImp : public EffectBase<T>, public EffectChorus {
|
|||||||
uint32_t x68_pitchOffsetPeriod; /**< intermediate block window quantity for calculating SRC state */
|
uint32_t x68_pitchOffsetPeriod; /**< intermediate block window quantity for calculating SRC state */
|
||||||
|
|
||||||
struct SrcInfo {
|
struct SrcInfo {
|
||||||
T* x6c_dest; /**< selected channel's live buffer */
|
float* x6c_dest; /**< selected channel's live buffer */
|
||||||
T* x70_smpBase; /**< selected channel's delay buffer */
|
float* x70_smpBase; /**< selected channel's delay buffer */
|
||||||
T* x74_old; /**< selected channel's 4-sample history buffer */
|
float* x74_old; /**< selected channel's 4-sample history buffer */
|
||||||
uint32_t x78_posLo; /**< 16.7 fixed-point low-part of sample index */
|
uint32_t x78_posLo; /**< 16.7 fixed-point low-part of sample index */
|
||||||
uint32_t x7c_posHi; /**< 16.7 fixed-point high-part of sample index */
|
uint32_t x7c_posHi; /**< 16.7 fixed-point high-part of sample index */
|
||||||
uint32_t x80_pitchLo; /**< 16.7 fixed-point low-part of sample-rate conversion differential */
|
uint32_t x80_pitchLo; /**< 16.7 fixed-point low-part of sample-rate conversion differential */
|
||||||
@ -111,7 +107,7 @@ public:
|
|||||||
EffectChorusImp(const EffectChorusInfo& info, double sampleRate)
|
EffectChorusImp(const EffectChorusInfo& info, double sampleRate)
|
||||||
: EffectChorusImp(info.baseDelay, info.variation, info.period, sampleRate) {}
|
: EffectChorusImp(info.baseDelay, info.variation, info.period, sampleRate) {}
|
||||||
|
|
||||||
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
||||||
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
||||||
|
|
||||||
EffectType Isa() const override { return EffectType::Chorus; }
|
EffectType Isa() const override { return EffectType::Chorus; }
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "amuse/IBackendVoice.hpp"
|
#include "amuse/IBackendVoice.hpp"
|
||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
template <typename T>
|
|
||||||
class EffectDelayImp;
|
class EffectDelayImp;
|
||||||
|
|
||||||
/** Parameters needed to create EffectDelay */
|
/** Parameters needed to create EffectDelay */
|
||||||
@ -50,8 +49,7 @@ protected:
|
|||||||
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>
|
using ImpType = EffectDelayImp;
|
||||||
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);
|
||||||
@ -102,14 +100,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Type-specific implementation of delay effect */
|
/** Type-specific implementation of delay effect */
|
||||||
template <typename T>
|
class EffectDelayImp : public EffectBase, public EffectDelay {
|
||||||
class EffectDelayImp : public EffectBase<T>, public EffectDelay {
|
|
||||||
std::array<uint32_t, NumChannels> x0_currentSize; /**< per-channel delay-line buffer sizes */
|
std::array<uint32_t, NumChannels> x0_currentSize; /**< per-channel delay-line buffer sizes */
|
||||||
std::array<uint32_t, NumChannels> xc_currentPos; /**< per-channel block-index */
|
std::array<uint32_t, NumChannels> xc_currentPos; /**< per-channel block-index */
|
||||||
std::array<uint32_t, NumChannels> x18_currentFeedback; /**< [0, 128] feedback attenuator */
|
std::array<uint32_t, NumChannels> x18_currentFeedback; /**< [0, 128] feedback attenuator */
|
||||||
std::array<uint32_t, NumChannels> x24_currentOutput; /**< [0, 128] total attenuator */
|
std::array<uint32_t, NumChannels> x24_currentOutput; /**< [0, 128] total attenuator */
|
||||||
|
|
||||||
std::array<std::unique_ptr<T[]>, NumChannels> x30_chanLines; /**< delay-line buffers for each channel */
|
std::array<std::unique_ptr<float[]>, 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 */
|
||||||
@ -120,7 +117,7 @@ public:
|
|||||||
EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate);
|
EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate);
|
||||||
EffectDelayImp(const EffectDelayInfo& info, double sampleRate);
|
EffectDelayImp(const EffectDelayInfo& info, double sampleRate);
|
||||||
|
|
||||||
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
||||||
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
||||||
|
|
||||||
EffectType Isa() const override { return EffectType::Delay; }
|
EffectType Isa() const override { return EffectType::Delay; }
|
||||||
|
@ -49,10 +49,7 @@ struct ReverbDelayLine {
|
|||||||
void setdelay(int32_t delay);
|
void setdelay(int32_t delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class EffectReverbStdImp;
|
class EffectReverbStdImp;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class EffectReverbHiImp;
|
class EffectReverbHiImp;
|
||||||
|
|
||||||
/** Reverb effect with configurable reflection filtering */
|
/** Reverb effect with configurable reflection filtering */
|
||||||
@ -66,15 +63,12 @@ protected:
|
|||||||
float x150_x1d8_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
float x150_x1d8_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
||||||
bool m_dirty = true; /**< needs update of internal parameter data */
|
bool m_dirty = true; /**< needs update of internal parameter data */
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
friend class EffectReverbStdImp;
|
friend class EffectReverbStdImp;
|
||||||
template <typename T>
|
|
||||||
friend class EffectReverbHiImp;
|
friend class EffectReverbHiImp;
|
||||||
EffectReverbStd(float coloration, float mix, float time, float damping, float preDelay);
|
EffectReverbStd(float coloration, float mix, float time, float damping, float preDelay);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
using ImpType = EffectReverbStdImp;
|
||||||
using ImpType = EffectReverbStdImp<T>;
|
|
||||||
|
|
||||||
void setColoration(float coloration) {
|
void setColoration(float coloration) {
|
||||||
x140_x1c8_coloration = std::clamp(coloration, 0.f, 1.f);
|
x140_x1c8_coloration = std::clamp(coloration, 0.f, 1.f);
|
||||||
@ -119,13 +113,11 @@ public:
|
|||||||
class EffectReverbHi : public EffectReverbStd {
|
class EffectReverbHi : public EffectReverbStd {
|
||||||
float x1dc_crosstalk; /**< [0.0, 1.0] factor defining how much reflections are allowed to bleed to other channels */
|
float x1dc_crosstalk; /**< [0.0, 1.0] factor defining how much reflections are allowed to bleed to other channels */
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
friend class EffectReverbHiImp;
|
friend class EffectReverbHiImp;
|
||||||
EffectReverbHi(float coloration, float mix, float time, float damping, float preDelay, float crosstalk);
|
EffectReverbHi(float coloration, float mix, float time, float damping, float preDelay, float crosstalk);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
using ImpType = EffectReverbHiImp;
|
||||||
using ImpType = EffectReverbHiImp<T>;
|
|
||||||
|
|
||||||
void setCrosstalk(float crosstalk) {
|
void setCrosstalk(float crosstalk) {
|
||||||
x1dc_crosstalk = std::clamp(crosstalk, 0.f, 1.f);
|
x1dc_crosstalk = std::clamp(crosstalk, 0.f, 1.f);
|
||||||
@ -144,8 +136,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Standard-quality 2-stage reverb */
|
/** Standard-quality 2-stage reverb */
|
||||||
template <typename T>
|
class EffectReverbStdImp : public EffectBase, public EffectReverbStd {
|
||||||
class EffectReverbStdImp : public EffectBase<T>, public EffectReverbStd {
|
|
||||||
using CombCoeffArray = std::array<std::array<float, 2>, NumChannels>;
|
using CombCoeffArray = std::array<std::array<float, 2>, NumChannels>;
|
||||||
using ReverbDelayArray = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
using ReverbDelayArray = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
||||||
using PreDelayArray = std::array<std::unique_ptr<float[]>, NumChannels>;
|
using PreDelayArray = std::array<std::unique_ptr<float[]>, NumChannels>;
|
||||||
@ -170,15 +161,14 @@ public:
|
|||||||
EffectReverbStdImp(const EffectReverbStdInfo& info, double sampleRate)
|
EffectReverbStdImp(const EffectReverbStdInfo& info, double sampleRate)
|
||||||
: EffectReverbStdImp(info.coloration, info.mix, info.time, info.damping, info.preDelay, sampleRate) {}
|
: EffectReverbStdImp(info.coloration, info.mix, info.time, info.damping, info.preDelay, sampleRate) {}
|
||||||
|
|
||||||
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
||||||
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
||||||
|
|
||||||
EffectType Isa() const override { return EffectType::ReverbStd; }
|
EffectType Isa() const override { return EffectType::ReverbStd; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 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>
|
class EffectReverbHiImp : public EffectBase, public EffectReverbHi {
|
||||||
class EffectReverbHiImp : public EffectBase<T>, public EffectReverbHi {
|
|
||||||
using AllPassDelayLines = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
using AllPassDelayLines = std::array<std::array<ReverbDelayLine, 2>, NumChannels>;
|
||||||
using CombCoefficients = std::array<std::array<float, 3>, NumChannels>;
|
using CombCoefficients = std::array<std::array<float, 3>, NumChannels>;
|
||||||
using CombDelayLines = std::array<std::array<ReverbDelayLine, 3>, NumChannels>;
|
using CombDelayLines = std::array<std::array<ReverbDelayLine, 3>, NumChannels>;
|
||||||
@ -201,8 +191,8 @@ class EffectReverbHiImp : public EffectBase<T>, public EffectReverbHi {
|
|||||||
double m_sampleRate; /**< copy of sample rate */
|
double m_sampleRate; /**< copy of sample rate */
|
||||||
void _setup(double sampleRate);
|
void _setup(double sampleRate);
|
||||||
void _update();
|
void _update();
|
||||||
void _handleReverb(T* audio, int chanIdx, int chanCount, int sampleCount);
|
void _handleReverb(float* audio, int chanIdx, int chanCount, int sampleCount);
|
||||||
void _doCrosstalk(T* audio, float wet, float dry, int chanCount, int sampleCount);
|
void _doCrosstalk(float* audio, float wet, float dry, int chanCount, int sampleCount);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EffectReverbHiImp(float coloration, float mix, float time, float damping, float preDelay, float crosstalk,
|
EffectReverbHiImp(float coloration, float mix, float time, float damping, float preDelay, float crosstalk,
|
||||||
@ -210,7 +200,7 @@ public:
|
|||||||
EffectReverbHiImp(const EffectReverbHiInfo& info, double sampleRate)
|
EffectReverbHiImp(const EffectReverbHiInfo& info, double sampleRate)
|
||||||
: EffectReverbHiImp(info.coloration, info.mix, info.time, info.damping, info.preDelay, info.crosstalk, sampleRate) {}
|
: EffectReverbHiImp(info.coloration, info.mix, info.time, info.damping, info.preDelay, info.crosstalk, sampleRate) {}
|
||||||
|
|
||||||
void applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) override;
|
||||||
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
void resetOutputSampleRate(double sampleRate) override { _setup(sampleRate); }
|
||||||
|
|
||||||
EffectType Isa() const override { return EffectType::ReverbHi; }
|
EffectType Isa() const override { return EffectType::ReverbHi; }
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
enum class SubmixFormat { Int16, Int32, Float };
|
|
||||||
|
|
||||||
/** Client-implemented submix instance */
|
/** Client-implemented submix instance */
|
||||||
class IBackendSubmix {
|
class IBackendSubmix {
|
||||||
public:
|
public:
|
||||||
@ -14,8 +12,5 @@ public:
|
|||||||
|
|
||||||
/** Amuse gets fixed sample rate of submix this way */
|
/** Amuse gets fixed sample rate of submix this way */
|
||||||
virtual double getSampleRate() const = 0;
|
virtual double getSampleRate() const = 0;
|
||||||
|
|
||||||
/** Amuse gets fixed sample format of submix this way */
|
|
||||||
virtual SubmixFormat getSampleFormat() const = 0;
|
|
||||||
};
|
};
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -23,36 +23,23 @@ class Submix {
|
|||||||
friend class Sequencer;
|
friend class Sequencer;
|
||||||
Engine& m_root;
|
Engine& m_root;
|
||||||
std::unique_ptr<IBackendSubmix> m_backendSubmix; /**< Handle to client-implemented backend submix */
|
std::unique_ptr<IBackendSubmix> m_backendSubmix; /**< Handle to client-implemented backend submix */
|
||||||
std::vector<std::unique_ptr<EffectBaseTypeless>> m_effectStack; /**< Ordered list of effects to apply to submix */
|
std::vector<std::unique_ptr<EffectBase>> m_effectStack; /**< Ordered list of effects to apply to submix */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Submix(Engine& engine);
|
Submix(Engine& engine);
|
||||||
|
|
||||||
/** Construct new effect */
|
/** Construct new effect */
|
||||||
template <class T, class... Args>
|
template <class T, class... Args>
|
||||||
std::unique_ptr<EffectBaseTypeless> _makeEffect(Args... args) {
|
std::unique_ptr<EffectBase> _makeEffect(Args... args) {
|
||||||
switch (m_backendSubmix->getSampleFormat()) {
|
using ImpType = typename T::ImpType;
|
||||||
case SubmixFormat::Int16: {
|
return std::make_unique<ImpType>(args..., m_backendSubmix->getSampleRate());
|
||||||
using ImpType = typename T::template ImpType<int16_t>;
|
|
||||||
return std::make_unique<ImpType>(args..., m_backendSubmix->getSampleRate());
|
|
||||||
}
|
|
||||||
case SubmixFormat::Int32:
|
|
||||||
default: {
|
|
||||||
using ImpType = typename T::template ImpType<int32_t>;
|
|
||||||
return std::make_unique<ImpType>(args..., m_backendSubmix->getSampleRate());
|
|
||||||
}
|
|
||||||
case SubmixFormat::Float: {
|
|
||||||
using ImpType = typename T::template ImpType<float>;
|
|
||||||
return std::make_unique<ImpType>(args..., m_backendSubmix->getSampleRate());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add new effect to effect stack and assume ownership */
|
/** Add new effect to effect stack and assume ownership */
|
||||||
template <class T, class... Args>
|
template <class T, class... Args>
|
||||||
T& makeEffect(Args... args) {
|
T& makeEffect(Args... args) {
|
||||||
m_effectStack.push_back(_makeEffect<T>(args...));
|
m_effectStack.push_back(_makeEffect<T>(args...));
|
||||||
return static_cast<typename T::template ImpType<float>&>(*m_effectStack.back());
|
return static_cast<typename T::ImpType&>(*m_effectStack.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add new chorus effect to effect stack and assume ownership */
|
/** Add new chorus effect to effect stack and assume ownership */
|
||||||
@ -85,12 +72,6 @@ public:
|
|||||||
/** Returns true when an effect callback is bound */
|
/** Returns true when an effect callback is bound */
|
||||||
bool canApplyEffect() const { return m_effectStack.size() != 0; }
|
bool canApplyEffect() const { return m_effectStack.size() != 0; }
|
||||||
|
|
||||||
/** in/out transformation entry for audio effect */
|
|
||||||
void applyEffect(int16_t* audio, size_t frameCount, const ChannelMap& chanMap) const;
|
|
||||||
|
|
||||||
/** in/out transformation entry for audio effect */
|
|
||||||
void applyEffect(int32_t* audio, size_t frameCount, const ChannelMap& chanMap) const;
|
|
||||||
|
|
||||||
/** in/out transformation entry for audio effect */
|
/** in/out transformation entry for audio effect */
|
||||||
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) const;
|
void applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) const;
|
||||||
|
|
||||||
@ -99,6 +80,6 @@ public:
|
|||||||
|
|
||||||
Engine& getEngine() { return m_root; }
|
Engine& getEngine() { return m_root; }
|
||||||
|
|
||||||
std::vector<std::unique_ptr<EffectBaseTypeless>>& getEffectStack() { return m_effectStack; }
|
std::vector<std::unique_ptr<EffectBase>>& getEffectStack() { return m_effectStack; }
|
||||||
};
|
};
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
void BooBackendVoice::VoiceCallback::preSupplyAudio(boo::IAudioVoice&, double dt) {
|
void BooBackendVoice::VoiceCallback::preSupplyAudio(boo2::IAudioVoice&, double dt) {
|
||||||
m_parent.m_clientVox.preSupplyAudio(dt);
|
m_parent.m_clientVox.preSupplyAudio(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BooBackendVoice::VoiceCallback::supplyAudio(boo::IAudioVoice&, size_t frames, int16_t* data) {
|
size_t BooBackendVoice::VoiceCallback::supplyAudio(boo2::IAudioVoice&, size_t frames, int16_t* data) {
|
||||||
return m_parent.m_clientVox.supplyAudio(frames, data);
|
return m_parent.m_clientVox.supplyAudio(frames, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ void BooBackendVoice::VoiceCallback::routeAudio(size_t frames, size_t channels,
|
|||||||
m_parent.m_clientVox.routeAudio(frames, dt, busId, in, out);
|
m_parent.m_clientVox.routeAudio(frames, dt, busId, in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
BooBackendVoice::BooBackendVoice(boo::IAudioVoiceEngine& engine, Voice& clientVox, double sampleRate, bool dynamicPitch)
|
BooBackendVoice::BooBackendVoice(boo2::IAudioVoiceEngine& engine, Voice& clientVox, double sampleRate, bool dynamicPitch)
|
||||||
: m_clientVox(clientVox), m_cb(*this), m_booVoice(engine.allocateNewMonoVoice(sampleRate, &m_cb, dynamicPitch)) {}
|
: m_clientVox(clientVox), m_cb(*this), m_booVoice(engine.allocateNewMonoVoice(sampleRate, &m_cb, dynamicPitch)) {}
|
||||||
|
|
||||||
void BooBackendVoice::resetSampleRate(double sampleRate) { m_booVoice->resetSampleRate(sampleRate); }
|
void BooBackendVoice::resetSampleRate(double sampleRate) { m_booVoice->resetSampleRate(sampleRate); }
|
||||||
@ -49,17 +49,7 @@ void BooBackendVoice::stop() { m_booVoice->stop(); }
|
|||||||
|
|
||||||
bool BooBackendSubmix::SubmixCallback::canApplyEffect() const { return m_parent.m_clientSmx.canApplyEffect(); }
|
bool BooBackendSubmix::SubmixCallback::canApplyEffect() const { return m_parent.m_clientSmx.canApplyEffect(); }
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(int16_t* audio, size_t frameCount, const boo::ChannelMap& chanMap,
|
void BooBackendSubmix::SubmixCallback::applyEffect(float* audio, size_t frameCount, const boo2::ChannelMap& chanMap,
|
||||||
double) const {
|
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, frameCount, reinterpret_cast<const ChannelMap&>(chanMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(int32_t* audio, size_t frameCount, const boo::ChannelMap& chanMap,
|
|
||||||
double) const {
|
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, frameCount, reinterpret_cast<const ChannelMap&>(chanMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(float* audio, size_t frameCount, const boo::ChannelMap& chanMap,
|
|
||||||
double) const {
|
double) const {
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, frameCount, reinterpret_cast<const ChannelMap&>(chanMap));
|
return m_parent.m_clientSmx.applyEffect(audio, frameCount, reinterpret_cast<const ChannelMap&>(chanMap));
|
||||||
}
|
}
|
||||||
@ -68,7 +58,7 @@ void BooBackendSubmix::SubmixCallback::resetOutputSampleRate(double sampleRate)
|
|||||||
m_parent.m_clientSmx.resetOutputSampleRate(sampleRate);
|
m_parent.m_clientSmx.resetOutputSampleRate(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
BooBackendSubmix::BooBackendSubmix(boo::IAudioVoiceEngine& engine, Submix& clientSmx, bool mainOut, int busId)
|
BooBackendSubmix::BooBackendSubmix(boo2::IAudioVoiceEngine& engine, Submix& clientSmx, bool mainOut, int busId)
|
||||||
: m_clientSmx(clientSmx), m_cb(*this), m_booSubmix(engine.allocateNewSubmix(mainOut, &m_cb, busId)) {}
|
: m_clientSmx(clientSmx), m_cb(*this), m_booSubmix(engine.allocateNewSubmix(mainOut, &m_cb, busId)) {}
|
||||||
|
|
||||||
void BooBackendSubmix::setSendLevel(IBackendSubmix* submix, float level, bool slew) {
|
void BooBackendSubmix::setSendLevel(IBackendSubmix* submix, float level, bool slew) {
|
||||||
@ -78,8 +68,6 @@ void BooBackendSubmix::setSendLevel(IBackendSubmix* submix, float level, bool sl
|
|||||||
|
|
||||||
double BooBackendSubmix::getSampleRate() const { return m_booSubmix->getSampleRate(); }
|
double BooBackendSubmix::getSampleRate() const { return m_booSubmix->getSampleRate(); }
|
||||||
|
|
||||||
SubmixFormat BooBackendSubmix::getSampleFormat() const { return SubmixFormat(m_booSubmix->getSampleFormat()); }
|
|
||||||
|
|
||||||
BooBackendMIDIReader::~BooBackendMIDIReader() {}
|
BooBackendMIDIReader::~BooBackendMIDIReader() {}
|
||||||
|
|
||||||
BooBackendMIDIReader::BooBackendMIDIReader(Engine& engine, bool useLock)
|
BooBackendMIDIReader::BooBackendMIDIReader(Engine& engine, bool useLock)
|
||||||
@ -247,7 +235,7 @@ void BooBackendMIDIReader::stopSeq() {}
|
|||||||
|
|
||||||
void BooBackendMIDIReader::reset() {}
|
void BooBackendMIDIReader::reset() {}
|
||||||
|
|
||||||
BooBackendVoiceAllocator::BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine) : m_booEngine(booEngine) {
|
BooBackendVoiceAllocator::BooBackendVoiceAllocator(boo2::IAudioVoiceEngine& booEngine) : m_booEngine(booEngine) {
|
||||||
booEngine.setCallbackInterface(this);
|
booEngine.setCallbackInterface(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,12 +262,12 @@ AudioChannelSet BooBackendVoiceAllocator::getAvailableSet() { return AudioChanne
|
|||||||
|
|
||||||
void BooBackendVoiceAllocator::setVolume(float vol) { m_booEngine.setVolume(vol); }
|
void BooBackendVoiceAllocator::setVolume(float vol) { m_booEngine.setVolume(vol); }
|
||||||
|
|
||||||
void BooBackendVoiceAllocator::on5MsInterval(boo::IAudioVoiceEngine& engine, double dt) {
|
void BooBackendVoiceAllocator::on5MsInterval(boo2::IAudioVoiceEngine& engine, double dt) {
|
||||||
if (m_cbInterface)
|
if (m_cbInterface)
|
||||||
m_cbInterface->_on5MsInterval(*this, dt);
|
m_cbInterface->_on5MsInterval(*this, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendVoiceAllocator::onPumpCycleComplete(boo::IAudioVoiceEngine& engine) {
|
void BooBackendVoiceAllocator::onPumpCycleComplete(boo2::IAudioVoiceEngine& engine) {
|
||||||
if (m_cbInterface)
|
if (m_cbInterface)
|
||||||
m_cbInterface->_onPumpCycleComplete(*this);
|
m_cbInterface->_onPumpCycleComplete(*this);
|
||||||
}
|
}
|
||||||
|
@ -145,21 +145,19 @@ EffectChorus::EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t peri
|
|||||||
, x94_variation(std::clamp(variation, 0u, 5u))
|
, x94_variation(std::clamp(variation, 0u, 5u))
|
||||||
, x98_period(std::clamp(period, 500u, 10000u)) {}
|
, x98_period(std::clamp(period, 500u, 10000u)) {}
|
||||||
|
|
||||||
template <typename T>
|
EffectChorusImp::EffectChorusImp(uint32_t baseDelay, uint32_t variation, uint32_t period, double sampleRate)
|
||||||
EffectChorusImp<T>::EffectChorusImp(uint32_t baseDelay, uint32_t variation, uint32_t period, double sampleRate)
|
|
||||||
: EffectChorus(baseDelay, variation, period) {
|
: EffectChorus(baseDelay, variation, period) {
|
||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectChorusImp::_setup(double sampleRate) {
|
||||||
void EffectChorusImp<T>::_setup(double sampleRate) {
|
|
||||||
m_sampsPerMs = std::ceil(sampleRate / 1000.0);
|
m_sampsPerMs = std::ceil(sampleRate / 1000.0);
|
||||||
m_blockSamples = m_sampsPerMs * 5;
|
m_blockSamples = m_sampsPerMs * 5;
|
||||||
|
|
||||||
delete[] x0_lastChans[0][0];
|
delete[] x0_lastChans[0][0];
|
||||||
|
|
||||||
const size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
const size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||||
T* buf = new T[chanPitch * NumChannels]();
|
auto* buf = new float[chanPitch * NumChannels]();
|
||||||
|
|
||||||
for (size_t c = 0; c < NumChannels; ++c) {
|
for (size_t c = 0; c < NumChannels; ++c) {
|
||||||
for (size_t i = 0; i < AMUSE_CHORUS_NUM_BLOCKS; ++i) {
|
for (size_t i = 0; i < AMUSE_CHORUS_NUM_BLOCKS; ++i) {
|
||||||
@ -172,8 +170,7 @@ void EffectChorusImp<T>::_setup(double sampleRate) {
|
|||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectChorusImp::_update() {
|
||||||
void EffectChorusImp<T>::_update() {
|
|
||||||
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||||
size_t fifteenSamps = 15 * m_sampsPerMs;
|
size_t fifteenSamps = 15 * m_sampsPerMs;
|
||||||
|
|
||||||
@ -189,19 +186,17 @@ void EffectChorusImp<T>::_update() {
|
|||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
EffectChorusImp::~EffectChorusImp() {
|
||||||
EffectChorusImp<T>::~EffectChorusImp() {
|
|
||||||
delete[] x0_lastChans[0][0];
|
delete[] x0_lastChans[0][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectChorusImp::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount) {
|
||||||
void EffectChorusImp<T>::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount) {
|
|
||||||
float old1 = x74_old[0];
|
float old1 = x74_old[0];
|
||||||
float old2 = x74_old[1];
|
float old2 = x74_old[1];
|
||||||
float old3 = x74_old[2];
|
float old3 = x74_old[2];
|
||||||
float cur = x70_smpBase[x7c_posHi];
|
float cur = x70_smpBase[x7c_posHi];
|
||||||
|
|
||||||
T* dest = x6c_dest;
|
auto* dest = x6c_dest;
|
||||||
for (size_t i = 0; i < blockSamples; ++i) {
|
for (size_t i = 0; i < blockSamples; ++i) {
|
||||||
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
||||||
|
|
||||||
@ -212,7 +207,7 @@ void EffectChorusImp<T>::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount)
|
|||||||
++x7c_posHi;
|
++x7c_posHi;
|
||||||
if (x7c_posHi == x88_trigger)
|
if (x7c_posHi == x88_trigger)
|
||||||
x7c_posHi = x8c_target;
|
x7c_posHi = x8c_target;
|
||||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
*dest = selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur;
|
||||||
dest += chanCount;
|
dest += chanCount;
|
||||||
old1 = old2;
|
old1 = old2;
|
||||||
old2 = old3;
|
old2 = old3;
|
||||||
@ -220,7 +215,7 @@ void EffectChorusImp<T>::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount)
|
|||||||
cur = x70_smpBase[x7c_posHi];
|
cur = x70_smpBase[x7c_posHi];
|
||||||
} else {
|
} else {
|
||||||
x78_posLo = ovrTest;
|
x78_posLo = ovrTest;
|
||||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
*dest = selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur;
|
||||||
dest += chanCount;
|
dest += chanCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,14 +225,13 @@ void EffectChorusImp<T>::SrcInfo::doSrc1(size_t blockSamples, size_t chanCount)
|
|||||||
x74_old[2] = old3;
|
x74_old[2] = old3;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectChorusImp::SrcInfo::doSrc2(size_t blockSamples, size_t chanCount) {
|
||||||
void EffectChorusImp<T>::SrcInfo::doSrc2(size_t blockSamples, size_t chanCount) {
|
|
||||||
float old1 = x74_old[0];
|
float old1 = x74_old[0];
|
||||||
float old2 = x74_old[1];
|
float old2 = x74_old[1];
|
||||||
float old3 = x74_old[2];
|
float old3 = x74_old[2];
|
||||||
float cur = x70_smpBase[x7c_posHi];
|
float cur = x70_smpBase[x7c_posHi];
|
||||||
|
|
||||||
T* dest = x6c_dest;
|
auto* dest = x6c_dest;
|
||||||
for (size_t i = 0; i < blockSamples; ++i) {
|
for (size_t i = 0; i < blockSamples; ++i) {
|
||||||
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
const float* selTab = &rsmpTab12khz[x78_posLo >> 23 & 0x1fc];
|
||||||
++x7c_posHi;
|
++x7c_posHi;
|
||||||
@ -258,14 +252,14 @@ void EffectChorusImp<T>::SrcInfo::doSrc2(size_t blockSamples, size_t chanCount)
|
|||||||
if (x7c_posHi == x88_trigger)
|
if (x7c_posHi == x88_trigger)
|
||||||
x7c_posHi = x8c_target;
|
x7c_posHi = x8c_target;
|
||||||
|
|
||||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
*dest = selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur;
|
||||||
dest += chanCount;
|
dest += chanCount;
|
||||||
|
|
||||||
cur = x70_smpBase[x7c_posHi];
|
cur = x70_smpBase[x7c_posHi];
|
||||||
} else {
|
} else {
|
||||||
x78_posLo = ovrTest;
|
x78_posLo = ovrTest;
|
||||||
|
|
||||||
*dest = ClampFull<T>(selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur);
|
*dest = selTab[0] * old1 + selTab[1] * old2 + selTab[2] * old3 + selTab[3] * cur;
|
||||||
dest += chanCount;
|
dest += chanCount;
|
||||||
|
|
||||||
old1 = old2;
|
old1 = old2;
|
||||||
@ -284,8 +278,7 @@ void EffectChorusImp<T>::SrcInfo::doSrc2(size_t blockSamples, size_t chanCount)
|
|||||||
x74_old[2] = old3;
|
x74_old[2] = old3;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectChorusImp::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) {
|
||||||
void EffectChorusImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) {
|
|
||||||
if (m_dirty)
|
if (m_dirty)
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
@ -293,12 +286,12 @@ 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;
|
||||||
std::array<T*, 8> bufs{
|
std::array<float*, 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;
|
auto* 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 < NumChannels; ++c) {
|
for (size_t c = 0; c < chanMap.m_channelCount && c < NumChannels; ++c) {
|
||||||
*bufs[c]++ = *inBuf++;
|
*bufs[c]++ = *inBuf++;
|
||||||
@ -314,7 +307,7 @@ void EffectChorusImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelM
|
|||||||
x60_pitchOffset = -x60_pitchOffset;
|
x60_pitchOffset = -x60_pitchOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* outBuf = audio;
|
auto* 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 < NumChannels; ++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;
|
||||||
@ -348,7 +341,4 @@ void EffectChorusImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class EffectChorusImp<int16_t>;
|
|
||||||
template class EffectChorusImp<int32_t>;
|
|
||||||
template class EffectChorusImp<float>;
|
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
|
|
||||||
namespace amuse {
|
namespace amuse {
|
||||||
|
|
||||||
template <typename T>
|
EffectDelayImp::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate) {
|
||||||
EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate) {
|
|
||||||
initDelay = std::clamp(initDelay, 10u, 5000u);
|
initDelay = std::clamp(initDelay, 10u, 5000u);
|
||||||
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
||||||
initOutput = std::clamp(initOutput, 0u, 100u);
|
initOutput = std::clamp(initOutput, 0u, 100u);
|
||||||
@ -20,8 +19,7 @@ EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uin
|
|||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
EffectDelayImp::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
||||||
EffectDelayImp<T>::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
|
||||||
for (size_t i = 0; i < NumChannels; ++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);
|
||||||
@ -31,40 +29,37 @@ EffectDelayImp<T>::EffectDelayImp(const EffectDelayInfo& info, double sampleRate
|
|||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectDelayImp::_setup(double sampleRate) {
|
||||||
void EffectDelayImp<T>::_setup(double sampleRate) {
|
|
||||||
m_sampsPerMs = std::ceil(sampleRate / 1000.0);
|
m_sampsPerMs = std::ceil(sampleRate / 1000.0);
|
||||||
m_blockSamples = m_sampsPerMs * 5;
|
m_blockSamples = m_sampsPerMs * 5;
|
||||||
|
|
||||||
_update();
|
_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectDelayImp::_update() {
|
||||||
void EffectDelayImp<T>::_update() {
|
|
||||||
for (size_t i = 0; i < NumChannels; ++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] = std::make_unique<T[]>(m_blockSamples * x0_currentSize[i]);
|
x30_chanLines[i] = std::make_unique<float[]>(m_blockSamples * x0_currentSize[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectDelayImp::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) {
|
||||||
void EffectDelayImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) {
|
|
||||||
if (m_dirty)
|
if (m_dirty)
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
for (size_t f = 0; f < frameCount;) {
|
for (size_t f = 0; f < frameCount;) {
|
||||||
for (unsigned c = 0; c < chanMap.m_channelCount; ++c) {
|
for (unsigned c = 0; c < chanMap.m_channelCount; ++c) {
|
||||||
T* chanAud = audio + c;
|
auto* chanAud = audio + c;
|
||||||
for (unsigned i = 0; i < m_blockSamples && f < frameCount; ++i, ++f) {
|
for (unsigned i = 0; i < m_blockSamples && f < frameCount; ++i, ++f) {
|
||||||
T& liveSamp = chanAud[chanMap.m_channelCount * i];
|
auto& liveSamp = chanAud[chanMap.m_channelCount * i];
|
||||||
T& samp = x30_chanLines[c][xc_currentPos[c] * m_blockSamples + i];
|
auto& samp = x30_chanLines[c][xc_currentPos[c] * m_blockSamples + i];
|
||||||
samp = ClampFull<T>(samp * x18_currentFeedback[c] / 128 + liveSamp);
|
samp = samp * x18_currentFeedback[c] / 128 + liveSamp;
|
||||||
liveSamp = samp * x24_currentOutput[c] / 128;
|
liveSamp = samp * x24_currentOutput[c] / 128;
|
||||||
}
|
}
|
||||||
xc_currentPos[c] = (xc_currentPos[c] + 1) % x0_currentSize[c];
|
xc_currentPos[c] = (xc_currentPos[c] + 1) % x0_currentSize[c];
|
||||||
@ -73,7 +68,4 @@ void EffectDelayImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class EffectDelayImp<int16_t>;
|
|
||||||
template class EffectDelayImp<int32_t>;
|
|
||||||
template class EffectDelayImp<float>;
|
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -62,21 +62,18 @@ EffectReverbStd::EffectReverbStd(float coloration, float mix, float time, float
|
|||||||
EffectReverbHi::EffectReverbHi(float coloration, float mix, float time, float damping, float preDelay, float crosstalk)
|
EffectReverbHi::EffectReverbHi(float coloration, float mix, float time, float damping, float preDelay, float crosstalk)
|
||||||
: EffectReverbStd(coloration, mix, time, damping, preDelay), x1dc_crosstalk(std::clamp(crosstalk, 0.f, 1.0f)) {}
|
: EffectReverbStd(coloration, mix, time, damping, preDelay), x1dc_crosstalk(std::clamp(crosstalk, 0.f, 1.0f)) {}
|
||||||
|
|
||||||
template <typename T>
|
EffectReverbStdImp::EffectReverbStdImp(float coloration, float mix, float time, float damping, float preDelay,
|
||||||
EffectReverbStdImp<T>::EffectReverbStdImp(float coloration, float mix, float time, float damping, float preDelay,
|
|
||||||
double sampleRate)
|
double sampleRate)
|
||||||
: EffectReverbStd(coloration, mix, time, damping, preDelay) {
|
: EffectReverbStd(coloration, mix, time, damping, preDelay) {
|
||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbStdImp::_setup(double sampleRate) {
|
||||||
void EffectReverbStdImp<T>::_setup(double sampleRate) {
|
|
||||||
m_sampleRate = sampleRate;
|
m_sampleRate = sampleRate;
|
||||||
_update();
|
_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbStdImp::_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 (size_t c = 0; c < NumChannels; ++c) {
|
for (size_t c = 0; c < NumChannels; ++c) {
|
||||||
@ -122,8 +119,7 @@ void EffectReverbStdImp<T>::_update() {
|
|||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbStdImp::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) {
|
||||||
void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) {
|
|
||||||
if (m_dirty)
|
if (m_dirty)
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
@ -212,7 +208,7 @@ void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const Chann
|
|||||||
linesAP[1].x4_outPoint = 0;
|
linesAP[1].x4_outPoint = 0;
|
||||||
|
|
||||||
/* Mix out */
|
/* Mix out */
|
||||||
audio[s * chanMap.m_channelCount + c] = ClampFull<T>(dampWet * allPass + dampDry * sample);
|
audio[s * chanMap.m_channelCount + c] = dampWet * allPass + dampDry * sample;
|
||||||
}
|
}
|
||||||
x130_preDelayPtr[c] = preDelayPtr;
|
x130_preDelayPtr[c] = preDelayPtr;
|
||||||
}
|
}
|
||||||
@ -220,21 +216,18 @@ void EffectReverbStdImp<T>::applyEffect(T* audio, size_t frameCount, const Chann
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
EffectReverbHiImp::EffectReverbHiImp(float coloration, float mix, float time, float damping, float preDelay,
|
||||||
EffectReverbHiImp<T>::EffectReverbHiImp(float coloration, float mix, float time, float damping, float preDelay,
|
|
||||||
float crosstalk, double sampleRate)
|
float crosstalk, double sampleRate)
|
||||||
: EffectReverbHi(coloration, mix, time, damping, preDelay, crosstalk) {
|
: EffectReverbHi(coloration, mix, time, damping, preDelay, crosstalk) {
|
||||||
_setup(sampleRate);
|
_setup(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbHiImp::_setup(double sampleRate) {
|
||||||
void EffectReverbHiImp<T>::_setup(double sampleRate) {
|
|
||||||
m_sampleRate = sampleRate;
|
m_sampleRate = sampleRate;
|
||||||
_update();
|
_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbHiImp::_update() {
|
||||||
void EffectReverbHiImp<T>::_update() {
|
|
||||||
const float timeSamples = x148_x1d0_time * m_sampleRate;
|
const float timeSamples = x148_x1d0_time * m_sampleRate;
|
||||||
const double rateRatio = m_sampleRate / NativeSampleRate;
|
const double rateRatio = m_sampleRate / NativeSampleRate;
|
||||||
|
|
||||||
@ -287,8 +280,7 @@ void EffectReverbHiImp<T>::_update() {
|
|||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbHiImp::_handleReverb(float* audio, int c, int chanCount, int sampleCount) {
|
||||||
void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sampleCount) {
|
|
||||||
const float dampWet = x19c_level * 0.6f;
|
const float dampWet = x19c_level * 0.6f;
|
||||||
const float dampDry = 0.6f - dampWet;
|
const float dampDry = 0.6f - dampWet;
|
||||||
|
|
||||||
@ -401,28 +393,26 @@ void EffectReverbHiImp<T>::_handleReverb(T* audio, int c, int chanCount, int sam
|
|||||||
lineLP.x4_outPoint = 0;
|
lineLP.x4_outPoint = 0;
|
||||||
|
|
||||||
/* Mix out */
|
/* Mix out */
|
||||||
audio[s * chanCount + c] = ClampFull<T>(dampWet * allPass + dampDry * sample);
|
audio[s * chanCount + c] = dampWet * allPass + dampDry * sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
x1b8_preDelayPtr[c] = preDelayPtr;
|
x1b8_preDelayPtr[c] = preDelayPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbHiImp::_doCrosstalk(float* audio, float wet, float dry, int chanCount, int sampleCount) {
|
||||||
void EffectReverbHiImp<T>::_doCrosstalk(T* audio, float wet, float dry, int chanCount, int sampleCount) {
|
|
||||||
for (int i = 0; i < sampleCount; ++i) {
|
for (int i = 0; i < sampleCount; ++i) {
|
||||||
T* base = &audio[chanCount * i];
|
auto* base = &audio[chanCount * i];
|
||||||
float allWet = 0;
|
float allWet = 0;
|
||||||
for (int c = 0; c < chanCount; ++c) {
|
for (int c = 0; c < chanCount; ++c) {
|
||||||
allWet += base[c] * wet;
|
allWet += base[c] * wet;
|
||||||
base[c] *= dry;
|
base[c] *= dry;
|
||||||
}
|
}
|
||||||
for (int c = 0; c < chanCount; ++c)
|
for (int c = 0; c < chanCount; ++c)
|
||||||
base[c] = ClampFull<T>(base[c] + allWet);
|
base[c] = base[c] + allWet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void EffectReverbHiImp::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) {
|
||||||
void EffectReverbHiImp<T>::applyEffect(T* audio, size_t frameCount, const ChannelMap& chanMap) {
|
|
||||||
if (m_dirty)
|
if (m_dirty)
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
@ -439,11 +429,4 @@ void EffectReverbHiImp<T>::applyEffect(T* audio, size_t frameCount, const Channe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class EffectReverbStdImp<int16_t>;
|
|
||||||
template class EffectReverbStdImp<int32_t>;
|
|
||||||
template class EffectReverbStdImp<float>;
|
|
||||||
|
|
||||||
template class EffectReverbHiImp<int16_t>;
|
|
||||||
template class EffectReverbHiImp<int32_t>;
|
|
||||||
template class EffectReverbHiImp<float>;
|
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
@ -29,23 +29,13 @@ EffectReverbHi& Submix::makeReverbHi(float coloration, float mix, float time, fl
|
|||||||
|
|
||||||
EffectReverbHi& Submix::makeReverbHi(const EffectReverbHiInfo& info) { return makeEffect<EffectReverbHi>(info); }
|
EffectReverbHi& Submix::makeReverbHi(const EffectReverbHiInfo& info) { return makeEffect<EffectReverbHi>(info); }
|
||||||
|
|
||||||
void Submix::applyEffect(int16_t* audio, size_t frameCount, const ChannelMap& chanMap) const {
|
|
||||||
for (const std::unique_ptr<EffectBaseTypeless>& effect : m_effectStack)
|
|
||||||
((EffectBase<int16_t>&)*effect).applyEffect(audio, frameCount, chanMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Submix::applyEffect(int32_t* audio, size_t frameCount, const ChannelMap& chanMap) const {
|
|
||||||
for (const std::unique_ptr<EffectBaseTypeless>& effect : m_effectStack)
|
|
||||||
((EffectBase<int32_t>&)*effect).applyEffect(audio, frameCount, chanMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Submix::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) const {
|
void Submix::applyEffect(float* audio, size_t frameCount, const ChannelMap& chanMap) const {
|
||||||
for (const std::unique_ptr<EffectBaseTypeless>& effect : m_effectStack)
|
for (const std::unique_ptr<EffectBase>& effect : m_effectStack)
|
||||||
((EffectBase<float>&)*effect).applyEffect(audio, frameCount, chanMap);
|
effect->applyEffect(audio, frameCount, chanMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Submix::resetOutputSampleRate(double sampleRate) {
|
void Submix::resetOutputSampleRate(double sampleRate) {
|
||||||
for (const std::unique_ptr<EffectBaseTypeless>& effect : m_effectStack)
|
for (const std::unique_ptr<EffectBase>& effect : m_effectStack)
|
||||||
effect->resetOutputSampleRate(sampleRate);
|
effect->resetOutputSampleRate(sampleRate);
|
||||||
}
|
}
|
||||||
} // namespace amuse
|
} // namespace amuse
|
||||||
|
Loading…
x
Reference in New Issue
Block a user