mirror of https://github.com/AxioDL/amuse.git
Work on Chorus effect
This commit is contained in:
parent
3cce975977
commit
7aad87ea8c
|
@ -42,9 +42,12 @@ class BooBackendSubmix : public IBackendSubmix
|
||||||
{
|
{
|
||||||
BooBackendSubmix& m_parent;
|
BooBackendSubmix& m_parent;
|
||||||
bool canApplyEffect() const;
|
bool canApplyEffect() const;
|
||||||
void applyEffect(int16_t* audio, const boo::ChannelMap& chanMap, double sampleRate) const;
|
void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
void applyEffect(int32_t* audio, const boo::ChannelMap& chanMap, double sampleRate) const;
|
const boo::ChannelMap& chanMap, double sampleRate) const;
|
||||||
void applyEffect(float* audio, const boo::ChannelMap& chanMap, double sampleRate) const;
|
void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const boo::ChannelMap& chanMap, double sampleRate) const;
|
||||||
|
void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const boo::ChannelMap& chanMap, double sampleRate) const;
|
||||||
SubmixCallback(BooBackendSubmix& parent) : m_parent(parent) {}
|
SubmixCallback(BooBackendSubmix& parent) : m_parent(parent) {}
|
||||||
} m_cb;
|
} m_cb;
|
||||||
std::unique_ptr<boo::IAudioSubmix> m_booSubmix;
|
std::unique_ptr<boo::IAudioSubmix> m_booSubmix;
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
#ifndef __AMUSE_COMMON_HPP__
|
#ifndef __AMUSE_COMMON_HPP__
|
||||||
#define __AMUSE_COMMON_HPP__
|
#define __AMUSE_COMMON_HPP__
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline T clamp(T a, T val, T b) {return std::max<T>(a, std::min<T>(b, val));}
|
||||||
|
|
||||||
#ifndef M_PIF
|
#ifndef M_PIF
|
||||||
#define M_PIF 3.14159265358979323846f /* pi */
|
#define M_PIF 3.14159265358979323846f /* pi */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,22 @@
|
||||||
#ifndef __AMUSE_EFFECTBASE_HPP__
|
#ifndef __AMUSE_EFFECTBASE_HPP__
|
||||||
#define __AMUSE_EFFECTBASE_HPP__
|
#define __AMUSE_EFFECTBASE_HPP__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
class ChannelMap;
|
||||||
|
|
||||||
class EffectBase
|
class EffectBase
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)=0;
|
||||||
|
virtual void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)=0;
|
||||||
|
virtual void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,66 @@
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define AMUSE_CHORUS_NUM_BLOCKS 3
|
||||||
|
|
||||||
/** Mixes the audio back into itself after continuously-varying delay */
|
/** Mixes the audio back into itself after continuously-varying delay */
|
||||||
class EffectChorus : public EffectBase
|
class EffectChorus : public EffectBase
|
||||||
{
|
{
|
||||||
uint32_t m_baseDelay; /**< [5, 15] minimum value (in ms) for computed delay */
|
int32_t* x0_lastLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
uint32_t m_variation; /**< [0, 5] time error (in ms) to set delay within */
|
int32_t* xc_lastRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
uint32_t m_period; /**< [500, 10000] time (in ms) of one delay-shift cycle */
|
int32_t* x18_lastRearLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
int32_t* x18_lastRearRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
int32_t* x18_lastCenter[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
int32_t* x18_lastLFE[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
int32_t* x18_lastSideLeft[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
int32_t* x18_lastSideRight[AMUSE_CHORUS_NUM_BLOCKS];
|
||||||
|
|
||||||
|
uint8_t x24_currentLast = 1;
|
||||||
|
int32_t x28_oldLeft[4] = {};
|
||||||
|
int32_t x38_oldRight[4] = {};
|
||||||
|
int32_t x48_oldRearLeft[4] = {};
|
||||||
|
int32_t x48_oldRearRight[4] = {};
|
||||||
|
int32_t x48_oldCenter[4] = {};
|
||||||
|
int32_t x48_oldLFE[4] = {};
|
||||||
|
int32_t x48_oldSideLeft[4] = {};
|
||||||
|
int32_t x48_oldSideRight[4] = {};
|
||||||
|
|
||||||
|
uint32_t x58_currentPosLo = 0;
|
||||||
|
uint32_t x5c_currentPosHi = 0;
|
||||||
|
|
||||||
|
int32_t x60_pitchOffset;
|
||||||
|
uint32_t x64_pitchOffsetPeriodCount;
|
||||||
|
uint32_t x68_pitchOffsetPeriod;
|
||||||
|
|
||||||
|
struct SrcInfo
|
||||||
|
{
|
||||||
|
int32_t* x6c_dest;
|
||||||
|
int32_t* x70_smpBase;
|
||||||
|
int32_t* x74_old;
|
||||||
|
uint32_t x78_posLo;
|
||||||
|
uint32_t x7c_posHi;
|
||||||
|
uint32_t x80_pitchLo;
|
||||||
|
uint32_t x84_pitchHi;
|
||||||
|
uint32_t x88_trigger;
|
||||||
|
uint32_t x8c_target = 0;
|
||||||
|
} x6c_src;
|
||||||
|
|
||||||
|
uint32_t x90_baseDelay; /**< [5, 15] minimum value (in ms) for computed delay */
|
||||||
|
uint32_t x94_variation; /**< [0, 5] time error (in ms) to set delay within */
|
||||||
|
uint32_t x98_period; /**< [500, 10000] time (in ms) of one delay-shift cycle */
|
||||||
|
|
||||||
|
double m_sampleRate;
|
||||||
|
uint32_t m_blockSamples;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~EffectChorus();
|
||||||
|
EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t period, double sampleRate);
|
||||||
|
void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,14 @@ class EffectDelay : public EffectBase
|
||||||
uint32_t m_delay[8]; /**< [10, 5000] time in ms of each channel's delay */
|
uint32_t m_delay[8]; /**< [10, 5000] time in ms of each channel's delay */
|
||||||
uint32_t m_feedback[8]; /**< [0, 100] percent to mix delayed signal with input signal */
|
uint32_t m_feedback[8]; /**< [0, 100] percent to mix delayed signal with input signal */
|
||||||
uint32_t m_output[8]; /**< [0, 100] total output percent */
|
uint32_t m_output[8]; /**< [0, 100] total output percent */
|
||||||
|
public:
|
||||||
|
EffectDelay(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput);
|
||||||
|
void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,15 @@ class EffectReverbHi : public EffectBase
|
||||||
float m_damping; /**< [0.0, 1.0] damping factor influencing low-pass filter of reflections */
|
float m_damping; /**< [0.0, 1.0] damping factor influencing low-pass filter of reflections */
|
||||||
float m_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
float m_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
||||||
float m_crosstalk; /**< [0.0, 100.0] factor defining how much reflections are allowed to bleed to other channels */
|
float m_crosstalk; /**< [0.0, 100.0] factor defining how much reflections are allowed to bleed to other channels */
|
||||||
|
public:
|
||||||
|
EffectReverbHi(float coloration, float mix, float time,
|
||||||
|
float damping, float preDelay, float crosstalk);
|
||||||
|
void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,15 @@ class EffectReverbStd : public EffectBase
|
||||||
float m_time; /**< [0.01, 10.0] time in seconds for reflection decay */
|
float m_time; /**< [0.01, 10.0] time in seconds for reflection decay */
|
||||||
float m_damping; /**< [0.0, 1.0] damping factor influencing low-pass filter of reflections */
|
float m_damping; /**< [0.0, 1.0] damping factor influencing low-pass filter of reflections */
|
||||||
float m_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
float m_preDelay; /**< [0.0, 0.1] time in seconds before initial reflection heard */
|
||||||
|
public:
|
||||||
|
EffectReverbStd(float coloration, float mix, float time,
|
||||||
|
float damping, float preDelay);
|
||||||
|
void applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
|
void applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,20 +48,20 @@ bool BooBackendSubmix::SubmixCallback::canApplyEffect() const
|
||||||
return m_parent.m_clientSmx.canApplyEffect();
|
return m_parent.m_clientSmx.canApplyEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(int16_t* audio, const boo::ChannelMap& chanMap,
|
void BooBackendSubmix::SubmixCallback::applyEffect(int16_t* audio, size_t frameCount,
|
||||||
double sampleRate) const
|
const boo::ChannelMap& chanMap, double sampleRate) const
|
||||||
{
|
{
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(int32_t* audio, const boo::ChannelMap& chanMap,
|
void BooBackendSubmix::SubmixCallback::applyEffect(int32_t* audio, size_t frameCount,
|
||||||
double sampleRate) const
|
const boo::ChannelMap& chanMap, double sampleRate) const
|
||||||
{
|
{
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooBackendSubmix::SubmixCallback::applyEffect(float* audio, const boo::ChannelMap& chanMap,
|
void BooBackendSubmix::SubmixCallback::applyEffect(float* audio, size_t frameCount,
|
||||||
double sampleRate) const
|
const boo::ChannelMap& chanMap, double sampleRate) const
|
||||||
{
|
{
|
||||||
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
return m_parent.m_clientSmx.applyEffect(audio, reinterpret_cast<const ChannelMap&>(chanMap), sampleRate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include "amuse/EffectChorus.hpp"
|
||||||
|
#include "amuse/Common.hpp"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace amuse
|
||||||
|
{
|
||||||
|
|
||||||
|
EffectChorus::EffectChorus(uint32_t baseDelay, uint32_t variation,
|
||||||
|
uint32_t period, double sampleRate)
|
||||||
|
: x90_baseDelay(clamp(5u, baseDelay, 15u)),
|
||||||
|
x94_variation(clamp(0u, variation, 5u)),
|
||||||
|
x98_period(clamp(500u, period, 10000u)),
|
||||||
|
m_sampleRate(sampleRate),
|
||||||
|
m_blockSamples(sampleRate * 160.0 / 32000.0)
|
||||||
|
{
|
||||||
|
int32_t* buf = new int32_t[m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8];
|
||||||
|
memset(buf, 0, m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS * 8 * sizeof(int32_t));
|
||||||
|
size_t chanPitch = m_blockSamples * AMUSE_CHORUS_NUM_BLOCKS;
|
||||||
|
|
||||||
|
x0_lastLeft[0] = buf;
|
||||||
|
x0_lastLeft[1] = x0_lastLeft[0] + m_blockSamples;
|
||||||
|
x0_lastLeft[2] = x0_lastLeft[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
xc_lastRight[0] = buf + chanPitch;
|
||||||
|
xc_lastRight[1] = xc_lastRight[0] + m_blockSamples;
|
||||||
|
xc_lastRight[2] = xc_lastRight[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastRearLeft[0] = buf + chanPitch * 2;
|
||||||
|
x18_lastRearLeft[1] = x18_lastRearLeft[0] + m_blockSamples;
|
||||||
|
x18_lastRearLeft[2] = x18_lastRearLeft[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastRearRight[0] = buf + chanPitch * 3;
|
||||||
|
x18_lastRearRight[1] = x18_lastRearRight[0] + m_blockSamples;
|
||||||
|
x18_lastRearRight[2] = x18_lastRearRight[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastCenter[0] = buf + chanPitch * 4;
|
||||||
|
x18_lastCenter[1] = x18_lastCenter[0] + m_blockSamples;
|
||||||
|
x18_lastCenter[2] = x18_lastCenter[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastLFE[0] = buf + chanPitch * 5;
|
||||||
|
x18_lastLFE[1] = x18_lastLFE[0] + m_blockSamples;
|
||||||
|
x18_lastLFE[2] = x18_lastLFE[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastSideLeft[0] = buf + chanPitch * 6;
|
||||||
|
x18_lastSideLeft[1] = x18_lastSideLeft[0] + m_blockSamples;
|
||||||
|
x18_lastSideLeft[2] = x18_lastSideLeft[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x18_lastSideRight[0] = buf + chanPitch * 7;
|
||||||
|
x18_lastSideRight[1] = x18_lastSideRight[0] + m_blockSamples;
|
||||||
|
x18_lastSideRight[2] = x18_lastSideRight[0] + m_blockSamples * 2;
|
||||||
|
|
||||||
|
x6c_src.x88_trigger = chanPitch;
|
||||||
|
|
||||||
|
x5c_currentPosHi = m_blockSamples * 2 - ((x90_baseDelay - 5) * m_sampleRate / 1000.f);
|
||||||
|
uint32_t temp = (x5c_currentPosHi + (x24_currentLast - 1) * m_blockSamples);
|
||||||
|
x5c_currentPosHi = temp - ((temp * 8 / 15) >> 8) * chanPitch;
|
||||||
|
|
||||||
|
x68_pitchOffsetPeriod = (x98_period * 2 / 10 + 1) & ~1;
|
||||||
|
x60_pitchOffset = x94_variation * 2048 / x68_pitchOffsetPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectChorus::~EffectChorus()
|
||||||
|
{
|
||||||
|
delete[] x0_lastLeft[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectChorus::applyEffect(int16_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectChorus::applyEffect(int32_t* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectChorus::applyEffect(float* audio, size_t frameCount,
|
||||||
|
const ChannelMap& chanMap, double sampleRate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue