mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
Merge pull request #55846 from ellenhp/fix_ogg_edge_cases
Fix ogg edge cases
This commit is contained in:
commit
d1dac8427a
@ -38,7 +38,9 @@
|
|||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
|
|
||||||
int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
||||||
ERR_FAIL_COND_V(!active, 0);
|
if (!active) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int todo = p_frames;
|
int todo = p_frames;
|
||||||
|
|
||||||
|
@ -36,23 +36,22 @@
|
|||||||
|
|
||||||
int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) {
|
||||||
ERR_FAIL_COND_V(!ready, 0);
|
ERR_FAIL_COND_V(!ready, 0);
|
||||||
ERR_FAIL_COND_V(!active, 0);
|
|
||||||
|
if (!active) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int todo = p_frames;
|
int todo = p_frames;
|
||||||
|
|
||||||
int start_buffer = 0;
|
int start_buffer = 0;
|
||||||
|
|
||||||
int frames_mixed_this_step = p_frames;
|
while (todo > 0 && active) {
|
||||||
|
|
||||||
while (todo && active) {
|
|
||||||
AudioFrame *buffer = p_buffer;
|
AudioFrame *buffer = p_buffer;
|
||||||
if (start_buffer > 0) {
|
if (start_buffer > 0) {
|
||||||
buffer = buffer + start_buffer;
|
buffer = buffer + start_buffer;
|
||||||
}
|
}
|
||||||
int mixed = _mix_frames_vorbis(buffer, todo);
|
int mixed = _mix_frames_vorbis(buffer, todo);
|
||||||
if (mixed < 0) {
|
ERR_FAIL_COND_V(mixed < 0, 0);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
todo -= mixed;
|
todo -= mixed;
|
||||||
frames_mixed += mixed;
|
frames_mixed += mixed;
|
||||||
start_buffer += mixed;
|
start_buffer += mixed;
|
||||||
@ -67,16 +66,14 @@ int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram
|
|||||||
// we still have buffer to fill, start from this element in the next iteration.
|
// we still have buffer to fill, start from this element in the next iteration.
|
||||||
start_buffer = p_frames - todo;
|
start_buffer = p_frames - todo;
|
||||||
} else {
|
} else {
|
||||||
frames_mixed_this_step = p_frames - todo;
|
|
||||||
for (int i = p_frames - todo; i < p_frames; i++) {
|
for (int i = p_frames - todo; i < p_frames; i++) {
|
||||||
p_buffer[i] = AudioFrame(0, 0);
|
p_buffer[i] = AudioFrame(0, 0);
|
||||||
}
|
}
|
||||||
active = false;
|
active = false;
|
||||||
todo = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return frames_mixed_this_step;
|
return p_frames - todo;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) {
|
int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) {
|
||||||
|
@ -135,9 +135,10 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
|
|||||||
|
|
||||||
uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale * playback_speed_scale) / double(target_rate)) * double(FP_LEN));
|
uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale * playback_speed_scale) / double(target_rate)) * double(FP_LEN));
|
||||||
|
|
||||||
int mixed_frames_total = p_frames;
|
int mixed_frames_total = -1;
|
||||||
|
|
||||||
for (int i = 0; i < p_frames; i++) {
|
int i;
|
||||||
|
for (i = 0; i < p_frames; i++) {
|
||||||
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
|
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
|
||||||
//standard cubic interpolation (great quality/performance ratio)
|
//standard cubic interpolation (great quality/performance ratio)
|
||||||
//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
|
//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
|
||||||
@ -147,7 +148,7 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
|
|||||||
AudioFrame y2 = internal_buffer[idx - 1];
|
AudioFrame y2 = internal_buffer[idx - 1];
|
||||||
AudioFrame y3 = internal_buffer[idx - 0];
|
AudioFrame y3 = internal_buffer[idx - 0];
|
||||||
|
|
||||||
if (idx <= internal_buffer_end && idx >= internal_buffer_end && mixed_frames_total == p_frames) {
|
if (idx >= internal_buffer_end && mixed_frames_total == -1) {
|
||||||
// The internal buffer ends somewhere in this range, and we haven't yet recorded the number of good frames we have.
|
// The internal buffer ends somewhere in this range, and we haven't yet recorded the number of good frames we have.
|
||||||
mixed_frames_total = i;
|
mixed_frames_total = i;
|
||||||
}
|
}
|
||||||
@ -167,24 +168,20 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
|
|||||||
internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
|
internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
|
||||||
internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
|
internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
|
||||||
internal_buffer[3] = internal_buffer[INTERNAL_BUFFER_LEN + 3];
|
internal_buffer[3] = internal_buffer[INTERNAL_BUFFER_LEN + 3];
|
||||||
if (is_playing()) {
|
int mixed_frames = _mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
|
||||||
int mixed_frames = _mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
|
if (mixed_frames != INTERNAL_BUFFER_LEN) {
|
||||||
if (mixed_frames != INTERNAL_BUFFER_LEN) {
|
// internal_buffer[mixed_frames] is the first frame of silence.
|
||||||
// internal_buffer[mixed_frames] is the first frame of silence.
|
internal_buffer_end = mixed_frames;
|
||||||
internal_buffer_end = mixed_frames;
|
|
||||||
} else {
|
|
||||||
// The internal buffer does not contain the first frame of silence.
|
|
||||||
internal_buffer_end = -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//fill with silence, not playing
|
// The internal buffer does not contain the first frame of silence.
|
||||||
for (int j = 0; j < INTERNAL_BUFFER_LEN; ++j) {
|
internal_buffer_end = -1;
|
||||||
internal_buffer[j + 4] = AudioFrame(0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mix_offset -= (INTERNAL_BUFFER_LEN << FP_BITS);
|
mix_offset -= (INTERNAL_BUFFER_LEN << FP_BITS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mixed_frames_total == -1 && i == p_frames) {
|
||||||
|
mixed_frames_total = p_frames;
|
||||||
|
}
|
||||||
return mixed_frames_total;
|
return mixed_frames_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user