mirror of
https://github.com/godotengine/godot.git
synced 2024-12-27 11:24:59 +08:00
125 lines
3.7 KiB
C++
125 lines
3.7 KiB
C++
|
#include "audio_effect_limiter.h"
|
||
|
|
||
|
void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count) {
|
||
|
|
||
|
float thresh = Math::db2linear(base->treshold);
|
||
|
float threshdb = base->treshold;
|
||
|
float ceiling = Math::db2linear(base->ceiling);
|
||
|
float ceildb = base->ceiling;
|
||
|
float makeup = Math::db2linear(ceildb - threshdb);
|
||
|
float makeupdb = ceildb - threshdb;
|
||
|
float sc = -base->soft_clip;
|
||
|
float scv = Math::db2linear(sc);
|
||
|
float sccomp = Math::db2linear(-sc);
|
||
|
float peakdb = ceildb + 25;
|
||
|
float peaklvl = Math::db2linear(peakdb);
|
||
|
float scratio = base->soft_clip_ratio;
|
||
|
float scmult = Math::abs((ceildb - sc) / (peakdb - sc));
|
||
|
|
||
|
for(int i=0;i<p_frame_count;i++) {
|
||
|
|
||
|
float spl0 = p_src_frames[i].l;
|
||
|
float spl1 = p_src_frames[i].r;
|
||
|
spl0 = spl0 * makeup;
|
||
|
spl1 = spl1 * makeup;
|
||
|
float sign0 = (spl0 < 0.0 ? -1.0 : 1.0 );
|
||
|
float sign1 = (spl1 < 0.0 ? -1.0 : 1.0 );
|
||
|
float abs0 = Math::abs(spl0);
|
||
|
float abs1 = Math::abs(spl1);
|
||
|
float overdb0 = Math::linear2db(abs0) - ceildb;
|
||
|
float overdb1 = Math::linear2db(abs1) - ceildb;
|
||
|
|
||
|
if (abs0 > scv)
|
||
|
{
|
||
|
spl0 = sign0 * (scv + Math::db2linear(overdb0 * scmult));
|
||
|
}
|
||
|
if (abs1 > scv)
|
||
|
{
|
||
|
spl1 = sign1 * (scv + Math::db2linear(overdb1 * scmult));
|
||
|
}
|
||
|
|
||
|
spl0 = MIN(ceiling, Math::abs(spl0)) * (spl0 < 0.0 ? -1.0 : 1.0);
|
||
|
spl1 = MIN(ceiling, Math::abs(spl1)) * (spl1 < 0.0 ? -1.0 : 1.0);
|
||
|
|
||
|
p_dst_frames[i].l = spl0;
|
||
|
p_dst_frames[i].r = spl1;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
Ref<AudioEffectInstance> AudioEffectLimiter::instance() {
|
||
|
Ref<AudioEffectLimiterInstance> ins;
|
||
|
ins.instance();
|
||
|
ins->base=Ref<AudioEffectLimiter>(this);
|
||
|
|
||
|
return ins;
|
||
|
}
|
||
|
|
||
|
|
||
|
void AudioEffectLimiter::set_treshold_db(float p_treshold) {
|
||
|
|
||
|
treshold=p_treshold;
|
||
|
}
|
||
|
|
||
|
float AudioEffectLimiter::get_treshold_db() const{
|
||
|
|
||
|
return treshold;
|
||
|
}
|
||
|
|
||
|
void AudioEffectLimiter::set_ceiling_db(float p_ceiling){
|
||
|
|
||
|
ceiling=p_ceiling;
|
||
|
}
|
||
|
float AudioEffectLimiter::get_ceiling_db() const{
|
||
|
|
||
|
return ceiling;
|
||
|
}
|
||
|
|
||
|
void AudioEffectLimiter::set_soft_clip_db(float p_soft_clip){
|
||
|
|
||
|
soft_clip=p_soft_clip;
|
||
|
}
|
||
|
float AudioEffectLimiter::get_soft_clip_db() const{
|
||
|
|
||
|
return soft_clip;
|
||
|
}
|
||
|
|
||
|
void AudioEffectLimiter::set_soft_clip_ratio(float p_soft_clip){
|
||
|
|
||
|
soft_clip_ratio=p_soft_clip;
|
||
|
}
|
||
|
float AudioEffectLimiter::get_soft_clip_ratio() const{
|
||
|
|
||
|
return soft_clip;
|
||
|
}
|
||
|
|
||
|
|
||
|
void AudioEffectLimiter::_bind_methods() {
|
||
|
|
||
|
ClassDB::bind_method(_MD("set_ceiling_db","ceiling"),&AudioEffectLimiter::set_ceiling_db);
|
||
|
ClassDB::bind_method(_MD("get_ceiling_db"),&AudioEffectLimiter::get_ceiling_db);
|
||
|
|
||
|
ClassDB::bind_method(_MD("set_treshold_db","treshold"),&AudioEffectLimiter::set_treshold_db);
|
||
|
ClassDB::bind_method(_MD("get_treshold_db"),&AudioEffectLimiter::get_treshold_db);
|
||
|
|
||
|
ClassDB::bind_method(_MD("set_soft_clip_db","soft_clip"),&AudioEffectLimiter::set_soft_clip_db);
|
||
|
ClassDB::bind_method(_MD("get_soft_clip_db"),&AudioEffectLimiter::get_soft_clip_db);
|
||
|
|
||
|
ClassDB::bind_method(_MD("set_soft_clip_ratio","soft_clip"),&AudioEffectLimiter::set_soft_clip_ratio);
|
||
|
ClassDB::bind_method(_MD("get_soft_clip_ratio"),&AudioEffectLimiter::get_soft_clip_ratio);
|
||
|
|
||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ceiling_db",PROPERTY_HINT_RANGE,"-20,-0.1,0.1"),_SCS("set_ceiling_db"),_SCS("get_ceiling_db"));
|
||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL,"treshold_db",PROPERTY_HINT_RANGE,"-30,0,0.1"),_SCS("set_treshold_db"),_SCS("get_treshold_db"));
|
||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL,"soft_clip_db",PROPERTY_HINT_RANGE,"0,6,0.1"),_SCS("set_soft_clip_db"),_SCS("get_soft_clip_db"));
|
||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL,"soft_clip_ratio",PROPERTY_HINT_RANGE,"3,20,0.1"),_SCS("set_soft_clip_ratio"),_SCS("get_soft_clip_ratio"));
|
||
|
}
|
||
|
|
||
|
AudioEffectLimiter::AudioEffectLimiter()
|
||
|
{
|
||
|
treshold=0;
|
||
|
ceiling=-0.1;
|
||
|
soft_clip=2;
|
||
|
soft_clip_ratio=10;
|
||
|
}
|