| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | #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() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_ceiling_db","ceiling"),&AudioEffectLimiter::set_ceiling_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_ceiling_db"),&AudioEffectLimiter::get_ceiling_db); | 
					
						
							| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_treshold_db","treshold"),&AudioEffectLimiter::set_treshold_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_treshold_db"),&AudioEffectLimiter::get_treshold_db); | 
					
						
							| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_soft_clip_db","soft_clip"),&AudioEffectLimiter::set_soft_clip_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_soft_clip_db"),&AudioEffectLimiter::get_soft_clip_db); | 
					
						
							| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_soft_clip_ratio","soft_clip"),&AudioEffectLimiter::set_soft_clip_ratio); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_soft_clip_ratio"),&AudioEffectLimiter::get_soft_clip_ratio); | 
					
						
							| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 01:11:37 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"ceiling_db",PROPERTY_HINT_RANGE,"-20,-0.1,0.1"),"set_ceiling_db","get_ceiling_db"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"treshold_db",PROPERTY_HINT_RANGE,"-30,0,0.1"),"set_treshold_db","get_treshold_db"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"soft_clip_db",PROPERTY_HINT_RANGE,"0,6,0.1"),"set_soft_clip_db","get_soft_clip_db"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"soft_clip_ratio",PROPERTY_HINT_RANGE,"3,20,0.1"),"set_soft_clip_ratio","get_soft_clip_ratio"); | 
					
						
							| 
									
										
										
										
											2017-01-22 20:39:53 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AudioEffectLimiter::AudioEffectLimiter() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	treshold=0; | 
					
						
							|  |  |  | 	ceiling=-0.1; | 
					
						
							|  |  |  | 	soft_clip=2; | 
					
						
							|  |  |  | 	soft_clip_ratio=10; | 
					
						
							|  |  |  | } |