diff options
Diffstat (limited to 'scene/resources/audio_stream_sample.cpp')
-rw-r--r-- | scene/resources/audio_stream_sample.cpp | 142 |
1 files changed, 73 insertions, 69 deletions
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index d630a1f3ee..600a859894 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -34,7 +34,6 @@ #include "core/os/file_access.h" void AudioStreamPlaybackSample::start(float p_from_pos) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { //no seeking in IMA_ADPCM for (int i = 0; i < 2; i++) { @@ -57,28 +56,25 @@ void AudioStreamPlaybackSample::start(float p_from_pos) { } void AudioStreamPlaybackSample::stop() { - active = false; } bool AudioStreamPlaybackSample::is_playing() const { - return active; } int AudioStreamPlaybackSample::get_loop_count() const { - return 0; } float AudioStreamPlaybackSample::get_playback_position() const { - return float(offset >> MIX_FRAC_BITS) / base->mix_rate; } -void AudioStreamPlaybackSample::seek(float p_time) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) +void AudioStreamPlaybackSample::seek(float p_time) { + if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { return; //no seeking in ima-adpcm + } float max = base->get_length(); if (p_time < 0) { @@ -92,22 +88,20 @@ void AudioStreamPlaybackSample::seek(float p_time) { template <class Depth, bool is_stereo, bool is_ima_adpcm> void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { - // this function will be compiled branchless by any decent compiler int32_t final, final_r, next, next_r; while (amount) { amount--; int64_t pos = offset >> MIX_FRAC_BITS; - if (is_stereo && !is_ima_adpcm) + if (is_stereo && !is_ima_adpcm) { pos <<= 1; + } if (is_ima_adpcm) { - int64_t sample_pos = pos + ima_adpcm[0].window_ofs; while (sample_pos > 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, @@ -126,7 +120,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds }; for (int i = 0; i < (is_stereo ? 2 : 1); i++) { - int16_t nibble, diff, step; ima_adpcm[i].last_nibble++; @@ -138,30 +131,36 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds step = _ima_adpcm_step_table[ima_adpcm[i].step_index]; ima_adpcm[i].step_index += _ima_adpcm_index_table[nibble]; - if (ima_adpcm[i].step_index < 0) + if (ima_adpcm[i].step_index < 0) { ima_adpcm[i].step_index = 0; - if (ima_adpcm[i].step_index > 88) + } + if (ima_adpcm[i].step_index > 88) { ima_adpcm[i].step_index = 88; + } diff = step >> 3; - if (nibble & 1) + if (nibble & 1) { diff += step >> 2; - if (nibble & 2) + } + if (nibble & 2) { diff += step >> 1; - if (nibble & 4) + } + if (nibble & 4) { diff += step; - if (nibble & 8) + } + if (nibble & 8) { diff = -diff; + } ima_adpcm[i].predictor += diff; - if (ima_adpcm[i].predictor < -0x8000) + if (ima_adpcm[i].predictor < -0x8000) { ima_adpcm[i].predictor = -0x8000; - else if (ima_adpcm[i].predictor > 0x7FFF) + } else if (ima_adpcm[i].predictor > 0x7FFF) { ima_adpcm[i].predictor = 0x7FFF; + } /* store loop if there */ if (ima_adpcm[i].last_nibble == ima_adpcm[i].loop_pos) { - ima_adpcm[i].loop_step_index = ima_adpcm[i].step_index; ima_adpcm[i].loop_predictor = ima_adpcm[i].predictor; } @@ -177,17 +176,18 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds } else { final = p_src[pos]; - if (is_stereo) + 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) + if (is_stereo) { final_r <<= 8; + } } if (is_stereo) { - next = p_src[pos + 2]; next_r = p_src[pos + 3]; } else { @@ -196,15 +196,17 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds if (sizeof(Depth) == 1) { next <<= 8; - if (is_stereo) + if (is_stereo) { next_r <<= 8; + } } int32_t frac = int64_t(offset & MIX_FRAC_MASK); final = final + ((next - final) * frac >> MIX_FRAC_BITS); - if (is_stereo) + if (is_stereo) { final_r = final_r + ((next_r - final_r) * frac >> MIX_FRAC_BITS); + } } if (!is_stereo) { @@ -220,7 +222,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds } void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { - if (!base->data || !active) { for (int i = 0; i < p_frames; i++) { p_buffer[i] = AudioFrame(0, 0); @@ -230,9 +231,15 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in int len = base->data_bytes; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break; + case AudioStreamSample::FORMAT_8_BITS: + len /= 1; + break; + case AudioStreamSample::FORMAT_16_BITS: + len /= 2; + break; + case AudioStreamSample::FORMAT_IMA_ADPCM: + len *= 2; + break; } if (base->stereo) { @@ -254,7 +261,8 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in sign = -1; } - float base_rate = AudioServer::get_singleton()->get_mix_rate(); + float global_rate_scale = AudioServer::get_singleton()->get_global_rate_scale(); + float base_rate = AudioServer::get_singleton()->get_mix_rate() * global_rate_scale; float srate = base->mix_rate; srate *= p_rate_scale; float fincrement = srate / base_rate; @@ -273,7 +281,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in AudioFrame *dst_buff = p_buffer; if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { - if (loop_format != AudioStreamSample::LOOP_DISABLED) { ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; @@ -282,7 +289,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } while (todo > 0) { - int64_t limit = 0; int32_t target = 0, aux = 0; @@ -305,7 +311,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } else { /* check for sample not reaching beginning */ if (offset < 0) { - active = false; break; } @@ -337,7 +342,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } else { /* no loop, check for end of sample */ if (offset >= length_fp) { - active = false; break; } @@ -363,24 +367,26 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in switch (base->format) { case AudioStreamSample::FORMAT_8_BITS: { - - if (is_stereo) + if (is_stereo) { do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); - else + } else { do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); + } } break; case AudioStreamSample::FORMAT_16_BITS: { - if (is_stereo) + if (is_stereo) { do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm); - else + } else { do_resample<int16_t, false, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm); + } } break; case AudioStreamSample::FORMAT_IMA_ADPCM: { - if (is_stereo) + if (is_stereo) { do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); - else + } else { do_resample<int8_t, false, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); + } } break; } @@ -398,7 +404,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } AudioStreamPlaybackSample::AudioStreamPlaybackSample() { - active = false; offset = 0; sign = 1; @@ -407,67 +412,66 @@ AudioStreamPlaybackSample::AudioStreamPlaybackSample() { ///////////////////// void AudioStreamSample::set_format(Format p_format) { - format = p_format; } AudioStreamSample::Format AudioStreamSample::get_format() const { - return format; } void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) { - loop_mode = p_loop_mode; } -AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const { +AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const { return loop_mode; } void AudioStreamSample::set_loop_begin(int p_frame) { - loop_begin = p_frame; } -int AudioStreamSample::get_loop_begin() const { +int AudioStreamSample::get_loop_begin() const { return loop_begin; } void AudioStreamSample::set_loop_end(int p_frame) { - loop_end = p_frame; } -int AudioStreamSample::get_loop_end() const { +int AudioStreamSample::get_loop_end() const { return loop_end; } void AudioStreamSample::set_mix_rate(int p_hz) { - ERR_FAIL_COND(p_hz == 0); mix_rate = p_hz; } -int AudioStreamSample::get_mix_rate() const { +int AudioStreamSample::get_mix_rate() const { return mix_rate; } -void AudioStreamSample::set_stereo(bool p_enable) { +void AudioStreamSample::set_stereo(bool p_enable) { stereo = p_enable; } -bool AudioStreamSample::is_stereo() const { +bool AudioStreamSample::is_stereo() const { return stereo; } float AudioStreamSample::get_length() const { - int len = data_bytes; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break; + case AudioStreamSample::FORMAT_8_BITS: + len /= 1; + break; + case AudioStreamSample::FORMAT_16_BITS: + len /= 2; + break; + case AudioStreamSample::FORMAT_IMA_ADPCM: + len *= 2; + break; } if (stereo) { @@ -478,7 +482,6 @@ float AudioStreamSample::get_length() const { } void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { - AudioServer::get_singleton()->lock(); if (data) { memfree(data); @@ -488,7 +491,6 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { int datalen = p_data.size(); if (datalen) { - const uint8_t *r = p_data.ptr(); int alloc_len = datalen + DATA_PAD * 2; data = memalloc(alloc_len); //alloc with some padding for interpolation @@ -500,14 +502,13 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->unlock(); } -Vector<uint8_t> AudioStreamSample::get_data() const { +Vector<uint8_t> AudioStreamSample::get_data() const { Vector<uint8_t> pv; if (data) { pv.resize(data_bytes); { - uint8_t *w = pv.ptrw(); uint8_t *dataptr = (uint8_t *)data; copymem(w, dataptr + DATA_PAD, data_bytes); @@ -536,9 +537,15 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { int byte_pr_sample = 0; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: byte_pr_sample = 1; break; - case AudioStreamSample::FORMAT_16_BITS: byte_pr_sample = 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break; + case AudioStreamSample::FORMAT_8_BITS: + byte_pr_sample = 1; + break; + case AudioStreamSample::FORMAT_16_BITS: + byte_pr_sample = 2; + break; + case AudioStreamSample::FORMAT_IMA_ADPCM: + byte_pr_sample = 4; + break; } String file_path = p_path; @@ -592,7 +599,6 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { } Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() { - Ref<AudioStreamPlaybackSample> sample; sample.instance(); sample->base = Ref<AudioStreamSample>(this); @@ -600,12 +606,10 @@ Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() { } String AudioStreamSample::get_stream_name() const { - return ""; } void AudioStreamSample::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data); ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data); |