summaryrefslogtreecommitdiff
path: root/servers/audio
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-01-15 16:06:14 -0300
committerJuan Linietsky <reduzio@gmail.com>2017-01-15 16:07:51 -0300
commitb400c69cd487f70d8164dd5550eb994253d359d6 (patch)
tree3ff9a43ef2fb12fa16bf0aca0f3f56fb7a1cf212 /servers/audio
parentb24b52d56bb3938bdeff9640b0730d7717f2b4c6 (diff)
Oops! Audio engine has vanished :D
Diffstat (limited to 'servers/audio')
-rw-r--r--servers/audio/audio_driver_dummy.cpp4
-rw-r--r--servers/audio/audio_driver_dummy.h8
-rw-r--r--servers/audio/audio_effect.cpp6
-rw-r--r--servers/audio/audio_effect.h26
-rw-r--r--servers/audio/audio_mixer_sw.cpp1222
-rw-r--r--servers/audio/audio_mixer_sw.h264
-rw-r--r--servers/audio/audio_server_sw.cpp1028
-rw-r--r--servers/audio/audio_server_sw.h286
-rw-r--r--servers/audio/sample_manager_sw.cpp320
-rw-r--r--servers/audio/sample_manager_sw.h129
10 files changed, 38 insertions, 3255 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index 6fe14b0fcb..0d9a915188 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;
+ output_format = SPEAKER_MODE_STEREO;
channels = 2;
int latency = GLOBAL_DEF("audio/output_latency",25);
@@ -97,7 +97,7 @@ 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;
};
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index c91a0db43a..a848b0630a 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 output_format;
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