소스 검색

Added functions to further improve music timing

Juan Linietsky 6 년 전
부모
커밋
c2027c8233
4개의 변경된 파일31개의 추가작업 그리고 2개의 파일을 삭제
  1. 16 2
      scene/audio/audio_stream_player.cpp
  2. 3 0
      scene/audio/audio_stream_player.h
  3. 11 0
      servers/audio_server.cpp
  4. 1 0
      servers/audio_server.h

+ 16 - 2
scene/audio/audio_stream_player.cpp

@@ -94,6 +94,7 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
 	//set volume for next mix
 	mix_volume_db = target_volume;
 
+	time_mixed += double(buffer_size) / AudioServer::get_singleton()->get_mix_rate();
 	_mix_to_bus(buffer,buffer_size);
 
 }
@@ -122,17 +123,23 @@ void AudioStreamPlayer::_mix_audio() {
 		_mix_internal(true);
 		stream_playback->stop();
 		setstop=false;
-	} else if (setseek >= 0.0) {
+	}
+
+	if (setseek >= 0.0 && !stop_has_priority) {
 		if (stream_playback->is_playing()) {
 
 			//fade out to avoid pops
 			_mix_internal(true);
+		} else {
+			time_mixed=0;
 		}
 		stream_playback->start(setseek);
 		setseek = -1.0; //reset seek
 		mix_volume_db = volume_db; //reset ramp
 	}
 
+	stop_has_priority = false;
+
 	_mix_internal(false);
 }
 
@@ -247,7 +254,7 @@ void AudioStreamPlayer::play(float p_from_pos) {
 	if (stream_playback.is_valid()) {
 		//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
 		setseek = p_from_pos;
-		setstop = false;
+		stop_has_priority=false;
 		active = true;
 		set_process_internal(true);
 	}
@@ -264,6 +271,7 @@ void AudioStreamPlayer::stop() {
 
 	if (stream_playback.is_valid() && active) {
 		setstop=true;
+		stop_has_priority=true;
 	}
 }
 
@@ -285,6 +293,10 @@ float AudioStreamPlayer::get_playback_position() {
 	return 0;
 }
 
+float AudioStreamPlayer::get_mix_time() const {
+	return time_mixed;
+}
+
 void AudioStreamPlayer::set_bus(const StringName &p_bus) {
 
 	//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("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("get_bus"), &AudioStreamPlayer::get_bus);
@@ -438,6 +451,7 @@ AudioStreamPlayer::AudioStreamPlayer() {
 	fadeout_buffer.resize(512);
 	setstop=false;
 	use_fadeout=false;
+	time_mixed = 0;
 
 	AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
 }

+ 3 - 0
scene/audio/audio_stream_player.h

@@ -52,11 +52,13 @@ private:
 	Vector<AudioFrame> fadeout_buffer;
 	bool use_fadeout;
 
+	double time_mixed;
 
 
 	volatile float setseek;
 	volatile bool active;
 	volatile bool setstop;
+	volatile bool stop_has_priority;
 
 	float mix_volume_db;
 	float pitch_scale;
@@ -98,6 +100,7 @@ public:
 	void stop();
 	bool is_playing() const;
 	float get_playback_position();
+	float get_mix_time() const;
 
 	void set_bus(const StringName &p_bus);
 	StringName get_bus() const;

+ 11 - 0
servers/audio_server.cpp

@@ -73,6 +73,11 @@ void AudioDriver::update_mix_time(int p_frames) {
 		_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 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();
 }
 
+double AudioServer::get_time_since_last_mix() const {
+
+	return AudioDriver::get_singleton()->get_time_since_last_mix();
+}
+
 AudioServer *AudioServer::singleton = NULL;
 
 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("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("capture_get_device_list"), &AudioServer::capture_get_device_list);

+ 1 - 0
servers/audio_server.h

@@ -357,6 +357,7 @@ public:
 
 	virtual double get_output_latency() 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_free(void *p_data);