Browse Source

Add backward looping support to AudioStreamSample (wav files)

MrCdK 6 years ago
parent
commit
b2bfcb53d6

+ 3 - 0
doc/classes/AudioStreamSample.xml

@@ -62,5 +62,8 @@
 		<constant name="LOOP_PING_PONG" value="2" enum="LoopMode">
 			Audio loops the data between loop_begin and loop_end playing back and forth.
 		</constant>
+		<constant name="LOOP_BACKWARD" value="3" enum="LoopMode">
+			Audio loops the data between loop_begin and loop_end playing backward only.
+		</constant>
 	</constants>
 </class>

+ 10 - 4
editor/import/resource_importer_wav.cpp

@@ -272,12 +272,18 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
 			for (int i = 0; i < 10; i++)
 				file->get_32(); // i wish to know why should i do this... no doc!
 
-			// only read 0x00 (loop forward) and 0x01 (loop ping-pong) and skip anything else because
-			// it's not supported (loop backward), reserved for future uses or sampler specific
+			// only read 0x00 (loop forward), 0x01 (loop ping-pong) and 0x02 (loop backward)
+			// Skip anything else because it's not supported, reserved for future uses or sampler specific
 			// from https://sites.google.com/site/musicgapi/technical-documents/wav-file-format#smpl (loop type values table)
 			int loop_type = file->get_32();
-			if (loop_type == 0x00 || loop_type == 0x01) {
-				loop = loop_type ? AudioStreamSample::LOOP_PING_PONG : AudioStreamSample::LOOP_FORWARD;
+			if (loop_type == 0x00 || loop_type == 0x01 || loop_type == 0x02) {
+				if (loop_type == 0x00) {
+					loop = AudioStreamSample::LOOP_FORWARD;
+				} else if (loop_type == 0x01) {
+					loop = AudioStreamSample::LOOP_PING_PONG;
+				} else if (loop_type == 0x02) {
+					loop = AudioStreamSample::LOOP_BACKWARD;
+				}
 				loop_begin = file->get_32();
 				loop_end = file->get_32();
 			}

+ 6 - 1
scene/resources/audio_stream_sample.cpp

@@ -249,6 +249,10 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
 
 	int32_t todo = p_frames;
 
+	if (base->loop_mode == AudioStreamSample::LOOP_BACKWARD) {
+		sign = -1;
+	}
+
 	float base_rate = AudioServer::get_singleton()->get_mix_rate();
 	float srate = base->mix_rate;
 	srate *= p_rate_scale;
@@ -621,7 +625,7 @@ void AudioStreamSample::_bind_methods() {
 
 	ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong"), "set_loop_mode", "get_loop_mode");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong,Backward"), "set_loop_mode", "get_loop_mode");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_begin"), "set_loop_begin", "get_loop_begin");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_end"), "set_loop_end", "get_loop_end");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_rate"), "set_mix_rate", "get_mix_rate");
@@ -634,6 +638,7 @@ void AudioStreamSample::_bind_methods() {
 	BIND_ENUM_CONSTANT(LOOP_DISABLED);
 	BIND_ENUM_CONSTANT(LOOP_FORWARD);
 	BIND_ENUM_CONSTANT(LOOP_PING_PONG);
+	BIND_ENUM_CONSTANT(LOOP_BACKWARD);
 }
 
 AudioStreamSample::AudioStreamSample() {

+ 2 - 1
scene/resources/audio_stream_sample.h

@@ -94,7 +94,8 @@ public:
 	enum LoopMode {
 		LOOP_DISABLED,
 		LOOP_FORWARD,
-		LOOP_PING_PONG
+		LOOP_PING_PONG,
+		LOOP_BACKWARD
 	};
 
 private: