| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- extends Control
- @onready var audio_player = $AudioStreamPlayer
- @onready var file_dialog = $FileDialog
- @onready var waveform_display = $WaveformPreview
- var outfile_path = "not_loaded"
- var rect_focus = false
- var mouse_pos_x
- #Used for waveform preview
- var voice_preview_generator : Node = null
- var stream : AudioStreamWAV = null
- var autoplay
- signal setnodetitle
- func _ready():
- var interface_settings = ConfigHandler.load_interface_settings()
- #Setup file dialogue to access system files and only accept wav files
- #get_window().files_dropped.connect(_on_files_dropped)
- file_dialog.access = FileDialog.ACCESS_FILESYSTEM
- file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
- file_dialog.filters = ["*.wav ; WAV audio files"]
- var input_folder = interface_settings.last_used_input_folder
- if input_folder != "no_file" and DirAccess.open(input_folder) != null:
- file_dialog.current_dir = input_folder
-
- file_dialog.connect("file_selected", Callable(self, "_on_file_selected"))
- audio_player.connect("finished", Callable(self, "_on_audio_finished"))
-
- if get_meta("loadenable") == false:
- #$PlayButton.size.x = 192
- #$PlayButton.position.x = 208
- $PlayButton.size.x = $Panel.size.x
- $PlayButton.position.x = $LoadButton.position.x
- $LoadButton.hide()
- $RecycleButton.hide()
- #else:
- #$Autoplay.hide()
-
- $WavError.hide()
-
- # Load the voice preview generator for waveform visualization
- voice_preview_generator = preload("res://addons/audio_preview/voice_preview_generator.tscn").instantiate()
- add_child(voice_preview_generator)
- voice_preview_generator.texture_ready.connect(_on_texture_ready)
-
- #setup meta to say the player is empty and no trim points have been set
- set_meta("trimfile", false)
- #func _on_files_dropped(files):
- #if files[0].get_extension() == "wav" or files[0].get_extension() == "WAV":
- #audio_player.stream = AudioStreamWAV.load_from_file(files[0])
- #if audio_player.stream.stereo == true: #checks if stream is stereo, not sure what this will do with a surround sound file
- #audio_player.stream = null #empties audio stream so stereo audio cant be played back
- #$WavError.show()
- #else:
- #voice_preview_generator.generate_preview(audio_player.stream) #this generates the waveform graphic
- #Global.infile = files[0] #this sets the global infile variable to the audio file path
- #print(Global.infile)
- #else:
- #$WavError.show()
- func _on_close_button_button_down() -> void:
- $WavError.hide()
- func _on_load_button_button_down() -> void:
- var interface_settings = ConfigHandler.load_interface_settings()
- var input_folder = interface_settings.last_used_input_folder
- if input_folder != "no_file" and DirAccess.open(input_folder) != null:
- file_dialog.current_dir = input_folder
- file_dialog.popup_centered()
- func _on_file_selected(path: String):
- ConfigHandler.save_interface_settings("last_used_input_folder", path.get_base_dir())
- audio_player.stream = AudioStreamWAV.load_from_file(path, {
- "compress/mode" = 0,
- "edit/loop_mode" = 1})
- voice_preview_generator.generate_preview(audio_player.stream)
- if audio_player.stream != null:
- var length = convert_length(audio_player.stream.get_length())
- $EndLabel.text = length
- setnodetitle.emit(path.get_file())
- else:
- $EndLabel.text = "00:00.00"
- set_meta("inputfile", path)
- set_meta("sample_rate", audio_player.stream.get_mix_rate())
- set_meta("stereo", audio_player.stream.is_stereo())
- set_meta("upsampled", false)
- reset_playback()
-
- #output signal that the input has loaded and it is safe to continue with running thread
- #Used for preview nodes in run_thread to avoid deleting the input file before it is done loading
-
-
- func reset_playback():
- $LoopRegion.size.x = 0
- $Playhead.position.x = 0
- $PlayButton.text = "Play"
- $Timer.stop()
- if get_meta("loadenable") == true:
- set_meta("timefile", false)
-
-
- func play_outfile(path: String):
- outfile_path = path
- audio_player.stream = AudioStreamWAV.load_from_file(path, {
- "compress/mode" = 0,
- "edit/loop_mode" = 1})
- print(audio_player.stream)
- if audio_player.stream == null:
- voice_preview_generator._reset_to_blank()
- reset_playback()
- return
- await voice_preview_generator.generate_preview(audio_player.stream)
- if audio_player.stream != null:
- var length = convert_length(audio_player.stream.get_length())
- $EndLabel.text = length
- else:
- $EndLabel.text = "00:00.00"
- reset_playback()
- if autoplay == true:
- _on_play_button_button_down()
-
- func recycle_outfile():
- print("recycle pressed")
- print(Global.cdpoutput)
- if Global.cdpoutput != "no_file":
- _on_file_selected(Global.cdpoutput)
- func _on_play_button_button_down() -> void:
- 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
-
- #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
- func _on_texture_ready(image_texture: ImageTexture):
- # Set the generated texture to the TextureRect (waveform display node)
- waveform_display.texture = image_texture
-
- # Called every frame. 'delta' is the elapsed time since the previous frame.
- func _process(delta: float) -> void:
- if $AudioStreamPlayer.playing:
- var length = $AudioStreamPlayer.stream.get_length()
- var total_distance = 399.0
- var speed = total_distance / length
- $Playhead.position.x += speed * delta
- if $Playhead.position.x >= 399:
- $Playhead.position.x = 0
-
- if 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:
- #if outfile_path != "not_loaded":
- #recycle_outfile_trigger.emit(outfile_path)
-
-
- func _on_button_button_down() -> void:
- if audio_player.stream:
- if audio_player.playing: #if audio is playing allow user to skip around the sound file
- $Timer.stop()
- var length = $AudioStreamPlayer.stream.get_length()
- var pixel_to_time = length / 399
- $Playhead.position.x = get_local_mouse_position().x
- if $LoopRegion.size.x == 0 or get_local_mouse_position().x > $LoopRegion.position.x + $LoopRegion.size.x: #loop position is not set or click is after loop position, play to end of file
- audio_player.seek(pixel_to_time * get_local_mouse_position().x)
- else: #if click position is before the loop position play from there and stop at the end of the loop position
- audio_player.seek(pixel_to_time * get_local_mouse_position().x)
- if $LoopRegion.position.x + $LoopRegion.size.x < 399:
- $Timer.start(pixel_to_time * ($LoopRegion.position.x + $LoopRegion.size.x - get_local_mouse_position().x))
- else:
- 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 audio_player.stream != null:
- if get_meta("loadenable") == true:
- if $LoopRegion.size.x > 0:
- set_meta("trimfile", true)
- var length = $AudioStreamPlayer.stream.get_length()
- var pixel_to_time = length / 399
- var start = pixel_to_time * $LoopRegion.position.x
- var starttime = convert_length(start)
- $StartLabel.text = starttime
- var end = start + (pixel_to_time * $LoopRegion.size.x)
- var endtime = convert_length(end)
- $EndLabel.text = endtime
- set_meta("trimpoints", [start, end])
- else:
- set_meta("trimfile", false)
- $StartLabel.text = "00:00.00"
- var end = convert_length($AudioStreamPlayer.stream.get_length())
- $EndLabel.text = end
-
- func convert_length(reportedseconds: float) -> String:
- var converted_length = reportedseconds
- var hours
- var minutes
- var seconds = int(reportedseconds) % 60
- seconds = seconds + (reportedseconds - int(reportedseconds))
-
- if reportedseconds > 3600:
- hours = reportedseconds / 3600
- minutes = (int(reportedseconds) % 3600) / 60
- converted_length = "%.0f:%02.0f:%05.2f" % [hours, minutes, seconds, 0.01]
- else:
- minutes = int((int(reportedseconds) % 3600) / 60)
- converted_length = "%02.0f:%05.2f" % [minutes, seconds]
-
- return converted_length
|