Просмотр исходного кода

improved input and output audio player functionality, made menu and new nodes go to mouse position

Jonathan Higgins 7 месяцев назад
Родитель
Сommit
f4c3ba7205
6 измененных файлов с 181 добавлено и 81 удалено
  1. 3 0
      Global.gd
  2. 2 2
      export_presets.cfg
  3. 76 10
      scenes/Nodes/audioplayer.gd
  4. 21 13
      scenes/Nodes/audioplayer.tscn
  5. 69 54
      scenes/main/control.gd
  6. 10 2
      scenes/main/control.tscn

+ 3 - 0
Global.gd

@@ -3,3 +3,6 @@ extends Node
 var infile = "no_file"
 var infile = "no_file"
 var infile_stereo = false
 var infile_stereo = false
 var outfile = "no_file"
 var outfile = "no_file"
+var trim_infile = false
+var infile_start = 0
+var infile_stop = 1

+ 2 - 2
export_presets.cfg

@@ -9,7 +9,7 @@ custom_features=""
 export_filter="all_resources"
 export_filter="all_resources"
 include_filter="*.thd, export_presets.cfg"
 include_filter="*.thd, export_presets.cfg"
 exclude_filter=""
 exclude_filter=""
-export_path="../SoundThread_Exports/SoundThread.exe"
+export_path="../SoundThread_Exports/v0.1.1-alpha/SoundThread.exe"
 patches=PackedStringArray()
 patches=PackedStringArray()
 encryption_include_filters=""
 encryption_include_filters=""
 encryption_exclude_filters=""
 encryption_exclude_filters=""
@@ -76,7 +76,7 @@ custom_features=""
 export_filter="all_resources"
 export_filter="all_resources"
 include_filter="*.thd, export_presets.cfg"
 include_filter="*.thd, export_presets.cfg"
 exclude_filter=""
 exclude_filter=""
-export_path="../SoundThread_Exports/SoundThread-hidpicheck.zip"
+export_path="../SoundThread_Exports/v0.1.1-alpha/SoundThread-v0.1.1-alpha_macos.zip"
 patches=PackedStringArray()
 patches=PackedStringArray()
 encryption_include_filters=""
 encryption_include_filters=""
 encryption_exclude_filters=""
 encryption_exclude_filters=""

+ 76 - 10
scenes/Nodes/audioplayer.gd

@@ -5,6 +5,8 @@ extends Control
 @onready var waveform_display = $WaveformPreview
 @onready var waveform_display = $WaveformPreview
 var outfile_path = "not_loaded"
 var outfile_path = "not_loaded"
 #signal recycle_outfile_trigger
 #signal recycle_outfile_trigger
+var rect_focus = false
+var mouse_pos_x
 
 
 #Used for waveform preview
 #Used for waveform preview
 var voice_preview_generator : Node = null
 var voice_preview_generator : Node = null
@@ -17,6 +19,7 @@ func _ready():
 	file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
 	file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
 	file_dialog.filters = ["*.wav ; WAV audio files"]
 	file_dialog.filters = ["*.wav ; WAV audio files"]
 	file_dialog.connect("file_selected", Callable(self, "_on_file_selected"))
 	file_dialog.connect("file_selected", Callable(self, "_on_file_selected"))
+	audio_player.connect("finished", Callable(self, "_on_audio_finished"))
 	
 	
 	if get_meta("loadenable") == true:
 	if get_meta("loadenable") == true:
 		$RecycleButton.hide()
 		$RecycleButton.hide()
@@ -60,6 +63,8 @@ func _on_file_selected(path: String):
 	voice_preview_generator.generate_preview(audio_player.stream)
 	voice_preview_generator.generate_preview(audio_player.stream)
 	Global.infile = path
 	Global.infile = path
 	print("Infile set: " + Global.infile)
 	print("Infile set: " + Global.infile)
+	$LoopRegion.size.x = 0
+	$Playhead.position.x = 0
 	
 	
 func play_outfile(path: String):
 func play_outfile(path: String):
 	outfile_path = path
 	outfile_path = path
@@ -76,18 +81,46 @@ func recycle_outfile(path: String):
 	voice_preview_generator.generate_preview(audio_player.stream)
 	voice_preview_generator.generate_preview(audio_player.stream)
 	Global.infile = path
 	Global.infile = path
 	print("Infile set: " + Global.infile)
 	print("Infile set: " + Global.infile)
+	$LoopRegion.size.x = 0
+	$Playhead.position.x = 0
 
 
 
 
 func _on_play_button_button_down() -> void:
 func _on_play_button_button_down() -> void:
-	if audio_player.stream:
-		audio_player.play()
-		$Playhead.position.x = 0
+	var playhead_position
+	#check if trim markers are set and set playhead position to correct location
+	if $LoopRegion.size.x == 0:
+		playhead_position = 0
+	else:
+		playhead_position = $LoopRegion.position.x
+	
+	$Playhead.position.x = playhead_position
 	
 	
-func _on_stop_button_button_down() -> void:
-	if audio_player.playing:
-		audio_player.stop()
-		$Playhead.position.x = 0
-		
+	#check if audio is playing, to decide if this is a play or stop button
+	if audio_player.stream:
+		if audio_player.playing:
+			audio_player.stop()
+			$Timer.stop()
+			$PlayButton.text = "Play"
+		else:
+			$PlayButton.text = "Stop"
+			if $LoopRegion.size.x == 0: #loop position is not set, play from start of file
+				audio_player.play()
+			else:
+				var length = $AudioStreamPlayer.stream.get_length()
+				var pixel_to_time = length / 399
+				audio_player.play(pixel_to_time * $LoopRegion.position.x)
+				if $LoopRegion.position.x + $LoopRegion.size.x < 399:
+					$Timer.start(pixel_to_time * $LoopRegion.size.x)
+				
+
+#timer for ending playback at end of loop
+func _on_timer_timeout() -> void:
+	_on_play_button_button_down() #"press" stop button
+
+func _on_audio_finished():
+	$PlayButton.text = "Play"
+
+
 # This function will be called when the waveform texture is ready
 # This function will be called when the waveform texture is ready
 func _on_texture_ready(image_texture: ImageTexture):
 func _on_texture_ready(image_texture: ImageTexture):
 	# Set the generated texture to the TextureRect (waveform display node)
 	# Set the generated texture to the TextureRect (waveform display node)
@@ -102,10 +135,43 @@ func _process(delta: float) -> void:
 		$Playhead.position.x += speed * delta
 		$Playhead.position.x += speed * delta
 		if $Playhead.position.x >= 399:
 		if $Playhead.position.x >= 399:
 			$Playhead.position.x = 0
 			$Playhead.position.x = 0
-		
-		
+	
+	if audio_player.playing == false and rect_focus == true:
+		if get_local_mouse_position().x > mouse_pos_x:
+			$LoopRegion.size.x = clamp(get_local_mouse_position().x - mouse_pos_x, 0, $Panel.size.x - (mouse_pos_x - $Panel.position.x))
+		else:
+			$LoopRegion.size.x = clamp(mouse_pos_x - get_local_mouse_position().x, 0, (mouse_pos_x - $Panel.position.x))
+			$LoopRegion.position.x = clamp(get_local_mouse_position().x, $Panel.position.x, $Panel.position.x + $Panel.size.x)
 
 
 #func _on_recycle_button_button_down() -> void:
 #func _on_recycle_button_button_down() -> void:
 	#if outfile_path != "not_loaded":
 	#if outfile_path != "not_loaded":
 		#recycle_outfile_trigger.emit(outfile_path)
 		#recycle_outfile_trigger.emit(outfile_path)
 	
 	
+
+
+
+	
+
+func _on_button_button_down() -> void:
+	print("focus entered")
+	mouse_pos_x = get_local_mouse_position().x
+	$LoopRegion.position.x = mouse_pos_x
+	rect_focus = true
+
+
+func _on_button_button_up() -> void:
+	rect_focus = false
+	if get_meta("loadenable") == true:
+		print("got meta")
+		if $LoopRegion.size.x > 0:
+			Global.trim_infile = true
+			var length = $AudioStreamPlayer.stream.get_length()
+			var pixel_to_time = length / 399
+			Global.infile_start = pixel_to_time * $LoopRegion.position.x
+			Global.infile_stop = Global.infile_start + (pixel_to_time * $LoopRegion.size.x)
+			print(Global.trim_infile)
+			print(Global.infile_start)
+			print(Global.infile_stop)
+		else:
+			Global.trim_infile = false
+			print(Global.trim_infile)

+ 21 - 13
scenes/Nodes/audioplayer.tscn

@@ -36,14 +36,14 @@ use_native_dialog = true
 [node name="LoadButton" type="Button" parent="."]
 [node name="LoadButton" type="Button" parent="."]
 layout_mode = 0
 layout_mode = 0
 offset_top = 104.0
 offset_top = 104.0
-offset_right = 128.0
+offset_right = 196.0
 offset_bottom = 147.0
 offset_bottom = 147.0
 text = "Load File"
 text = "Load File"
 
 
 [node name="RecycleButton" type="Button" parent="." groups=["outputnode"]]
 [node name="RecycleButton" type="Button" parent="." groups=["outputnode"]]
 layout_mode = 0
 layout_mode = 0
 offset_top = 104.0
 offset_top = 104.0
-offset_right = 128.0
+offset_right = 196.0
 offset_bottom = 147.0
 offset_bottom = 147.0
 tooltip_text = "Copies your output file back to your input for further processing."
 tooltip_text = "Copies your output file back to your input for further processing."
 text = "Recycle File"
 text = "Recycle File"
@@ -51,19 +51,11 @@ metadata/outputfunction = "recycle"
 
 
 [node name="PlayButton" type="Button" parent="."]
 [node name="PlayButton" type="Button" parent="."]
 layout_mode = 0
 layout_mode = 0
-offset_left = 136.0
-offset_top = 104.0
-offset_right = 264.0
-offset_bottom = 147.0
-text = "Play"
-
-[node name="StopButton" type="Button" parent="."]
-layout_mode = 0
-offset_left = 272.0
+offset_left = 204.0
 offset_top = 104.0
 offset_top = 104.0
 offset_right = 400.0
 offset_right = 400.0
 offset_bottom = 147.0
 offset_bottom = 147.0
-text = "Stop"
+text = "Play"
 
 
 [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
 [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
 
 
@@ -105,8 +97,24 @@ points = PackedVector2Array(0, 0, 0, 96)
 width = 2.0
 width = 2.0
 default_color = Color(1, 1, 1, 0.541176)
 default_color = Color(1, 1, 1, 0.541176)
 
 
+[node name="LoopRegion" type="ColorRect" parent="."]
+layout_mode = 0
+offset_bottom = 96.0
+focus_mode = 1
+color = Color(1, 1, 1, 0.0941176)
+
+[node name="Button" type="Button" parent="."]
+layout_mode = 0
+offset_right = 400.0
+offset_bottom = 96.0
+flat = true
+
+[node name="Timer" type="Timer" parent="."]
+
 [connection signal="button_down" from="LoadButton" to="." method="_on_load_button_button_down"]
 [connection signal="button_down" from="LoadButton" to="." method="_on_load_button_button_down"]
 [connection signal="button_down" from="RecycleButton" to="." method="_on_recycle_button_button_down"]
 [connection signal="button_down" from="RecycleButton" to="." method="_on_recycle_button_button_down"]
 [connection signal="button_down" from="PlayButton" to="." method="_on_play_button_button_down"]
 [connection signal="button_down" from="PlayButton" to="." method="_on_play_button_button_down"]
-[connection signal="button_down" from="StopButton" to="." method="_on_stop_button_button_down"]
 [connection signal="button_down" from="WavError/CloseButton" to="." method="_on_close_button_button_down"]
 [connection signal="button_down" from="WavError/CloseButton" to="." method="_on_close_button_button_down"]
+[connection signal="button_down" from="Button" to="." method="_on_button_button_down"]
+[connection signal="button_up" from="Button" to="." method="_on_button_button_up"]
+[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]

+ 69 - 54
scenes/main/control.gd

@@ -70,8 +70,6 @@ func _ready() -> void:
 			window.content_scale_factor = 2
 			window.content_scale_factor = 2
 	
 	
 	
 	
-	
-	
 func new_patch():
 func new_patch():
 	#clear old patch
 	#clear old patch
 	graph_edit.clear_connections()
 	graph_edit.clear_connections()
@@ -187,7 +185,14 @@ func showmenu():
 	#stores mouse position at time of right click to later place a node in that location
 	#stores mouse position at time of right click to later place a node in that location
 	if Input.is_action_just_pressed("open_menu"):
 	if Input.is_action_just_pressed("open_menu"):
 		if mainmenu_visible == false:
 		if mainmenu_visible == false:
-			effect_position = get_viewport().get_mouse_position()
+			effect_position = graph_edit.get_local_mouse_position()
+			#$mainmenu.position.x = min(effect_position.x, get_viewport().get_visible_rect().size.x - $mainmenu.size.x)
+			#$mainmenu.position.y = min(effect_position.y, get_viewport().get_visible_rect().size.y - $mainmenu.size.y)
+			$mainmenu.position.x = clamp(get_viewport().get_mouse_position().x, $mainmenu/select_effect.size.x / 2, get_viewport().get_visible_rect().size.x - ($mainmenu/select_effect.size.x / 2))
+			$mainmenu.position.y = clamp(get_viewport().get_mouse_position().y, ($mainmenu/select_effect.size.y / 2) + $ColorRect.size.y, get_viewport().get_visible_rect().size.y - ($mainmenu/select_effect.size.y / 2))
+			print($GraphEdit.scroll_offset)
+			#print(DisplayServer.window_get_size()) #actual window size
+			#print(get_viewport().get_visible_rect().size) # window size asjusted for retina scaling
 			$mainmenu.show()
 			$mainmenu.show()
 			mainmenu_visible = true
 			mainmenu_visible = true
 		else:
 		else:
@@ -204,7 +209,7 @@ func _on_button_pressed(button: Button):
 	#and position it close to the origin right click to open the menu
 	#and position it close to the origin right click to open the menu
 	var effect: GraphNode = Nodes.get_node(NodePath(button.name)).duplicate()
 	var effect: GraphNode = Nodes.get_node(NodePath(button.name)).duplicate()
 	get_node("GraphEdit").add_child(effect, true)
 	get_node("GraphEdit").add_child(effect, true)
-	effect.position_offset = effect_position
+	effect.set_position_offset((effect_position + graph_edit.scroll_offset) / graph_edit.zoom) #set node to current mouse position in graph edit
 	_register_inputs_in_node(effect) #link sliders for changes tracking
 	_register_inputs_in_node(effect) #link sliders for changes tracking
 	_register_node_movement() #link nodes for tracking position changes for changes tracking
 	_register_node_movement() #link nodes for tracking position changes for changes tracking
 
 
@@ -583,7 +588,17 @@ func run_thread_with_branches():
 	var process_count = 0
 	var process_count = 0
 
 
 	# Start with the original input file
 	# Start with the original input file
-	var current_infile = Global.infile
+	var starting_infile = Global.infile
+	
+	#If trim is enabled trim input audio
+	if Global.trim_infile == true:
+		run_command(cdpprogs_location + "/sfedit cut 1" + " \"%s\"" % starting_infile + " \"%s_trimmed.wav\"" % Global.outfile + " " + str(Global.infile_start) + " " + str(Global.infile_stop))
+		starting_infile = Global.outfile + "_trimmed.wav"
+		# Mark trimmed file for cleanup if needed
+		if delete_intermediate_outputs:
+			intermediate_files.append(Global.outfile + "_trimmed.wav")
+			
+	var current_infile = starting_infile
 
 
 	# Iterate over the processing nodes in topological order
 	# Iterate over the processing nodes in topological order
 	for node_name in sorted:
 	for node_name in sorted:
@@ -615,8 +630,8 @@ func run_thread_with_branches():
 			current_infile = input_files[0]
 			current_infile = input_files[0]
 
 
 		## If no input, use the original input file
 		## If no input, use the original input file
-		#else:
-			#current_infile = Global.infile
+		else:
+			current_infile = starting_infile
 
 
 		# Build the command for the current node's audio processing
 		# Build the command for the current node's audio processing
 		var slider_data = _get_slider_values_ordered(node)
 		var slider_data = _get_slider_values_ordered(node)
@@ -1084,53 +1099,53 @@ func run_command(command: String) -> Array:
 	
 	
 	return output
 	return output
 
 
-func run_batch_file():
-	var is_windows = OS.get_name() == "Windows"
-	var script_ext = ".bat" if is_windows else ".sh"
-	var script_name = "ordered_script" + script_ext
-	var script_path = ProjectSettings.globalize_path("user://%s" % script_name)
-
-	var output: Array = []
-	var error: Array = []
-
-	var exit_code := 0
-	if is_windows:
-		exit_code = OS.execute("cmd.exe", ["/c", script_path], output, true, true)
-	else:
-		exit_code = OS.execute("sh", [script_path], output, true, true)
-
-	var output_str := ""
-	for item in output:
-		output_str += item + "\n"
-
-	var error_str := ""
-	for item in error:
-		error_str += item + "\n"
-
-	if exit_code == 0:
-		if output_str.contains("ERROR:"): #checks if CDP reported an error but passed exit code 0 anyway
-			console_output.append_text("[color=red][b]Processes failed[/b][/color]\n\n")
-			console_output.append_text("[b]Error:[/b]\n")
-			console_output.scroll_to_line(console_output.get_line_count() - 1)
-			console_output.append_text(output_str + "\n")
-		else:
-			console_output.append_text("[color=green]Processes ran successfully[/color]\n\n")
-			console_output.append_text("[b]Output:[/b]\n")
-			console_output.scroll_to_line(console_output.get_line_count() - 1)
-			console_output.append_text(output_str + "\n")
-			
-			if final_output_dir.ends_with(".wav"):
-				output_audio_player.play_outfile(final_output_dir)
-				outfile = final_output_dir
-			
-			var interface_settings = ConfigHandler.load_interface_settings() #checks if close console is enabled and closes console on a success
-			if interface_settings.auto_close_console:
-				$Console.hide()
-	else:
-		console_output.append_text("[color=red][b]Processes failed with exit code: %d[/b][/color]\n\n" % exit_code)
-		console_output.append_text("[b]Error:[/b]\n")
-		console_output.scroll_to_line(console_output.get_line_count() - 1)
-		console_output.append_text(error_str + "\n")
+#func run_batch_file():
+	#var is_windows = OS.get_name() == "Windows"
+	#var script_ext = ".bat" if is_windows else ".sh"
+	#var script_name = "ordered_script" + script_ext
+	#var script_path = ProjectSettings.globalize_path("user://%s" % script_name)
+#
+	#var output: Array = []
+	#var error: Array = []
+#
+	#var exit_code := 0
+	#if is_windows:
+		#exit_code = OS.execute("cmd.exe", ["/c", script_path], output, true, true)
+	#else:
+		#exit_code = OS.execute("sh", [script_path], output, true, true)
+#
+	#var output_str := ""
+	#for item in output:
+		#output_str += item + "\n"
+#
+	#var error_str := ""
+	#for item in error:
+		#error_str += item + "\n"
+#
+	#if exit_code == 0:
+		#if output_str.contains("ERROR:"): #checks if CDP reported an error but passed exit code 0 anyway
+			#console_output.append_text("[color=red][b]Processes failed[/b][/color]\n\n")
+			#console_output.append_text("[b]Error:[/b]\n")
+			#console_output.scroll_to_line(console_output.get_line_count() - 1)
+			#console_output.append_text(output_str + "\n")
+		#else:
+			#console_output.append_text("[color=green]Processes ran successfully[/color]\n\n")
+			#console_output.append_text("[b]Output:[/b]\n")
+			#console_output.scroll_to_line(console_output.get_line_count() - 1)
+			#console_output.append_text(output_str + "\n")
+			#
+			#if final_output_dir.ends_with(".wav"):
+				#output_audio_player.play_outfile(final_output_dir)
+				#outfile = final_output_dir
+			#
+			#var interface_settings = ConfigHandler.load_interface_settings() #checks if close console is enabled and closes console on a success
+			#if interface_settings.auto_close_console:
+				#$Console.hide()
+	#else:
+		#console_output.append_text("[color=red][b]Processes failed with exit code: %d[/b][/color]\n\n" % exit_code)
+		#console_output.append_text("[b]Error:[/b]\n")
+		#console_output.scroll_to_line(console_output.get_line_count() - 1)
+		#console_output.append_text(error_str + "\n")
 	
 	
 func path_exists_through_all_nodes() -> bool:
 func path_exists_through_all_nodes() -> bool:
 	var all_nodes = {}
 	var all_nodes = {}

+ 10 - 2
scenes/main/control.tscn

@@ -31,8 +31,16 @@ access = 2
 use_native_dialog = true
 use_native_dialog = true
 
 
 [node name="mainmenu" parent="." instance=ExtResource("3_dtf4o")]
 [node name="mainmenu" parent="." instance=ExtResource("3_dtf4o")]
-layout_mode = 1
-offset_top = 35.0
+layout_mode = 0
+anchors_preset = 0
+anchor_right = 0.0
+anchor_bottom = 0.0
+offset_left = 600.0
+offset_top = 456.0
+offset_right = 600.0
+offset_bottom = 456.0
+grow_horizontal = 1
+grow_vertical = 1
 
 
 [node name="NoLocationPopup" type="Window" parent="." groups=["popup_windows"]]
 [node name="NoLocationPopup" type="Window" parent="." groups=["popup_windows"]]
 auto_translate_mode = 1
 auto_translate_mode = 1