diff options
-rw-r--r-- | servers/audio/effects/audio_effect_chorus.cpp | 364 | ||||
-rw-r--r-- | servers/audio/effects/audio_effect_chorus.h | 115 | ||||
-rw-r--r-- | servers/audio/effects/audio_effect_panner.cpp | 47 | ||||
-rw-r--r-- | servers/audio/effects/audio_effect_panner.h | 40 | ||||
-rw-r--r-- | servers/register_server_types.cpp | 37 |
5 files changed, 589 insertions, 14 deletions
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp new file mode 100644 index 0000000000..0b7c909071 --- /dev/null +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -0,0 +1,364 @@ +#include "audio_effect_chorus.h" +#include "servers/audio_server.h" + +void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count) { + + int todo = p_frame_count; + + while(todo) { + + int to_mix = MIN(todo,256); //can't mix too much + + _process_chunk(p_src_frames,p_dst_frames,to_mix); + + p_src_frames+=to_mix; + p_dst_frames+=to_mix; + + todo-=to_mix; + } +} + +void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count) { + + + //fill ringbuffer + for(int i=0;i<p_frame_count;i++) { + audio_buffer[(buffer_pos+i)&buffer_mask]=p_src_frames[i]; + p_dst_frames[i]=p_src_frames[i]*base->dry; + } + + float mix_rate = AudioServer::get_singleton()->get_mix_rate(); + + /* process voices */ + for (int vc=0;vc<base->voice_count;vc++) { + + AudioEffectChorus::Voice &v=base->voice[vc]; + + + double time_to_mix=(float)p_frame_count/mix_rate; + double cycles_to_mix=time_to_mix*v.rate; + + unsigned int local_rb_pos=buffer_pos; + AudioFrame *dst_buff=p_dst_frames; + AudioFrame *rb_buff=audio_buffer.ptr(); + + double delay_msec=v.delay; + unsigned int delay_frames=Math::fast_ftoi((delay_msec/1000.0)*mix_rate); + float max_depth_frames=(v.depth/1000.0)*mix_rate; + + uint64_t local_cycles=cycles[vc]; + uint64_t increment=llrint(cycles_to_mix/(double)p_frame_count*(double)(1<<AudioEffectChorus::CYCLES_FRAC)); + + //check the LFO doesnt read ahead of the write pos + if ((((int)max_depth_frames)+10)>delay_frames) { //10 as some threshold to avoid precision stuff + delay_frames+=(int)max_depth_frames-delay_frames; + delay_frames+=10; //threshold to avoid precision stuff + + } + + + + //low pass filter + if (v.cutoff==0) + continue; + float auxlp=expf(-2.0*M_PI*v.cutoff/mix_rate); + float c1=1.0-auxlp; + float c2=auxlp; + AudioFrame h=filter_h[vc]; + if (v.cutoff>=AudioEffectChorus::MS_CUTOFF_MAX) { + c1=1.0; c2=0.0; + } + + //vol modifier + + AudioFrame vol_modifier=AudioFrame(base->wet,base->wet) * Math::db2linear(v.level); + vol_modifier.l*=CLAMP( 1.0 - v.pan, 0, 1); + vol_modifier.r*=CLAMP( 1.0 + v.pan, 0, 1); + + + + for (int i=0;i<p_frame_count;i++) { + + /** COMPUTE WAVEFORM **/ + + float phase=(float)(local_cycles&AudioEffectChorus::CYCLES_MASK)/(float)(1<<AudioEffectChorus::CYCLES_FRAC); + + float wave_delay=sinf(phase*2.0*M_PI)*max_depth_frames; + + int wave_delay_frames=lrint(floor(wave_delay)); + float wave_delay_frac=wave_delay-(float)wave_delay_frames; + + /** COMPUTE RINGBUFFER POS**/ + + unsigned int rb_source=local_rb_pos; + rb_source-=delay_frames; + + rb_source-=wave_delay_frames; + + /** READ FROM RINGBUFFER, LINEARLY INTERPOLATE */ + + AudioFrame val=rb_buff[rb_source&buffer_mask]; + AudioFrame val_next=rb_buff[(rb_source-1)&buffer_mask]; + + val+=(val_next-val)*wave_delay_frac; + + val=val*c1+h*c2; + h=val; + + /** MIX VALUE TO OUTPUT **/ + + dst_buff[i]+=val*vol_modifier; + + local_cycles+=increment; + local_rb_pos++; + + } + + filter_h[vc]=h; + cycles[vc]+=Math::fast_ftoi(cycles_to_mix*(double)(1<<AudioEffectChorus::CYCLES_FRAC)); + } + + buffer_pos+=p_frame_count; +} + + +Ref<AudioEffectInstance> AudioEffectChorus::instance() { + + Ref<AudioEffectChorusInstance> ins; + ins.instance(); + ins->base=Ref<AudioEffectChorus>(this); + for(int i=0;i<4;i++) { + ins->filter_h[i]=AudioFrame(0,0); + ins->cycles[i]=0; + } + + float ring_buffer_max_size=AudioEffectChorus::MAX_DELAY_MS+AudioEffectChorus::MAX_DEPTH_MS+AudioEffectChorus::MAX_WIDTH_MS; + + ring_buffer_max_size*=2; //just to avoid complications + ring_buffer_max_size/=1000.0;//convert to seconds + ring_buffer_max_size*=AudioServer::get_singleton()->get_mix_rate(); + + int ringbuff_size=ring_buffer_max_size; + + int bits=0; + + while(ringbuff_size>0) { + bits++; + ringbuff_size/=2; + } + + ringbuff_size=1<<bits; + ins->buffer_mask=ringbuff_size-1; + ins->buffer_pos=0; + ins->audio_buffer.resize(ringbuff_size); + for(int i=0;i<ringbuff_size;i++) { + ins->audio_buffer[i]=AudioFrame(0,0); + } + + return ins; +} + +void AudioEffectChorus::set_voice_count(int p_voices) { + + ERR_FAIL_COND(p_voices<1 || p_voices>=MAX_VOICES); + voice_count=p_voices; + _change_notify(); +} + + +int AudioEffectChorus::get_voice_count() const{ + + return voice_count; +} + +void AudioEffectChorus::set_voice_delay_ms(int p_voice,float p_delay_ms){ + + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].delay=p_delay_ms; + +} +float AudioEffectChorus::get_voice_delay_ms(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + return voice[p_voice].delay; +} + +void AudioEffectChorus::set_voice_rate_hz(int p_voice,float p_rate_hz){ + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].rate=p_rate_hz; +} +float AudioEffectChorus::get_voice_rate_hz(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + + return voice[p_voice].rate; +} + +void AudioEffectChorus::set_voice_depth_ms(int p_voice,float p_depth_ms){ + + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].depth=p_depth_ms; +} +float AudioEffectChorus::get_voice_depth_ms(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + + return voice[p_voice].depth; +} + +void AudioEffectChorus::set_voice_level_db(int p_voice,float p_level_db){ + + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].level=p_level_db; +} +float AudioEffectChorus::get_voice_level_db(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + + return voice[p_voice].level; +} + + +void AudioEffectChorus::set_voice_cutoff_hz(int p_voice,float p_cutoff_hz){ + + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].cutoff=p_cutoff_hz; +} +float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + + return voice[p_voice].cutoff; +} + +void AudioEffectChorus::set_voice_pan(int p_voice,float p_pan){ + + ERR_FAIL_INDEX(p_voice,MAX_VOICES); + + voice[p_voice].pan=p_pan; +} +float AudioEffectChorus::get_voice_pan(int p_voice) const{ + + ERR_FAIL_INDEX_V(p_voice,MAX_VOICES,0); + + return voice[p_voice].pan; +} + + +void AudioEffectChorus::set_wet(float amount){ + + + wet=amount; +} +float AudioEffectChorus::get_wet() const{ + + return wet; +} + +void AudioEffectChorus::set_dry(float amount){ + + dry=amount; + +} +float AudioEffectChorus::get_dry() const{ + + return dry; +} + +void AudioEffectChorus::_validate_property(PropertyInfo& property) const { + + if (property.name.begins_with("voice/")) { + int voice_idx = property.name.get_slice("/",1).to_int(); + if (voice_idx>voice_count) { + property.usage=0; + } + } +} + + +void AudioEffectChorus::_bind_methods() { + + ClassDB::bind_method(_MD("set_voice_count","voices"),&AudioEffectChorus::set_voice_count); + ClassDB::bind_method(_MD("get_voice_count"),&AudioEffectChorus::get_voice_count); + + + ClassDB::bind_method(_MD("set_voice_delay_ms","voice_idx","delay_ms"),&AudioEffectChorus::set_voice_delay_ms); + ClassDB::bind_method(_MD("get_voice_delay_ms","voice_idx"),&AudioEffectChorus::get_voice_delay_ms); + + ClassDB::bind_method(_MD("set_voice_rate_hz","voice_idx","rate_hz"),&AudioEffectChorus::set_voice_rate_hz); + ClassDB::bind_method(_MD("get_voice_rate_hz","voice_idx"),&AudioEffectChorus::get_voice_rate_hz); + + ClassDB::bind_method(_MD("set_voice_depth_ms","voice_idx","depth_ms"),&AudioEffectChorus::set_voice_depth_ms); + ClassDB::bind_method(_MD("get_voice_depth_ms","voice_idx"),&AudioEffectChorus::get_voice_depth_ms); + + ClassDB::bind_method(_MD("set_voice_level_db","voice_idx","level_db"),&AudioEffectChorus::set_voice_level_db); + ClassDB::bind_method(_MD("get_voice_level_db","voice_idx"),&AudioEffectChorus::get_voice_level_db); + + ClassDB::bind_method(_MD("set_voice_cutoff_hz","voice_idx","cutoff_hz"),&AudioEffectChorus::set_voice_cutoff_hz); + ClassDB::bind_method(_MD("get_voice_cutoff_hz","voice_idx"),&AudioEffectChorus::get_voice_cutoff_hz); + + ClassDB::bind_method(_MD("set_voice_pan","voice_idx","pan"),&AudioEffectChorus::set_voice_pan); + ClassDB::bind_method(_MD("get_voice_pan","voice_idx"),&AudioEffectChorus::get_voice_pan); + + ClassDB::bind_method(_MD("set_wet","amount"),&AudioEffectChorus::set_wet); + ClassDB::bind_method(_MD("get_wet"),&AudioEffectChorus::get_wet); + + ClassDB::bind_method(_MD("set_dry","amount"),&AudioEffectChorus::set_dry); + ClassDB::bind_method(_MD("get_dry"),&AudioEffectChorus::get_dry); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"voice_count",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("set_voice_count"),_SCS("get_voice_count")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dry",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_dry"),_SCS("get_dry")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"wet",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_wet"),_SCS("get_wet")); + + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/delay_ms",PROPERTY_HINT_RANGE,"0,50,0.01"),_SCS("set_voice_delay_ms"),_SCS("get_voice_delay_ms"),0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/rate_hz",PROPERTY_HINT_RANGE,"0.1,20,0.1"),_SCS("set_voice_rate_hz"),_SCS("get_voice_rate_hz"),0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/depth_ms",PROPERTY_HINT_RANGE,"0,20,0.01"),_SCS("set_voice_depth_ms"),_SCS("get_voice_depth_ms"),0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/level_db",PROPERTY_HINT_RANGE,"-60,24,0.1"),_SCS("set_voice_level_db"),_SCS("get_voice_level_db"),0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/cutoff_hz",PROPERTY_HINT_RANGE,"1,16000,1"),_SCS("set_voice_cutoff_hz"),_SCS("get_voice_cutoff_hz"),0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/1/pan",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_voice_pan"),_SCS("get_voice_pan"),0); + + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/delay_ms",PROPERTY_HINT_RANGE,"0,50,0.01"),_SCS("set_voice_delay_ms"),_SCS("get_voice_delay_ms"),1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/rate_hz",PROPERTY_HINT_RANGE,"0.1,20,0.1"),_SCS("set_voice_rate_hz"),_SCS("get_voice_rate_hz"),1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/depth_ms",PROPERTY_HINT_RANGE,"0,20,0.01"),_SCS("set_voice_depth_ms"),_SCS("get_voice_depth_ms"),1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/level_db",PROPERTY_HINT_RANGE,"-60,24,0.1"),_SCS("set_voice_level_db"),_SCS("get_voice_level_db"),1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/cutoff_hz",PROPERTY_HINT_RANGE,"1,16000,1"),_SCS("set_voice_cutoff_hz"),_SCS("get_voice_cutoff_hz"),1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/2/pan",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_voice_pan"),_SCS("get_voice_pan"),1); + + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/delay_ms",PROPERTY_HINT_RANGE,"0,50,0.01"),_SCS("set_voice_delay_ms"),_SCS("get_voice_delay_ms"),2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/rate_hz",PROPERTY_HINT_RANGE,"0.1,20,0.1"),_SCS("set_voice_rate_hz"),_SCS("get_voice_rate_hz"),2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/depth_ms",PROPERTY_HINT_RANGE,"0,20,0.01"),_SCS("set_voice_depth_ms"),_SCS("get_voice_depth_ms"),2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/level_db",PROPERTY_HINT_RANGE,"-60,24,0.1"),_SCS("set_voice_level_db"),_SCS("get_voice_level_db"),2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/cutoff_hz",PROPERTY_HINT_RANGE,"1,16000,1"),_SCS("set_voice_cutoff_hz"),_SCS("get_voice_cutoff_hz"),2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/3/pan",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_voice_pan"),_SCS("get_voice_pan"),2); + + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/delay_ms",PROPERTY_HINT_RANGE,"0,50,0.01"),_SCS("set_voice_delay_ms"),_SCS("get_voice_delay_ms"),3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/rate_hz",PROPERTY_HINT_RANGE,"0.1,20,0.1"),_SCS("set_voice_rate_hz"),_SCS("get_voice_rate_hz"),3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/depth_ms",PROPERTY_HINT_RANGE,"0,20,0.01"),_SCS("set_voice_depth_ms"),_SCS("get_voice_depth_ms"),3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/level_db",PROPERTY_HINT_RANGE,"-60,24,0.1"),_SCS("set_voice_level_db"),_SCS("get_voice_level_db"),3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/cutoff_hz",PROPERTY_HINT_RANGE,"1,16000,1"),_SCS("set_voice_cutoff_hz"),_SCS("get_voice_cutoff_hz"),3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL,"voice/4/pan",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_voice_pan"),_SCS("get_voice_pan"),3); + +} + +AudioEffectChorus::AudioEffectChorus() +{ + voice_count=2; + voice[0].delay=15; + voice[1].delay=20; + voice[0].rate=0.8; + voice[1].rate=1.2; + voice[0].depth=2; + voice[1].depth=3; + voice[0].cutoff=8000; + voice[1].cutoff=8000; + voice[0].pan=-0.5; + voice[1].pan=0.5; + + wet=0.5; + dry=1.0; +} diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h new file mode 100644 index 0000000000..4cfba5d61a --- /dev/null +++ b/servers/audio/effects/audio_effect_chorus.h @@ -0,0 +1,115 @@ +#ifndef AUDIOEFFECTCHORUS_H +#define AUDIOEFFECTCHORUS_H + + +#include "servers/audio/audio_effect.h" + +class AudioEffectChorus; + +class AudioEffectChorusInstance : public AudioEffectInstance { + GDCLASS(AudioEffectChorusInstance,AudioEffectInstance) +friend class AudioEffectChorus; + Ref<AudioEffectChorus> base; + + Vector<AudioFrame> audio_buffer; + unsigned int buffer_pos; + unsigned int buffer_mask; + + AudioFrame filter_h[4]; + uint64_t cycles[4]; + + void _process_chunk(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count); + +public: + + virtual void process(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count); + +}; + + +class AudioEffectChorus : public AudioEffect { + GDCLASS(AudioEffectChorus,AudioEffect) + +friend class AudioEffectChorusInstance; +public: + enum { + + MAX_DELAY_MS=50, + MAX_DEPTH_MS=20, + MAX_WIDTH_MS=50, + MAX_VOICES=4, + CYCLES_FRAC=16, + CYCLES_MASK=(1<<CYCLES_FRAC)-1, + MAX_CHANNELS=4, + MS_CUTOFF_MAX=16000 + }; + +private: + + struct Voice { + + float delay; + float rate; + float depth; + float level; + float cutoff; + float pan; + + Voice() { + + delay=12.0; + rate=1; + depth=0; + level=0; + cutoff=MS_CUTOFF_MAX; + pan=0; + + } + + } voice[MAX_VOICES]; + + int voice_count; + + float wet; + float dry; + + +protected: + void _validate_property(PropertyInfo& property) const; + + static void _bind_methods(); +public: + + void set_voice_count(int p_voices); + int get_voice_count() const; + + void set_voice_delay_ms(int p_voice,float p_delay_ms); + float get_voice_delay_ms(int p_voice) const; + + void set_voice_rate_hz(int p_voice,float p_rate_hz); + float get_voice_rate_hz(int p_voice) const; + + void set_voice_depth_ms(int p_voice,float p_depth_ms); + float get_voice_depth_ms(int p_voice) const; + + void set_voice_level_db(int p_voice,float p_level_db); + float get_voice_level_db(int p_voice) const; + + void set_voice_cutoff_hz(int p_voice,float p_cutoff_hz); + float get_voice_cutoff_hz(int p_voice) const; + + void set_voice_pan(int p_voice,float p_pan); + float get_voice_pan(int p_voice) const; + + void set_wet(float amount); + float get_wet() const; + + void set_dry(float amount); + float get_dry() const; + + Ref<AudioEffectInstance> instance(); + + AudioEffectChorus(); +}; + +#endif // AUDIOEFFECTCHORUS_H diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp new file mode 100644 index 0000000000..e296b0d998 --- /dev/null +++ b/servers/audio/effects/audio_effect_panner.cpp @@ -0,0 +1,47 @@ +#include "audio_effect_panner.h" + + +void AudioEffectPannerInstance::process(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count) { + + + float lvol = CLAMP( 1.0 - base->pan, 0, 1); + float rvol = CLAMP( 1.0 + base->pan, 0, 1); + + for(int i=0;i<p_frame_count;i++) { + + p_dst_frames[i].l = p_src_frames[i].l * lvol + p_src_frames[i].r * (1.0 - rvol); + p_dst_frames[i].r = p_src_frames[i].r * rvol + p_src_frames[i].l * (1.0 - lvol); + + } + +} + + +Ref<AudioEffectInstance> AudioEffectPanner::instance() { + Ref<AudioEffectPannerInstance> ins; + ins.instance(); + ins->base=Ref<AudioEffectPanner>(this); + return ins; +} + +void AudioEffectPanner::set_pan(float p_cpanume) { + pan=p_cpanume; +} + +float AudioEffectPanner::get_pan() const { + + return pan; +} + +void AudioEffectPanner::_bind_methods() { + + ClassDB::bind_method(_MD("set_pan","cpanume"),&AudioEffectPanner::set_pan); + ClassDB::bind_method(_MD("get_pan"),&AudioEffectPanner::get_pan); + + ADD_PROPERTY(PropertyInfo(Variant::REAL,"pan",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_pan"),_SCS("get_pan")); +} + +AudioEffectPanner::AudioEffectPanner() +{ + pan=0; +} diff --git a/servers/audio/effects/audio_effect_panner.h b/servers/audio/effects/audio_effect_panner.h new file mode 100644 index 0000000000..bc1bb00815 --- /dev/null +++ b/servers/audio/effects/audio_effect_panner.h @@ -0,0 +1,40 @@ +#ifndef AUDIOEFFECTPANNER_H +#define AUDIOEFFECTPANNER_H + +#include "servers/audio/audio_effect.h" + +class AudioEffectPanner; + +class AudioEffectPannerInstance : public AudioEffectInstance { + GDCLASS(AudioEffectPannerInstance,AudioEffectInstance) +friend class AudioEffectPanner; + Ref<AudioEffectPanner> base; + +public: + + virtual void process(const AudioFrame *p_src_frames,AudioFrame *p_dst_frames,int p_frame_count); + +}; + + +class AudioEffectPanner : public AudioEffect { + GDCLASS(AudioEffectPanner,AudioEffect) + +friend class AudioEffectPannerInstance; + float pan; + +protected: + + static void _bind_methods(); +public: + + + Ref<AudioEffectInstance> instance(); + void set_pan(float p_volume); + float get_pan() const; + + AudioEffectPanner(); +}; + + +#endif // AUDIOEFFECTPANNER_H diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index d336bd7b6c..4a1758bbee 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -43,6 +43,8 @@ #include "audio/effects/audio_effect_eq.h" #include "audio/effects/audio_effect_distortion.h" #include "audio/effects/audio_effect_stereo_enhance.h" +#include "audio/effects/audio_effect_panner.h" +#include "audio/effects/audio_effect_chorus.h" static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsage>* r_usage) { @@ -79,25 +81,32 @@ void register_server_types() { ClassDB::register_virtual_class<AudioStreamPlayback>(); ClassDB::register_virtual_class<AudioEffect>(); - ClassDB::register_class<AudioEffectAmplify>(); + { + //audio effects + ClassDB::register_class<AudioEffectAmplify>(); - ClassDB::register_class<AudioEffectReverb>(); + ClassDB::register_class<AudioEffectReverb>(); - ClassDB::register_class<AudioEffectLowPass>(); - ClassDB::register_class<AudioEffectHighPass>(); - ClassDB::register_class<AudioEffectBandPass>(); - ClassDB::register_class<AudioEffectNotchPass>(); - ClassDB::register_class<AudioEffectBandLimit>(); - ClassDB::register_class<AudioEffectLowShelf>(); - ClassDB::register_class<AudioEffectHighShelf>(); + ClassDB::register_class<AudioEffectLowPass>(); + ClassDB::register_class<AudioEffectHighPass>(); + ClassDB::register_class<AudioEffectBandPass>(); + ClassDB::register_class<AudioEffectNotchPass>(); + ClassDB::register_class<AudioEffectBandLimit>(); + ClassDB::register_class<AudioEffectLowShelf>(); + ClassDB::register_class<AudioEffectHighShelf>(); - ClassDB::register_class<AudioEffectEQ6>(); - ClassDB::register_class<AudioEffectEQ10>(); - ClassDB::register_class<AudioEffectEQ21>(); + ClassDB::register_class<AudioEffectEQ6>(); + ClassDB::register_class<AudioEffectEQ10>(); + ClassDB::register_class<AudioEffectEQ21>(); - ClassDB::register_class<AudioEffectDistortion>(); + ClassDB::register_class<AudioEffectDistortion>(); + + ClassDB::register_class<AudioEffectStereoEnhance>(); + + ClassDB::register_class<AudioEffectPanner>(); + ClassDB::register_class<AudioEffectChorus>(); + } - ClassDB::register_class<AudioEffectStereoEnhance>(); ClassDB::register_virtual_class<Physics2DDirectBodyState>(); ClassDB::register_virtual_class<Physics2DDirectSpaceState>(); |