You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Added functions to further improve music timing
This commit is contained in:
@@ -94,6 +94,7 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
|
|||||||
//set volume for next mix
|
//set volume for next mix
|
||||||
mix_volume_db = target_volume;
|
mix_volume_db = target_volume;
|
||||||
|
|
||||||
|
time_mixed += double(buffer_size) / AudioServer::get_singleton()->get_mix_rate();
|
||||||
_mix_to_bus(buffer,buffer_size);
|
_mix_to_bus(buffer,buffer_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -122,17 +123,23 @@ void AudioStreamPlayer::_mix_audio() {
|
|||||||
_mix_internal(true);
|
_mix_internal(true);
|
||||||
stream_playback->stop();
|
stream_playback->stop();
|
||||||
setstop=false;
|
setstop=false;
|
||||||
} else if (setseek >= 0.0) {
|
}
|
||||||
|
|
||||||
|
if (setseek >= 0.0 && !stop_has_priority) {
|
||||||
if (stream_playback->is_playing()) {
|
if (stream_playback->is_playing()) {
|
||||||
|
|
||||||
//fade out to avoid pops
|
//fade out to avoid pops
|
||||||
_mix_internal(true);
|
_mix_internal(true);
|
||||||
|
} else {
|
||||||
|
time_mixed=0;
|
||||||
}
|
}
|
||||||
stream_playback->start(setseek);
|
stream_playback->start(setseek);
|
||||||
setseek = -1.0; //reset seek
|
setseek = -1.0; //reset seek
|
||||||
mix_volume_db = volume_db; //reset ramp
|
mix_volume_db = volume_db; //reset ramp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop_has_priority = false;
|
||||||
|
|
||||||
_mix_internal(false);
|
_mix_internal(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +254,7 @@ void AudioStreamPlayer::play(float p_from_pos) {
|
|||||||
if (stream_playback.is_valid()) {
|
if (stream_playback.is_valid()) {
|
||||||
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
|
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
|
||||||
setseek = p_from_pos;
|
setseek = p_from_pos;
|
||||||
setstop = false;
|
stop_has_priority=false;
|
||||||
active = true;
|
active = true;
|
||||||
set_process_internal(true);
|
set_process_internal(true);
|
||||||
}
|
}
|
||||||
@@ -264,6 +271,7 @@ void AudioStreamPlayer::stop() {
|
|||||||
|
|
||||||
if (stream_playback.is_valid() && active) {
|
if (stream_playback.is_valid() && active) {
|
||||||
setstop=true;
|
setstop=true;
|
||||||
|
stop_has_priority=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,6 +293,10 @@ float AudioStreamPlayer::get_playback_position() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AudioStreamPlayer::get_mix_time() const {
|
||||||
|
return time_mixed;
|
||||||
|
}
|
||||||
|
|
||||||
void AudioStreamPlayer::set_bus(const StringName &p_bus) {
|
void AudioStreamPlayer::set_bus(const StringName &p_bus) {
|
||||||
|
|
||||||
//if audio is active, must lock this
|
//if audio is active, must lock this
|
||||||
@@ -388,6 +400,7 @@ void AudioStreamPlayer::_bind_methods() {
|
|||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing);
|
ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing);
|
||||||
ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer::get_playback_position);
|
ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer::get_playback_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_mix_time"), &AudioStreamPlayer::get_mix_time);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus);
|
ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus);
|
||||||
ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus);
|
ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus);
|
||||||
@@ -438,6 +451,7 @@ AudioStreamPlayer::AudioStreamPlayer() {
|
|||||||
fadeout_buffer.resize(512);
|
fadeout_buffer.resize(512);
|
||||||
setstop=false;
|
setstop=false;
|
||||||
use_fadeout=false;
|
use_fadeout=false;
|
||||||
|
time_mixed = 0;
|
||||||
|
|
||||||
AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
|
AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,11 +52,13 @@ private:
|
|||||||
Vector<AudioFrame> fadeout_buffer;
|
Vector<AudioFrame> fadeout_buffer;
|
||||||
bool use_fadeout;
|
bool use_fadeout;
|
||||||
|
|
||||||
|
double time_mixed;
|
||||||
|
|
||||||
|
|
||||||
volatile float setseek;
|
volatile float setseek;
|
||||||
volatile bool active;
|
volatile bool active;
|
||||||
volatile bool setstop;
|
volatile bool setstop;
|
||||||
|
volatile bool stop_has_priority;
|
||||||
|
|
||||||
float mix_volume_db;
|
float mix_volume_db;
|
||||||
float pitch_scale;
|
float pitch_scale;
|
||||||
@@ -98,6 +100,7 @@ public:
|
|||||||
void stop();
|
void stop();
|
||||||
bool is_playing() const;
|
bool is_playing() const;
|
||||||
float get_playback_position();
|
float get_playback_position();
|
||||||
|
float get_mix_time() const;
|
||||||
|
|
||||||
void set_bus(const StringName &p_bus);
|
void set_bus(const StringName &p_bus);
|
||||||
StringName get_bus() const;
|
StringName get_bus() const;
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ void AudioDriver::update_mix_time(int p_frames) {
|
|||||||
_last_mix_time = OS::get_singleton()->get_ticks_usec();
|
_last_mix_time = OS::get_singleton()->get_ticks_usec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double AudioDriver::get_time_since_last_mix() const {
|
||||||
|
|
||||||
|
return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
double AudioDriver::get_time_to_next_mix() const {
|
double AudioDriver::get_time_to_next_mix() const {
|
||||||
|
|
||||||
double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
|
double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
|
||||||
@@ -1110,6 +1115,11 @@ double AudioServer::get_time_to_next_mix() const {
|
|||||||
return AudioDriver::get_singleton()->get_time_to_next_mix();
|
return AudioDriver::get_singleton()->get_time_to_next_mix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double AudioServer::get_time_since_last_mix() const {
|
||||||
|
|
||||||
|
return AudioDriver::get_singleton()->get_time_since_last_mix();
|
||||||
|
}
|
||||||
|
|
||||||
AudioServer *AudioServer::singleton = NULL;
|
AudioServer *AudioServer::singleton = NULL;
|
||||||
|
|
||||||
void *AudioServer::audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_data) {
|
void *AudioServer::audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_data) {
|
||||||
@@ -1352,6 +1362,7 @@ void AudioServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_device", "device"), &AudioServer::set_device);
|
ClassDB::bind_method(D_METHOD("set_device", "device"), &AudioServer::set_device);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_time_to_next_mix"), &AudioServer::get_time_to_next_mix);
|
ClassDB::bind_method(D_METHOD("get_time_to_next_mix"), &AudioServer::get_time_to_next_mix);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_time_since_last_mix"), &AudioServer::get_time_since_last_mix);
|
||||||
ClassDB::bind_method(D_METHOD("get_output_latency"), &AudioServer::get_output_latency);
|
ClassDB::bind_method(D_METHOD("get_output_latency"), &AudioServer::get_output_latency);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list);
|
ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list);
|
||||||
|
|||||||
@@ -357,6 +357,7 @@ public:
|
|||||||
|
|
||||||
virtual double get_output_latency() const;
|
virtual double get_output_latency() const;
|
||||||
virtual double get_time_to_next_mix() const;
|
virtual double get_time_to_next_mix() const;
|
||||||
|
virtual double get_time_since_last_mix() const;
|
||||||
|
|
||||||
void *audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_data = NULL);
|
void *audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_data = NULL);
|
||||||
void audio_data_free(void *p_data);
|
void audio_data_free(void *p_data);
|
||||||
|
|||||||
Reference in New Issue
Block a user