summaryrefslogtreecommitdiff
path: root/scene/resources/audio_stream_sample.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/audio_stream_sample.cpp')
-rw-r--r--scene/resources/audio_stream_sample.cpp142
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);