diff options
Diffstat (limited to 'servers')
42 files changed, 380 insertions, 6670 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 6fe14b0fcb..6e0c0089ca 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -43,7 +43,7 @@ Error AudioDriverDummy::init() { mix_rate = 44100; - output_format = OUTPUT_STEREO; + speaker_mode = SPEAKER_MODE_STEREO; channels = 2; int latency = GLOBAL_DEF("audio/output_latency",25); @@ -97,16 +97,18 @@ int AudioDriverDummy::get_mix_rate() const { return mix_rate; }; -AudioDriverSW::OutputFormat AudioDriverDummy::get_output_format() const { +AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const { - return output_format; + return speaker_mode; }; + void AudioDriverDummy::lock() { if (!thread || !mutex) return; mutex->lock(); }; + void AudioDriverDummy::unlock() { if (!thread || !mutex) diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index c91a0db43a..78ec41ea09 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -29,13 +29,13 @@ #ifndef AUDIO_DRIVER_DUMMY_H #define AUDIO_DRIVER_DUMMY_H -#include "servers/audio/audio_server_sw.h" +#include "servers/audio_server.h" #include "core/os/thread.h" #include "core/os/mutex.h" -class AudioDriverDummy : public AudioDriverSW { +class AudioDriverDummy : public AudioDriver { Thread* thread; Mutex* mutex; @@ -46,7 +46,7 @@ class AudioDriverDummy : public AudioDriverSW { int buffer_size; unsigned int mix_rate; - OutputFormat output_format; + SpeakerMode speaker_mode; int channels; @@ -64,7 +64,7 @@ public: virtual Error init(); virtual void start(); virtual int get_mix_rate() const; - virtual OutputFormat get_output_format() const; + virtual SpeakerMode get_speaker_mode() const; virtual void lock(); virtual void unlock(); virtual void finish(); diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp new file mode 100644 index 0000000000..372c0cbc13 --- /dev/null +++ b/servers/audio/audio_effect.cpp @@ -0,0 +1,6 @@ +#include "audio_effect.h" + +AudioEffect::AudioEffect() +{ + +} diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h new file mode 100644 index 0000000000..2fcd22251b --- /dev/null +++ b/servers/audio/audio_effect.h @@ -0,0 +1,26 @@ +#ifndef AUDIOEFFECT_H +#define AUDIOEFFECT_H + +#include "audio_frame.h" +#include "resource.h" + + +class AudioEffectInstance : public Reference { + GDCLASS(AudioEffectInstance,Reference) + +public: + + virtual void process(AudioFrame *p_frames,int p_frame_count)=0; + +}; + + +class AudioEffect : public Resource { + GDCLASS(AudioEffect,Resource) +public: + + virtual Ref<AudioEffectInstance> instance()=0; + AudioEffect(); +}; + +#endif // AUDIOEFFECT_H diff --git a/servers/audio/audio_mixer_sw.cpp b/servers/audio/audio_mixer_sw.cpp deleted file mode 100644 index 0123b66430..0000000000 --- a/servers/audio/audio_mixer_sw.cpp +++ /dev/null @@ -1,1222 +0,0 @@ -/*************************************************************************/ -/* audio_mixer_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "audio_mixer_sw.h" -#include "print_string.h" -#include "os/os.h" -//TODO implement FAST_AUDIO macro - -#ifdef FAST_AUDIO -#define NO_REVERB -#endif - -template<class Depth,bool is_stereo,bool is_ima_adpcm,bool use_filter,bool use_fx,AudioMixerSW::InterpolationType type,AudioMixerSW::MixChannels mix_mode> -void AudioMixerSW::do_resample(const Depth* p_src, int32_t *p_dst, ResamplerState *p_state) { - - // this function will be compiled branchless by any decent compiler - - int32_t final,final_r,next,next_r; - int32_t *reverb_dst = p_state->reverb_buffer; - while (p_state->amount--) { - - int32_t pos=p_state->pos >> MIX_FRAC_BITS; - if (is_stereo && !is_ima_adpcm) - pos<<=1; - - if (is_ima_adpcm) { - - int sample_pos = pos + p_state->ima_adpcm[0].window_ofs; - - while(sample_pos>p_state->ima_adpcm[0].last_nibble) { - - - static const int16_t _ima_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 - }; - - static const int8_t _ima_adpcm_index_table[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 - }; - - for(int i=0;i<(is_stereo?2:1);i++) { - - - int16_t nibble,diff,step; - - p_state->ima_adpcm[i].last_nibble++; - const uint8_t *src_ptr=p_state->ima_adpcm[i].ptr; - - - uint8_t nbb = src_ptr[ (p_state->ima_adpcm[i].last_nibble>>1) * (is_stereo?2:1) + i ]; - nibble = (p_state->ima_adpcm[i].last_nibble&1)?(nbb>>4):(nbb&0xF); - step=_ima_adpcm_step_table[p_state->ima_adpcm[i].step_index]; - - - p_state->ima_adpcm[i].step_index += _ima_adpcm_index_table[nibble]; - if (p_state->ima_adpcm[i].step_index<0) - p_state->ima_adpcm[i].step_index=0; - if (p_state->ima_adpcm[i].step_index>88) - p_state->ima_adpcm[i].step_index=88; - - diff = step >> 3 ; - if (nibble & 1) - diff += step >> 2 ; - if (nibble & 2) - diff += step >> 1 ; - if (nibble & 4) - diff += step ; - if (nibble & 8) - diff = -diff ; - - p_state->ima_adpcm[i].predictor+=diff; - if (p_state->ima_adpcm[i].predictor<-0x8000) - p_state->ima_adpcm[i].predictor=-0x8000; - else if (p_state->ima_adpcm[i].predictor>0x7FFF) - p_state->ima_adpcm[i].predictor=0x7FFF; - - - /* store loop if there */ - if (p_state->ima_adpcm[i].last_nibble==p_state->ima_adpcm[i].loop_pos) { - - p_state->ima_adpcm[i].loop_step_index = p_state->ima_adpcm[i].step_index; - p_state->ima_adpcm[i].loop_predictor = p_state->ima_adpcm[i].predictor; - } - - //printf("%i - %i - pred %i\n",int(p_state->ima_adpcm[i].last_nibble),int(nibble),int(p_state->ima_adpcm[i].predictor)); - - } - - } - - final=p_state->ima_adpcm[0].predictor; - if (is_stereo) { - final_r=p_state->ima_adpcm[1].predictor; - } - - } else { - final=p_src[pos]; - if (is_stereo) - final_r=p_src[pos+1]; - - if (sizeof(Depth)==1) { /* conditions will not exist anymore when compiled! */ - final<<=8; - if (is_stereo) - final_r<<=8; - } - - if (type==INTERPOLATION_LINEAR) { - - if (is_stereo) { - - next=p_src[pos+2]; - next_r=p_src[pos+3]; - } else { - next=p_src[pos+1]; - } - - if (sizeof(Depth)==1) { - next<<=8; - if (is_stereo) - next_r<<=8; - } - - int32_t frac=int32_t(p_state->pos&MIX_FRAC_MASK); - - final=final+((next-final)*frac >> MIX_FRAC_BITS); - if (is_stereo) - final_r=final_r+((next_r-final_r)*frac >> MIX_FRAC_BITS); - } - } - - if (use_filter) { - - Channel::Mix::Filter *f = p_state->filter_l; - float finalf=final; - float pre = finalf; - finalf = ((finalf*p_state->coefs.b0) + (f->hb[0]*p_state->coefs.b1) + (f->hb[1]*p_state->coefs.b2) + (f->ha[0]*p_state->coefs.a1) + (f->ha[1]*p_state->coefs.a2) - ); - - f->ha[1]=f->ha[0]; - f->hb[1]=f->hb[0]; - f->hb[0]=pre; - f->ha[0]=finalf; - - final=Math::fast_ftoi(finalf); - - if (is_stereo) { - - f = p_state->filter_r; - finalf=final_r; - pre = finalf; - finalf = ((finalf*p_state->coefs.b0) + (f->hb[0]*p_state->coefs.b1) + (f->hb[1]*p_state->coefs.b2) + (f->ha[0]*p_state->coefs.a1) + (f->ha[1]*p_state->coefs.a2) - ); - f->ha[1]=f->ha[0]; - f->hb[1]=f->hb[0]; - f->hb[0]=pre; - f->ha[0]=finalf; - - final_r=Math::fast_ftoi(finalf); - - } - - p_state->coefs.b0+=p_state->coefs_inc.b0; - p_state->coefs.b1+=p_state->coefs_inc.b1; - p_state->coefs.b2+=p_state->coefs_inc.b2; - p_state->coefs.a1+=p_state->coefs_inc.a1; - p_state->coefs.a2+=p_state->coefs_inc.a2; - } - - if (!is_stereo) { - final_r=final; //copy to right channel if stereo - } - - //convert back to 24 bits and mix to buffers - - if (mix_mode==MIX_STEREO) { - *p_dst++ +=(final*(p_state->vol[0]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *p_dst++ +=(final_r*(p_state->vol[1]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - - p_state->vol[0]+=p_state->vol_inc[0]; - p_state->vol[1]+=p_state->vol_inc[1]; - - if (use_fx) { - *reverb_dst++ +=(final*(p_state->reverb_vol[0]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *reverb_dst++ +=(final_r*(p_state->reverb_vol[1]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - p_state->reverb_vol[0]+=p_state->reverb_vol_inc[0]; - p_state->reverb_vol[1]+=p_state->reverb_vol_inc[1]; - } - - - } else if (mix_mode==MIX_QUAD) { - - *p_dst++ +=(final*(p_state->vol[0]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *p_dst++ +=(final_r*(p_state->vol[1]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - - *p_dst++ +=(final*(p_state->vol[2]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *p_dst++ +=(final_r*(p_state->vol[3]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - - p_state->vol[0]+=p_state->vol_inc[0]; - p_state->vol[1]+=p_state->vol_inc[1]; - p_state->vol[2]+=p_state->vol_inc[2]; - p_state->vol[3]+=p_state->vol_inc[3]; - - if (use_fx) { - *reverb_dst++ +=(final*(p_state->reverb_vol[0]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *reverb_dst++ +=(final_r*(p_state->reverb_vol[1]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *reverb_dst++ +=(final*(p_state->reverb_vol[2]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - *reverb_dst++ +=(final_r*(p_state->reverb_vol[3]>>MIX_VOLRAMP_FRAC_BITS))>>MIX_VOL_MOVE_TO_24; - p_state->reverb_vol[0]+=p_state->reverb_vol_inc[0]; - p_state->reverb_vol[1]+=p_state->reverb_vol_inc[1]; - p_state->reverb_vol[2]+=p_state->reverb_vol_inc[2]; - p_state->reverb_vol[3]+=p_state->reverb_vol_inc[3]; - } - } - - p_state->pos+=p_state->increment; - } -} - - -void AudioMixerSW::mix_channel(Channel& c) { - - - if (!sample_manager->is_sample(c.sample)) { - // sample is gone! - c.active=false; - return; - } - - - /* some 64-bit fixed point precaches */ - - int64_t loop_begin_fp=((int64_t)sample_manager->sample_get_loop_begin(c.sample) << MIX_FRAC_BITS); - int64_t loop_end_fp=((int64_t)sample_manager->sample_get_loop_end(c.sample) << MIX_FRAC_BITS); - int64_t length_fp=((int64_t)sample_manager->sample_get_length(c.sample) << MIX_FRAC_BITS); - int64_t begin_limit=(sample_manager->sample_get_loop_format(c.sample)!=AS::SAMPLE_LOOP_NONE)?loop_begin_fp:0; - int64_t end_limit=(sample_manager->sample_get_loop_format(c.sample)!=AS::SAMPLE_LOOP_NONE)?loop_end_fp:length_fp; - bool is_stereo=sample_manager->sample_is_stereo(c.sample); - - int32_t todo=mix_chunk_size; - //int mixed=0; - bool use_filter=false; - - ResamplerState rstate; - - /* compute voume ramps, increment, etc */ - - - - for(int i=0;i<mix_channels;i++) { - c.mix.old_vol[i]=c.mix.vol[i]; - c.mix.old_reverb_vol[i]=c.mix.reverb_vol[i]; - c.mix.old_chorus_vol[i]=c.mix.chorus_vol[i]; - } - - float vol = c.vol*channel_nrg; - - float reverb_vol = c.reverb_send*channel_nrg; - float chorus_vol = c.chorus_send*channel_nrg; - - if (mix_channels==2) { - //stereo pan - float pan = c.pan * 0.5 + 0.5; - float panv[2]={ - (1.0 - pan)*(1<<MIX_VOL_FRAC_BITS), - (pan)*(1<<MIX_VOL_FRAC_BITS) - }; - - for(int i=0;i<2;i++) { - - c.mix.vol[i]=Math::fast_ftoi(vol*panv[i]); - c.mix.reverb_vol[i]=Math::fast_ftoi(reverb_vol*panv[i]); - c.mix.chorus_vol[i]=Math::fast_ftoi(chorus_vol*panv[i]); - } - - } else { - //qudra pan - float panx = c.pan * 0.5 + 0.5; - float pany = c.depth * 0.5 + 0.5; - // with this model every speaker plays at 0.25 energy at the center.. i'm not sure if it's correct but it seems to be balanced - float panv[4]={ - (1.0-pany)*(1.0-panx)*(1<<MIX_VOL_FRAC_BITS), - (1.0-pany)*( panx)*(1<<MIX_VOL_FRAC_BITS), - ( pany)*(1.0-panx)*(1<<MIX_VOL_FRAC_BITS), - ( pany)*( panx)*(1<<MIX_VOL_FRAC_BITS) - }; - - for(int i=0;i<4;i++) { - - c.mix.vol[i]=Math::fast_ftoi(vol*panv[i]); - c.mix.reverb_vol[i]=Math::fast_ftoi(reverb_vol*panv[i]); - c.mix.chorus_vol[i]=Math::fast_ftoi(chorus_vol*panv[i]); - } - - } - - if (c.first_mix) { // avoid ramp up - - for(int i=0;i<mix_channels;i++) { - c.mix.old_vol[i]=c.mix.vol[i]; - c.mix.old_reverb_vol[i]=c.mix.reverb_vol[i]; - c.mix.old_chorus_vol[i]=c.mix.chorus_vol[i]; - } - - c.first_mix=false; - } - - - - Channel::Filter::Coefs filter_coefs; - Channel::Filter::Coefs filter_inc; - - if (c.filter.type!=AudioMixer::FILTER_NONE) { - - filter_coefs=c.filter.old_coefs; - filter_inc.b0=(c.filter.coefs.b0-filter_coefs.b0)/(1<<mix_chunk_bits); - filter_inc.b1=(c.filter.coefs.b1-filter_coefs.b1)/(1<<mix_chunk_bits); - filter_inc.b2=(c.filter.coefs.b2-filter_coefs.b2)/(1<<mix_chunk_bits); - filter_inc.a1=(c.filter.coefs.a1-filter_coefs.a1)/(1<<mix_chunk_bits); - filter_inc.a2=(c.filter.coefs.a2-filter_coefs.a2)/(1<<mix_chunk_bits); - use_filter=true; - } - - if (c.mix.increment>0) - c.mix.increment=((int64_t)c.speed<<MIX_FRAC_BITS)/mix_rate; - else - c.mix.increment=-((int64_t)c.speed<<MIX_FRAC_BITS)/mix_rate; - - //volume ramp - - - for(int i=0;i<mix_channels;i++) { - rstate.vol_inc[i]=((c.mix.vol[i]-c.mix.old_vol[i])<<MIX_VOLRAMP_FRAC_BITS)>>mix_chunk_bits; - rstate.vol[i]=c.mix.old_vol[i]<<MIX_VOLRAMP_FRAC_BITS; - rstate.reverb_vol_inc[i]=((c.mix.reverb_vol[i]-c.mix.old_reverb_vol[i])<<MIX_VOLRAMP_FRAC_BITS)>>mix_chunk_bits; - rstate.reverb_vol[i]=c.mix.old_reverb_vol[i]<<MIX_VOLRAMP_FRAC_BITS; - rstate.chorus_vol_inc[i]=((c.mix.chorus_vol[i]-c.mix.old_chorus_vol[i])<<MIX_VOLRAMP_FRAC_BITS)>>mix_chunk_bits; - rstate.chorus_vol[i]=c.mix.old_chorus_vol[i]<<MIX_VOLRAMP_FRAC_BITS; - } - - - //looping - - AS::SampleLoopFormat loop_format=sample_manager->sample_get_loop_format(c.sample); - AS::SampleFormat format=sample_manager->sample_get_format(c.sample); - - bool use_fx=false; - - if (fx_enabled) { - - for(int i=0;i<mix_channels;i++) { - if (c.mix.old_reverb_vol[i] || c.mix.reverb_vol[i] || c.mix.old_chorus_vol[i] || c.mix.chorus_vol[i] ) { - use_fx=true; - break; - } - } - } - - /* audio data */ - - const void *data=sample_manager->sample_get_data_ptr(c.sample); - int32_t *dst_buff=mix_buffer; - -#ifndef NO_REVERB - rstate.reverb_buffer=reverb_state[c.reverb_room].buffer; -#endif - - /* @TODO validar loops al registrar? */ - - rstate.coefs=filter_coefs; - rstate.coefs_inc=filter_inc; - rstate.filter_l=&c.mix.filter_l; - rstate.filter_r=&c.mix.filter_r; - - if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) { - - rstate.ima_adpcm=c.mix.ima_adpcm; - if (loop_format!=AS::SAMPLE_LOOP_NONE) { - c.mix.ima_adpcm[0].loop_pos=loop_begin_fp>>MIX_FRAC_BITS; - c.mix.ima_adpcm[1].loop_pos=loop_begin_fp>>MIX_FRAC_BITS; - loop_format=AS::SAMPLE_LOOP_FORWARD; - } - } - - while (todo>0) { - - int64_t limit=0; - int32_t target=0,aux=0; - - /** LOOP CHECKING **/ - - if ( c.mix.increment < 0 ) { - /* going backwards */ - - if ( loop_format!=AS::SAMPLE_LOOP_NONE && c.mix.offset < loop_begin_fp ) { - /* loopstart reached */ - if ( loop_format==AS::SAMPLE_LOOP_PING_PONG ) { - /* bounce ping pong */ - c.mix.offset= loop_begin_fp + ( loop_begin_fp-c.mix.offset ); - c.mix.increment=-c.mix.increment; - } else { - /* go to loop-end */ - c.mix.offset=loop_end_fp-(loop_begin_fp-c.mix.offset); - } - } else { - /* check for sample not reaching begining */ - if(c.mix.offset < 0) { - - c.active=false; - break; - } - } - } else { - /* going forward */ - if( loop_format!=AS::SAMPLE_LOOP_NONE && c.mix.offset >= loop_end_fp ) { - /* loopend reached */ - - if ( loop_format==AS::SAMPLE_LOOP_PING_PONG ) { - /* bounce ping pong */ - c.mix.offset=loop_end_fp-(c.mix.offset-loop_end_fp); - c.mix.increment=-c.mix.increment; - } else { - /* go to loop-begin */ - - if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) { - for(int i=0;i<2;i++) { - c.mix.ima_adpcm[i].step_index=c.mix.ima_adpcm[i].loop_step_index; - c.mix.ima_adpcm[i].predictor=c.mix.ima_adpcm[i].loop_predictor; - c.mix.ima_adpcm[i].last_nibble=loop_begin_fp>>MIX_FRAC_BITS; - } - c.mix.offset=loop_begin_fp; - } else { - c.mix.offset=loop_begin_fp+(c.mix.offset-loop_end_fp); - } - - } - } else { - /* no loop, check for end of sample */ - if(c.mix.offset >= length_fp) { - - c.active=false; - break; - } - } - } - - /** MIXCOUNT COMPUTING **/ - - /* next possible limit (looppoints or sample begin/end */ - limit=(c.mix.increment < 0) ?begin_limit:end_limit; - - /* compute what is shorter, the todo or the limit? */ - aux=(limit-c.mix.offset)/c.mix.increment+1; - target=(aux<todo)?aux:todo; /* mix target is the shorter buffer */ - - /* check just in case */ - if ( target<=0 ) { - c.active=false; - break; - } - - todo-=target; - - int32_t offset=c.mix.offset&mix_chunk_mask; /* strip integer */ - c.mix.offset-=offset; - - rstate.increment=c.mix.increment; - rstate.amount=target; - rstate.pos=offset; - -/* Macros to call the resample function for all possibilities, creating a dedicated-non branchy function call for each thanks to template magic*/ - -#define CALL_RESAMPLE_FUNC( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - do_resample<m_depth,m_stereo,m_ima_adpcm, m_use_filter,m_use_fx,m_interp, m_mode>(\ - src_ptr,\ - dst_buff,&rstate); - - -#define CALL_RESAMPLE_INTERP( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - if(m_interp==INTERPOLATION_RAW) {\ - CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_RAW,m_mode);\ - } else if(m_interp==INTERPOLATION_LINEAR) {\ - CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_LINEAR,m_mode);\ - } else if(m_interp==INTERPOLATION_CUBIC) {\ - CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_CUBIC,m_mode);\ - }\ - -#define CALL_RESAMPLE_FX( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - if(m_use_fx) {\ - CALL_RESAMPLE_INTERP(m_depth,m_stereo, m_ima_adpcm,m_use_filter,true,m_interp, m_mode);\ - } else {\ - CALL_RESAMPLE_INTERP(m_depth,m_stereo, m_ima_adpcm,m_use_filter,false,m_interp, m_mode);\ - }\ - - -#define CALL_RESAMPLE_FILTER( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - if(m_use_filter) {\ - CALL_RESAMPLE_FX(m_depth,m_stereo, m_ima_adpcm,true,m_use_fx,m_interp, m_mode);\ - } else {\ - CALL_RESAMPLE_FX(m_depth,m_stereo, m_ima_adpcm,false,m_use_fx,m_interp, m_mode);\ - }\ - -#define CALL_RESAMPLE_STEREO( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - if(m_stereo) {\ - CALL_RESAMPLE_FILTER(m_depth,true,m_ima_adpcm, m_use_filter,m_use_fx,m_interp, m_mode);\ - } else {\ - CALL_RESAMPLE_FILTER(m_depth,false,m_ima_adpcm,m_use_filter,m_use_fx,m_interp, m_mode);\ - }\ - -#define CALL_RESAMPLE_MODE( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\ - if(m_mode==MIX_STEREO) {\ - CALL_RESAMPLE_STEREO(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,m_interp, MIX_STEREO);\ - } else {\ - CALL_RESAMPLE_STEREO(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,m_interp, MIX_QUAD);\ - }\ - - - - - if (format==AS::SAMPLE_FORMAT_PCM8) { - - int8_t *src_ptr = &((int8_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ]; - CALL_RESAMPLE_MODE(int8_t,is_stereo,false,use_filter,use_fx,interpolation_type,mix_channels); - - } else if (format==AS::SAMPLE_FORMAT_PCM16) { - int16_t *src_ptr = &((int16_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ]; - CALL_RESAMPLE_MODE(int16_t,is_stereo,false,use_filter,use_fx,interpolation_type,mix_channels); - - } else if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) { - for(int i=0;i<2;i++) { - c.mix.ima_adpcm[i].window_ofs=c.mix.offset>>MIX_FRAC_BITS; - c.mix.ima_adpcm[i].ptr=(const uint8_t*)data; - } - int8_t *src_ptr = NULL; - CALL_RESAMPLE_MODE(int8_t,is_stereo,true,use_filter,use_fx,interpolation_type,mix_channels); - - } - - c.mix.offset+=rstate.pos; - dst_buff+=target*mix_channels; - rstate.reverb_buffer+=target*mix_channels; - } - - c.filter.old_coefs=c.filter.coefs; -} - -void AudioMixerSW::mix_chunk() { - - ERR_FAIL_COND(mix_chunk_left); - - inside_mix=true; - - // emit tick in usecs - for (int i=0;i<mix_chunk_size*mix_channels;i++) { - - mix_buffer[i]=0; - } -#ifndef NO_REVERB - for(int i=0;i<max_reverbs;i++) - reverb_state[i].used_in_chunk=false; -#endif - - - audio_mixer_chunk_call(mix_chunk_size); - - int ac=0; - for (int i=0;i<MAX_CHANNELS;i++) { - - if (!channels[i].active) - continue; - ac++; - - /* process volume */ - Channel&c=channels[i]; -#ifndef NO_REVERB - bool has_reverb = c.reverb_send>CMP_EPSILON && fx_enabled; - if (has_reverb || c.had_prev_reverb) { - - if (!reverb_state[c.reverb_room].used_in_chunk) { - //zero the room - int32_t *buff = reverb_state[c.reverb_room].buffer; - int len = mix_chunk_size*mix_channels; - for (int j=0;j<len;j++) { - - buff[j]=0; // buffer in use, clear it for appending - } - reverb_state[c.reverb_room].used_in_chunk=true; - } - } -#else - bool has_reverb = false; -#endif - bool has_chorus = c.chorus_send>CMP_EPSILON && fx_enabled; - - - mix_channel(c); - - c.had_prev_reverb=has_reverb; - c.had_prev_chorus=has_chorus; - - } - - //process reverb -#ifndef NO_REVERB - if (fx_enabled) { - - - for(int i=0;i<max_reverbs;i++) { - - if (!reverb_state[i].enabled && !reverb_state[i].used_in_chunk) - continue; //this reverb is not in use - - int32_t *src=NULL; - - if (reverb_state[i].used_in_chunk) - src=reverb_state[i].buffer; - else - src=zero_buffer; - - bool in_use=false; - - int passes=mix_channels/2; - - for(int j=0;j<passes;j++) { - - if (reverb_state[i].reverb[j].process((int*)&src[j*2],(int*)&mix_buffer[j*2],mix_chunk_size,passes)) - in_use=true; - } - - if (in_use) { - reverb_state[i].enabled=true; - reverb_state[i].frames_idle=0; - //copy data over - - } else { - reverb_state[i].frames_idle+=mix_chunk_size; - if (false) { // go idle because too many frames passed - //disable this reverb, as nothing important happened on it - reverb_state[i].enabled=false; - reverb_state[i].frames_idle=0; - } - } - - } - } -#endif - mix_chunk_left=mix_chunk_size; - inside_mix=false; -} - -int AudioMixerSW::mix(int32_t *p_buffer,int p_frames) { - - int todo=p_frames; - int mixes=0; - - while(todo) { - - - if (!mix_chunk_left) { - - if (step_callback) - step_callback(step_udata); - mix_chunk(); - mixes++; - } - - int to_mix=MIN(mix_chunk_left,todo); - int from=mix_chunk_size-mix_chunk_left; - - for (int i=0;i<to_mix*2;i++) { - - (*p_buffer++)=mix_buffer[from*2+i]; - } - - mix_chunk_left-=to_mix; - todo-=to_mix; - } - - return mixes; -} - -uint64_t AudioMixerSW::get_step_usecs() const { - - double mct = (1<<mix_chunk_bits)/double(mix_rate); - return mct*1000000.0; -} - -int AudioMixerSW::_get_channel(ChannelID p_channel) const { - - if (p_channel<0) { - return -1; - } - - int idx=p_channel%MAX_CHANNELS; - int check=p_channel/MAX_CHANNELS; - ERR_FAIL_INDEX_V(idx,MAX_CHANNELS,-1); - if (channels[idx].check!=check) { - return -1; - } - if (!channels[idx].active) { - return -1; - } - - return idx; -} - -AudioMixer::ChannelID AudioMixerSW::channel_alloc(RID p_sample) { - - ERR_FAIL_COND_V( !sample_manager->is_sample(p_sample), INVALID_CHANNEL ); - - - int index=-1; - for (int i=0;i<MAX_CHANNELS;i++) { - - if (!channels[i].active) { - index=i; - break; - } - } - - if (index==-1) - return INVALID_CHANNEL; - - Channel &c=channels[index]; - - // init variables - c.sample=p_sample; - c.vol=1; - c.pan=0; - c.depth=0; - c.height=0; - c.chorus_send=0; - c.reverb_send=0; - c.reverb_room=REVERB_HALL; - c.positional=false; - c.filter.type=FILTER_NONE; - c.speed=sample_manager->sample_get_mix_rate(p_sample); - c.active=true; - c.check=channel_id_count++; - c.first_mix=true; - - // init mix variables - - c.mix.offset=0; - c.mix.increment=1; - //zero everything when this errors - for(int i=0;i<4;i++) { - c.mix.vol[i]=0; - c.mix.reverb_vol[i]=0; - c.mix.chorus_vol[i]=0; - - c.mix.old_vol[i]=0; - c.mix.old_reverb_vol[i]=0; - c.mix.old_chorus_vol[i]=0; - } - - c.had_prev_chorus=false; - c.had_prev_reverb=false; - c.had_prev_vol=false; - - - if (sample_manager->sample_get_format(c.sample)==AudioServer::SAMPLE_FORMAT_IMA_ADPCM) { - - for(int i=0;i<2;i++) { - c.mix.ima_adpcm[i].step_index=0; - c.mix.ima_adpcm[i].predictor=0; - c.mix.ima_adpcm[i].loop_step_index=0; - c.mix.ima_adpcm[i].loop_predictor=0; - c.mix.ima_adpcm[i].last_nibble=-1; - c.mix.ima_adpcm[i].loop_pos=0x7FFFFFFF; - c.mix.ima_adpcm[i].window_ofs=0; - c.mix.ima_adpcm[i].ptr=NULL; - } - } - - ChannelID ret_id = index+c.check*MAX_CHANNELS; - - return ret_id; - -} - -void AudioMixerSW::channel_set_volume(ChannelID p_channel, float p_gain) { - - if (p_gain>3) // avoid gain going too high - p_gain=3; - if (p_gain<0) - p_gain=0; - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - Channel &c = channels[chan]; - - //Math::exp( p_db * 0.11512925464970228420089957273422 ); - c.vol=p_gain; - -} - -void AudioMixerSW::channel_set_pan(ChannelID p_channel, float p_pan, float p_depth,float p_height) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - Channel &c = channels[chan]; - - c.pan=p_pan; - c.depth=p_depth; - c.height=p_height; - -} -void AudioMixerSW::channel_set_filter(ChannelID p_channel, FilterType p_type, float p_cutoff, float p_resonance, float p_gain) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c = channels[chan]; - - if (c.filter.type==p_type && c.filter.cutoff==p_cutoff && c.filter.resonance==p_resonance && c.filter.gain==p_gain) - return; //bye - - - bool type_changed = p_type!=c.filter.type; - - c.filter.type=p_type; - c.filter.cutoff=p_cutoff; - c.filter.resonance=p_resonance; - c.filter.gain=p_gain; - - - AudioFilterSW filter; - switch(p_type) { - case FILTER_NONE: { - - return; //do nothing else - } break; - case FILTER_LOWPASS: { - filter.set_mode(AudioFilterSW::LOWPASS); - } break; - case FILTER_BANDPASS: { - filter.set_mode(AudioFilterSW::BANDPASS); - } break; - case FILTER_HIPASS: { - filter.set_mode(AudioFilterSW::HIGHPASS); - } break; - case FILTER_NOTCH: { - filter.set_mode(AudioFilterSW::NOTCH); - } break; - case FILTER_PEAK: { - filter.set_mode(AudioFilterSW::PEAK); - } break; - case FILTER_BANDLIMIT: { - filter.set_mode(AudioFilterSW::BANDLIMIT); - } break; - case FILTER_LOW_SHELF: { - filter.set_mode(AudioFilterSW::LOWSHELF); - } break; - case FILTER_HIGH_SHELF: { - filter.set_mode(AudioFilterSW::HIGHSHELF); - } break; - } - - filter.set_cutoff(p_cutoff); - filter.set_resonance(p_resonance); - filter.set_gain(p_gain); - filter.set_sampling_rate(mix_rate); - filter.set_stages(1); - - AudioFilterSW::Coeffs coefs; - filter.prepare_coefficients(&coefs); - - if (!type_changed) - c.filter.old_coefs=c.filter.coefs; - - c.filter.coefs.b0=coefs.b0; - c.filter.coefs.b1=coefs.b1; - c.filter.coefs.b2=coefs.b2; - c.filter.coefs.a1=coefs.a1; - c.filter.coefs.a2=coefs.a2; - - - if (type_changed) { - //type changed reset filter - c.filter.old_coefs=c.filter.coefs; - c.mix.filter_l.ha[0]=0; - c.mix.filter_l.ha[1]=0; - c.mix.filter_l.hb[0]=0; - c.mix.filter_l.hb[1]=0; - c.mix.filter_r.ha[0]=0; - c.mix.filter_r.ha[1]=0; - c.mix.filter_r.hb[0]=0; - c.mix.filter_r.hb[1]=0; - } - - -} -void AudioMixerSW::channel_set_chorus(ChannelID p_channel, float p_chorus ) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c = channels[chan]; - c.chorus_send=p_chorus; - -} -void AudioMixerSW::channel_set_reverb(ChannelID p_channel, ReverbRoomType p_room_type, float p_reverb) { - - ERR_FAIL_INDEX(p_room_type,MAX_REVERBS); - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c = channels[chan]; - c.reverb_room=p_room_type; - c.reverb_send=p_reverb; - -} - -void AudioMixerSW::channel_set_mix_rate(ChannelID p_channel, int p_mix_rate) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c = channels[chan]; - c.speed=p_mix_rate; - -} -void AudioMixerSW::channel_set_positional(ChannelID p_channel, bool p_positional) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c = channels[chan]; - c.positional=p_positional; -} - -float AudioMixerSW::channel_get_volume(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - //Math::log( c.vol ) * 8.6858896380650365530225783783321; - return c.vol; -} - -float AudioMixerSW::channel_get_pan(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.pan; -} -float AudioMixerSW::channel_get_pan_depth(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.depth; -} -float AudioMixerSW::channel_get_pan_height(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.height; - -} -AudioMixer::FilterType AudioMixerSW::channel_get_filter_type(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return FILTER_NONE; - - const Channel &c = channels[chan]; - return c.filter.type; -} -float AudioMixerSW::channel_get_filter_cutoff(ChannelID p_channel) const { - - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.filter.cutoff; - -} -float AudioMixerSW::channel_get_filter_resonance(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.filter.resonance; - -} - -float AudioMixerSW::channel_get_filter_gain(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.filter.gain; -} - - -float AudioMixerSW::channel_get_chorus(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.chorus_send; - -} -AudioMixer::ReverbRoomType AudioMixerSW::channel_get_reverb_type(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return REVERB_HALL; - - const Channel &c = channels[chan]; - return c.reverb_room; - -} -float AudioMixerSW::channel_get_reverb(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.reverb_send; -} - -int AudioMixerSW::channel_get_mix_rate(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return 0; - - const Channel &c = channels[chan]; - return c.speed; -} -bool AudioMixerSW::channel_is_positional(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return false; - - const Channel &c = channels[chan]; - return c.positional; -} - -bool AudioMixerSW::channel_is_valid(ChannelID p_channel) const { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return false; - return channels[chan].active; -} - - -void AudioMixerSW::channel_free(ChannelID p_channel) { - - int chan = _get_channel(p_channel); - if (chan<0 || chan >=MAX_CHANNELS) - return; - - Channel &c=channels[chan]; - - if (!c.active) - return; - - bool has_vol=false; - - for(int i=0;i<mix_channels;i++) { - - if (c.mix.vol[i]) - has_vol=true; - if (c.mix.reverb_vol[i]) - has_vol=true; - if (c.mix.chorus_vol[i]) - has_vol=true; - } - if (c.active && has_vol && inside_mix) { - // drive voice to zero, and run a chunk, the VRAMP will fade it good - c.vol=0; - c.reverb_send=0; - c.chorus_send=0; - mix_channel(c); - } - /* @TODO RAMP DOWN ON STOP */ - c.active=false; -} - - - -AudioMixerSW::AudioMixerSW(SampleManagerSW *p_sample_manager,int p_desired_latency_ms,int p_mix_rate,MixChannels p_mix_channels,bool p_use_fx,InterpolationType p_interp,MixStepCallback p_step_callback,void *p_step_udata) { - - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("AudioServerSW Params: "); - print_line(" -mix chans: "+itos(p_mix_channels)); - print_line(" -mix rate: "+itos(p_mix_rate)); - print_line(" -latency: "+itos(p_desired_latency_ms)); - print_line(" -fx: "+itos(p_use_fx)); - print_line(" -interp: "+itos(p_interp)); - } - sample_manager=p_sample_manager; - mix_channels=p_mix_channels; - mix_rate=p_mix_rate; - step_callback=p_step_callback; - step_udata=p_step_udata; - - - mix_chunk_bits=nearest_shift( p_desired_latency_ms * p_mix_rate / 1000 ); - - mix_chunk_size=(1<<mix_chunk_bits); - mix_chunk_mask=mix_chunk_size-1; - mix_buffer = memnew_arr(int32_t,mix_chunk_size*mix_channels); -#ifndef NO_REVERB - zero_buffer = memnew_arr(int32_t,mix_chunk_size*mix_channels); - for(int i=0;i<mix_chunk_size*mix_channels;i++) - zero_buffer[i]=0; //zero buffer is zero... - - max_reverbs=MAX_REVERBS; - int reverberators=mix_channels/2; - - reverb_state = memnew_arr(ReverbState,max_reverbs); - for(int i=0;i<max_reverbs;i++) { - reverb_state[i].enabled=false; - reverb_state[i].reverb = memnew_arr(ReverbSW,reverberators); - reverb_state[i].buffer = memnew_arr(int32_t,mix_chunk_size*mix_channels); - reverb_state[i].frames_idle=0; - for(int j=0;j<reverberators;j++) { - static ReverbSW::ReverbMode modes[MAX_REVERBS]={ReverbSW::REVERB_MODE_STUDIO_SMALL,ReverbSW::REVERB_MODE_STUDIO_MEDIUM,ReverbSW::REVERB_MODE_STUDIO_LARGE,ReverbSW::REVERB_MODE_HALL}; - reverb_state[i].reverb[j].set_mix_rate(p_mix_rate); - reverb_state[i].reverb[j].set_mode(modes[i]); - } - - } - fx_enabled=p_use_fx; -#else - fx_enabled=false; -#endif - mix_chunk_left=0; - - interpolation_type=p_interp; - channel_id_count=1; - inside_mix=false; - channel_nrg=1.0; - -} - -void AudioMixerSW::set_mixer_volume(float p_volume) { - - channel_nrg=p_volume; -} - -AudioMixerSW::~AudioMixerSW() { - - memdelete_arr(mix_buffer); - -#ifndef NO_REVERB - memdelete_arr(zero_buffer); - for(int i=0;i<max_reverbs;i++) { - memdelete_arr(reverb_state[i].reverb); - memdelete_arr(reverb_state[i].buffer); - } - memdelete_arr(reverb_state); -#endif - - -} diff --git a/servers/audio/audio_mixer_sw.h b/servers/audio/audio_mixer_sw.h deleted file mode 100644 index 952cad4cfa..0000000000 --- a/servers/audio/audio_mixer_sw.h +++ /dev/null @@ -1,264 +0,0 @@ -/*************************************************************************/ -/* audio_mixer_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef AUDIO_MIXER_SW_H -#define AUDIO_MIXER_SW_H - -#include "servers/audio_server.h" -#include "servers/audio/sample_manager_sw.h" -#include "servers/audio/audio_filter_sw.h" -#include "servers/audio/reverb_sw.h" - -class AudioMixerSW : public AudioMixer { -public: - - enum InterpolationType { - - INTERPOLATION_RAW, - INTERPOLATION_LINEAR, - INTERPOLATION_CUBIC - }; - - enum MixChannels { - - MIX_STEREO=2, - MIX_QUAD=4 - }; - - typedef void (*MixStepCallback)(void*); - -private: - SampleManagerSW *sample_manager; - - enum { - - MAX_CHANNELS=64, - // fixed point defs - - MIX_FRAC_BITS=13, - MIX_FRAC_LEN=(1<<MIX_FRAC_BITS), - MIX_FRAC_MASK=MIX_FRAC_LEN-1, - MIX_VOL_FRAC_BITS=12, - MIX_VOLRAMP_FRAC_BITS=16, - MIX_VOLRAMP_FRAC_LEN=(1<<MIX_VOLRAMP_FRAC_BITS), - MIX_VOLRAMP_FRAC_MASK=MIX_VOLRAMP_FRAC_LEN-1, - MIX_FILTER_FRAC_BITS=16, - MIX_FILTER_RAMP_FRAC_BITS=8, - MIX_VOL_MOVE_TO_24=4 - }; - - - struct Channel { - - RID sample; - struct Mix { - int64_t offset; - int32_t increment; - - int32_t vol[4]; - int32_t reverb_vol[4]; - int32_t chorus_vol[4]; - - int32_t old_vol[4]; - int32_t old_reverb_vol[4]; - int32_t old_chorus_vol[4]; - - - struct Filter { //history (stereo) - float ha[2],hb[2]; - } filter_l,filter_r; - - struct IMA_ADPCM_State { - - int16_t step_index; - int32_t predictor; - /* values at loop point */ - int16_t loop_step_index; - int32_t loop_predictor; - int32_t last_nibble; - int32_t loop_pos; - int32_t window_ofs; - const uint8_t *ptr; - } ima_adpcm[2]; - - } mix; - - float vol; - float pan; - float depth; - float height; - - float chorus_send; - ReverbRoomType reverb_room; - float reverb_send; - int speed; - int check; - bool positional; - - bool had_prev_reverb; - bool had_prev_chorus; - bool had_prev_vol; - - struct Filter { - - bool dirty; - - FilterType type; - float cutoff; - float resonance; - float gain; - - struct Coefs { - - float a1,a2,b0,b1,b2; // fixed point coefficients - } coefs,old_coefs; - - } filter; - - bool first_mix; - bool active; - Channel() { active=false; check=-1; first_mix=false; filter.dirty=true; filter.type=FILTER_NONE; filter.cutoff=8000; filter.resonance=0; filter.gain=0; } - }; - - Channel channels[MAX_CHANNELS]; - - uint32_t mix_rate; - bool fx_enabled; - InterpolationType interpolation_type; - - int mix_chunk_bits; - int mix_chunk_size; - int mix_chunk_mask; - - int32_t *mix_buffer; - int32_t *zero_buffer; // fx feed when no input was mixed - - struct ResamplerState { - - uint32_t amount; - int32_t increment; - - - int32_t pos; - - - int32_t vol[4]; - int32_t reverb_vol[4]; - int32_t chorus_vol[4]; - - int32_t vol_inc[4]; - int32_t reverb_vol_inc[4]; - int32_t chorus_vol_inc[4]; - - - - Channel::Mix::Filter *filter_l; - Channel::Mix::Filter *filter_r; - Channel::Filter::Coefs coefs; - Channel::Filter::Coefs coefs_inc; - - Channel::Mix::IMA_ADPCM_State *ima_adpcm; - - int32_t *reverb_buffer; - }; - - - - template<class Depth,bool is_stereo,bool use_filter,bool is_ima_adpcm,bool use_fx,InterpolationType type,MixChannels> - _FORCE_INLINE_ void do_resample(const Depth* p_src, int32_t *p_dst, ResamplerState *p_state); - - MixChannels mix_channels; - - void mix_channel(Channel& p_channel); - int mix_chunk_left; - void mix_chunk(); - - float channel_nrg; - int channel_id_count; - bool inside_mix; - MixStepCallback step_callback; - void *step_udata; - _FORCE_INLINE_ int _get_channel(ChannelID p_channel) const; - - int max_reverbs; - struct ReverbState { - - bool used_in_chunk; - bool enabled; - ReverbSW *reverb; - int frames_idle; - int32_t *buffer; //reverb is sent here - ReverbState() { enabled=false; frames_idle=0; used_in_chunk=false; } - }; - - ReverbState *reverb_state; - - -public: - - - virtual ChannelID channel_alloc(RID p_sample); - - virtual void channel_set_volume(ChannelID p_channel, float p_gain); - virtual void channel_set_pan(ChannelID p_channel, float p_pan, float p_depth=0,float height=0); //pan and depth go from -1 to 1 - virtual void channel_set_filter(ChannelID p_channel, FilterType p_type, float p_cutoff, float p_resonance, float p_gain=1.0); - virtual void channel_set_chorus(ChannelID p_channel, float p_chorus ); - virtual void channel_set_reverb(ChannelID p_channel, ReverbRoomType p_room_type, float p_reverb); - virtual void channel_set_mix_rate(ChannelID p_channel, int p_mix_rate); - virtual void channel_set_positional(ChannelID p_channel, bool p_positional); - - virtual float channel_get_volume(ChannelID p_channel) const; - virtual float channel_get_pan(ChannelID p_channel) const; //pan and depth go from -1 to 1 - virtual float channel_get_pan_depth(ChannelID p_channel) const; //pan and depth go from -1 to 1 - virtual float channel_get_pan_height(ChannelID p_channel) const; //pan and depth go from -1 to 1 - virtual FilterType channel_get_filter_type(ChannelID p_channel) const; - virtual float channel_get_filter_cutoff(ChannelID p_channel) const; - virtual float channel_get_filter_resonance(ChannelID p_channel) const; - virtual float channel_get_filter_gain(ChannelID p_channel) const; - - virtual float channel_get_chorus(ChannelID p_channel) const; - virtual ReverbRoomType channel_get_reverb_type(ChannelID p_channel) const; - virtual float channel_get_reverb(ChannelID p_channel) const; - - virtual int channel_get_mix_rate(ChannelID p_channel) const; - virtual bool channel_is_positional(ChannelID p_channel) const; - - virtual bool channel_is_valid(ChannelID p_channel) const; - - virtual void channel_free(ChannelID p_channel); - - int mix(int32_t *p_buffer,int p_frames); //return amount of mixsteps - uint64_t get_step_usecs() const; - - virtual void set_mixer_volume(float p_volume); - - AudioMixerSW(SampleManagerSW *p_sample_manager,int p_desired_latency_ms,int p_mix_rate,MixChannels p_mix_channels,bool p_use_fx=true,InterpolationType p_interp=INTERPOLATION_LINEAR,MixStepCallback p_step_callback=NULL,void *p_callback_udata=NULL); - ~AudioMixerSW(); -}; - -#endif // AUDIO_MIXER_SW_H diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp deleted file mode 100644 index f508a130b4..0000000000 --- a/servers/audio/audio_server_sw.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/*************************************************************************/ -/* audio_server_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "audio_server_sw.h" -#include "globals.h" -#include "os/os.h" - -struct _AudioDriverLock { - - _AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->lock(); } - ~_AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->unlock(); } - -}; - -#define AUDIO_LOCK _AudioDriverLock _adlock; - -AudioMixer *AudioServerSW::get_mixer() { - - return mixer; -} - -/* CALLBACKS */ - -void AudioServerSW::audio_mixer_chunk_callback(int p_frames) { -/* - for(List<Stream*>::Element *E=event_streams.front();E;E=E->next()) { - - if (E->get()->active) - E->get()->audio_stream->mix(NULL,p_frames); - } -*/ -} - -void AudioServerSW::_mixer_callback(void *p_udata) { - - AudioServerSW *self = (AudioServerSW*)p_udata; - for(List<Stream*>::Element *E=self->active_audio_streams.front();E;E=E->next()) { - - if (!E->get()->active) - continue; - - EventStream *es=E->get()->event_stream; - if (!es) - continue; - - es->update(self->mixer_step_usecs); - } - -} - -void AudioServerSW::driver_process_chunk(int p_frames,int32_t *p_buffer) { - - - - int samples=p_frames*internal_buffer_channels; - - for(int i=0;i<samples;i++) { - internal_buffer[i]=0; - } - - while(voice_rb.commands_left()) { - - VoiceRBSW::Command cmd = voice_rb.pop_command(); - - if (cmd.type==VoiceRBSW::Command::CMD_CHANGE_ALL_FX_VOLUMES) { - - SelfList<Voice>*al = active_list.first(); - while(al) { - - Voice *v=al->self(); - if (v->channel!=AudioMixer::INVALID_CHANNEL) { - mixer->channel_set_volume(v->channel,v->volume*fx_volume_scale); - } - al=al->next(); - } - - continue; - } - if (!voice_owner.owns(cmd.voice)) - continue; - - - Voice *v = voice_owner.get(cmd.voice); - - switch(cmd.type) { - case VoiceRBSW::Command::CMD_NONE: { - - - } break; - case VoiceRBSW::Command::CMD_PLAY: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_free(v->channel); - - RID sample = cmd.play.sample; - if (!sample_manager->is_sample(sample)) - continue; - - v->channel=mixer->channel_alloc(sample); - v->volume=1.0; - mixer->channel_set_volume(v->channel,fx_volume_scale); - if (v->channel==AudioMixer::INVALID_CHANNEL) { -#ifdef AUDIO_DEBUG - WARN_PRINT("AUDIO: all channels used, failed to allocate voice"); -#endif - v->active=false; - break; // no voices left? - } - - v->active=true; // this kind of ensures it works - if (!v->active_item.in_list()) - active_list.add(&v->active_item); - - } break; - case VoiceRBSW::Command::CMD_STOP: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) { - mixer->channel_free(v->channel); - if (v->active_item.in_list()) { - active_list.remove(&v->active_item); - } - } - v->active=false; - } break; - case VoiceRBSW::Command::CMD_SET_VOLUME: { - - - if (v->channel!=AudioMixer::INVALID_CHANNEL) { - v->volume=cmd.volume.volume; - mixer->channel_set_volume(v->channel,cmd.volume.volume*fx_volume_scale); - } - - } break; - case VoiceRBSW::Command::CMD_SET_PAN: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_pan(v->channel,cmd.pan.pan,cmd.pan.depth,cmd.pan.height); - - } break; - case VoiceRBSW::Command::CMD_SET_FILTER: { - - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_filter(v->channel,(AudioMixer::FilterType)cmd.filter.type,cmd.filter.cutoff,cmd.filter.resonance,cmd.filter.gain); - } break; - case VoiceRBSW::Command::CMD_SET_CHORUS: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_chorus(v->channel,cmd.chorus.send); - - } break; - case VoiceRBSW::Command::CMD_SET_REVERB: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_reverb(v->channel,(AudioMixer::ReverbRoomType)cmd.reverb.room,cmd.reverb.send); - - } break; - case VoiceRBSW::Command::CMD_SET_MIX_RATE: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_mix_rate(v->channel,cmd.mix_rate.mix_rate); - - } break; - case VoiceRBSW::Command::CMD_SET_POSITIONAL: { - - if (v->channel!=AudioMixer::INVALID_CHANNEL) - mixer->channel_set_positional(v->channel,cmd.positional.positional); - - } break; - default: {} - - } - } - - mixer->mix(internal_buffer,p_frames); - //uint64_t stepsize=mixer->get_step_usecs(); - - - for(List<Stream*>::Element *E=active_audio_streams.front();E;E=E->next()) { - - ERR_CONTINUE(!E->get()->active); // bug? - - - AudioStream *as=E->get()->audio_stream; - if (!as) - continue; - - int channels=as->get_channel_count(); - if (channels==0) - continue; // does not want mix - if (!as->mix(stream_buffer,p_frames)) - continue; //nothing was mixed!! - - int32_t stream_vol_scale=(stream_volume*stream_volume_scale*E->get()->volume_scale)*(1<<STREAM_SCALE_BITS); - -#define STRSCALE(m_val) (((m_val>>STREAM_SCALE_BITS)*stream_vol_scale)>>8) - switch(internal_buffer_channels) { - - case 2: { - - switch(channels) { - case 1: { - - for(int i=0;i<p_frames;i++) { - - internal_buffer[(i<<1)+0]+=STRSCALE(stream_buffer[i]); - internal_buffer[(i<<1)+1]+=STRSCALE(stream_buffer[i]); - } - } break; - case 2: { - - for(int i=0;i<p_frames*2;i++) { - - internal_buffer[i]+=STRSCALE(stream_buffer[i]); - } - } break; - case 4: { - - for(int i=0;i<p_frames;i++) { - - internal_buffer[(i<<2)+0]+=STRSCALE((stream_buffer[(i<<2)+0]+stream_buffer[(i<<2)+2])>>1); - internal_buffer[(i<<2)+1]+=STRSCALE((stream_buffer[(i<<2)+1]+stream_buffer[(i<<2)+3])>>1); - } - } break; - - } break; - - } break; - case 4: { - - switch(channels) { - case 1: { - - for(int i=0;i<p_frames;i++) { - - internal_buffer[(i<<2)+0]+=STRSCALE(stream_buffer[i]); - internal_buffer[(i<<2)+1]+=STRSCALE(stream_buffer[i]); - internal_buffer[(i<<2)+2]+=STRSCALE(stream_buffer[i]); - internal_buffer[(i<<2)+3]+=STRSCALE(stream_buffer[i]); - } - } break; - case 2: { - - for(int i=0;i<p_frames*2;i++) { - - internal_buffer[(i<<2)+0]+=STRSCALE(stream_buffer[(i<<1)+0]); - internal_buffer[(i<<2)+1]+=STRSCALE(stream_buffer[(i<<1)+1]); - internal_buffer[(i<<2)+2]+=STRSCALE(stream_buffer[(i<<1)+0]); - internal_buffer[(i<<2)+3]+=STRSCALE(stream_buffer[(i<<1)+1]); - } - } break; - case 4: { - - for(int i=0;i<p_frames*4;i++) { - internal_buffer[i]+=STRSCALE(stream_buffer[i]); - } - } break; - - } break; - - } break; - case 6: { - - - } break; - } - -#undef STRSCALE - } - - SelfList<Voice> *activeE=active_list.first(); - while(activeE) { - - SelfList<Voice> *activeN=activeE->next(); - if (activeE->self()->channel==AudioMixer::INVALID_CHANNEL || !mixer->channel_is_valid(activeE->self()->channel)) { - - active_list.remove(activeE); - activeE->self()->active=false; - - } - activeE=activeN; - } - - uint32_t peak=0; - for(int i=0;i<samples;i++) { - //clamp to (1<<24) using branchless code - int32_t in = internal_buffer[i]; -#ifdef DEBUG_ENABLED - { - int mask = (in >> (32 - 1)); - uint32_t p = (in + mask) ^ mask; - if (p>peak) - peak=p; - } -#endif - int32_t lo = -0x800000, hi=0x7FFFFF; - lo-=in; - hi-=in; - in += (lo & ((lo < 0) - 1)) + (hi & ((hi > 0) - 1)); - p_buffer[i]=in<<8; - } - - if (peak>max_peak) - max_peak=peak; -} - -void AudioServerSW::driver_process(int p_frames,int32_t *p_buffer) { - - - _output_delay=p_frames/double(AudioDriverSW::get_singleton()->get_mix_rate()); - //process in chunks to make sure to never process more than INTERNAL_BUFFER_SIZE - int todo=p_frames; - while(todo) { - - int tomix=MIN(todo,INTERNAL_BUFFER_SIZE); - driver_process_chunk(tomix,p_buffer); - p_buffer+=tomix; - todo-=tomix; - } - - -} - -/* SAMPLE API */ - -RID AudioServerSW::sample_create(SampleFormat p_format, bool p_stereo, int p_length) { - - AUDIO_LOCK - - return sample_manager->sample_create(p_format,p_stereo,p_length); -} - -void AudioServerSW::sample_set_description(RID p_sample, const String& p_description) { - - AUDIO_LOCK - sample_manager->sample_set_description(p_sample,p_description); -} -String AudioServerSW::sample_get_description(RID p_sample) const { - - AUDIO_LOCK - return sample_manager->sample_get_description(p_sample); -} - -AS::SampleFormat AudioServerSW::sample_get_format(RID p_sample) const { - //AUDIO_LOCK - return sample_manager->sample_get_format(p_sample); -} -bool AudioServerSW::sample_is_stereo(RID p_sample) const { - //AUDIO_LOCK - return sample_manager->sample_is_stereo(p_sample); -} -int AudioServerSW::sample_get_length(RID p_sample) const { - ///AUDIO_LOCK - return sample_manager->sample_get_length(p_sample); -} - -const void* AudioServerSW::sample_get_data_ptr(RID p_sample) const { - ///AUDIO_LOCK - return sample_manager->sample_get_data_ptr(p_sample); -} - -void AudioServerSW::sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer) { - AUDIO_LOCK - sample_manager->sample_set_data(p_sample,p_buffer); -} -PoolVector<uint8_t> AudioServerSW::sample_get_data(RID p_sample) const { - AUDIO_LOCK - return sample_manager->sample_get_data(p_sample); -} - -void AudioServerSW::sample_set_mix_rate(RID p_sample,int p_rate) { - AUDIO_LOCK - sample_manager->sample_set_mix_rate(p_sample,p_rate); -} -int AudioServerSW::sample_get_mix_rate(RID p_sample) const { - AUDIO_LOCK - return sample_manager->sample_get_mix_rate(p_sample); -} - -void AudioServerSW::sample_set_loop_format(RID p_sample,SampleLoopFormat p_format) { - AUDIO_LOCK - sample_manager->sample_set_loop_format(p_sample,p_format); -} -AS::SampleLoopFormat AudioServerSW::sample_get_loop_format(RID p_sample) const { - AUDIO_LOCK - return sample_manager->sample_get_loop_format(p_sample); -} - -void AudioServerSW::sample_set_loop_begin(RID p_sample,int p_pos) { - AUDIO_LOCK - sample_manager->sample_set_loop_begin(p_sample,p_pos); -} -int AudioServerSW::sample_get_loop_begin(RID p_sample) const { - AUDIO_LOCK - return sample_manager->sample_get_loop_begin(p_sample); -} - -void AudioServerSW::sample_set_loop_end(RID p_sample,int p_pos) { - AUDIO_LOCK - sample_manager->sample_set_loop_end(p_sample,p_pos); -} -int AudioServerSW::sample_get_loop_end(RID p_sample) const { - AUDIO_LOCK - return sample_manager->sample_get_loop_end(p_sample); -} - -/* VOICE API */ - -RID AudioServerSW::voice_create() { - - Voice * v = memnew( Voice ); - v->channel=AudioMixer::INVALID_CHANNEL; - - AUDIO_LOCK - return voice_owner.make_rid(v); - -} -void AudioServerSW::voice_play(RID p_voice, RID p_sample) { - - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND(!v); - v->active=true; // force actvive (will be disabled later i gues..) - - //stop old, start new - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_PLAY; - cmd.voice=p_voice; - cmd.play.sample=p_sample; - voice_rb.push_command(cmd); - -} - -void AudioServerSW::voice_set_volume(RID p_voice, float p_volume) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_VOLUME; - cmd.voice=p_voice; - cmd.volume.volume=p_volume; - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_pan(RID p_voice, float p_pan, float p_depth,float p_height) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_PAN; - cmd.voice=p_voice; - cmd.pan.pan=p_pan; - cmd.pan.depth=p_depth; - cmd.pan.height=p_height; - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance,float p_gain) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_FILTER; - cmd.voice=p_voice; - cmd.filter.type=p_type; - cmd.filter.cutoff=p_cutoff; - cmd.filter.resonance=p_resonance; - cmd.filter.gain=p_gain; - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_chorus(RID p_voice, float p_chorus ) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_CHORUS; - cmd.voice=p_voice; - cmd.chorus.send=p_chorus; - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_reverb(RID p_voice, ReverbRoomType p_room_type, float p_reverb) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_REVERB; - cmd.voice=p_voice; - cmd.reverb.room=p_room_type; - cmd.reverb.send=p_reverb; - - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_mix_rate(RID p_voice, int p_mix_rate) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_MIX_RATE; - cmd.voice=p_voice; - cmd.mix_rate.mix_rate=p_mix_rate; - voice_rb.push_command(cmd); - -} -void AudioServerSW::voice_set_positional(RID p_voice, bool p_positional) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_SET_POSITIONAL; - cmd.voice=p_voice; - cmd.positional.positional=p_positional; - voice_rb.push_command(cmd); - -} - -float AudioServerSW::voice_get_volume(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_volume( v->channel ); - -} -float AudioServerSW::voice_get_pan(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_pan( v->channel ); - -} -float AudioServerSW::voice_get_pan_depth(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_pan_depth( v->channel ); - -} -float AudioServerSW::voice_get_pan_height(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_pan_height( v->channel ); - -} -AS::FilterType AudioServerSW::voice_get_filter_type(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, AS::FILTER_NONE); - - return (AS::FilterType)mixer->channel_get_filter_type(v->channel); - -} -float AudioServerSW::voice_get_filter_cutoff(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_filter_cutoff( v->channel ); - -} -float AudioServerSW::voice_get_filter_resonance(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_filter_resonance( v->channel ); - -} -float AudioServerSW::voice_get_chorus(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_chorus( v->channel ); - -} -AS::ReverbRoomType AudioServerSW::voice_get_reverb_type(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, REVERB_SMALL); - - return (AS::ReverbRoomType)mixer->channel_get_reverb_type( v->channel ); - -} -float AudioServerSW::voice_get_reverb(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_reverb( v->channel ); - -} - -int AudioServerSW::voice_get_mix_rate(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_get_mix_rate( v->channel ); - -} -bool AudioServerSW::voice_is_positional(RID p_voice) const { - - AUDIO_LOCK - Voice *v = voice_owner.get( p_voice ); - ERR_FAIL_COND_V(!v, 0); - - return mixer->channel_is_positional( v->channel ); - -} - -void AudioServerSW::voice_stop(RID p_voice) { - - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_STOP; - cmd.voice=p_voice; - voice_rb.push_command(cmd); - - //return mixer->channel_free( v->channel ); - -} - -bool AudioServerSW::voice_is_active(RID p_voice) const { - - Voice *v = voice_owner.get(p_voice); - ERR_FAIL_COND_V(!v,false); - return v->active; - -} - -/* STREAM API */ - -RID AudioServerSW::audio_stream_create(AudioStream *p_stream) { - - AUDIO_LOCK - Stream *s = memnew(Stream); - s->audio_stream=p_stream; - s->event_stream=NULL; - s->active=false; - s->E=NULL; - s->volume_scale=1.0; - p_stream->set_mix_rate(AudioDriverSW::get_singleton()->get_mix_rate()); - - return stream_owner.make_rid(s); -} - -RID AudioServerSW::event_stream_create(EventStream *p_stream) { - - AUDIO_LOCK - Stream *s = memnew(Stream); - s->audio_stream=NULL; - s->event_stream=p_stream; - s->active=false; - s->E=NULL; - s->volume_scale=1.0; - //p_stream->set_mix_rate(AudioDriverSW::get_singleton()->get_mix_rate()); - - return stream_owner.make_rid(s); - - -} - - -void AudioServerSW::stream_set_active(RID p_stream, bool p_active) { - - - Stream *s = stream_owner.get(p_stream); - ERR_FAIL_COND(!s); - _THREAD_SAFE_METHOD_ - - if (s->active==p_active) - return; - AUDIO_LOCK; - s->active=p_active; - if (p_active) - s->E=active_audio_streams.push_back(s); - else { - active_audio_streams.erase(s->E); - s->E=NULL; - } - - -} - -bool AudioServerSW::stream_is_active(RID p_stream) const { - - Stream *s = stream_owner.get(p_stream); - ERR_FAIL_COND_V(!s,false); - return s->active; -} - -void AudioServerSW::stream_set_volume_scale(RID p_stream, float p_scale) { - - Stream *s = stream_owner.get(p_stream); - ERR_FAIL_COND(!s); - s->volume_scale=p_scale; - -} - -float AudioServerSW::stream_set_volume_scale(RID p_stream) const { - - Stream *s = stream_owner.get(p_stream); - ERR_FAIL_COND_V(!s,0); - return s->volume_scale; - -} - - -void AudioServerSW::free(RID p_id) { - - if(voice_owner.owns(p_id)) { - - Voice *v = voice_owner.get(p_id); - AUDIO_LOCK - mixer->channel_free( v->channel ); - voice_owner.free(p_id); - memdelete(v); - - } else if (stream_owner.owns(p_id)) { - - - Stream *s=stream_owner.get(p_id); - - if (s->active) { - stream_set_active(p_id,false); - } - - memdelete(s); - stream_owner.free(p_id); - - } else if (sample_manager->is_sample(p_id)) { - - AUDIO_LOCK - sample_manager->free(p_id); - } - -} - -void AudioServerSW::_thread_func(void *self) { - - Thread::set_name("AudioServerSW"); - - AudioServerSW *as=(AudioServerSW *)self; - - while (!as->exit_update_thread) { - as->_update_streams(true); - OS::get_singleton()->delay_usec(5000); - } - -} - -void AudioServerSW::init() { - - int latency = GLOBAL_DEF("audio/mixer_latency",10); - internal_buffer_channels=2; // read from driver - internal_buffer = memnew_arr(int32_t,INTERNAL_BUFFER_SIZE*internal_buffer_channels); - stream_buffer = memnew_arr(int32_t,INTERNAL_BUFFER_SIZE*4); //max 4 channels - AudioMixerSW::MixChannels mix_chans = AudioMixerSW::MIX_STEREO; - - switch(AudioDriverSW::get_singleton()->get_output_format()) { - - case AudioDriverSW::OUTPUT_MONO: - case AudioDriverSW::OUTPUT_STEREO: - mix_chans=AudioMixerSW::MIX_STEREO; - break; - case AudioDriverSW::OUTPUT_QUAD: - case AudioDriverSW::OUTPUT_5_1: - mix_chans=AudioMixerSW::MIX_QUAD; - break; - } - - mixer = memnew( AudioMixerSW( sample_manager, latency, AudioDriverSW::get_singleton()->get_mix_rate(),mix_chans,mixer_use_fx,mixer_interp,_mixer_callback,this ) ); - mixer_step_usecs=mixer->get_step_usecs(); - - _output_delay=0; - - stream_volume=0.3; - // start the audio driver - if (AudioDriverSW::get_singleton()) - AudioDriverSW::get_singleton()->start(); - -#ifndef NO_THREADS - exit_update_thread=false; - thread = Thread::create(_thread_func,this); -#endif - -} - -void AudioServerSW::finish() { - -#ifndef NO_THREADS - exit_update_thread=true; - Thread::wait_to_finish(thread); - memdelete(thread); -#endif - - if (AudioDriverSW::get_singleton()) - AudioDriverSW::get_singleton()->finish(); - - memdelete_arr(internal_buffer); - memdelete_arr(stream_buffer); - memdelete(mixer); - -} - -void AudioServerSW::_update_streams(bool p_thread) { - - _THREAD_SAFE_METHOD_ - for(List<Stream*>::Element *E=active_audio_streams.front();E;) { //stream might be removed durnig this callback - - List<Stream*>::Element *N=E->next(); - - if (E->get()->audio_stream && p_thread == E->get()->audio_stream->can_update_mt()) - E->get()->audio_stream->update(); - - E=N; - } - -} - -void AudioServerSW::update() { - - _update_streams(false); -#ifdef NO_THREADS - - _update_streams(true); -#endif -} - - -void AudioServerSW::lock() { - - AudioDriverSW::get_singleton()->lock(); -} - -void AudioServerSW::unlock() { - AudioDriverSW::get_singleton()->unlock(); - -} - -int AudioServerSW::get_default_mix_rate() const { - - return AudioDriverSW::get_singleton()->get_mix_rate(); -} -int AudioServerSW::get_default_channel_count() const { - return internal_buffer_channels; -} - -void AudioServerSW::set_mixer_params(AudioMixerSW::InterpolationType p_interp, bool p_use_fx) { - - mixer_interp=p_interp; - mixer_use_fx=p_use_fx; -} - -void AudioServerSW::set_stream_global_volume_scale(float p_volume) { - - stream_volume_scale=p_volume; -} - -float AudioServerSW::get_stream_global_volume_scale() const { - - return stream_volume_scale; - - -} - -void AudioServerSW::set_fx_global_volume_scale(float p_volume) { - - fx_volume_scale=p_volume; - //mixer->set_mixer_volume(fx_volume_scale); - VoiceRBSW::Command cmd; - cmd.type=VoiceRBSW::Command::CMD_CHANGE_ALL_FX_VOLUMES; - cmd.voice=RID(); - cmd.volume.volume=p_volume; - voice_rb.push_command(cmd); - -} - - -float AudioServerSW::get_fx_global_volume_scale() const { - - return fx_volume_scale; -} - -void AudioServerSW::set_event_voice_global_volume_scale(float p_volume) { - - event_voice_volume_scale=p_volume; - //mixer->set_mixer_volume(event_voice_volume_scale); -} - - -float AudioServerSW::get_event_voice_global_volume_scale() const { - - return event_voice_volume_scale; -} - -double AudioServerSW::get_output_delay() const { - - return _output_delay+AudioDriverSW::get_singleton()->get_latency(); -} - -double AudioServerSW::get_mix_time() const { - - return AudioDriverSW::get_singleton()->get_mix_time(); -} - -uint32_t AudioServerSW::read_output_peak() const { - - uint32_t val = max_peak; - uint32_t *p = (uint32_t*)&max_peak; - *p=0; - return val; -} - -AudioServerSW::AudioServerSW(SampleManagerSW *p_sample_manager) { - - sample_manager=p_sample_manager; - String interp = GLOBAL_DEF("audio/mixer_interp","linear"); - GlobalConfig::get_singleton()->set_custom_property_info("audio/mixer_interp",PropertyInfo(Variant::STRING,"audio/mixer_interp",PROPERTY_HINT_ENUM,"raw,linear,cubic")); - if (interp=="raw") - mixer_interp=AudioMixerSW::INTERPOLATION_RAW; - else if (interp=="cubic") - mixer_interp=AudioMixerSW::INTERPOLATION_CUBIC; - else - mixer_interp=AudioMixerSW::INTERPOLATION_LINEAR; - mixer_use_fx = GLOBAL_DEF("audio/use_chorus_reverb",true); - stream_volume_scale=GLOBAL_DEF("audio/stream_volume_scale",1.0); - fx_volume_scale=GLOBAL_DEF("audio/fx_volume_scale",1.0); - event_voice_volume_scale=GLOBAL_DEF("audio/event_voice_volume_scale",0.5); - max_peak=0; - - -} - -AudioServerSW::~AudioServerSW() { - -} - - -AudioDriverSW *AudioDriverSW::singleton=NULL; -AudioDriverSW *AudioDriverSW::get_singleton() { - - return singleton; -} - -void AudioDriverSW::set_singleton() { - - singleton=this; -} - -void AudioDriverSW::audio_server_process(int p_frames,int32_t *p_buffer,bool p_update_mix_time) { - - AudioServerSW * audio_server = static_cast<AudioServerSW*>(AudioServer::get_singleton()); - if (p_update_mix_time) - update_mix_time(p_frames); - audio_server->driver_process(p_frames,p_buffer); -} - -void AudioDriverSW::update_mix_time(int p_frames) { - - _mix_amount+=p_frames; - _last_mix_time=OS::get_singleton()->get_ticks_usec(); -} - -double AudioDriverSW::get_mix_time() const { - - double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; - total+=_mix_amount/(double)get_mix_rate(); - return total; - -} - - -AudioDriverSW::AudioDriverSW() { - - _last_mix_time=0; - _mix_amount=0; -} - - -AudioDriverSW *AudioDriverManagerSW::drivers[MAX_DRIVERS]; -int AudioDriverManagerSW::driver_count=0; - - - -void AudioDriverManagerSW::add_driver(AudioDriverSW *p_driver) { - - ERR_FAIL_COND(driver_count>=MAX_DRIVERS); - drivers[driver_count++]=p_driver; -} - -int AudioDriverManagerSW::get_driver_count() { - - return driver_count; -} -AudioDriverSW *AudioDriverManagerSW::get_driver(int p_driver) { - - ERR_FAIL_INDEX_V(p_driver,driver_count,NULL); - return drivers[p_driver]; -} - diff --git a/servers/audio/audio_server_sw.h b/servers/audio/audio_server_sw.h deleted file mode 100644 index 52b45351c3..0000000000 --- a/servers/audio/audio_server_sw.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************/ -/* audio_server_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef AUDIO_SERVER_SW_H -#define AUDIO_SERVER_SW_H - -#include "servers/audio_server.h" -#include "servers/audio/audio_mixer_sw.h" -#include "servers/audio/voice_rb_sw.h" -#include "self_list.h" -#include "os/thread_safe.h" -#include "os/thread.h" -class AudioServerSW : public AudioServer { - - GDCLASS( AudioServerSW, AudioServer ); - - _THREAD_SAFE_CLASS_ - - enum { - INTERNAL_BUFFER_SIZE=4096, - STREAM_SCALE_BITS=12 - - }; - - SampleManagerSW *sample_manager; - AudioMixerSW *mixer; - - virtual AudioMixer *get_mixer(); - virtual void audio_mixer_chunk_callback(int p_frames); - - struct Voice : public RID_Data { - - float volume; - volatile bool active; - SelfList<Voice> active_item; - AudioMixer::ChannelID channel; - - - Voice () : active_item(this) { channel=AudioMixer::INVALID_CHANNEL; active=false;} - }; - - mutable RID_Owner<Voice> voice_owner; - SelfList<Voice>::List active_list; - - struct Stream : public RID_Data { - bool active; - List<Stream*>::Element *E; - AudioStream *audio_stream; - EventStream *event_stream; - float volume_scale; - }; - - List<Stream*> active_audio_streams; - - //List<Stream*> event_streams; - - int32_t * internal_buffer; - int internal_buffer_channels; - int32_t * stream_buffer; - - mutable RID_Owner<Stream> stream_owner; - - float stream_volume; - float stream_volume_scale; - float fx_volume_scale; - float event_voice_volume_scale; - float peak_left,peak_right; - uint32_t max_peak; - - double _output_delay; - - VoiceRBSW voice_rb; - - bool exit_update_thread; - Thread *thread; - static void _thread_func(void *self); - - void _update_streams(bool p_thread); - void driver_process_chunk(int p_frames,int32_t *p_buffer); - - AudioMixerSW::InterpolationType mixer_interp; - bool mixer_use_fx; - uint64_t mixer_step_usecs; - - static void _mixer_callback(void *p_udata); -friend class AudioDriverSW; - void driver_process(int p_frames,int32_t *p_buffer); -public: - - - /* SAMPLE API */ - - virtual RID sample_create(SampleFormat p_format, bool p_stereo, int p_length); - - virtual void sample_set_description(RID p_sample, const String& p_description); - virtual String sample_get_description(RID p_sample) const; - - virtual SampleFormat sample_get_format(RID p_sample) const; - virtual bool sample_is_stereo(RID p_sample) const; - virtual int sample_get_length(RID p_sample) const; - const void* sample_get_data_ptr(RID p_sample) const; - - virtual void sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer); - virtual PoolVector<uint8_t> sample_get_data(RID p_sample) const; - - virtual void sample_set_mix_rate(RID p_sample,int p_rate); - virtual int sample_get_mix_rate(RID p_sample) const; - - virtual void sample_set_loop_format(RID p_sample,SampleLoopFormat p_format); - virtual SampleLoopFormat sample_get_loop_format(RID p_sample) const; - - virtual void sample_set_loop_begin(RID p_sample,int p_pos); - virtual int sample_get_loop_begin(RID p_sample) const; - - virtual void sample_set_loop_end(RID p_sample,int p_pos); - virtual int sample_get_loop_end(RID p_sample) const; - - /* VOICE API */ - - virtual RID voice_create(); - - virtual void voice_play(RID p_voice, RID p_sample); - - virtual void voice_set_volume(RID p_voice, float p_volume); - virtual void voice_set_pan(RID p_voice, float p_pan, float p_depth=0,float height=0); //pan and depth go from -1 to 1 - virtual void voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance,float p_gain=0); - virtual void voice_set_chorus(RID p_voice, float p_chorus ); - virtual void voice_set_reverb(RID p_voice, ReverbRoomType p_room_type, float p_reverb); - virtual void voice_set_mix_rate(RID p_voice, int p_mix_rate); - virtual void voice_set_positional(RID p_voice, bool p_positional); - - virtual float voice_get_volume(RID p_voice) const; - virtual float voice_get_pan(RID p_voice) const; //pan and depth go from -1 to 1 - virtual float voice_get_pan_depth(RID p_voice) const; //pan and depth go from -1 to 1 - virtual float voice_get_pan_height(RID p_voice) const; //pan and depth go from -1 to 1 - virtual FilterType voice_get_filter_type(RID p_voice) const; - virtual float voice_get_filter_cutoff(RID p_voice) const; - virtual float voice_get_filter_resonance(RID p_voice) const; - virtual float voice_get_chorus(RID p_voice) const; - virtual ReverbRoomType voice_get_reverb_type(RID p_voice) const; - virtual float voice_get_reverb(RID p_voice) const; - - virtual int voice_get_mix_rate(RID p_voice) const; - virtual bool voice_is_positional(RID p_voice) const; - - virtual void voice_stop(RID p_voice); - virtual bool voice_is_active(RID p_voice) const; - - /* STREAM API */ - - virtual RID audio_stream_create(AudioStream *p_stream); - virtual RID event_stream_create(EventStream *p_stream); - - virtual void stream_set_active(RID p_stream, bool p_active); - virtual bool stream_is_active(RID p_stream) const; - - virtual void stream_set_volume_scale(RID p_stream, float p_scale); - virtual float stream_set_volume_scale(RID p_stream) const; - - virtual void free(RID p_id); - - virtual void init(); - virtual void finish(); - virtual void update(); - - virtual void lock(); - virtual void unlock(); - virtual int get_default_channel_count() const; - virtual int get_default_mix_rate() const; - - void set_mixer_params(AudioMixerSW::InterpolationType p_interp, bool p_use_fx); - - virtual void set_stream_global_volume_scale(float p_volume); - virtual void set_fx_global_volume_scale(float p_volume); - virtual void set_event_voice_global_volume_scale(float p_volume); - - - virtual float get_stream_global_volume_scale() const; - virtual float get_fx_global_volume_scale() const; - virtual float get_event_voice_global_volume_scale() const; - - virtual uint32_t read_output_peak() const; - - virtual double get_mix_time() const; //useful for video -> audio sync - - virtual double get_output_delay() const; - - - AudioServerSW(SampleManagerSW *p_sample_manager); - ~AudioServerSW(); - -}; - - -class AudioDriverSW { - - - static AudioDriverSW *singleton; - uint64_t _last_mix_time; - uint64_t _mix_amount; - - -protected: - - void audio_server_process(int p_frames,int32_t *p_buffer,bool p_update_mix_time=true); - void update_mix_time(int p_frames); - -public: - - - double get_mix_time() const; //useful for video -> audio sync - - enum OutputFormat { - - OUTPUT_MONO, - OUTPUT_STEREO, - OUTPUT_QUAD, - OUTPUT_5_1 - }; - - static AudioDriverSW *get_singleton(); - void set_singleton(); - - virtual const char* get_name() const=0; - - virtual Error init()=0; - virtual void start()=0; - virtual int get_mix_rate() const =0; - virtual OutputFormat get_output_format() const=0; - virtual void lock()=0; - virtual void unlock()=0; - virtual void finish()=0; - - virtual float get_latency() { return 0; } - - - - - AudioDriverSW(); - virtual ~AudioDriverSW() {}; -}; - - - -class AudioDriverManagerSW { - - enum { - - MAX_DRIVERS=10 - }; - - static AudioDriverSW *drivers[MAX_DRIVERS]; - static int driver_count; -public: - - static void add_driver(AudioDriverSW *p_driver); - static int get_driver_count(); - static AudioDriverSW *get_driver(int p_driver); -}; - -#endif // AUDIO_SERVER_SW_H diff --git a/servers/audio/sample_manager_sw.cpp b/servers/audio/sample_manager_sw.cpp deleted file mode 100644 index fe4cc36776..0000000000 --- a/servers/audio/sample_manager_sw.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/*************************************************************************/ -/* sample_manager_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "sample_manager_sw.h" - -#include "print_string.h" - -SampleManagerSW::~SampleManagerSW() -{ -} - - - -RID SampleManagerMallocSW::sample_create(AS::SampleFormat p_format, bool p_stereo, int p_length) { - - Sample *s = memnew( Sample ); - int datalen = p_length; - if (p_format==AS::SAMPLE_FORMAT_PCM16) - datalen*=2; - else if (p_format==AS::SAMPLE_FORMAT_IMA_ADPCM) { - if (datalen&1) { - datalen++; - } - datalen/=2; - datalen+=4; - } - - if (p_stereo) - datalen*=2; - -#define SAMPLE_EXTRA 16 - - s->data = memalloc(datalen+SAMPLE_EXTRA); //help the interpolator by allocating a little more.. - for(int i=0;i<SAMPLE_EXTRA;i++) { - - uint8_t *data = (uint8_t*)s->data; - data[datalen+i]=0; - } - if (!s->data) { - - memdelete(s); - ERR_EXPLAIN("Cannot allocate sample of requested size."); - ERR_FAIL_V(RID()); - } - - s->format=p_format; - s->length=p_length; - s->length_bytes=datalen; - s->stereo=p_stereo; - s->loop_begin=0; - s->loop_end=0; - s->loop_format=AS::SAMPLE_LOOP_NONE; - s->mix_rate=44100; - - AudioServer::get_singleton()->lock(); - RID rid = sample_owner.make_rid(s); - AudioServer::get_singleton()->unlock(); - - return rid; -} - -void SampleManagerMallocSW::sample_set_description(RID p_sample, const String& p_description) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - - s->description=p_description; -} - -String SampleManagerMallocSW::sample_get_description(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,String()); - - return s->description; -} - - -AS::SampleFormat SampleManagerMallocSW::sample_get_format(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,AS::SAMPLE_FORMAT_PCM8); - - return s->format; -} - -bool SampleManagerMallocSW::sample_is_stereo(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,false); - - return s->stereo; - -} -int SampleManagerMallocSW::sample_get_length(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,-1); - - return s->length; -} - -void SampleManagerMallocSW::sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - - int buff_size=p_buffer.size(); - ERR_FAIL_COND(buff_size==0); - - - ERR_EXPLAIN("Sample buffer size does not match sample size."); - //print_line("len bytes: "+itos(s->length_bytes)+" bufsize: "+itos(buff_size)); - ERR_FAIL_COND(s->length_bytes!=buff_size); - PoolVector<uint8_t>::Read buffer_r=p_buffer.read(); - const uint8_t *src = buffer_r.ptr(); - uint8_t *dst = (uint8_t*)s->data; - //print_line("set data: "+itos(s->length_bytes)); - - for(int i=0;i<s->length_bytes;i++) { - - dst[i]=src[i]; - } - - switch(s->format) { - - case AS::SAMPLE_FORMAT_PCM8: { - - if (s->stereo) { - dst[s->length]=dst[s->length-2]; - dst[s->length+1]=dst[s->length-1]; - } else { - - dst[s->length]=dst[s->length-1]; - } - - } break; - case AS::SAMPLE_FORMAT_PCM16: { - - if (s->stereo) { - dst[s->length]=dst[s->length-4]; - dst[s->length+1]=dst[s->length-3]; - dst[s->length+2]=dst[s->length-2]; - dst[s->length+3]=dst[s->length-1]; - } else { - - dst[s->length]=dst[s->length-2]; - dst[s->length+1]=dst[s->length-1]; - } - - } break; - - } - - - -} - -const PoolVector<uint8_t> SampleManagerMallocSW::sample_get_data(RID p_sample) const { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,PoolVector<uint8_t>()); - - PoolVector<uint8_t> ret_buffer; - ret_buffer.resize(s->length_bytes); - PoolVector<uint8_t>::Write buffer_w=ret_buffer.write(); - uint8_t *dst = buffer_w.ptr(); - const uint8_t *src = (const uint8_t*)s->data; - - for(int i=0;i<s->length_bytes;i++) { - - dst[i]=src[i]; - } - - buffer_w = PoolVector<uint8_t>::Write(); //unlock - - return ret_buffer; -} - -void *SampleManagerMallocSW::sample_get_data_ptr(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,NULL); - - return s->data; - -} - -void SampleManagerMallocSW::sample_set_mix_rate(RID p_sample,int p_rate) { - - ERR_FAIL_COND(p_rate<1); - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - - s->mix_rate=p_rate; - - -} -int SampleManagerMallocSW::sample_get_mix_rate(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,-1); - - return s->mix_rate; - -} -void SampleManagerMallocSW::sample_set_loop_format(RID p_sample,AS::SampleLoopFormat p_format) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - - s->loop_format=p_format; - -} -AS::SampleLoopFormat SampleManagerMallocSW::sample_get_loop_format(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,AS::SAMPLE_LOOP_NONE); - - return s->loop_format; -} - -void SampleManagerMallocSW::sample_set_loop_begin(RID p_sample,int p_pos) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - ERR_FAIL_INDEX(p_pos,s->length); - - s->loop_begin=p_pos; -} -int SampleManagerMallocSW::sample_get_loop_begin(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,-1); - - return s->loop_begin; -} - -void SampleManagerMallocSW::sample_set_loop_end(RID p_sample,int p_pos) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - if (p_pos>s->length) - p_pos=s->length; - s->loop_end=p_pos; - -} -int SampleManagerMallocSW::sample_get_loop_end(RID p_sample) const { - - const Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND_V(!s,-1); - - return s->loop_end; -} - -bool SampleManagerMallocSW::is_sample(RID p_sample) const { - - return sample_owner.owns(p_sample); - -} -void SampleManagerMallocSW::free(RID p_sample) { - - Sample *s = sample_owner.get(p_sample); - ERR_FAIL_COND(!s); - AudioServer::get_singleton()->lock(); - sample_owner.free(p_sample); - AudioServer::get_singleton()->unlock(); - - memfree(s->data); - memdelete(s); - -} - -SampleManagerMallocSW::SampleManagerMallocSW() { - - -} - -SampleManagerMallocSW::~SampleManagerMallocSW() { - - // check for sample leakage - List<RID> owned_list; - sample_owner.get_owned_list(&owned_list); - - while(owned_list.size()) { - - Sample *s = sample_owner.get(owned_list.front()->get()); - String err="Leaked sample of size: "+itos(s->length_bytes)+" description: "+s->description; - ERR_PRINT(err.utf8().get_data()); - free(owned_list.front()->get()); - owned_list.pop_front(); - } - -} diff --git a/servers/audio/sample_manager_sw.h b/servers/audio/sample_manager_sw.h deleted file mode 100644 index 93cad96f1a..0000000000 --- a/servers/audio/sample_manager_sw.h +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************/ -/* sample_manager_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SAMPLE_MANAGER_SW_H -#define SAMPLE_MANAGER_SW_H - -#include "servers/audio_server.h" - -class SampleManagerSW { -public: - - /* SAMPLE API */ - - virtual RID sample_create(AS::SampleFormat p_format, bool p_stereo, int p_length)=0; - - virtual void sample_set_description(RID p_sample, const String& p_description)=0; - virtual String sample_get_description(RID p_sample) const=0; - - virtual AS::SampleFormat sample_get_format(RID p_sample) const=0; - virtual bool sample_is_stereo(RID p_sample) const=0; - virtual int sample_get_length(RID p_sample) const=0; - - virtual void sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer)=0; - virtual const PoolVector<uint8_t> sample_get_data(RID p_sample) const=0; - - virtual void *sample_get_data_ptr(RID p_sample) const=0; - - virtual void sample_set_mix_rate(RID p_sample,int p_rate)=0; - virtual int sample_get_mix_rate(RID p_sample) const=0; - - virtual void sample_set_loop_format(RID p_sample,AS::SampleLoopFormat p_format)=0; - virtual AS::SampleLoopFormat sample_get_loop_format(RID p_sample) const=0; - - virtual void sample_set_loop_begin(RID p_sample,int p_pos)=0; - virtual int sample_get_loop_begin(RID p_sample) const=0; - - virtual void sample_set_loop_end(RID p_sample,int p_pos)=0; - virtual int sample_get_loop_end(RID p_sample) const=0; - - virtual bool is_sample(RID) const=0; - virtual void free(RID p_sample)=0; - - - - virtual ~SampleManagerSW(); -}; - - -class SampleManagerMallocSW : public SampleManagerSW { - - - struct Sample : public RID_Data { - - void *data; - int length; - int length_bytes; - AS::SampleFormat format; - bool stereo; - AS::SampleLoopFormat loop_format; - int loop_begin; - int loop_end; - int mix_rate; - String description; - }; - - mutable RID_Owner<Sample> sample_owner; -public: - - /* SAMPLE API */ - - virtual RID sample_create(AS::SampleFormat p_format, bool p_stereo, int p_length); - - virtual void sample_set_description(RID p_sample, const String& p_description); - virtual String sample_get_description(RID p_sample) const; - - virtual AS::SampleFormat sample_get_format(RID p_sample) const; - virtual bool sample_is_stereo(RID p_sample) const; - virtual int sample_get_length(RID p_sample) const; - - virtual void sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer); - virtual const PoolVector<uint8_t> sample_get_data(RID p_sample) const; - - virtual void *sample_get_data_ptr(RID p_sample) const; - - virtual void sample_set_mix_rate(RID p_sample,int p_rate); - virtual int sample_get_mix_rate(RID p_sample) const; - - virtual void sample_set_loop_format(RID p_sample,AS::SampleLoopFormat p_format); - virtual AS::SampleLoopFormat sample_get_loop_format(RID p_sample) const; - - virtual void sample_set_loop_begin(RID p_sample,int p_pos); - virtual int sample_get_loop_begin(RID p_sample) const; - - virtual void sample_set_loop_end(RID p_sample,int p_pos); - virtual int sample_get_loop_end(RID p_sample) const; - - virtual bool is_sample(RID) const; - virtual void free(RID p_sample); - - SampleManagerMallocSW(); - virtual ~SampleManagerMallocSW(); -}; - -#endif // SAMPLE_MANAGER_SW_H diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 5037b19924..9b938a7f86 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -28,171 +28,265 @@ /*************************************************************************/ #include "audio_server.h" #include "globals.h" +#include "os/os.h" +AudioDriver *AudioDriver::singleton=NULL; +AudioDriver *AudioDriver::get_singleton() { -void AudioMixer::audio_mixer_chunk_call(int p_frames) { + return singleton; +} + +void AudioDriver::set_singleton() { - AudioServer::get_singleton()->audio_mixer_chunk_callback(p_frames); + singleton=this; } -AudioMixer *AudioServer::EventStream::get_mixer() const { +void AudioDriver::audio_server_process(int p_frames,int32_t *p_buffer,bool p_update_mix_time) { - return AudioServer::get_singleton()->get_mixer(); + AudioServer * audio_server = static_cast<AudioServer*>(AudioServer::get_singleton()); + if (p_update_mix_time) + update_mix_time(p_frames); +// audio_server->driver_process(p_frames,p_buffer); } -AudioServer *AudioServer::singleton=NULL; +void AudioDriver::update_mix_time(int p_frames) { -AudioServer *AudioServer::get_singleton() { + _mix_amount+=p_frames; + _last_mix_time=OS::get_singleton()->get_ticks_usec(); +} - return singleton; +double AudioDriver::get_mix_time() const { + + double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; + total+=_mix_amount/(double)get_mix_rate(); + return total; + +} + + +AudioDriver::AudioDriver() { + + _last_mix_time=0; + _mix_amount=0; +} + + +AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS]; +int AudioDriverManager::driver_count=0; + + + +void AudioDriverManager::add_driver(AudioDriver *p_driver) { + + ERR_FAIL_COND(driver_count>=MAX_DRIVERS); + drivers[driver_count++]=p_driver; +} + +int AudioDriverManager::get_driver_count() { + + return driver_count; +} +AudioDriver *AudioDriverManager::get_driver(int p_driver) { + + ERR_FAIL_INDEX_V(p_driver,driver_count,NULL); + return drivers[p_driver]; +} + + +////////////////////////////////////////////// +////////////////////////////////////////////// +////////////////////////////////////////////// +////////////////////////////////////////////// + +void AudioServer::set_bus_count(int p_count) { + + ERR_FAIL_COND(p_count<1); + ERR_FAIL_INDEX(p_count,256); + lock(); + buses.resize(p_count); + unlock(); +} + +int AudioServer::get_bus_count() const { + + return buses.size(); } -void AudioServer::sample_set_signed_data(RID p_sample, const PoolVector<float>& p_buffer) { +void AudioServer::set_bus_mode(int p_bus,BusMode p_mode) { - SampleFormat format = sample_get_format(p_sample); + ERR_FAIL_INDEX(p_bus,buses.size()); + +} +AudioServer::BusMode AudioServer::get_bus_mode(int p_bus) const { + + ERR_FAIL_INDEX_V(p_bus,buses.size(),BUS_MODE_STEREO); + + return buses[p_bus].mode; +} + +void AudioServer::set_bus_name(int p_bus,const String& p_name) { + + ERR_FAIL_INDEX(p_bus,buses.size()); + buses[p_bus].name=p_name; + +} +String AudioServer::get_bus_name(int p_bus) const { + + ERR_FAIL_INDEX_V(p_bus,buses.size(),String()); + return buses[p_bus].name; +} - ERR_EXPLAIN("IMA ADPCM is not supported."); - ERR_FAIL_COND(format==SAMPLE_FORMAT_IMA_ADPCM); +void AudioServer::set_bus_volume_db(int p_bus,float p_volume_db) { - int len = p_buffer.size(); - ERR_FAIL_COND( len == 0 ); + ERR_FAIL_INDEX(p_bus,buses.size()); + buses[p_bus].volume_db=p_volume_db; - PoolVector<uint8_t> data; - PoolVector<uint8_t>::Write w; - PoolVector<float>::Read r = p_buffer.read(); +} +float AudioServer::get_bus_volume_db(int p_bus) const { - switch(format) { - case SAMPLE_FORMAT_PCM8: { - data.resize(len); - w=data.write(); + ERR_FAIL_INDEX_V(p_bus,buses.size(),0); + return buses[p_bus].volume_db; - int8_t *samples8 = (int8_t*)w.ptr(); +} - for(int i=0;i<len;i++) { +void AudioServer::add_bus_effect(int p_bus,const Ref<AudioEffect>& p_effect,int p_at_pos) { - float sample = Math::floor( r[i] * (1<<8) ); - if (sample<-128) - sample=-128; - else if (sample>127) - sample=127; - samples8[i]=sample; - } - } break; - case SAMPLE_FORMAT_PCM16: { - data.resize(len*2); - w=data.write(); + ERR_FAIL_COND(p_effect.is_null()); + ERR_FAIL_INDEX(p_bus,buses.size()); - int16_t *samples16 = (int16_t*)w.ptr(); + lock(); - for(int i=0;i<len;i++) { + Bus::Effect fx; + fx.effect=p_effect; + //fx.instance=p_effect->instance(); + fx.enabled=true; - float sample = Math::floor( r[i] * (1<<16) ); - if (sample<-32768) - sample=-32768; - else if (sample>32767) - sample=32767; - samples16[i]=sample; - } - } break; + if (p_at_pos>=buses[p_bus].effects.size() || p_at_pos<0) { + buses[p_bus].effects.push_back(fx); + } else { + buses[p_bus].effects.insert(p_at_pos,fx); } - w = PoolVector<uint8_t>::Write(); + unlock(); +} + + +void AudioServer::remove_bus_effect(int p_bus,int p_effect) { + + ERR_FAIL_INDEX(p_bus,buses.size()); - sample_set_data(p_sample,data); + lock(); + buses[p_bus].effects.remove(p_effect); + unlock(); } -void AudioServer::_bind_methods() { +int AudioServer::get_bus_effect_count(int p_bus) { + + ERR_FAIL_INDEX_V(p_bus,buses.size(),0); + + return buses[p_bus].effects.size(); + +} + +Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus,int p_effect) { + + ERR_FAIL_INDEX_V(p_bus,buses.size(),Ref<AudioEffect>()); + ERR_FAIL_INDEX_V(p_effect,buses[p_bus].effects.size(),Ref<AudioEffect>()); + + return buses[p_bus].effects[p_effect].effect; + +} + +void AudioServer::swap_bus_effects(int p_bus,int p_effect,int p_by_effect) { + + ERR_FAIL_INDEX(p_bus,buses.size()); + ERR_FAIL_INDEX(p_effect,buses[p_bus].effects.size()); + ERR_FAIL_INDEX(p_by_effect,buses[p_bus].effects.size()); + + lock(); + SWAP( buses[p_bus].effects[p_effect], buses[p_bus].effects[p_by_effect] ); + unlock(); +} + +void AudioServer::set_bus_effect_enabled(int p_bus,int p_effect,bool p_enabled) { + + ERR_FAIL_INDEX(p_bus,buses.size()); + ERR_FAIL_INDEX(p_effect,buses[p_bus].effects.size()); + buses[p_bus].effects[p_effect].enabled=p_enabled; - ClassDB::bind_method(_MD("sample_create","format","stereo","length"), &AudioServer::sample_create ); - ClassDB::bind_method(_MD("sample_set_description","sample","description"), &AudioServer::sample_set_description ); - ClassDB::bind_method(_MD("sample_get_description","sample"), &AudioServer::sample_get_description ); +} +bool AudioServer::is_bus_effect_enabled(int p_bus,int p_effect) const { + + ERR_FAIL_INDEX_V(p_bus,buses.size(),false); + ERR_FAIL_INDEX_V(p_effect,buses[p_bus].effects.size(),false); + return buses[p_bus].effects[p_effect].enabled; - ClassDB::bind_method(_MD("sample_get_format","sample"), &AudioServer::sample_get_format ); - ClassDB::bind_method(_MD("sample_is_stereo","sample"), &AudioServer::sample_is_stereo ); - ClassDB::bind_method(_MD("sample_get_length","sample"), &AudioServer::sample_get_length ); +} - ClassDB::bind_method(_MD("sample_set_signed_data","sample","data"), &AudioServer::sample_set_signed_data ); - ClassDB::bind_method(_MD("sample_set_data","sample","data"), &AudioServer::sample_set_data ); - ClassDB::bind_method(_MD("sample_get_data","sample"), &AudioServer::sample_get_data ); +void AudioServer::init() { - ClassDB::bind_method(_MD("sample_set_mix_rate","sample","mix_rate"), &AudioServer::sample_set_mix_rate ); - ClassDB::bind_method(_MD("sample_get_mix_rate","sample"), &AudioServer::sample_get_mix_rate ); + set_bus_count(1);; + set_bus_name(0,"Master"); +} +void AudioServer::finish() { - ClassDB::bind_method(_MD("sample_set_loop_format","sample","loop_format"), &AudioServer::sample_set_loop_format ); - ClassDB::bind_method(_MD("sample_get_loop_format","sample"), &AudioServer::sample_get_loop_format ); + buses.clear(); +} +void AudioServer::update() { - ClassDB::bind_method(_MD("sample_set_loop_begin","sample","pos"), &AudioServer::sample_set_loop_begin ); - ClassDB::bind_method(_MD("sample_get_loop_begin","sample"), &AudioServer::sample_get_loop_begin ); +} - ClassDB::bind_method(_MD("sample_set_loop_end","sample","pos"), &AudioServer::sample_set_loop_end ); - ClassDB::bind_method(_MD("sample_get_loop_end","sample"), &AudioServer::sample_get_loop_end ); +/* MISC config */ +void AudioServer::lock() { + + AudioDriver::get_singleton()->lock(); +} +void AudioServer::unlock() { + + AudioDriver::get_singleton()->unlock(); + +} - ClassDB::bind_method(_MD("voice_create"), &AudioServer::voice_create ); - ClassDB::bind_method(_MD("voice_play","voice","sample"), &AudioServer::voice_play ); - ClassDB::bind_method(_MD("voice_set_volume","voice","volume"), &AudioServer::voice_set_volume ); - ClassDB::bind_method(_MD("voice_set_pan","voice","pan","depth","height"), &AudioServer::voice_set_pan,DEFVAL(0),DEFVAL(0) ); - ClassDB::bind_method(_MD("voice_set_filter","voice","type","cutoff","resonance","gain"), &AudioServer::voice_set_filter,DEFVAL(0) ); - ClassDB::bind_method(_MD("voice_set_chorus","voice","chorus"), &AudioServer::voice_set_chorus ); - ClassDB::bind_method(_MD("voice_set_reverb","voice","room","reverb"), &AudioServer::voice_set_reverb ); - ClassDB::bind_method(_MD("voice_set_mix_rate","voice","rate"), &AudioServer::voice_set_mix_rate ); - ClassDB::bind_method(_MD("voice_set_positional","voice","enabled"), &AudioServer::voice_set_positional ); +AudioServer::SpeakerMode AudioServer::get_speaker_mode() const { + return (AudioServer::SpeakerMode)AudioDriver::get_singleton()->get_speaker_mode(); +} +float AudioServer::get_mix_rate() const { - ClassDB::bind_method(_MD("voice_get_volume","voice"), &AudioServer::voice_get_volume ); - ClassDB::bind_method(_MD("voice_get_pan","voice"), &AudioServer::voice_get_pan ); - ClassDB::bind_method(_MD("voice_get_pan_height","voice"), &AudioServer::voice_get_pan_height ); - ClassDB::bind_method(_MD("voice_get_pan_depth","voice"), &AudioServer::voice_get_pan_depth ); - ClassDB::bind_method(_MD("voice_get_filter_type","voice"), &AudioServer::voice_get_filter_type ); - ClassDB::bind_method(_MD("voice_get_filter_cutoff","voice"), &AudioServer::voice_get_filter_cutoff ); - ClassDB::bind_method(_MD("voice_get_filter_resonance","voice"), &AudioServer::voice_get_filter_resonance ); - ClassDB::bind_method(_MD("voice_get_chorus","voice"), &AudioServer::voice_get_chorus ); - ClassDB::bind_method(_MD("voice_get_reverb_type","voice"), &AudioServer::voice_get_reverb_type ); - ClassDB::bind_method(_MD("voice_get_reverb","voice"), &AudioServer::voice_get_reverb ); - ClassDB::bind_method(_MD("voice_get_mix_rate","voice"), &AudioServer::voice_get_mix_rate ); - ClassDB::bind_method(_MD("voice_is_positional","voice"), &AudioServer::voice_is_positional ); + return AudioDriver::get_singleton()->get_mix_rate(); +} - ClassDB::bind_method(_MD("voice_stop","voice"), &AudioServer::voice_stop ); +float AudioServer::read_output_peak_db() const { - ClassDB::bind_method(_MD("free_rid","rid"), &AudioServer::free ); + return 0; +} - ClassDB::bind_method(_MD("set_stream_global_volume_scale","scale"), &AudioServer::set_stream_global_volume_scale ); - ClassDB::bind_method(_MD("get_stream_global_volume_scale"), &AudioServer::get_stream_global_volume_scale ); +AudioServer *AudioServer::get_singleton() { - ClassDB::bind_method(_MD("set_fx_global_volume_scale","scale"), &AudioServer::set_fx_global_volume_scale ); - ClassDB::bind_method(_MD("get_fx_global_volume_scale"), &AudioServer::get_fx_global_volume_scale ); + return singleton; +} - ClassDB::bind_method(_MD("set_event_voice_global_volume_scale","scale"), &AudioServer::set_event_voice_global_volume_scale ); - ClassDB::bind_method(_MD("get_event_voice_global_volume_scale"), &AudioServer::get_event_voice_global_volume_scale ); +double AudioServer::get_mix_time() const { - BIND_CONSTANT( SAMPLE_FORMAT_PCM8 ); - BIND_CONSTANT( SAMPLE_FORMAT_PCM16 ); - BIND_CONSTANT( SAMPLE_FORMAT_IMA_ADPCM ); + return 0; +} +double AudioServer::get_output_delay() const { - BIND_CONSTANT( SAMPLE_LOOP_NONE ); - BIND_CONSTANT( SAMPLE_LOOP_FORWARD ); - BIND_CONSTANT( SAMPLE_LOOP_PING_PONG ); + return 0; +} - BIND_CONSTANT( FILTER_NONE ); - BIND_CONSTANT( FILTER_LOWPASS ); - BIND_CONSTANT( FILTER_BANDPASS ); - BIND_CONSTANT( FILTER_HIPASS ); - BIND_CONSTANT( FILTER_NOTCH ); - BIND_CONSTANT( FILTER_BANDLIMIT ); ///< cutoff is LP resonace is HP +AudioServer* AudioServer::singleton=NULL; - BIND_CONSTANT( REVERB_SMALL ); - BIND_CONSTANT( REVERB_MEDIUM ); - BIND_CONSTANT( REVERB_LARGE ); - BIND_CONSTANT( REVERB_HALL ); - GLOBAL_DEF("audio/stream_buffering_ms",500); - GLOBAL_DEF("audio/video_delay_compensation_ms",300); +void AudioServer::_bind_methods() { } + AudioServer::AudioServer() { singleton=this; @@ -202,3 +296,4 @@ AudioServer::~AudioServer() { } + diff --git a/servers/audio_server.h b/servers/audio_server.h index 1482b40d4c..77aca39760 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -31,261 +31,171 @@ #include "variant.h" #include "object.h" +#include "audio_frame.h" +#include "servers/audio/audio_effect.h" -class AudioMixer { -protected: - void audio_mixer_chunk_call(int p_frames); -public: +class AudioDriver { - enum { - INVALID_CHANNEL=0xFFFFFFFF - }; + static AudioDriver *singleton; + uint64_t _last_mix_time; + uint64_t _mix_amount; + - typedef uint32_t ChannelID; +protected: - /* CHANNEL API */ + void audio_server_process(int p_frames,int32_t *p_buffer,bool p_update_mix_time=true); + void update_mix_time(int p_frames); - enum FilterType { - FILTER_NONE, - FILTER_LOWPASS, - FILTER_BANDPASS, - FILTER_HIPASS, - FILTER_NOTCH, - FILTER_PEAK, - FILTER_BANDLIMIT, ///< cutoff is LP resonace is HP - FILTER_LOW_SHELF, - FILTER_HIGH_SHELF +public: - }; - enum ReverbRoomType { + double get_mix_time() const; //useful for video -> audio sync - REVERB_SMALL, - REVERB_MEDIUM, - REVERB_LARGE, - REVERB_HALL, - MAX_REVERBS + enum SpeakerMode { + SPEAKER_MODE_STEREO, + SPEAKER_SURROUND_51, + SPEAKER_SURROUND_71, }; - virtual ChannelID channel_alloc(RID p_sample)=0; + static AudioDriver *get_singleton(); + void set_singleton(); - virtual void channel_set_volume(ChannelID p_channel, float p_gain)=0; - virtual void channel_set_pan(ChannelID p_channel, float p_pan, float p_depth=0,float height=0)=0; //pan and depth go from -1 to 1 - virtual void channel_set_filter(ChannelID p_channel, FilterType p_type, float p_cutoff, float p_resonance, float p_gain=1.0)=0; - virtual void channel_set_chorus(ChannelID p_channel, float p_chorus )=0; - virtual void channel_set_reverb(ChannelID p_channel, ReverbRoomType p_room_type, float p_reverb)=0; - virtual void channel_set_mix_rate(ChannelID p_channel, int p_mix_rate)=0; - virtual void channel_set_positional(ChannelID p_channel, bool p_positional)=0; + virtual const char* get_name() const=0; - virtual float channel_get_volume(ChannelID p_channel) const=0; - virtual float channel_get_pan(ChannelID p_channel) const=0; //pan and depth go from -1 to 1 - virtual float channel_get_pan_depth(ChannelID p_channel) const=0; //pan and depth go from -1 to 1 - virtual float channel_get_pan_height(ChannelID p_channel) const=0; //pan and depth go from -1 to 1 - virtual FilterType channel_get_filter_type(ChannelID p_channel) const=0; - virtual float channel_get_filter_cutoff(ChannelID p_channel) const=0; - virtual float channel_get_filter_resonance(ChannelID p_channel) const=0; - virtual float channel_get_filter_gain(ChannelID p_channel) const=0; - virtual float channel_get_chorus(ChannelID p_channel) const=0; - virtual ReverbRoomType channel_get_reverb_type(ChannelID p_channel) const=0; - virtual float channel_get_reverb(ChannelID p_channel) const=0; - - virtual int channel_get_mix_rate(ChannelID p_channel) const=0; - virtual bool channel_is_positional(ChannelID p_channel) const=0; - virtual bool channel_is_valid(ChannelID p_channel) const=0; + virtual Error init()=0; + virtual void start()=0; + virtual int get_mix_rate() const =0; + virtual SpeakerMode get_speaker_mode() const=0; + virtual void lock()=0; + virtual void unlock()=0; + virtual void finish()=0; + virtual float get_latency() { return 0; } - virtual void channel_free(ChannelID p_channel)=0; - virtual void set_mixer_volume(float p_volume)=0; - virtual ~AudioMixer() {} + AudioDriver(); + virtual ~AudioDriver() {} }; -class AudioServer : public Object { - GDCLASS( AudioServer, Object ); +class AudioDriverManager { - static AudioServer *singleton; -protected: -friend class AudioStream; -friend class EventStream; -friend class AudioMixer; + enum { - virtual AudioMixer *get_mixer()=0; - virtual void audio_mixer_chunk_callback(int p_frames)=0; + MAX_DRIVERS=10 + }; - static void _bind_methods(); + static AudioDriver *drivers[MAX_DRIVERS]; + static int driver_count; public: - - class EventStream { - protected: - AudioMixer *get_mixer() const; - public: - virtual void update(uint64_t p_usec)=0; - - virtual ~EventStream() {} - }; - - class AudioStream { - public: - virtual int get_channel_count() const=0; - virtual void set_mix_rate(int p_rate)=0; //notify the stream of the mix rate - virtual bool mix(int32_t *p_buffer,int p_frames)=0; - virtual void update()=0; - virtual bool can_update_mt() const { return true; } - virtual ~AudioStream() {} - }; + static void add_driver(AudioDriver *p_driver); + static int get_driver_count(); + static AudioDriver *get_driver(int p_driver); +}; - enum SampleFormat { +class AudioServer : public Object { - SAMPLE_FORMAT_PCM8, - SAMPLE_FORMAT_PCM16, - SAMPLE_FORMAT_IMA_ADPCM + GDCLASS( AudioServer, Object ) +public: + enum BusMode { + BUS_MODE_STEREO, + BUS_MODE_SURROUND }; - enum SampleLoopFormat { - SAMPLE_LOOP_NONE, - SAMPLE_LOOP_FORWARD, - SAMPLE_LOOP_PING_PONG // not supported in every platform - + //re-expose this her, as AudioDriver is not exposed to script + enum SpeakerMode { + SPEAKER_MODE_STEREO, + SPEAKER_SURROUND_51, + SPEAKER_SURROUND_71, }; +private: + uint32_t buffer_size; - /* SAMPLE API */ - - virtual RID sample_create(SampleFormat p_format, bool p_stereo, int p_length)=0; - - virtual void sample_set_description(RID p_sample, const String& p_description)=0; - virtual String sample_get_description(RID p_sample) const=0; - - virtual SampleFormat sample_get_format(RID p_sample) const=0; - virtual bool sample_is_stereo(RID p_sample) const=0; - virtual int sample_get_length(RID p_sample) const=0; - virtual const void* sample_get_data_ptr(RID p_sample) const=0; - - virtual void sample_set_signed_data(RID p_sample, const PoolVector<float>& p_buffer); - virtual void sample_set_data(RID p_sample, const PoolVector<uint8_t>& p_buffer)=0; - virtual PoolVector<uint8_t> sample_get_data(RID p_sample) const=0; + struct Bus { - virtual void sample_set_mix_rate(RID p_sample,int p_rate)=0; - virtual int sample_get_mix_rate(RID p_sample) const=0; + String name; + BusMode mode; + Vector<AudioFrame> buffer; - virtual void sample_set_loop_format(RID p_sample,SampleLoopFormat p_format)=0; - virtual SampleLoopFormat sample_get_loop_format(RID p_sample) const=0; + struct Effect { + Ref<AudioEffect> effect; + Ref<AudioEffectInstance> instance; + bool enabled; + }; - virtual void sample_set_loop_begin(RID p_sample,int p_pos)=0; - virtual int sample_get_loop_begin(RID p_sample) const=0; + Vector<Effect> effects; - virtual void sample_set_loop_end(RID p_sample,int p_pos)=0; - virtual int sample_get_loop_end(RID p_sample) const=0; - - - /* VOICE API */ - - enum FilterType { - FILTER_NONE, - FILTER_LOWPASS, - FILTER_BANDPASS, - FILTER_HIPASS, - FILTER_NOTCH, - FILTER_PEAK, - FILTER_BANDLIMIT, ///< cutoff is LP resonace is HP - FILTER_LOW_SHELF, - FILTER_HIGH_SHELF + float volume_db; }; - enum ReverbRoomType { - REVERB_SMALL, - REVERB_MEDIUM, - REVERB_LARGE, - REVERB_HALL - }; + Vector<Bus> buses; - virtual RID voice_create()=0; - virtual void voice_play(RID p_voice, RID p_sample)=0; + static void _bind_methods(); - virtual void voice_set_volume(RID p_voice, float p_volume)=0; - virtual void voice_set_pan(RID p_voice, float p_pan, float p_depth=0,float height=0)=0; //pan and depth go from -1 to 1 - virtual void voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance, float p_gain=0)=0; - virtual void voice_set_chorus(RID p_voice, float p_chorus )=0; - virtual void voice_set_reverb(RID p_voice, ReverbRoomType p_room_type, float p_reverb)=0; - virtual void voice_set_mix_rate(RID p_voice, int p_mix_rate)=0; - virtual void voice_set_positional(RID p_voice, bool p_positional)=0; + static AudioServer* singleton; +public: - virtual float voice_get_volume(RID p_voice) const=0; - virtual float voice_get_pan(RID p_voice) const=0; //pan and depth go from -1 to 1 - virtual float voice_get_pan_depth(RID p_voice) const=0; //pan and depth go from -1 to 1 - virtual float voice_get_pan_height(RID p_voice) const=0; //pan and depth go from -1 to 1 - virtual FilterType voice_get_filter_type(RID p_voice) const=0; - virtual float voice_get_filter_cutoff(RID p_voice) const=0; - virtual float voice_get_filter_resonance(RID p_voice) const=0; - virtual float voice_get_chorus(RID p_voice) const=0; - virtual ReverbRoomType voice_get_reverb_type(RID p_voice) const=0; - virtual float voice_get_reverb(RID p_voice) const=0; - virtual int voice_get_mix_rate(RID p_voice) const=0; - virtual bool voice_is_positional(RID p_voice) const=0; + void set_bus_count(int p_count); + int get_bus_count() const; - virtual void voice_stop(RID p_voice)=0; - virtual bool voice_is_active(RID p_voice) const=0; + void set_bus_mode(int p_bus,BusMode p_mode); + BusMode get_bus_mode(int p_bus) const; - /* STREAM API */ + void set_bus_name(int p_bus,const String& p_name); + String get_bus_name(int p_bus) const; - virtual RID audio_stream_create(AudioStream *p_stream)=0; - virtual RID event_stream_create(EventStream *p_stream)=0; + void set_bus_volume_db(int p_bus,float p_volume_db); + float get_bus_volume_db(int p_bus) const; - virtual void stream_set_active(RID p_stream, bool p_active)=0; - virtual bool stream_is_active(RID p_stream) const=0; + void add_bus_effect(int p_bus,const Ref<AudioEffect>& p_effect,int p_at_pos=-1); + void remove_bus_effect(int p_bus,int p_effect); - virtual void stream_set_volume_scale(RID p_stream, float p_scale)=0; - virtual float stream_set_volume_scale(RID p_stream) const=0; + int get_bus_effect_count(int p_bus); + Ref<AudioEffect> get_bus_effect(int p_bus,int p_effect); - /* Audio Physics API */ + void swap_bus_effects(int p_bus,int p_effect,int p_by_effect); - virtual void free(RID p_id)=0; + void set_bus_effect_enabled(int p_bus,int p_effect,bool p_enabled); + bool is_bus_effect_enabled(int p_bus,int p_effect) const; - virtual void init()=0; - virtual void finish()=0; - virtual void update()=0; + virtual void init(); + virtual void finish(); + virtual void update(); /* MISC config */ - virtual void lock()=0; - virtual void unlock()=0; - virtual int get_default_channel_count() const=0; - virtual int get_default_mix_rate() const=0; + virtual void lock(); + virtual void unlock(); - virtual void set_stream_global_volume_scale(float p_volume)=0; - virtual void set_fx_global_volume_scale(float p_volume)=0; - virtual void set_event_voice_global_volume_scale(float p_volume)=0; - virtual float get_stream_global_volume_scale() const=0; - virtual float get_fx_global_volume_scale() const=0; - virtual float get_event_voice_global_volume_scale() const=0; + virtual SpeakerMode get_speaker_mode() const; + virtual float get_mix_rate() const; - virtual uint32_t read_output_peak() const=0; + virtual float read_output_peak_db() const; static AudioServer *get_singleton(); - virtual double get_mix_time() const=0; //useful for video -> audio sync - virtual double get_output_delay() const=0; + virtual double get_mix_time() const; //useful for video -> audio sync + virtual double get_output_delay() const; AudioServer(); virtual ~AudioServer(); }; -VARIANT_ENUM_CAST( AudioServer::SampleFormat ); -VARIANT_ENUM_CAST( AudioServer::SampleLoopFormat ); -VARIANT_ENUM_CAST( AudioServer::FilterType ); -VARIANT_ENUM_CAST( AudioServer::ReverbRoomType ); +VARIANT_ENUM_CAST( AudioServer::BusMode ) +VARIANT_ENUM_CAST( AudioServer::SpeakerMode ) typedef AudioServer AS; + #endif // AUDIO_SERVER_H diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 84389c9b78..8aed07d5e5 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -126,14 +126,14 @@ void AreaSW::set_space_override_mode(PhysicsServer::AreaSpaceOverrideMode p_mode void AreaSW::set_param(PhysicsServer::AreaParameter p_param, const Variant& p_value) { switch(p_param) { - case PhysicsServer::AREA_PARAM_GRAVITY: gravity=p_value; ; break; - case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; ; break; - case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break; - case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break; - case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break; - case PhysicsServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; ; break; - case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; ; break; - case PhysicsServer::AREA_PARAM_PRIORITY: priority=p_value; ; break; + case PhysicsServer::AREA_PARAM_GRAVITY: gravity=p_value; break; + case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; break; + case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; break; + case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; break; + case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; break; + case PhysicsServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; break; + case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; break; + case PhysicsServer::AREA_PARAM_PRIORITY: priority=p_value; break; } diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 81604dd5e1..a67dda3a01 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -621,7 +621,7 @@ void BodySW::integrate_velocities(real_t p_step) { if (ang_vel!=0.0) { Vector3 ang_vel_axis = total_angular_velocity / ang_vel; - Basis rot( ang_vel_axis, -ang_vel*p_step ); + Basis rot( ang_vel_axis, ang_vel*p_step ); Basis identity3(1, 0, 0, 0, 1, 0, 0, 0, 1); transform.origin += ((identity3 - rot) * transform.basis).xform(center_of_mass_local); transform.basis = rot * transform.basis; diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h index 2cc2d7d45e..20b3efc7fb 100644 --- a/servers/physics/broad_phase_sw.h +++ b/servers/physics/broad_phase_sw.h @@ -30,7 +30,7 @@ #define BROAD_PHASE_SW_H #include "math_funcs.h" -#include "aabb.h" +#include "rect3.h" class CollisionObjectSW; diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp index d02303e23d..d41012caa4 100644 --- a/servers/physics/collision_solver_sat.cpp +++ b/servers/physics/collision_solver_sat.cpp @@ -639,7 +639,7 @@ static void _collision_sphere_convex_polygon(const ShapeSW *p_a,const Transform Vector3 n1=v2-v1; Vector3 n2=v2-v3; - Vector3 axis = n1.cross(n2).cross(n1).normalized();; + Vector3 axis = n1.cross(n2).cross(n1).normalized(); if (!separator.test_axis( axis )) return; diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp index 277346fbbb..d50d5a1a73 100644 --- a/servers/physics/joints/hinge_joint_sw.cpp +++ b/servers/physics/joints/hinge_joint_sw.cpp @@ -371,7 +371,7 @@ void HingeJointSW::solve(float p_step) { real_t desiredMotorVel = m_motorTargetVelocity; real_t motor_relvel = desiredMotorVel - projRelVel; - real_t unclippedMotorImpulse = m_kHinge * motor_relvel;; + real_t unclippedMotorImpulse = m_kHinge * motor_relvel; //todo: should clip against accumulated impulse real_t clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index 9f8d1107f4..4114980b82 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -1620,7 +1620,7 @@ void HeightMapShapeSW::_setup(PoolVector<real_t> p_heights,int p_width,int p_dep heights=p_heights; width=p_width; - depth=p_depth;; + depth=p_depth; cell_size=p_cell_size; PoolVector<real_t>::Read r = heights. read(); diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 8ccdd51067..2625502717 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -125,14 +125,14 @@ void Area2DSW::set_space_override_mode(Physics2DServer::AreaSpaceOverrideMode p_ void Area2DSW::set_param(Physics2DServer::AreaParameter p_param, const Variant& p_value) { switch(p_param) { - case Physics2DServer::AREA_PARAM_GRAVITY: gravity=p_value; ; break; - case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; ; break; - case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break; - case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break; - case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break; - case Physics2DServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; ; break; - case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; ; break; - case Physics2DServer::AREA_PARAM_PRIORITY: priority=p_value; ; break; + case Physics2DServer::AREA_PARAM_GRAVITY: gravity=p_value; break; + case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; break; + case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; break; + case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; break; + case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; break; + case Physics2DServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; break; + case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; break; + case Physics2DServer::AREA_PARAM_PRIORITY: priority=p_value; break; } diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index 72ae221c39..e6b62ffa66 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -249,7 +249,7 @@ bool BodyPair2DSW::setup(float p_step) { Transform2D xform_A = xform_Au * A->get_shape_transform(shape_A); Transform2D xform_Bu = B->get_transform(); - xform_Bu.translate(-A->get_transform().get_origin()); + xform_Bu.elements[2]-=A->get_transform().get_origin(); Transform2D xform_B = xform_Bu * B->get_shape_transform(shape_B); Shape2DSW *shape_A_ptr=A->get_shape(shape_A); diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp index 02d59b69f0..20a5934eb8 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/collision_solver_2d_sw.cpp @@ -203,14 +203,14 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A,const Transfo cinfo.aabb_tests=0; Transform2D rel_transform = p_transform_A; - rel_transform.translate(-p_transform_B.get_origin()); + rel_transform.elements[2]-=p_transform_B.get_origin(); //quickly compute a local Rect2 Rect2 local_aabb; for(int i=0;i<2;i++) { - Vector2 axis( p_transform_B.get_axis(i) ); + Vector2 axis( p_transform_B.elements[i] ); float axis_scale = 1.0/axis.length(); axis*=axis_scale; diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp index 8730bb9ee8..027f318d2d 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp +++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp @@ -95,7 +95,7 @@ void Physics2DServerWrapMT::sync() { else step_sem->wait(); //must not wait if a step was not issued } - physics_2d_server->sync();; + physics_2d_server->sync(); } void Physics2DServerWrapMT::flush_queries(){ @@ -105,7 +105,7 @@ void Physics2DServerWrapMT::flush_queries(){ void Physics2DServerWrapMT::end_sync() { - physics_2d_server->end_sync();; + physics_2d_server->end_sync(); } void Physics2DServerWrapMT::init() { diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 9160d064ef..07a9d84ec8 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -150,7 +150,7 @@ _FORCE_INLINE_ void project_range_cast(const Vector2& p_cast, const Vector2& p_n real_t mina,maxa;\ real_t minb,maxb;\ Transform2D ofsb=p_transform;\ - ofsb.translate(p_cast);\ + ofsb.elements[2]+=p_cast;\ project_range(p_normal,p_transform,mina,maxa);\ project_range(p_normal,ofsb,minb,maxb); \ r_min=MIN(mina,minb);\ diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index e95707f135..a48b6d3827 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -714,7 +714,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co break; } - body_transform.translate(recover_motion); + body_transform.elements[2]+=recover_motion; body_aabb.pos+=recover_motion; recover_attempts--; @@ -863,7 +863,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co //it collided, let's get the rest info in unsafe advance Transform2D ugt = body_transform; - ugt.translate(p_motion*unsafe); + ugt.elements[2]+=p_motion*unsafe; _RestCallbackData2D rcd; rcd.best_len=0; diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index bd5a58e57b..39b790111b 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -179,7 +179,7 @@ int Physics2DShapeQueryParameters::get_object_type_mask() const{ } void Physics2DShapeQueryParameters::set_exclude(const Vector<RID>& p_exclude) { - exclude.clear();; + exclude.clear(); for(int i=0;i<p_exclude.size();i++) exclude.insert(p_exclude[i]); diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 93553efb27..ab13e2b3a5 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -178,7 +178,7 @@ int PhysicsShapeQueryParameters::get_object_type_mask() const{ } void PhysicsShapeQueryParameters::set_exclude(const Vector<RID>& p_exclude) { - exclude.clear();; + exclude.clear(); for(int i=0;i<p_exclude.size();i++) exclude.insert(p_exclude[i]); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 9a98890a26..8b831f4ff6 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -33,10 +33,9 @@ #include "audio_server.h" #include "physics_server.h" #include "physics_2d_server.h" -#include "spatial_sound_server.h" -#include "spatial_sound_2d_server.h" #include "script_debugger_remote.h" #include "visual/shader_types.h" + static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsage>* r_usage) { List<VS::TextureInfo> tinfo; @@ -65,8 +64,6 @@ void register_server_types() { GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("AudioServer",AudioServer::get_singleton()) ); GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("PhysicsServer",PhysicsServer::get_singleton()) ); GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("Physics2DServer",Physics2DServer::get_singleton()) ); - GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("SpatialSoundServer",SpatialSoundServer::get_singleton()) ); - GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("SpatialSound2DServer",SpatialSound2DServer::get_singleton()) ); shader_types = memnew( ShaderTypes ); diff --git a/servers/spatial_sound/SCsub b/servers/spatial_sound/SCsub deleted file mode 100644 index ccc76e823f..0000000000 --- a/servers/spatial_sound/SCsub +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -Import('env') - -env.add_source_files(env.servers_sources, "*.cpp") - -Export('env') diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp deleted file mode 100644 index d550134d82..0000000000 --- a/servers/spatial_sound/spatial_sound_server_sw.cpp +++ /dev/null @@ -1,1071 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_server_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "spatial_sound_server_sw.h" -#include "os/os.h" -#include "servers/audio/audio_filter_sw.h" - - - -int SpatialSoundServerSW::InternalAudioStream::get_channel_count() const { - - return AudioServer::get_singleton()->get_default_channel_count(); -} - -void SpatialSoundServerSW::InternalAudioStream::set_mix_rate(int p_rate) { - - -} - -void SpatialSoundServerSW::InternalAudioStream::update() { - - owner->_update_sources(); -} - -bool SpatialSoundServerSW::InternalAudioStream::mix(int32_t *p_buffer,int p_frames) { - - return owner->internal_buffer_mix(p_buffer,p_frames); -} - -void SpatialSoundServerSW::_update_sources() { - - _THREAD_SAFE_METHOD_ - for (Set<Source*>::Element *E=streaming_sources.front();E;E=E->next()) { - - Source *s=E->get(); - ERR_CONTINUE(!s->stream); - s->stream->update(); - } -} - - -SpatialSoundServerSW::Room::Room() { - - //params[ROOM_PARAM_SPEED_OF_SOUND]=343.0; - params[ROOM_PARAM_SPEED_OF_SOUND_SCALE]=1; - params[ROOM_PARAM_DOPPLER_FACTOR]=1.0; - params[ROOM_PARAM_PITCH_SCALE]=1.0; - params[ROOM_PARAM_VOLUME_SCALE_DB]=0; - params[ROOM_PARAM_REVERB_SEND]=0; - params[ROOM_PARAM_CHORUS_SEND]=0; - params[ROOM_PARAM_ATTENUATION_SCALE]=1.0; - params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]=5000; - params[ROOM_PARAM_ATTENUATION_HF_FLOOR_DB]=-24.0; - params[ROOM_PARAM_ATTENUATION_HF_RATIO_EXP]=1.0; - params[ROOM_PARAM_ATTENUATION_REVERB_SCALE]=0.0; - override_other_sources=false; - reverb=ROOM_REVERB_HALL; - octree_id=0; - level=-1; - - -} - - -SpatialSoundServerSW::Source::Source() { - - params[SOURCE_PARAM_VOLUME_DB]=0.0; - params[SOURCE_PARAM_PITCH_SCALE]=1.0; - params[SOURCE_PARAM_ATTENUATION_MIN_DISTANCE]=1; - params[SOURCE_PARAM_ATTENUATION_MAX_DISTANCE]=100; - params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]=1.0; //linear (and not really good) - params[SOURCE_PARAM_EMISSION_CONE_DEGREES]=180.0; //cone disabled - params[SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB]=-6.0; //minus 6 db attenuation - stream=NULL; - voices.resize(1); - last_voice=0; -} - -SpatialSoundServerSW::Source::Voice::Voice() { - - active=false; - restart=false; - pitch_scale=1.0; - volume_scale=0.0; - voice_rid=AudioServer::get_singleton()->voice_create(); - -} -SpatialSoundServerSW::Source::Voice::~Voice() { - - AudioServer::get_singleton()->free(voice_rid); -} - - -SpatialSoundServerSW::Listener::Listener() { - - params[LISTENER_PARAM_VOLUME_SCALE_DB]=0.0; - params[LISTENER_PARAM_PITCH_SCALE]=1.0; - params[LISTENER_PARAM_ATTENUATION_SCALE]=1.0; - params[LISTENER_PARAM_RECEPTION_CONE_DEGREES]=60.0; - params[LISTENER_PARAM_RECEPTION_CONE_ATTENUATION_DB]=-6; // minus six decibels - -} - -/* SPACE */ -RID SpatialSoundServerSW::space_create() { - - Space* space = memnew( Space ); - RID space_rid = space_owner.make_rid(space); - space->default_room=room_create(); - room_set_space(space->default_room,space_rid); - return space_rid; -} - -/* ROOM */ - -RID SpatialSoundServerSW::room_create() { - - Room *room = memnew( Room ); - return room_owner.make_rid(room); -} - -void SpatialSoundServerSW::room_set_space(RID p_room,RID p_space) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - - if (room->space.is_valid()) { - - Space *space = space_owner.get(room->space); - space->rooms.erase(p_room); - space->octree.erase(room->octree_id); - //room->octree_id=0; - } - - room->space=RID(); - - if (p_space.is_valid()) { - - Space *space = space_owner.get(p_space); - ERR_FAIL_COND(!space); - space->rooms.insert(p_room); - room->octree_id=space->octree.create(room,Rect3()); - //set bounds - Rect3 aabb = room->bounds.is_empty()?Rect3():room->bounds.get_aabb(); - space->octree.move(room->octree_id,room->transform.xform(aabb)); - room->space=p_space; - } - - -} - -RID SpatialSoundServerSW::room_get_space(RID p_room) const { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,RID()); - - - return room->space; -} - - - -void SpatialSoundServerSW::room_set_bounds(RID p_room, const BSP_Tree& p_bounds) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - - room->bounds=p_bounds; - - if (!room->space.is_valid()) - return; - - Rect3 aabb = room->bounds.is_empty()?Rect3():room->bounds.get_aabb(); - Space* space = space_owner.get(room->space); - ERR_FAIL_COND(!space); - - space->octree.move(room->octree_id,room->transform.xform(aabb)); - -} -BSP_Tree SpatialSoundServerSW::room_get_bounds(RID p_room) const { - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,BSP_Tree()); - - return room->bounds; -} - -void SpatialSoundServerSW::room_set_transform(RID p_room, const Transform& p_transform) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->transform=p_transform; - room->inverse_transform=p_transform.affine_inverse(); // needs to be done to unscale BSP properly - - if (!room->space.is_valid()) - return; - - if (!room->bounds.is_empty()) { - - Space* space = space_owner.get(room->space); - ERR_FAIL_COND(!space); - - space->octree.move(room->octree_id,room->transform.xform(room->bounds.get_aabb())); - } -} - -Transform SpatialSoundServerSW::room_get_transform(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,Transform()); - return room->transform; -} - - -void SpatialSoundServerSW::room_set_param(RID p_room, RoomParam p_param, float p_value) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - ERR_FAIL_INDEX(p_param,ROOM_PARAM_MAX); - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->params[p_param]=p_value; - -} -float SpatialSoundServerSW::room_get_param(RID p_room, RoomParam p_param) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - ERR_FAIL_INDEX_V(p_param,ROOM_PARAM_MAX,0); - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,0); - return room->params[p_param]; -} - -void SpatialSoundServerSW::room_set_level(RID p_room, int p_level) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->level =p_level; - -} - -int SpatialSoundServerSW::room_get_level(RID p_room) const { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,0); - return room->level; - -} - - -void SpatialSoundServerSW::room_set_reverb(RID p_room, RoomReverb p_reverb) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->reverb=p_reverb; - -} -SpatialSoundServerSW::RoomReverb SpatialSoundServerSW::room_get_reverb(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,ROOM_REVERB_SMALL); - return room->reverb; -} - -//useful for underwater or rooms with very strange conditions -void SpatialSoundServerSW::room_set_force_params_to_all_sources(RID p_room, bool p_force) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->override_other_sources=p_force; - -} -bool SpatialSoundServerSW::room_is_forcing_params_to_all_sources(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,false); - return room->override_other_sources; -} - -/* SOURCE */ - -RID SpatialSoundServerSW::source_create(RID p_space) { - - Space *space = space_owner.get(p_space); - ERR_FAIL_COND_V(!space,RID()); - - Source *source = memnew( Source ); - source->space=p_space; - RID source_rid = source_owner.make_rid(source); - space->sources.insert(source_rid); - - return source_rid; -} - - -void SpatialSoundServerSW::source_set_polyphony(RID p_source,int p_voice_count) { - - - ERR_FAIL_COND(p_voice_count<=0); // more than 32 is too much, change this if you really need more - if (p_voice_count>32) { - - ERR_PRINT("Voices will be clipped to 32"); - p_voice_count=32; - } - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - - if (p_voice_count<source->voices.size()) { - - for(int i=p_voice_count;i<source->voices.size();i++) { - active_voices.erase(ActiveVoice(source,i)); //erase from active voices - } - } - source->voices.resize(p_voice_count); - -} - -int SpatialSoundServerSW::source_get_polyphony(RID p_source) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,-1); - return source->voices.size(); - -} - -void SpatialSoundServerSW::source_set_transform(RID p_source, const Transform& p_transform) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - source->transform=p_transform; - source->transform.orthonormalize(); -} -Transform SpatialSoundServerSW::source_get_transform(RID p_source) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,Transform()); - return source->transform; -} - -void SpatialSoundServerSW::source_set_param(RID p_source, SourceParam p_param, float p_value) { - - ERR_FAIL_INDEX(p_param,SOURCE_PARAM_MAX); - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - source->params[p_param]=p_value; - -} -float SpatialSoundServerSW::source_get_param(RID p_source, SourceParam p_param) const { - ERR_FAIL_INDEX_V(p_param,SOURCE_PARAM_MAX,0); - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,0); - return source->params[p_param]; - - -} - -void SpatialSoundServerSW::source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - AudioServer::get_singleton()->lock(); - source->stream=p_stream; - _THREAD_SAFE_METHOD_ - - if (!p_stream) { - streaming_sources.erase(source); - active_voices.erase(ActiveVoice(source,VOICE_IS_STREAM)); - } else { - streaming_sources.insert(source); - active_voices.insert(ActiveVoice(source,VOICE_IS_STREAM)); - zeromem(source->stream_data.filter_state,sizeof(Source::StreamData::FilterState)*4); //reset filter for safetyness - p_stream->set_mix_rate(AudioServer::get_singleton()->get_default_mix_rate()); - } - - AudioServer::get_singleton()->unlock(); - -} //null to unset - -SpatialSoundServer::SourceVoiceID SpatialSoundServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,SOURCE_INVALID_VOICE); - - int to_play=0; - - if (p_voice==SOURCE_NEXT_VOICE) { - to_play=source->last_voice+1; - if (to_play>=source->voices.size()) - to_play=0; - - } else - to_play=p_voice; - - ERR_FAIL_INDEX_V(to_play,source->voices.size(),SOURCE_INVALID_VOICE); - - source->voices[to_play].restart=true; - source->voices[to_play].sample_rid=p_sample; - source->voices[to_play].sample_mix_rate=p_mix_rate; - source->voices[to_play].pitch_scale=1; - source->voices[to_play].volume_scale=0; - source->last_voice=to_play; - active_voices.insert(ActiveVoice(source,to_play)); - return to_play; -} - -/* VOICES */ -void SpatialSoundServerSW::source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - source->voices[p_voice].pitch_scale=p_pitch_scale; - -} -void SpatialSoundServerSW::source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_db) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - source->voices[p_voice].volume_scale=p_db; - -} - -bool SpatialSoundServerSW::source_is_voice_active(RID p_source, SourceVoiceID p_voice) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,false); - ERR_FAIL_INDEX_V(p_voice,source->voices.size(),false); - return source->voices[p_voice].active || source->voices[p_voice].restart; - -} -void SpatialSoundServerSW::source_stop_voice(RID p_source, SourceVoiceID p_voice) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - if (source->voices[p_voice].active) { - AudioServer::get_singleton()->voice_stop(source->voices[p_voice].voice_rid); - } - source->voices[p_voice].active=false; - source->voices[p_voice].restart=false; - active_voices.erase(ActiveVoice(source,p_voice)); -} - -/* LISTENER */ - -RID SpatialSoundServerSW::listener_create() { - - Listener *listener = memnew( Listener ); - RID listener_rid = listener_owner.make_rid(listener); - return listener_rid; - -} - -void SpatialSoundServerSW::listener_set_space(RID p_listener,RID p_space) { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - - if (listener->space.is_valid()) { - - Space *lspace = space_owner.get(listener->space); - ERR_FAIL_COND(!lspace); - lspace->listeners.erase(p_listener); - } - - listener->space=RID(); - - if (p_space.is_valid()) { - Space *space = space_owner.get(p_space); - ERR_FAIL_COND(!space); - - listener->space=p_space; - space->listeners.insert(p_listener); - } - -} - -void SpatialSoundServerSW::listener_set_transform(RID p_listener, const Transform& p_transform) { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - listener->transform=p_transform; - listener->transform.orthonormalize(); //must be done.. -} -Transform SpatialSoundServerSW::listener_get_transform(RID p_listener) const { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND_V(!listener,Transform()); - return listener->transform; -} - -void SpatialSoundServerSW::listener_set_param(RID p_listener, ListenerParam p_param, float p_value) { - - ERR_FAIL_INDEX(p_param,LISTENER_PARAM_MAX); - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - listener->params[p_param]=p_value; -} - -float SpatialSoundServerSW::listener_get_param(RID p_listener, ListenerParam p_param) const { - - ERR_FAIL_INDEX_V(p_param,LISTENER_PARAM_MAX,0); - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND_V(!listener,0); - return listener->params[p_param]; -} - - -/* MISC */ - -void SpatialSoundServerSW::free(RID p_id) { - - - if (space_owner.owns(p_id)) { - - Space *space = space_owner.get(p_id); - free(space->default_room); - - while(space->listeners.size()) { - listener_set_space(space->listeners.front()->get(),RID()); - } - while(space->sources.size()) { - free(space->sources.front()->get()); - } - while(space->rooms.size()) { - room_set_space(space->rooms.front()->get(),RID()); - } - space_owner.free(p_id); - memdelete(space); - - } else if (source_owner.owns(p_id)) { - - Source *source = source_owner.get(p_id); - if (source->stream) - source_set_audio_stream(p_id,NULL); - - Space *space = space_owner.get(source->space); - ERR_FAIL_COND(!space); - space->sources.erase(p_id); - for(int i=0;i<source->voices.size();i++) { - active_voices.erase(ActiveVoice(source,i)); - } - source_owner.free(p_id); - memdelete(source); - } else if (listener_owner.owns(p_id)) { - - Listener *listener = listener_owner.get(p_id); - if (listener->space.is_valid()) { - Space *space = space_owner.get(listener->space); - ERR_FAIL_COND(!space); - space->listeners.erase(p_id); - } - listener_owner.free(p_id); - memdelete(listener); - - } else if (room_owner.owns(p_id)) { - - Room *room = room_owner.get(p_id); - - if (room->space.is_valid()) { - Space *space = space_owner.get(room->space); - ERR_FAIL_COND(!space); - space->octree.erase(room->octree_id); - space->rooms.erase(p_id); - } - room_owner.free(p_id); - memdelete(room); - } else { - ERR_PRINT("Attempt to free invalid ID") ; - } - -} - -void SpatialSoundServerSW::_clean_up_owner(RID_OwnerBase *p_owner, const char *p_area) { - - List<RID> rids; - p_owner->get_owned_list(&rids); - - for(List<RID>::Element *I=rids.front();I;I=I->next()) { - if (OS::get_singleton()->is_stdout_verbose()) { - - print_line("Leaked RID ("+itos(I->get().get_id())+") of type "+String(p_area)); - } - free(I->get()); - } -} - -void SpatialSoundServerSW::init() { - - internal_buffer = memnew_arr(int32_t, INTERNAL_BUFFER_SIZE*INTERNAL_BUFFER_MAX_CHANNELS); - internal_buffer_channels=AudioServer::get_singleton()->get_default_channel_count(); - - internal_audio_stream = memnew( InternalAudioStream ); - internal_audio_stream->owner=this; - internal_audio_stream_rid = AudioServer::get_singleton()->audio_stream_create(internal_audio_stream); - - AudioServer::get_singleton()->stream_set_active(internal_audio_stream_rid,true); - -} - - - -static float _get_attenuation(float cosine, float angle, float attenuation) { - - - float listener_ang = Math::rad2deg(Math::acos(cosine))-angle; - - if (listener_ang>0 && angle<180.0) { - listener_ang/=(180.0-angle); - return Math::db2linear(Math::sin(listener_ang*(Math_PI/2.0))*attenuation); - } - return 1.0; -} - - -bool SpatialSoundServerSW::internal_buffer_mix(int32_t *p_buffer,int p_frames) { - - if (streaming_sources.size()==0) - return false; //nothing to mix - - - for (Set<Source*>::Element *E=streaming_sources.front();E;E=E->next()) { - - Source *s=E->get(); - ERR_CONTINUE(!s->stream); - - int channels = s->stream->get_channel_count(); - Source::StreamData &sd=s->stream_data; - - int todo=p_frames; - - AudioFilterSW filter; - filter.set_sampling_rate(AudioServer::get_singleton()->get_default_mix_rate()); - filter.set_cutoff(sd.filter_cutoff); - filter.set_gain(sd.filter_gain); - filter.set_resonance(1); - filter.set_mode(AudioFilterSW::HIGHSHELF); - filter.set_stages(1); - AudioFilterSW::Coeffs coefs; - filter.prepare_coefficients(&coefs); - - int32_t in[4]; -#ifndef SPATIAL_SOUND_SERVER_NO_FILTER -#define DO_FILTER(m_c)\ - {\ - float val = in[m_c];\ - float pre=val;\ - val = val*coefs.b0 + sd.filter_state[m_c].hb[0]*coefs.b1 + sd.filter_state[m_c].hb[1]*coefs.b2 + sd.filter_state[m_c].ha[0]*coefs.a1 + sd.filter_state[m_c].ha[1]*coefs.a2;\ - sd.filter_state[m_c].ha[1]=sd.filter_state[m_c].ha[0];\ - sd.filter_state[m_c].hb[1]=sd.filter_state[m_c].hb[0]; \ - sd.filter_state[m_c].hb[0]=pre;\ - sd.filter_state[m_c].ha[0]=val;\ - in[m_c]=Math::fast_ftoi(val);\ - } -#else -#define DO_FILTER(m_c) -#endif - - while(todo) { - - int to_mix=MIN(todo,INTERNAL_BUFFER_SIZE); - - s->stream->mix(internal_buffer,to_mix); - - switch(internal_buffer_channels) { - - case 2: { - - float p = sd.panning.x*0.5+0.5; - float panf[2]={ (1.0-p),p }; - panf[0]*=sd.volume; - panf[1]*=sd.volume; - - int32_t pan[2]={Math::fast_ftoi(panf[0]*(1<<16)),Math::fast_ftoi(panf[1]*(1<<16))}; - - switch(channels) { - case 1: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[i]; - in[1]=internal_buffer[i]; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - case 2: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<1)+0]; - in[1]=internal_buffer[(i<<1)+1]; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - case 4: { - - for(int i=0;i<to_mix;i++) { - - in[0]=(internal_buffer[(i<<2)+0]+internal_buffer[(i<<2)+2])>>1; - in[1]=(internal_buffer[(i<<2)+1]+internal_buffer[(i<<2)+3])>>1; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - - } break; - - } break; - case 4: { - - float xp = sd.panning.x*0.5+0.5; - float yp = sd.panning.y*0.5+0.5; - float panf[4]={ (1.0-xp)*(1.0-yp),(xp)*(1.0-yp),(1.0-xp)*(yp),(xp)*(yp) }; - panf[0]*=sd.volume; - panf[1]*=sd.volume; - panf[2]*=sd.volume; - panf[3]*=sd.volume; - - int32_t pan[4]={ - Math::fast_ftoi(panf[0]*(1<<16)), - Math::fast_ftoi(panf[1]*(1<<16)), - Math::fast_ftoi(panf[2]*(1<<16)), - Math::fast_ftoi(panf[3]*(1<<16))}; - - switch(channels) { - case 1: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[i]; - in[1]=internal_buffer[i]; - in[2]=internal_buffer[i]; - in[3]=internal_buffer[i]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - case 2: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<1)+0]; - in[1]=internal_buffer[(i<<1)+1]; - in[2]=internal_buffer[(i<<1)+0]; - in[3]=internal_buffer[(i<<1)+1]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - case 4: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<2)+0]; - in[1]=internal_buffer[(i<<2)+1]; - in[2]=internal_buffer[(i<<2)+2]; - in[3]=internal_buffer[(i<<2)+3]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - - } break; - - } break; - case 6: { - - - } break; - } - p_buffer+=to_mix*internal_buffer_channels; - todo-=to_mix; - - } - - } - - return true; -} - -void SpatialSoundServerSW::update(float p_delta) { - - List<ActiveVoice> to_disable; - - - for(Set<ActiveVoice>::Element *E=active_voices.front();E;E=E->next()) { - - Source *source = E->get().source; - int voice = E->get().voice; - - if (voice!=VOICE_IS_STREAM) { - Source::Voice &v=source->voices[voice]; - ERR_CONTINUE(!v.active && !v.restart); // likely a bug... - } - - //this could be optimized at some point... am not sure - Space *space=space_owner.get(source->space); - Room *room=room_owner.get(space->default_room); - int max_level=-0x80000000; - int rooms_culled = space->octree.cull_point(source->transform.origin,cull_rooms,MAX_CULL_ROOMS); - for(int i=0;i<rooms_culled;i++) { - - Room *r=cull_rooms[i]; - ERR_CONTINUE( r->bounds.is_empty() ); // how did this happen?? - if (r->level<=max_level) //ignore optimization (level too low) - continue; - Vector3 local_point = r->inverse_transform.xform(source->transform.origin); - if (!r->bounds.point_is_inside(local_point)) - continue; - room=r; - max_level=r->level; - - } - - - //compute mixing weights (support for multiple listeners in the same output) - float total_distance=0; - for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) { - Listener *listener=listener_owner.get(L->get()); - total_distance+=listener->transform.origin.distance_to(source->transform.origin); - } - - //compute spatialization variables, weighted according to distance - float volume_attenuation = 0.0; - float air_absorption_hf_cutoff = 0.0; - float air_absorption = 0.0; - float pitch_scale=1.0; - Vector3 panning; - - - //print_line("listeners: "+itos(space->listeners.size())); - - - for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) { - - Listener *listener=listener_owner.get(L->get()); - - Vector3 rel_vector = listener->transform.xform_inv(source->transform.origin); - Vector3 source_rel_vector = source->transform.xform_inv(listener->transform.origin).normalized(); - float distance=rel_vector.length(); - float weight = distance/total_distance; - float pscale=1.0; - - float distance_scale=listener->params[LISTENER_PARAM_ATTENUATION_SCALE]*room->params[ROOM_PARAM_ATTENUATION_SCALE]; - float distance_min=source->params[SOURCE_PARAM_ATTENUATION_MIN_DISTANCE]*distance_scale; - float distance_max=source->params[SOURCE_PARAM_ATTENUATION_MAX_DISTANCE]*distance_scale; - float attenuation_exp=source->params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]; - float attenuation=1; - - //print_line("DIST MIN: "+rtos(distance_min)); - //print_line("DIST MAX: "+rtos(distance_max)); - if (distance_max>0) { - distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); - } - - float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; - float hf_attenuation_exp = room->params[ROOM_PARAM_ATTENUATION_HF_RATIO_EXP]; - float hf_attenuation_floor = room->params[ROOM_PARAM_ATTENUATION_HF_FLOOR_DB]; - float absorption=Math::db2linear(Math::lerp(hf_attenuation_floor,0,Math::pow(attenuation,hf_attenuation_exp))); - - // source emission cone - - float emission_deg=source->params[SOURCE_PARAM_EMISSION_CONE_DEGREES]; - float emission_attdb=source->params[SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB]; - absorption*=_get_attenuation(source_rel_vector.dot(Vector3(0,0,-1)),emission_deg,emission_attdb); - - Vector3 vpanning=rel_vector.normalized(); - - //listener stuff - - { - - // head cone - - float reception_deg=listener->params[LISTENER_PARAM_RECEPTION_CONE_DEGREES]; - float reception_attdb=listener->params[LISTENER_PARAM_RECEPTION_CONE_ATTENUATION_DB]; - - absorption*=_get_attenuation(vpanning.dot(Vector3(0,0,-1)),reception_deg,reception_attdb); - - // scale - - attenuation*=Math::db2linear(listener->params[LISTENER_PARAM_VOLUME_SCALE_DB]); - pscale*=Math::db2linear(listener->params[LISTENER_PARAM_PITCH_SCALE]); - - - } - - - - - //add values - - volume_attenuation+=weight*attenuation; // plus other stuff i guess - air_absorption+=weight*absorption; - air_absorption_hf_cutoff+=weight*hf_attenuation_cutoff; - panning+=vpanning*weight; - //pitch_scale+=pscale*weight; - - } - - RoomReverb reverb_room; - float reverb_send; - - /* APPLY ROOM SETTINGS */ - - { - pitch_scale*=room->params[ROOM_PARAM_PITCH_SCALE]; - volume_attenuation*=Math::db2linear(room->params[ROOM_PARAM_VOLUME_SCALE_DB]); - reverb_room=room->reverb; - reverb_send=Math::lerp(1.0,volume_attenuation,room->params[ROOM_PARAM_ATTENUATION_REVERB_SCALE])*room->params[ROOM_PARAM_REVERB_SEND]; - - } - - /* UPDATE VOICE & STREAM */ - - - - if (voice==VOICE_IS_STREAM) { - - //update voice!! - source->stream_data.panning=panning; - source->stream_data.volume=volume_attenuation*Math::db2linear(source->params[SOURCE_PARAM_VOLUME_DB]); - source->stream_data.reverb=reverb_room; - source->stream_data.reverb_send=reverb_send; - source->stream_data.filter_gain=air_absorption; - source->stream_data.filter_cutoff=air_absorption_hf_cutoff; - - if (!source->stream) //stream is gone bye bye - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - - } else if (voice>=0) { - //update stream!! - Source::Voice &v=source->voices[voice]; - - if (v.restart) - AudioServer::get_singleton()->voice_play(v.voice_rid,v.sample_rid); - - float volume_scale = Math::db2linear(v.volume_scale)*Math::db2linear(source->params[SOURCE_PARAM_VOLUME_DB]); - float volume = volume_attenuation*volume_scale; - reverb_send*=volume_scale; - int mix_rate = v.sample_mix_rate*v.pitch_scale*pitch_scale*source->params[SOURCE_PARAM_PITCH_SCALE]; - - - if (mix_rate<=0) { - ERR_PRINT("Invalid mix rate for voice (0) check for invalid pitch_scale param."); - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - continue; //invalid mix rate, disabling - } - if (v.restart || v.last_volume!=volume) - AudioServer::get_singleton()->voice_set_volume(v.voice_rid,volume); - if (v.restart || v.last_mix_rate!=mix_rate) - AudioServer::get_singleton()->voice_set_mix_rate(v.voice_rid,mix_rate); - if (v.restart || v.last_filter_gain!=air_absorption || v.last_filter_cutoff!=air_absorption_hf_cutoff) - AudioServer::get_singleton()->voice_set_filter(v.voice_rid,AudioServer::FILTER_HIGH_SHELF,air_absorption_hf_cutoff,1.0,air_absorption); - if (v.restart || v.last_panning!=panning) - AudioServer::get_singleton()->voice_set_pan(v.voice_rid,panning.x,panning.y,panning.z); - if (v.restart || v.last_reverb_room!=reverb_room || v.last_reverb_send!=reverb_send) - AudioServer::get_singleton()->voice_set_reverb(v.voice_rid,AudioServer::ReverbRoomType(reverb_room),reverb_send); - - v.last_volume=volume; - v.last_mix_rate=mix_rate; - v.last_filter_gain=air_absorption; - v.last_filter_cutoff=air_absorption_hf_cutoff; - v.last_panning=panning; - v.restart=false; - v.active=true; - - if (!AudioServer::get_singleton()->voice_is_active(v.voice_rid)) - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - } - } - - while(to_disable.size()) { - - ActiveVoice av = to_disable.front()->get(); - av.source->voices[av.voice].active=false; - av.source->voices[av.voice].restart=false; - active_voices.erase(av); - to_disable.pop_front(); - } - -} -void SpatialSoundServerSW::finish() { - - AudioServer::get_singleton()->free(internal_audio_stream_rid); - memdelete(internal_audio_stream); - - _clean_up_owner(&source_owner,"Source"); - _clean_up_owner(&listener_owner,"Listener"); - _clean_up_owner(&room_owner,"Room"); - _clean_up_owner(&space_owner,"Space"); - - memdelete_arr(internal_buffer); -} - -SpatialSoundServerSW::SpatialSoundServerSW() { - -} diff --git a/servers/spatial_sound/spatial_sound_server_sw.h b/servers/spatial_sound/spatial_sound_server_sw.h deleted file mode 100644 index 901b781ac2..0000000000 --- a/servers/spatial_sound/spatial_sound_server_sw.h +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_server_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPATIAL_SOUND_SERVER_SW_H -#define SPATIAL_SOUND_SERVER_SW_H - -#include "servers/spatial_sound_server.h" -#include "octree.h" -#include "os/thread_safe.h" - - -class SpatialSoundServerSW : public SpatialSoundServer { - - GDCLASS(SpatialSoundServerSW,SpatialSoundServer); - - _THREAD_SAFE_CLASS_ - - enum { - MAX_CULL_ROOMS=128, - INTERNAL_BUFFER_SIZE=4096, - INTERNAL_BUFFER_MAX_CHANNELS=4, - VOICE_IS_STREAM=-1 - - }; - - - struct InternalAudioStream : public AudioServer::AudioStream { - - ::SpatialSoundServerSW *owner; - virtual int get_channel_count() const; - virtual void set_mix_rate(int p_rate); //notify the stream of the mix rate - virtual bool mix(int32_t *p_buffer,int p_frames); - virtual void update(); - }; - - InternalAudioStream *internal_audio_stream; - RID internal_audio_stream_rid; - int32_t *internal_buffer; - int internal_buffer_channels; - - bool internal_buffer_mix(int32_t *p_buffer,int p_frames); - - struct Room; - - struct Space : public RID_Data { - - RID default_room; - Set<RID> rooms; - Set<RID> sources; - Set<RID> listeners; - - Octree<Room> octree; - }; - - mutable RID_Owner<Space> space_owner; - - struct Room : public RID_Data{ - RID space; - Transform transform; - Transform inverse_transform; - BSP_Tree bounds; - RoomReverb reverb; - float params[ROOM_PARAM_MAX]; - bool override_other_sources; - OctreeElementID octree_id; - int level; - - Room(); - }; - - mutable RID_Owner<Room> room_owner; - - - - struct Source : public RID_Data { - - struct Voice { - - RID voice_rid; - RID sample_rid; - bool active; - bool restart; - float pitch_scale; - float volume_scale; - int sample_mix_rate; - - - float last_volume; - float last_filter_gain; - float last_filter_cutoff; - Vector3 last_panning; - int last_mix_rate; - RoomReverb last_reverb_room; - float last_reverb_send; - - Voice(); - ~Voice(); - }; - - struct StreamData { - - - Vector3 panning; - RoomReverb reverb; - float reverb_send; - float volume; - float filter_gain; - float filter_cutoff; - - struct FilterState { - - float ha[2]; - float hb[2]; - } filter_state[4]; - - StreamData() { - - reverb_send=0; - reverb=ROOM_REVERB_HALL; - volume=1.0; - filter_gain=1; - filter_cutoff=5000; - - } - } stream_data; - - RID space; - Transform transform; - float params[SOURCE_PARAM_MAX]; - AudioServer::AudioStream *stream; - Vector<Voice> voices; - int last_voice; - - Source(); - }; - - mutable RID_Owner<Source> source_owner; - - struct Listener : public RID_Data { - - RID space; - Transform transform; - float params[LISTENER_PARAM_MAX]; - - Listener(); - }; - - mutable RID_Owner<Listener> listener_owner; - - struct ActiveVoice { - - Source *source; - int voice; - bool operator<(const ActiveVoice& p_voice) const { return (voice==p_voice.voice)?(source<p_voice.source):(voice<p_voice.voice); } - ActiveVoice(Source *p_source=NULL,int p_voice=0) { source=p_source; voice=p_voice; } - }; - - Room *cull_rooms[MAX_CULL_ROOMS]; - - Set<Source*> streaming_sources; - Set<ActiveVoice> active_voices; - - void _clean_up_owner(RID_OwnerBase *p_owner, const char *p_area); - void _update_sources(); - -public: - - /* SPACE */ - virtual RID space_create(); - - /* ROOM */ - - virtual RID room_create(); - virtual void room_set_space(RID p_room,RID p_space); - virtual RID room_get_space(RID p_room) const; - - virtual void room_set_bounds(RID p_room, const BSP_Tree& p_bounds); - virtual BSP_Tree room_get_bounds(RID p_room) const; - virtual void room_set_transform(RID p_room, const Transform& p_transform); - virtual Transform room_get_transform(RID p_room) const; - - - virtual void room_set_param(RID p_room, RoomParam p_param, float p_value); - virtual float room_get_param(RID p_room, RoomParam p_param) const; - - virtual void room_set_level(RID p_room, int p_level); - virtual int room_get_level(RID p_room) const; - - virtual void room_set_reverb(RID p_room, RoomReverb p_reverb); - virtual RoomReverb room_get_reverb(RID p_room) const; - - //useful for underwater or rooms with very strange conditions - virtual void room_set_force_params_to_all_sources(RID p_room, bool p_force); - virtual bool room_is_forcing_params_to_all_sources(RID p_room) const; - - /* SOURCE */ - - virtual RID source_create(RID p_space); - - virtual void source_set_polyphony(RID p_source,int p_voice_count); - virtual int source_get_polyphony(RID p_source) const; - - virtual void source_set_transform(RID p_source, const Transform& p_transform); - virtual Transform source_get_transform(RID p_source) const; - - virtual void source_set_param(RID p_source, SourceParam p_param, float p_value); - virtual float source_get_param(RID p_source, SourceParam p_param) const; - - virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream); //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice=SOURCE_NEXT_VOICE); - /* VOICES */ - virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale); - virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume); - - virtual bool source_is_voice_active(RID p_source, SourceVoiceID p_voice) const; - virtual void source_stop_voice(RID p_source, SourceVoiceID p_voice); - - /* LISTENER */ - - virtual RID listener_create(); - virtual void listener_set_space(RID p_listener, RID p_space); - - virtual void listener_set_transform(RID p_listener, const Transform& p_transform); - virtual Transform listener_get_transform(RID p_listener) const; - - virtual void listener_set_param(RID p_listener, ListenerParam p_param, float p_value); - virtual float listener_get_param(RID p_listener, ListenerParam p_param) const; - - - /* MISC */ - - virtual void free(RID p_id); - - virtual void init(); - virtual void update(float p_delta); - virtual void finish(); - - SpatialSoundServerSW(); -}; - -#endif // SPATIAL_SOUND_SERVER_SW_H diff --git a/servers/spatial_sound_2d/SCsub b/servers/spatial_sound_2d/SCsub deleted file mode 100644 index ccc76e823f..0000000000 --- a/servers/spatial_sound_2d/SCsub +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -Import('env') - -env.add_source_files(env.servers_sources, "*.cpp") - -Export('env') diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp deleted file mode 100644 index 2bcc9644f1..0000000000 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp +++ /dev/null @@ -1,1042 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_2d_server_sw.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "spatial_sound_2d_server_sw.h" - -#include "os/os.h" -#include "servers/audio/audio_filter_sw.h" - - - -int SpatialSound2DServerSW::InternalAudioStream::get_channel_count() const { - - return AudioServer::get_singleton()->get_default_channel_count(); -} - -void SpatialSound2DServerSW::InternalAudioStream::set_mix_rate(int p_rate) { - - -} - -void SpatialSound2DServerSW::InternalAudioStream::update() { - - owner->_update_sources(); -} - -bool SpatialSound2DServerSW::InternalAudioStream::mix(int32_t *p_buffer,int p_frames) { - - return owner->internal_buffer_mix(p_buffer,p_frames); -} - -void SpatialSound2DServerSW::_update_sources() { - - _THREAD_SAFE_METHOD_ - for (Set<Source*>::Element *E=streaming_sources.front();E;E=E->next()) { - - Source *s=E->get(); - ERR_CONTINUE(!s->stream); - s->stream->update(); - } -} - - -SpatialSound2DServerSW::Room::Room() { - - //params[ROOM_PARAM_SPEED_OF_SOUND]=343.0; - params[ROOM_PARAM_PITCH_SCALE]=1.0; - params[ROOM_PARAM_VOLUME_SCALE_DB]=0; - params[ROOM_PARAM_REVERB_SEND]=0; - params[ROOM_PARAM_CHORUS_SEND]=0; - params[ROOM_PARAM_ATTENUATION_SCALE]=1.0; - params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]=5000; - params[ROOM_PARAM_ATTENUATION_HF_FLOOR_DB]=-24.0; - params[ROOM_PARAM_ATTENUATION_HF_RATIO_EXP]=1.0; - params[ROOM_PARAM_ATTENUATION_REVERB_SCALE]=0.0; - override_other_sources=false; - reverb=ROOM_REVERB_HALL; - //octree_id=0; - level=-1; - - -} - - -SpatialSound2DServerSW::Source::Source() { - - params[SOURCE_PARAM_VOLUME_DB]=0.0; - params[SOURCE_PARAM_PITCH_SCALE]=1.0; - params[SOURCE_PARAM_ATTENUATION_MIN_DISTANCE]=1; - params[SOURCE_PARAM_ATTENUATION_MAX_DISTANCE]=100; - params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]=1.0; //linear (and not really good) - stream=NULL; - voices.resize(1); - last_voice=0; -} - -SpatialSound2DServerSW::Source::Voice::Voice() { - - active=false; - restart=false; - pitch_scale=1.0; - volume_scale=0.0; - voice_rid=AudioServer::get_singleton()->voice_create(); - -} -SpatialSound2DServerSW::Source::Voice::~Voice() { - - AudioServer::get_singleton()->free(voice_rid); -} - - -SpatialSound2DServerSW::Listener::Listener() { - - params[LISTENER_PARAM_VOLUME_SCALE_DB]=0.0; - params[LISTENER_PARAM_PITCH_SCALE]=1.0; - params[LISTENER_PARAM_ATTENUATION_SCALE]=1.0; - params[LISTENER_PARAM_PAN_RANGE]=128; - -} - -/* SPACE */ -RID SpatialSound2DServerSW::space_create() { - - Space* space = memnew( Space ); - RID space_rid = space_owner.make_rid(space); - space->default_room=room_create(); - room_set_space(space->default_room,space_rid); - return space_rid; -} - -/* ROOM */ - -RID SpatialSound2DServerSW::room_create() { - - Room *room = memnew( Room ); - return room_owner.make_rid(room); -} - -void SpatialSound2DServerSW::room_set_space(RID p_room,RID p_space) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - - if (room->space.is_valid()) { - - Space *space = space_owner.get(room->space); - space->rooms.erase(p_room); - //space->octree.erase(room->octree_id); - //room->octree_id=0; - } - - room->space=RID(); - - if (p_space.is_valid()) { - - Space *space = space_owner.get(p_space); - ERR_FAIL_COND(!space); - space->rooms.insert(p_room); - //room->octree_id=space->octree.create(room,AABB()); - //set bounds - //AABB aabb = room->bounds.is_empty()?AABB():room->bounds.get_aabb(); - //space->octree.move(room->octree_id,room->transform.xform(aabb)); - room->space=p_space; - } - - -} - -RID SpatialSound2DServerSW::room_get_space(RID p_room) const { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,RID()); - - - return room->space; -} - - - -void SpatialSound2DServerSW::room_set_bounds(RID p_room, const PoolVector<Point2>& p_bounds) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - - room->bounds=p_bounds; - - if (!room->space.is_valid()) - return; - - //AABB aabb = room->bounds.is_empty()?AABB():room->bounds.get_aabb(); - //Space* space = space_owner.get(room->space); - //ERR_FAIL_COND(!space); - - //space->octree.move(room->octree_id,room->transform.xform(aabb)); - -} -PoolVector<Point2> SpatialSound2DServerSW::room_get_bounds(RID p_room) const { - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,PoolVector<Point2>()); - - return room->bounds; -} - -void SpatialSound2DServerSW::room_set_transform(RID p_room, const Transform2D& p_transform) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->transform=p_transform; - room->inverse_transform=p_transform.affine_inverse(); // needs to be done to unscale BSP properly - - if (!room->space.is_valid()) - return; - - /* - if (!room->bounds.is_empty()) { - - Space* space = space_owner.get(room->space); - ERR_FAIL_COND(!space); - - //space->octree.move(room->octree_id,room->transform.xform(room->bounds.get_aabb())); - }*/ -} - -Transform2D SpatialSound2DServerSW::room_get_transform(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,Transform2D()); - return room->transform; -} - - -void SpatialSound2DServerSW::room_set_param(RID p_room, RoomParam p_param, float p_value) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - ERR_FAIL_INDEX(p_param,ROOM_PARAM_MAX); - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->params[p_param]=p_value; - -} -float SpatialSound2DServerSW::room_get_param(RID p_room, RoomParam p_param) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - ERR_FAIL_INDEX_V(p_param,ROOM_PARAM_MAX,0); - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,0); - return room->params[p_param]; -} - -void SpatialSound2DServerSW::room_set_level(RID p_room, int p_level) { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->level =p_level; - -} - -int SpatialSound2DServerSW::room_get_level(RID p_room) const { - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,0); - return room->level; - -} - - -void SpatialSound2DServerSW::room_set_reverb(RID p_room, RoomReverb p_reverb) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->reverb=p_reverb; - -} -SpatialSound2DServerSW::RoomReverb SpatialSound2DServerSW::room_get_reverb(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,ROOM_REVERB_SMALL); - return room->reverb; -} - -//useful for underwater or rooms with very strange conditions -void SpatialSound2DServerSW::room_set_force_params_to_all_sources(RID p_room, bool p_force) { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND(!room); - room->override_other_sources=p_force; - -} -bool SpatialSound2DServerSW::room_is_forcing_params_to_all_sources(RID p_room) const { - - if (space_owner.owns(p_room)) - p_room=space_owner.get(p_room)->default_room; - - Room *room = room_owner.get(p_room); - ERR_FAIL_COND_V(!room,false); - return room->override_other_sources; -} - -/* SOURCE */ - -RID SpatialSound2DServerSW::source_create(RID p_space) { - - Space *space = space_owner.get(p_space); - ERR_FAIL_COND_V(!space,RID()); - - Source *source = memnew( Source ); - source->space=p_space; - RID source_rid = source_owner.make_rid(source); - space->sources.insert(source_rid); - - return source_rid; -} - - -void SpatialSound2DServerSW::source_set_polyphony(RID p_source,int p_voice_count) { - - - ERR_FAIL_COND(p_voice_count<=0); // more than 32 is too much, change this if you really need more - if (p_voice_count>32) { - - ERR_PRINT("Voices will be clipped to 32"); - p_voice_count=32; - } - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - - if (p_voice_count<source->voices.size()) { - - for(int i=p_voice_count;i<source->voices.size();i++) { - active_voices.erase(ActiveVoice(source,i)); //erase from active voices - } - } - source->voices.resize(p_voice_count); - -} - -int SpatialSound2DServerSW::source_get_polyphony(RID p_source) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,-1); - return source->voices.size(); - -} - -void SpatialSound2DServerSW::source_set_transform(RID p_source, const Transform2D& p_transform) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - source->transform=p_transform; - source->transform.orthonormalize(); -} -Transform2D SpatialSound2DServerSW::source_get_transform(RID p_source) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,Transform2D()); - return source->transform; -} - -void SpatialSound2DServerSW::source_set_param(RID p_source, SourceParam p_param, float p_value) { - - ERR_FAIL_INDEX(p_param,SOURCE_PARAM_MAX); - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - source->params[p_param]=p_value; - -} -float SpatialSound2DServerSW::source_get_param(RID p_source, SourceParam p_param) const { - ERR_FAIL_INDEX_V(p_param,SOURCE_PARAM_MAX,0); - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,0); - return source->params[p_param]; - - -} - -void SpatialSound2DServerSW::source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - AudioServer::get_singleton()->lock(); - source->stream=p_stream; - _THREAD_SAFE_METHOD_ - - if (!p_stream) { - streaming_sources.erase(source); - active_voices.erase(ActiveVoice(source,VOICE_IS_STREAM)); - } else { - streaming_sources.insert(source); - active_voices.insert(ActiveVoice(source,VOICE_IS_STREAM)); - zeromem(source->stream_data.filter_state,sizeof(Source::StreamData::FilterState)*4); //reset filter for safetyness - p_stream->set_mix_rate(AudioServer::get_singleton()->get_default_mix_rate()); - } - - AudioServer::get_singleton()->unlock(); - -} //null to unset - -SpatialSound2DServer::SourceVoiceID SpatialSound2DServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,SOURCE_INVALID_VOICE); - - int to_play=0; - - if (p_voice==SOURCE_NEXT_VOICE) { - to_play=source->last_voice+1; - if (to_play>=source->voices.size()) - to_play=0; - - } else - to_play=p_voice; - - ERR_FAIL_INDEX_V(to_play,source->voices.size(),SOURCE_INVALID_VOICE); - - source->voices[to_play].restart=true; - source->voices[to_play].sample_rid=p_sample; - source->voices[to_play].sample_mix_rate=p_mix_rate; - source->voices[to_play].pitch_scale=1; - source->voices[to_play].volume_scale=0; - source->last_voice=to_play; - active_voices.insert(ActiveVoice(source,to_play)); - return to_play; -} - -/* VOICES */ -void SpatialSound2DServerSW::source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - source->voices[p_voice].pitch_scale=p_pitch_scale; - -} -void SpatialSound2DServerSW::source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_db) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - source->voices[p_voice].volume_scale=p_db; - -} - -bool SpatialSound2DServerSW::source_is_voice_active(RID p_source, SourceVoiceID p_voice) const { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND_V(!source,false); - ERR_FAIL_INDEX_V(p_voice,source->voices.size(),false); - return source->voices[p_voice].active || source->voices[p_voice].restart; - -} -void SpatialSound2DServerSW::source_stop_voice(RID p_source, SourceVoiceID p_voice) { - - Source *source = source_owner.get(p_source); - ERR_FAIL_COND(!source); - ERR_FAIL_INDEX(p_voice,source->voices.size()); - if (source->voices[p_voice].active) { - AudioServer::get_singleton()->voice_stop(source->voices[p_voice].voice_rid); - } - source->voices[p_voice].active=false; - source->voices[p_voice].restart=false; - active_voices.erase(ActiveVoice(source,p_voice)); -} - -/* LISTENER */ - -RID SpatialSound2DServerSW::listener_create() { - - Listener *listener = memnew( Listener ); - RID listener_rid = listener_owner.make_rid(listener); - return listener_rid; - -} - -void SpatialSound2DServerSW::listener_set_space(RID p_listener,RID p_space) { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - - if (listener->space.is_valid()) { - - Space *lspace = space_owner.get(listener->space); - ERR_FAIL_COND(!lspace); - lspace->listeners.erase(p_listener); - } - - listener->space=RID(); - - if (p_space.is_valid()) { - Space *space = space_owner.get(p_space); - ERR_FAIL_COND(!space); - - listener->space=p_space; - space->listeners.insert(p_listener); - } - -} - -void SpatialSound2DServerSW::listener_set_transform(RID p_listener, const Transform2D& p_transform) { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - listener->transform=p_transform; - listener->transform.orthonormalize(); //must be done.. -} -Transform2D SpatialSound2DServerSW::listener_get_transform(RID p_listener) const { - - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND_V(!listener,Transform2D()); - return listener->transform; -} - -void SpatialSound2DServerSW::listener_set_param(RID p_listener, ListenerParam p_param, float p_value) { - - ERR_FAIL_INDEX(p_param,LISTENER_PARAM_MAX); - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND(!listener); - listener->params[p_param]=p_value; -} - -float SpatialSound2DServerSW::listener_get_param(RID p_listener, ListenerParam p_param) const { - - ERR_FAIL_INDEX_V(p_param,LISTENER_PARAM_MAX,0); - Listener *listener = listener_owner.get(p_listener); - ERR_FAIL_COND_V(!listener,0); - return listener->params[p_param]; -} - - -/* MISC */ - -void SpatialSound2DServerSW::free(RID p_id) { - - - if (space_owner.owns(p_id)) { - - Space *space = space_owner.get(p_id); - free(space->default_room); - - while(space->listeners.size()) { - listener_set_space(space->listeners.front()->get(),RID()); - } - while(space->sources.size()) { - free(space->sources.front()->get()); - } - while(space->rooms.size()) { - room_set_space(space->rooms.front()->get(),RID()); - } - space_owner.free(p_id); - memdelete(space); - - } else if (source_owner.owns(p_id)) { - - Source *source = source_owner.get(p_id); - if (source->stream) - source_set_audio_stream(p_id,NULL); - - Space *space = space_owner.get(source->space); - ERR_FAIL_COND(!space); - space->sources.erase(p_id); - for(int i=0;i<source->voices.size();i++) { - active_voices.erase(ActiveVoice(source,i)); - } - source_owner.free(p_id); - memdelete(source); - } else if (listener_owner.owns(p_id)) { - - Listener *listener = listener_owner.get(p_id); - if (listener->space.is_valid()) { - Space *space = space_owner.get(listener->space); - ERR_FAIL_COND(!space); - space->listeners.erase(p_id); - } - listener_owner.free(p_id); - memdelete(listener); - - } else if (room_owner.owns(p_id)) { - - Room *room = room_owner.get(p_id); - - if (room->space.is_valid()) { - Space *space = space_owner.get(room->space); - ERR_FAIL_COND(!space); - //space->octree.erase(room->octree_id); - space->rooms.erase(p_id); - } - room_owner.free(p_id); - memdelete(room); - } else { - ERR_PRINT("Attempt to free invalid ID") ; - } - -} - -void SpatialSound2DServerSW::_clean_up_owner(RID_OwnerBase *p_owner, const char *p_area) { - - List<RID> rids; - p_owner->get_owned_list(&rids); - - for(List<RID>::Element *I=rids.front();I;I=I->next()) { - if (OS::get_singleton()->is_stdout_verbose()) { - - print_line("Leaked RID ("+itos(I->get().get_id())+") of type "+String(p_area)); - } - free(I->get()); - } -} - -void SpatialSound2DServerSW::init() { - - internal_buffer = memnew_arr(int32_t, INTERNAL_BUFFER_SIZE*INTERNAL_BUFFER_MAX_CHANNELS); - internal_buffer_channels=AudioServer::get_singleton()->get_default_channel_count(); - - internal_audio_stream = memnew( InternalAudioStream ); - internal_audio_stream->owner=this; - internal_audio_stream_rid = AudioServer::get_singleton()->audio_stream_create(internal_audio_stream); - - AudioServer::get_singleton()->stream_set_active(internal_audio_stream_rid,true); - -} - - - -bool SpatialSound2DServerSW::internal_buffer_mix(int32_t *p_buffer,int p_frames) { - - if (streaming_sources.size()==0) - return false; //nothing to mix - - - for (Set<Source*>::Element *E=streaming_sources.front();E;E=E->next()) { - - Source *s=E->get(); - ERR_CONTINUE(!s->stream); - - int channels = s->stream->get_channel_count(); - Source::StreamData &sd=s->stream_data; - - int todo=p_frames; - - AudioFilterSW filter; - filter.set_sampling_rate(AudioServer::get_singleton()->get_default_mix_rate()); - filter.set_cutoff(sd.filter_cutoff); - filter.set_gain(sd.filter_gain); - filter.set_resonance(1); - filter.set_mode(AudioFilterSW::HIGHSHELF); - filter.set_stages(1); - AudioFilterSW::Coeffs coefs; - filter.prepare_coefficients(&coefs); - - int32_t in[4]; -#ifndef SPATIAL_SOUND_SERVER_NO_FILTER -#define DO_FILTER(m_c)\ - {\ - float val = in[m_c];\ - float pre=val;\ - val = val*coefs.b0 + sd.filter_state[m_c].hb[0]*coefs.b1 + sd.filter_state[m_c].hb[1]*coefs.b2 + sd.filter_state[m_c].ha[0]*coefs.a1 + sd.filter_state[m_c].ha[1]*coefs.a2;\ - sd.filter_state[m_c].ha[1]=sd.filter_state[m_c].ha[0];\ - sd.filter_state[m_c].hb[1]=sd.filter_state[m_c].hb[0]; \ - sd.filter_state[m_c].hb[0]=pre;\ - sd.filter_state[m_c].ha[0]=val;\ - in[m_c]=Math::fast_ftoi(val);\ - } -#else -#define DO_FILTER(m_c) -#endif - - while(todo) { - - int to_mix=MIN(todo,INTERNAL_BUFFER_SIZE); - - s->stream->mix(internal_buffer,to_mix); - - switch(internal_buffer_channels) { - - case 2: { - - float p = sd.panning.x*0.5+0.5; - float panf[2]={ (1.0-p),p }; - panf[0]*=sd.volume; - panf[1]*=sd.volume; - - int32_t pan[2]={Math::fast_ftoi(panf[0]*(1<<16)),Math::fast_ftoi(panf[1]*(1<<16))}; - - switch(channels) { - case 1: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[i]; - in[1]=internal_buffer[i]; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - case 2: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<1)+0]; - in[1]=internal_buffer[(i<<1)+1]; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - case 4: { - - for(int i=0;i<to_mix;i++) { - - in[0]=(internal_buffer[(i<<2)+0]+internal_buffer[(i<<2)+2])>>1; - in[1]=(internal_buffer[(i<<2)+1]+internal_buffer[(i<<2)+3])>>1; - DO_FILTER(0); - DO_FILTER(1); - p_buffer[(i<<1)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<1)+1]=((in[1]>>16)*pan[1]); - } - } break; - - } break; - - } break; - case 4: { - - float xp = sd.panning.x*0.5+0.5; - float yp = sd.panning.y*0.5+0.5; - float panf[4]={ (1.0-xp)*(1.0-yp),(xp)*(1.0-yp),(1.0-xp)*(yp),(xp)*(yp) }; - panf[0]*=sd.volume; - panf[1]*=sd.volume; - panf[2]*=sd.volume; - panf[3]*=sd.volume; - - int32_t pan[4]={ - Math::fast_ftoi(panf[0]*(1<<16)), - Math::fast_ftoi(panf[1]*(1<<16)), - Math::fast_ftoi(panf[2]*(1<<16)), - Math::fast_ftoi(panf[3]*(1<<16))}; - - switch(channels) { - case 1: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[i]; - in[1]=internal_buffer[i]; - in[2]=internal_buffer[i]; - in[3]=internal_buffer[i]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - case 2: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<1)+0]; - in[1]=internal_buffer[(i<<1)+1]; - in[2]=internal_buffer[(i<<1)+0]; - in[3]=internal_buffer[(i<<1)+1]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - case 4: { - - for(int i=0;i<to_mix;i++) { - - in[0]=internal_buffer[(i<<2)+0]; - in[1]=internal_buffer[(i<<2)+1]; - in[2]=internal_buffer[(i<<2)+2]; - in[3]=internal_buffer[(i<<2)+3]; - DO_FILTER(0); - DO_FILTER(1); - DO_FILTER(2); - DO_FILTER(3); - p_buffer[(i<<2)+0]=((in[0]>>16)*pan[0]); - p_buffer[(i<<2)+1]=((in[1]>>16)*pan[1]); - p_buffer[(i<<2)+2]=((in[2]>>16)*pan[2]); - p_buffer[(i<<2)+3]=((in[3]>>16)*pan[3]); - } - } break; - - } break; - - } break; - case 6: { - - - } break; - } - p_buffer+=to_mix*internal_buffer_channels; - todo-=to_mix; - - } - - } - - return true; -} - -void SpatialSound2DServerSW::update(float p_delta) { - - List<ActiveVoice> to_disable; - - for(Set<ActiveVoice>::Element *E=active_voices.front();E;E=E->next()) { - - Source *source = E->get().source; - int voice = E->get().voice; - - if (voice!=VOICE_IS_STREAM) { - Source::Voice &v=source->voices[voice]; - ERR_CONTINUE(!v.active && !v.restart); // likely a bug... - } - - //this could be optimized at some point... am not sure - Space *space=space_owner.get(source->space); - Room *room=room_owner.get(space->default_room); - - //compute mixing weights (support for multiple listeners in the same output) - float total_distance=0; - for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) { - Listener *listener=listener_owner.get(L->get()); - float d = listener->transform.get_origin().distance_to(source->transform.get_origin()); - if (d==0) - d=0.1; - total_distance+=d; - } - - //compute spatialization variables, weighted according to distance - float volume_attenuation = 0.0; - float air_absorption_hf_cutoff = 0.0; - float air_absorption = 0.0; - float pitch_scale=0.0; - Vector2 panning; - - for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) { - - Listener *listener=listener_owner.get(L->get()); - - Vector2 rel_vector = -listener->transform.xform_inv(source->transform.get_origin()); - //Vector2 source_rel_vector = source->transform.xform_inv(listener->transform.get_origin()).normalized(); - float distance=rel_vector.length(); - float weight = distance/total_distance; - float pscale=1.0; - - float distance_scale=listener->params[LISTENER_PARAM_ATTENUATION_SCALE]*room->params[ROOM_PARAM_ATTENUATION_SCALE]; - float distance_min=source->params[SOURCE_PARAM_ATTENUATION_MIN_DISTANCE]*distance_scale; - float distance_max=source->params[SOURCE_PARAM_ATTENUATION_MAX_DISTANCE]*distance_scale; - float attenuation_exp=source->params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]; - float attenuation=1; - - if (distance_max>0) { - distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); - } - - float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; - float hf_attenuation_exp = room->params[ROOM_PARAM_ATTENUATION_HF_RATIO_EXP]; - float hf_attenuation_floor = room->params[ROOM_PARAM_ATTENUATION_HF_FLOOR_DB]; - float absorption=Math::db2linear(Math::lerp(hf_attenuation_floor,0,Math::pow(attenuation,hf_attenuation_exp))); - - // source emission cone -/* only for 3D - float emission_deg=source->params[SOURCE_PARAM_EMISSION_CONE_DEGREES]; - float emission_attdb=source->params[SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB]; - absorption*=_get_attenuation(source_rel_vector.dot(Vector2(0,0,-1)),emission_deg,emission_attdb); -*/ - Vector2 vpanning=rel_vector.normalized(); - if (distance < listener->params[LISTENER_PARAM_PAN_RANGE]) - vpanning*=distance/listener->params[LISTENER_PARAM_PAN_RANGE]; - - //listener stuff - - { - - // head cone -/* only for 3D - float reception_deg=listener->params[LISTENER_PARAM_RECEPTION_CONE_DEGREES]; - float reception_attdb=listener->params[LISTENER_PARAM_RECEPTION_CONE_ATTENUATION_DB]; - - absorption*=_get_attenuation(vpanning.dot(Vector2(0,0,-1)),reception_deg,reception_attdb); -*/ - - // scale - - attenuation*=Math::db2linear(listener->params[LISTENER_PARAM_VOLUME_SCALE_DB]); - pscale*=Math::db2linear(listener->params[LISTENER_PARAM_PITCH_SCALE]); - - - } - - - - - //add values - - volume_attenuation+=weight*attenuation; // plus other stuff i guess - air_absorption+=weight*absorption; - air_absorption_hf_cutoff+=weight*hf_attenuation_cutoff; - panning+=vpanning*weight; - pitch_scale+=pscale*weight; - - } - - RoomReverb reverb_room=ROOM_REVERB_HALL; - float reverb_send=0; - - /* APPLY ROOM SETTINGS */ - - { - pitch_scale*=room->params[ROOM_PARAM_PITCH_SCALE]; - volume_attenuation*=Math::db2linear(room->params[ROOM_PARAM_VOLUME_SCALE_DB]); - reverb_room=room->reverb; - reverb_send=Math::lerp(1.0,volume_attenuation,room->params[ROOM_PARAM_ATTENUATION_REVERB_SCALE])*room->params[ROOM_PARAM_REVERB_SEND]; - - } - - /* UPDATE VOICE & STREAM */ - - - - if (voice==VOICE_IS_STREAM) { - - //update voice!! - source->stream_data.panning=panning; - source->stream_data.volume=volume_attenuation*Math::db2linear(source->params[SOURCE_PARAM_VOLUME_DB]); - source->stream_data.reverb=reverb_room; - source->stream_data.reverb_send=reverb_send; - source->stream_data.filter_gain=air_absorption; - source->stream_data.filter_cutoff=air_absorption_hf_cutoff; - - if (!source->stream) //stream is gone bye bye - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - - } else if (voice>=0) { - //update stream!! - Source::Voice &v=source->voices[voice]; - - if (v.restart) - AudioServer::get_singleton()->voice_play(v.voice_rid,v.sample_rid); - - float volume_scale = Math::db2linear(v.volume_scale)*Math::db2linear(source->params[SOURCE_PARAM_VOLUME_DB]); - float volume = volume_attenuation*volume_scale; - reverb_send*=volume_scale; - int mix_rate = v.sample_mix_rate*v.pitch_scale*pitch_scale*source->params[SOURCE_PARAM_PITCH_SCALE]; - - - if (mix_rate<=0) { - - ERR_PRINT("Invalid mix rate for voice (0) check for invalid pitch_scale param."); - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - continue; //invalid mix rate, disabling - } - if (v.restart || v.last_volume!=volume) - AudioServer::get_singleton()->voice_set_volume(v.voice_rid,volume); - if (v.restart || v.last_mix_rate!=mix_rate) - AudioServer::get_singleton()->voice_set_mix_rate(v.voice_rid,mix_rate); - if (v.restart || v.last_filter_gain!=air_absorption || v.last_filter_cutoff!=air_absorption_hf_cutoff) - AudioServer::get_singleton()->voice_set_filter(v.voice_rid,AudioServer::FILTER_HIGH_SHELF,air_absorption_hf_cutoff,1.0,air_absorption); - if (v.restart || v.last_panning!=panning) { - AudioServer::get_singleton()->voice_set_pan(v.voice_rid,-panning.x,panning.y,0); - } - if (v.restart || v.last_reverb_room!=reverb_room || v.last_reverb_send!=reverb_send) - AudioServer::get_singleton()->voice_set_reverb(v.voice_rid,AudioServer::ReverbRoomType(reverb_room),reverb_send); - - v.last_volume=volume; - v.last_mix_rate=mix_rate; - v.last_filter_gain=air_absorption; - v.last_filter_cutoff=air_absorption_hf_cutoff; - v.last_panning=panning; - v.last_reverb_room=reverb_room; - v.last_reverb_send=reverb_send; - v.restart=false; - v.active=true; - - if (!AudioServer::get_singleton()->voice_is_active(v.voice_rid)) - to_disable.push_back(ActiveVoice(source,voice)); // oh well.. - } - } - - while(to_disable.size()) { - - ActiveVoice av = to_disable.front()->get(); - av.source->voices[av.voice].active=false; - av.source->voices[av.voice].restart=false; - active_voices.erase(av); - to_disable.pop_front(); - } - -} -void SpatialSound2DServerSW::finish() { - - AudioServer::get_singleton()->free(internal_audio_stream_rid); - memdelete(internal_audio_stream); - - _clean_up_owner(&source_owner,"Source"); - _clean_up_owner(&listener_owner,"Listener"); - _clean_up_owner(&room_owner,"Room"); - _clean_up_owner(&space_owner,"Space"); - - memdelete_arr(internal_buffer); -} - -SpatialSound2DServerSW::SpatialSound2DServerSW() { - -} diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h deleted file mode 100644 index 7999a8c22b..0000000000 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_2d_server_sw.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPATIAL_SOUND_2D_SERVER_SW_H -#define SPATIAL_SOUND_2D_SERVER_SW_H - -#include "servers/spatial_sound_2d_server.h" - -#include "os/thread_safe.h" - - -class SpatialSound2DServerSW : public SpatialSound2DServer { - - GDCLASS(SpatialSound2DServerSW,SpatialSound2DServer); - - _THREAD_SAFE_CLASS_ - - enum { - INTERNAL_BUFFER_SIZE=4096, - INTERNAL_BUFFER_MAX_CHANNELS=4, - VOICE_IS_STREAM=-1 - - }; - - - struct InternalAudioStream : public AudioServer::AudioStream { - - ::SpatialSound2DServerSW *owner; - virtual int get_channel_count() const; - virtual void set_mix_rate(int p_rate); //notify the stream of the mix rate - virtual bool mix(int32_t *p_buffer,int p_frames); - virtual void update(); - }; - - InternalAudioStream *internal_audio_stream; - RID internal_audio_stream_rid; - int32_t *internal_buffer; - int internal_buffer_channels; - - bool internal_buffer_mix(int32_t *p_buffer,int p_frames); - - struct Room; - - struct Space : public RID_Data { - - RID default_room; - Set<RID> rooms; - Set<RID> sources; - Set<RID> listeners; - - //Octree<Room> octree; - }; - - mutable RID_Owner<Space> space_owner; - - struct Room : public RID_Data { - RID space; - Transform2D transform; - Transform2D inverse_transform; - PoolVector<Point2> bounds; - RoomReverb reverb; - float params[ROOM_PARAM_MAX]; - bool override_other_sources; - //OctreeElementID octree_id; - int level; - - Room(); - }; - - mutable RID_Owner<Room> room_owner; - - - - struct Source : public RID_Data { - - struct Voice { - - RID voice_rid; - RID sample_rid; - bool active; - bool restart; - float pitch_scale; - float volume_scale; - int sample_mix_rate; - - - float last_volume; - float last_filter_gain; - float last_filter_cutoff; - Vector2 last_panning; - int last_mix_rate; - RoomReverb last_reverb_room; - float last_reverb_send; - - Voice(); - ~Voice(); - }; - - struct StreamData { - - - Vector2 panning; - RoomReverb reverb; - float reverb_send; - float volume; - float filter_gain; - float filter_cutoff; - - struct FilterState { - - float ha[2]; - float hb[2]; - } filter_state[4]; - - StreamData() { - - reverb_send=0; - reverb=ROOM_REVERB_HALL; - volume=1.0; - filter_gain=1; - filter_cutoff=5000; - - } - } stream_data; - - RID space; - Transform2D transform; - float params[SOURCE_PARAM_MAX]; - AudioServer::AudioStream *stream; - Vector<Voice> voices; - int last_voice; - - Source(); - }; - - mutable RID_Owner<Source> source_owner; - - struct Listener : public RID_Data { - - RID space; - Transform2D transform; - float params[LISTENER_PARAM_MAX]; - - Listener(); - }; - - mutable RID_Owner<Listener> listener_owner; - - struct ActiveVoice { - - Source *source; - int voice; - bool operator<(const ActiveVoice& p_voice) const { return (voice==p_voice.voice)?(source<p_voice.source):(voice<p_voice.voice); } - ActiveVoice(Source *p_source=NULL,int p_voice=0) { source=p_source; voice=p_voice; } - }; - - //Room *cull_rooms[MAX_CULL_ROOMS]; - - Set<Source*> streaming_sources; - Set<ActiveVoice> active_voices; - - void _clean_up_owner(RID_OwnerBase *p_owner, const char *p_area); - void _update_sources(); - -public: - - /* SPACE */ - virtual RID space_create(); - - /* ROOM */ - - virtual RID room_create(); - virtual void room_set_space(RID p_room,RID p_space); - virtual RID room_get_space(RID p_room) const; - - virtual void room_set_bounds(RID p_room, const PoolVector<Point2>& p_bounds); - virtual PoolVector<Point2> room_get_bounds(RID p_room) const; - virtual void room_set_transform(RID p_room, const Transform2D& p_transform); - virtual Transform2D room_get_transform(RID p_room) const; - - - virtual void room_set_param(RID p_room, RoomParam p_param, float p_value); - virtual float room_get_param(RID p_room, RoomParam p_param) const; - - virtual void room_set_level(RID p_room, int p_level); - virtual int room_get_level(RID p_room) const; - - virtual void room_set_reverb(RID p_room, RoomReverb p_reverb); - virtual RoomReverb room_get_reverb(RID p_room) const; - - //useful for underwater or rooms with very strange conditions - virtual void room_set_force_params_to_all_sources(RID p_room, bool p_force); - virtual bool room_is_forcing_params_to_all_sources(RID p_room) const; - - /* SOURCE */ - - virtual RID source_create(RID p_space); - - virtual void source_set_polyphony(RID p_source,int p_voice_count); - virtual int source_get_polyphony(RID p_source) const; - - virtual void source_set_transform(RID p_source, const Transform2D& p_transform); - virtual Transform2D source_get_transform(RID p_source) const; - - virtual void source_set_param(RID p_source, SourceParam p_param, float p_value); - virtual float source_get_param(RID p_source, SourceParam p_param) const; - - virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream); //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice=SOURCE_NEXT_VOICE); - /* VOICES */ - virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale); - virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume); - - virtual bool source_is_voice_active(RID p_source, SourceVoiceID p_voice) const; - virtual void source_stop_voice(RID p_source, SourceVoiceID p_voice); - - /* LISTENER */ - - virtual RID listener_create(); - virtual void listener_set_space(RID p_listener, RID p_space); - - virtual void listener_set_transform(RID p_listener, const Transform2D& p_transform); - virtual Transform2D listener_get_transform(RID p_listener) const; - - virtual void listener_set_param(RID p_listener, ListenerParam p_param, float p_value); - virtual float listener_get_param(RID p_listener, ListenerParam p_param) const; - - - /* MISC */ - - virtual void free(RID p_id); - - virtual void init(); - virtual void update(float p_delta); - virtual void finish(); - - SpatialSound2DServerSW(); -}; - -#endif // SPATIAL_SOUND_2D_SERVER_SW_H diff --git a/servers/spatial_sound_2d_server.cpp b/servers/spatial_sound_2d_server.cpp deleted file mode 100644 index 90f384ea2e..0000000000 --- a/servers/spatial_sound_2d_server.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_2d_server.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "spatial_sound_2d_server.h" - -SpatialSound2DServer *SpatialSound2DServer::singleton=NULL; - - -SpatialSound2DServer *SpatialSound2DServer::get_singleton() { - - return singleton; -} - - -SpatialSound2DServer::SpatialSound2DServer() { - - ERR_FAIL_COND(singleton!=NULL); - singleton=this; -} diff --git a/servers/spatial_sound_2d_server.h b/servers/spatial_sound_2d_server.h deleted file mode 100644 index 331caf8198..0000000000 --- a/servers/spatial_sound_2d_server.h +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_2d_server.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPATIAL_SOUND_2D_SERVER_H -#define SPATIAL_SOUND_2D_SERVER_H - -#include "object.h" -#include "bsp_tree.h" -#include "servers/audio_server.h" - -class SpatialSound2DServer : public Object { - - GDCLASS(SpatialSound2DServer,Object); - static SpatialSound2DServer *singleton; -public: - - - enum { - SOURCE_INVALID_VOICE=-1, - SOURCE_NEXT_VOICE=-2, - }; - - typedef int SourceVoiceID; - - /* SPACE */ - virtual RID space_create()=0; - - /* ROOM */ - - virtual RID room_create()=0; - virtual void room_set_space(RID p_room,RID p_space)=0; - virtual RID room_get_space(RID p_room) const=0; - - - virtual void room_set_bounds(RID p_room, const PoolVector<Point2>& p_bounds)=0; - virtual PoolVector<Point2> room_get_bounds(RID p_room) const=0; - virtual void room_set_transform(RID p_room, const Transform2D& p_transform)=0; - virtual Transform2D room_get_transform(RID p_room) const=0; - - enum RoomParam { - ROOM_PARAM_PITCH_SCALE, - ROOM_PARAM_VOLUME_SCALE_DB, - ROOM_PARAM_REVERB_SEND, - ROOM_PARAM_CHORUS_SEND, - ROOM_PARAM_ATTENUATION_SCALE, - ROOM_PARAM_ATTENUATION_HF_CUTOFF, - ROOM_PARAM_ATTENUATION_HF_FLOOR_DB, - ROOM_PARAM_ATTENUATION_HF_RATIO_EXP, - ROOM_PARAM_ATTENUATION_REVERB_SCALE, - ROOM_PARAM_MAX - }; - - virtual void room_set_param(RID p_room, RoomParam p_param, float p_value)=0; - virtual float room_get_param(RID p_room, RoomParam p_param) const=0; - - enum RoomReverb { - ROOM_REVERB_SMALL, - ROOM_REVERB_MEDIUM, - ROOM_REVERB_LARGE, - ROOM_REVERB_HALL - }; - - virtual void room_set_reverb(RID p_room, RoomReverb p_reverb)=0; - virtual RoomReverb room_get_reverb(RID p_room) const=0; - - virtual void room_set_level(RID p_room, int p_level)=0; - virtual int room_get_level(RID p_room) const=0; - - //useful for underwater or rooms with very strange conditions - virtual void room_set_force_params_to_all_sources(RID p_room, bool p_force)=0; - virtual bool room_is_forcing_params_to_all_sources(RID p_room) const=0; - - /* SOURCE */ - - virtual RID source_create(RID p_space)=0; - - virtual void source_set_transform(RID p_source, const Transform2D& p_transform)=0; - virtual Transform2D source_get_transform(RID p_source) const=0; - - virtual void source_set_polyphony(RID p_source,int p_voice_count)=0; - virtual int source_get_polyphony(RID p_source) const=0; - - enum SourceParam { - - SOURCE_PARAM_VOLUME_DB, - SOURCE_PARAM_PITCH_SCALE, - SOURCE_PARAM_ATTENUATION_MIN_DISTANCE, - SOURCE_PARAM_ATTENUATION_MAX_DISTANCE, - SOURCE_PARAM_ATTENUATION_DISTANCE_EXP, - SOURCE_PARAM_MAX - }; - - virtual void source_set_param(RID p_source, SourceParam p_param, float p_value)=0; - virtual float source_get_param(RID p_source, SourceParam p_param) const=0; - - virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream)=0; //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice=SOURCE_NEXT_VOICE)=0; - //voices - virtual void source_voice_set_pitch_scale(RID p_source,SourceVoiceID p_voice, float p_pitch_scale)=0; - virtual void source_voice_set_volume_scale_db(RID p_source,SourceVoiceID p_voice, float p_volume_db)=0; - - virtual bool source_is_voice_active(RID p_source,SourceVoiceID p_voice) const=0; - virtual void source_stop_voice(RID p_source,SourceVoiceID p_voice)=0; - - /* LISTENER */ - - enum ListenerParam { - - LISTENER_PARAM_VOLUME_SCALE_DB, - LISTENER_PARAM_PITCH_SCALE, - LISTENER_PARAM_ATTENUATION_SCALE, - LISTENER_PARAM_PAN_RANGE, - LISTENER_PARAM_MAX - }; - - virtual RID listener_create()=0; - virtual void listener_set_space(RID p_listener, RID p_space)=0; - - virtual void listener_set_transform(RID p_listener, const Transform2D& p_transform)=0; - virtual Transform2D listener_get_transform(RID p_listener) const=0; - - virtual void listener_set_param(RID p_listener, ListenerParam p_param, float p_value)=0; - virtual float listener_get_param(RID p_listener, ListenerParam p_param) const=0; - - /* MISC */ - - virtual void free(RID p_id)=0; - - virtual void init()=0; - virtual void update(float p_delta)=0; - virtual void finish()=0; - - static SpatialSound2DServer *get_singleton(); - - SpatialSound2DServer(); - -}; - -#endif // SPATIAL_SOUND_2D_SERVER_H diff --git a/servers/spatial_sound_server.cpp b/servers/spatial_sound_server.cpp deleted file mode 100644 index f49367d4c0..0000000000 --- a/servers/spatial_sound_server.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_server.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "spatial_sound_server.h" - -SpatialSoundServer *SpatialSoundServer::singleton=NULL; - - -SpatialSoundServer *SpatialSoundServer::get_singleton() { - - return singleton; -} - - -SpatialSoundServer::SpatialSoundServer() { - - ERR_FAIL_COND(singleton!=NULL); - singleton=this; -} diff --git a/servers/spatial_sound_server.h b/servers/spatial_sound_server.h deleted file mode 100644 index 69ef71c84f..0000000000 --- a/servers/spatial_sound_server.h +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************/ -/* spatial_sound_server.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPATIAL_SOUND_SERVER_H -#define SPATIAL_SOUND_SERVER_H - -#include "object.h" -#include "bsp_tree.h" -#include "servers/audio_server.h" - -class SpatialSoundServer : public Object { - GDCLASS(SpatialSoundServer,Object); - - static SpatialSoundServer *singleton; -public: - - - enum { - SOURCE_INVALID_VOICE=-1, - SOURCE_NEXT_VOICE=-2, - }; - - typedef int SourceVoiceID; - - /* SPACE */ - virtual RID space_create()=0; - - /* ROOM */ - - virtual RID room_create()=0; - virtual void room_set_space(RID p_room,RID p_space)=0; - virtual RID room_get_space(RID p_room) const=0; - - - virtual void room_set_bounds(RID p_room, const BSP_Tree& p_bounds)=0; - virtual BSP_Tree room_get_bounds(RID p_room) const=0; - virtual void room_set_transform(RID p_room, const Transform& p_transform)=0; - virtual Transform room_get_transform(RID p_room) const=0; - - enum RoomParam { - ROOM_PARAM_SPEED_OF_SOUND_SCALE, - ROOM_PARAM_DOPPLER_FACTOR, - ROOM_PARAM_PITCH_SCALE, - ROOM_PARAM_VOLUME_SCALE_DB, - ROOM_PARAM_REVERB_SEND, - ROOM_PARAM_CHORUS_SEND, - ROOM_PARAM_ATTENUATION_SCALE, - ROOM_PARAM_ATTENUATION_HF_CUTOFF, - ROOM_PARAM_ATTENUATION_HF_FLOOR_DB, - ROOM_PARAM_ATTENUATION_HF_RATIO_EXP, - ROOM_PARAM_ATTENUATION_REVERB_SCALE, - ROOM_PARAM_MAX - }; - - virtual void room_set_param(RID p_room, RoomParam p_param, float p_value)=0; - virtual float room_get_param(RID p_room, RoomParam p_param) const=0; - - enum RoomReverb { - ROOM_REVERB_SMALL, - ROOM_REVERB_MEDIUM, - ROOM_REVERB_LARGE, - ROOM_REVERB_HALL - }; - - virtual void room_set_reverb(RID p_room, RoomReverb p_reverb)=0; - virtual RoomReverb room_get_reverb(RID p_room) const=0; - - virtual void room_set_level(RID p_room, int p_level)=0; - virtual int room_get_level(RID p_room) const=0; - - //useful for underwater or rooms with very strange conditions - virtual void room_set_force_params_to_all_sources(RID p_room, bool p_force)=0; - virtual bool room_is_forcing_params_to_all_sources(RID p_room) const=0; - - /* SOURCE */ - - virtual RID source_create(RID p_space)=0; - - virtual void source_set_transform(RID p_source, const Transform& p_transform)=0; - virtual Transform source_get_transform(RID p_source) const=0; - - virtual void source_set_polyphony(RID p_source,int p_voice_count)=0; - virtual int source_get_polyphony(RID p_source) const=0; - - enum SourceParam { - - SOURCE_PARAM_VOLUME_DB, - SOURCE_PARAM_PITCH_SCALE, - SOURCE_PARAM_ATTENUATION_MIN_DISTANCE, - SOURCE_PARAM_ATTENUATION_MAX_DISTANCE, - SOURCE_PARAM_ATTENUATION_DISTANCE_EXP, - SOURCE_PARAM_EMISSION_CONE_DEGREES, - SOURCE_PARAM_EMISSION_CONE_ATTENUATION_DB, - SOURCE_PARAM_MAX - }; - - virtual void source_set_param(RID p_source, SourceParam p_param, float p_value)=0; - virtual float source_get_param(RID p_source, SourceParam p_param) const=0; - - virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream)=0; //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice=SOURCE_NEXT_VOICE)=0; - //voices - virtual void source_voice_set_pitch_scale(RID p_source,SourceVoiceID p_voice, float p_pitch_scale)=0; - virtual void source_voice_set_volume_scale_db(RID p_source,SourceVoiceID p_voice, float p_volume_db)=0; - - virtual bool source_is_voice_active(RID p_source,SourceVoiceID p_voice) const=0; - virtual void source_stop_voice(RID p_source,SourceVoiceID p_voice)=0; - - /* LISTENER */ - - enum ListenerParam { - - LISTENER_PARAM_VOLUME_SCALE_DB, - LISTENER_PARAM_PITCH_SCALE, - LISTENER_PARAM_ATTENUATION_SCALE, - LISTENER_PARAM_RECEPTION_CONE_DEGREES, - LISTENER_PARAM_RECEPTION_CONE_ATTENUATION_DB, - LISTENER_PARAM_MAX - }; - - virtual RID listener_create()=0; - virtual void listener_set_space(RID p_listener, RID p_space)=0; - - virtual void listener_set_transform(RID p_listener, const Transform& p_transform)=0; - virtual Transform listener_get_transform(RID p_listener) const=0; - - virtual void listener_set_param(RID p_listener, ListenerParam p_param, float p_value)=0; - virtual float listener_get_param(RID p_listener, ListenerParam p_param) const=0; - - /* MISC */ - - virtual void free(RID p_id)=0; - - virtual void init()=0; - virtual void update(float p_delta)=0; - virtual void finish()=0; - - static SpatialSoundServer *get_singleton(); - - SpatialSoundServer(); -}; - -#endif // SPATIAL_SOUND_SERVER_H diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 94a514e7c1..44bc9bfef5 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -1226,7 +1226,7 @@ public: virtual void multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color)=0; virtual RID multimesh_get_mesh(RID p_multimesh) const=0; - virtual AABB multimesh_get_aabb(RID p_multimesh) const=0;; + virtual AABB multimesh_get_aabb(RID p_multimesh) const=0; virtual Transform multimesh_instance_get_transform(RID p_multimesh,int p_index) const=0; virtual Color multimesh_instance_get_color(RID p_multimesh,int p_index) const=0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 6a6f437816..7dfd9822f7 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -374,7 +374,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx++; return _make_token(TK_OP_GREATER_EQUAL); } else if (GETCHAR(0)=='<') { - char_idx++;; + char_idx++; if (GETCHAR(0)=='=') { char_idx++; return _make_token(TK_OP_ASSIGN_SHIFT_RIGHT); @@ -1966,7 +1966,7 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode* p_block,const Map<Stri return true; } - _set_tkpos(pos);; + _set_tkpos(pos); while(true) { @@ -2557,7 +2557,7 @@ ShaderLanguage::Node* ShaderLanguage::_parse_expression(BlockNode* p_block,const } else if (l==2) { member_type=DataType(dt-2); } else if (l==3) { - member_type=DataType(dt-1);; + member_type=DataType(dt-1); } else if (l==4) { member_type=dt; } else { diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 2f7bcccf73..f4031b711d 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -934,7 +934,7 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - int new_size = nearest_power_of_2(p_size);; + int new_size = nearest_power_of_2(p_size); if (new_size==clight->shadow_buffer_size) return; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index e3bc0fb6c6..279da9149e 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -123,6 +123,7 @@ void VisualServerRaster::finish(){ VSG::rasterizer->finalize(); } + /* STATUS INFORMATION */ diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index da73980e08..1799585576 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -156,7 +156,7 @@ RID VisualServer::_make_test_cube() { PoolVector<Vector3> uvs; int vtx_idx=0; -#define ADD_VTX(m_idx);\ +#define ADD_VTX(m_idx) \ vertices.push_back( face_points[m_idx] );\ normals.push_back( normal_points[m_idx] );\ tangents.push_back( normal_points[m_idx][1] );\ |