bool AudioStreamGibberish::mix(int32_t *p_buffer, int p_frames) { if (!active) return false; zeromem(p_buffer,p_frames*sizeof(int32_t)); if (!paused && active_voices==0) { active_voices=1; playback[0].idx=randomize(); playback[0].fp_pos=0; playback[0].scale=Math::random(1,1+pitch_random_scale); } for(int i=0;i<active_voices;i++) { RID s = _samples[playback[i].idx]->get_rid(); uint64_t fp_pos=playback[i].fp_pos; const void *data = AudioServer::get_singleton()->sample_get_data_ptr(s); bool is16 = AudioServer::get_singleton()->sample_get_format(s)==AudioServer::SAMPLE_FORMAT_PCM16; int skip = AudioServer::get_singleton()->sample_is_stereo(s) ? 1: 0; uint64_t max = AudioServer::get_singleton()->sample_get_length(s) * uint64_t(FP_LEN); int mrate = AudioServer::get_singleton()->sample_get_mix_rate(s) * pitch_scale * playback[i].scale; uint64_t increment = uint64_t(mrate) * uint64_t(FP_LEN) / get_mix_rate(); float vol_begin = _get_vol_at_pos(fp_pos>>FP_BITS,max>>FP_BITS,xfade_time*mrate); float vol_end = _get_vol_at_pos((fp_pos+p_frames*increment)>>FP_BITS,max>>FP_BITS,xfade_time*mrate); int32_t vol = CLAMP(int32_t(vol_begin * 65535),0,65535); int32_t vol_to = CLAMP(int32_t(vol_end * 65535),0,65535); int32_t vol_inc = (vol_to-vol)/p_frames; bool done=false; if (is16) { const int16_t *smp = (int16_t*)data; for(int i=0;i<p_frames;i++) { if (fp_pos >= max) { done=true; break; } int idx = (fp_pos>>FP_BITS)<<skip; p_buffer[i]+=int32_t(smp[idx])*vol; vol+=vol_inc; fp_pos+=increment; } } else { const int8_t *smp = (int8_t*)data; for(int i=0;i<p_frames;i++) { if (fp_pos >= max) { done=true; break; } int idx = (fp_pos>>FP_BITS)<<skip; p_buffer[i]+=(int32_t(smp[idx])<<8)*vol; vol+=vol_inc; fp_pos+=increment; } } playback[i].fp_pos=fp_pos; if (!paused && active_voices==1 && (vol_end < vol_begin || done)) { //xfade to something else i gues active_voices=2; playback[1].idx=randomize(); playback[1].fp_pos=0; playback[1].scale=Math::random(1,1+pitch_random_scale); } if (done) { if (i==0 && active_voices==2) { playback[0]=playback[1]; i--; } active_voices--; } }
double AudioDriver::get_mix_time() const { double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; total += _mix_amount / (double)get_mix_rate(); return total; }