-Added ramp fadeout in AudioStreamPlayer, removes clips on audio restart
-Fixed bug in AudioStreamPlayerSampler not completely writing the target buffer if sample ends, fixes #12307
This commit is contained in:
parent
c1855dcff1
commit
48d57e4a30
3 changed files with 57 additions and 26 deletions
|
@ -31,20 +31,7 @@
|
|||
|
||||
#include "engine.h"
|
||||
|
||||
void AudioStreamPlayer::_mix_audio() {
|
||||
|
||||
if (!stream_playback.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (setseek >= 0.0) {
|
||||
stream_playback->start(setseek);
|
||||
setseek = -1.0; //reset seek
|
||||
}
|
||||
void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
|
||||
|
||||
int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
|
||||
|
||||
|
@ -52,19 +39,24 @@ void AudioStreamPlayer::_mix_audio() {
|
|||
AudioFrame *buffer = mix_buffer.ptr();
|
||||
int buffer_size = mix_buffer.size();
|
||||
|
||||
if (p_fadeout) {
|
||||
buffer_size = MIN(buffer_size, 16); //short fadeout ramp
|
||||
}
|
||||
|
||||
//mix
|
||||
stream_playback->mix(buffer, 1.0, buffer_size);
|
||||
|
||||
//multiply volume interpolating to avoid clicks if this changes
|
||||
float target_volume = p_fadeout ? -80.0 : volume_db;
|
||||
float vol = Math::db2linear(mix_volume_db);
|
||||
float vol_inc = (Math::db2linear(volume_db) - vol) / float(buffer_size);
|
||||
float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size);
|
||||
|
||||
for (int i = 0; i < buffer_size; i++) {
|
||||
buffer[i] *= vol;
|
||||
vol += vol_inc;
|
||||
}
|
||||
//set volume for next mix
|
||||
mix_volume_db = volume_db;
|
||||
mix_volume_db = target_volume;
|
||||
|
||||
AudioFrame *targets[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
|
@ -95,6 +87,30 @@ void AudioStreamPlayer::_mix_audio() {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioStreamPlayer::_mix_audio() {
|
||||
|
||||
if (!stream_playback.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (setseek >= 0.0) {
|
||||
if (stream_playback->is_playing()) {
|
||||
|
||||
//fade out to avoid pops
|
||||
_mix_internal(true);
|
||||
}
|
||||
stream_playback->start(setseek);
|
||||
setseek = -1.0; //reset seek
|
||||
mix_volume_db = volume_db; //reset ramp
|
||||
}
|
||||
|
||||
_mix_internal(false);
|
||||
}
|
||||
|
||||
void AudioStreamPlayer::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
|
@ -163,7 +179,7 @@ float AudioStreamPlayer::get_volume_db() const {
|
|||
void AudioStreamPlayer::play(float p_from_pos) {
|
||||
|
||||
if (stream_playback.is_valid()) {
|
||||
mix_volume_db = volume_db; //reset volume ramp
|
||||
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
|
||||
setseek = p_from_pos;
|
||||
active = true;
|
||||
set_process_internal(true);
|
||||
|
|
|
@ -59,6 +59,7 @@ private:
|
|||
|
||||
MixTarget mix_target;
|
||||
|
||||
void _mix_internal(bool p_fadeout);
|
||||
void _mix_audio();
|
||||
static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer *>(self)->_mix_audio(); }
|
||||
|
||||
|
|
|
@ -31,17 +31,23 @@
|
|||
|
||||
void AudioStreamPlaybackSample::start(float p_from_pos) {
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ima_adpcm[i].step_index = 0;
|
||||
ima_adpcm[i].predictor = 0;
|
||||
ima_adpcm[i].loop_step_index = 0;
|
||||
ima_adpcm[i].loop_predictor = 0;
|
||||
ima_adpcm[i].last_nibble = -1;
|
||||
ima_adpcm[i].loop_pos = 0x7FFFFFFF;
|
||||
ima_adpcm[i].window_ofs = 0;
|
||||
if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
|
||||
//no seeking in IMA_ADPCM
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ima_adpcm[i].step_index = 0;
|
||||
ima_adpcm[i].predictor = 0;
|
||||
ima_adpcm[i].loop_step_index = 0;
|
||||
ima_adpcm[i].loop_predictor = 0;
|
||||
ima_adpcm[i].last_nibble = -1;
|
||||
ima_adpcm[i].loop_pos = 0x7FFFFFFF;
|
||||
ima_adpcm[i].window_ofs = 0;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
} else {
|
||||
seek(p_from_pos);
|
||||
}
|
||||
|
||||
seek(p_from_pos);
|
||||
sign = 1;
|
||||
active = true;
|
||||
}
|
||||
|
@ -373,6 +379,14 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
|
|||
|
||||
dst_buff += target;
|
||||
}
|
||||
|
||||
if (todo) {
|
||||
//bit was missing from mix
|
||||
int todo_ofs = p_frames - todo;
|
||||
for (int i = todo_ofs; i < p_frames; i++) {
|
||||
p_buffer[i] = AudioFrame(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AudioStreamPlaybackSample::get_length() const {
|
||||
|
|
Loading…
Reference in a new issue