]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Modules/Voice/subsystem_voice.gd
Squashed commit of the following:
[wolf-seeking-sheep.git] / addons / dialogic / Modules / Voice / subsystem_voice.gd
1 extends DialogicSubsystem
2 ## Subsystem that manages setting voice lines for text events.
3 ##
4 ## It's recommended to use the [class DialogicVoiceEvent] to set the voice lines
5 ## for text events and not start playing them directly.
6
7
8 ## Emitted whenever a new voice line starts playing.
9 ## The [param info] contains the following keys and values:
10 ## [br]
11 ## Key      |   Value Type  | Value [br]
12 ## -------- | ------------- | ----- [br]
13 ## `file`   | [type String] | The path to file played. [br]
14 signal voiceline_started(info: Dictionary)
15
16
17 ## Emitted whenever a voice line finished playing.
18 ## The [param info] contains the following keys and values:
19 ## [br]
20 ## Key              |   Value Type  | Value [br]
21 ## ---------------- | ------------- | ----- [br]
22 ## `file`           | [type String] | The path to file played. [br]
23 ## `remaining_time` | [type float]  | The remaining time of the voiceline. [br]
24 signal voiceline_finished(info: Dictionary)
25
26
27 ## Emitted whenever a voice line gets interrupted and does not finish playing.
28 ## The [param info] contains the following keys and values:
29 ## [br]
30 ## Key              |   Value Type  | Value [br]
31 ## ---------------- | ------------- | ----- [br]
32 ## `file`           | [type String] | The path to file played. [br]
33 ## `remaining_time` | [type float]  | The remaining time of the voiceline. [br]
34 signal voiceline_stopped(info: Dictionary)
35
36
37 ## The current audio file being played.
38 var current_audio_file: String
39
40 ## The audio player for the voiceline.
41 var voice_player := AudioStreamPlayer.new()
42
43 #region STATE
44 ####################################################################################################
45
46 ## Stops the current voice from playing.
47 func pause() -> void:
48         voice_player.stream_paused = true
49
50
51 ## Resumes a paused voice.
52 func resume() -> void:
53         voice_player.stream_paused = false
54
55 #endregion
56
57
58 #region MAIN METHODS
59 ####################################################################################################
60
61 func _ready() -> void:
62         add_child(voice_player)
63         voice_player.finished.connect(_on_voice_finished)
64
65
66 ## Whether the current event is a text event and has a voice
67 ## event before it.
68 func is_voiced(index: int) -> bool:
69         if index > 0 and dialogic.current_timeline_events[index] is DialogicTextEvent:
70                 if dialogic.current_timeline_events[index-1] is DialogicVoiceEvent:
71                         return true
72
73         return false
74
75
76 ## Plays the voice line. This will be invoked by Dialogic.
77 ## Requires [method set_file] to be called before or nothing plays.
78 func play_voice() -> void:
79         voice_player.play()
80         voiceline_started.emit({'file': current_audio_file})
81
82
83 ## Set a voice file [param path] to be played, then invoke [method play_voice].
84 ##
85 ## This method does not check if [param path] is a valid file.
86 func set_file(path: String) -> void:
87         if current_audio_file == path:
88                 return
89
90         current_audio_file = path
91         var audio: AudioStream = load(path)
92         voice_player.stream = audio
93
94
95 ## Set the volume to a [param value] in decibels.
96 func set_volume(value: float) -> void:
97         voice_player.volume_db = value
98
99
100 ## Set the voice player's bus to a [param bus_name].
101 func set_bus(bus_name: String) -> void:
102         voice_player.bus = bus_name
103
104
105 ## Stops the current voice line from playing.
106 func stop_audio() -> void:
107         if voice_player.playing:
108                 voiceline_stopped.emit({'file':current_audio_file, 'remaining_time':get_remaining_time()})
109
110         voice_player.stop()
111
112
113 ## Called when the voice line finishes playing.
114 ## Connected to [signal finished] on [member voice_player]
115 func _on_voice_finished() -> void:
116         voiceline_finished.emit({'file':current_audio_file, 'remaining_time':get_remaining_time()})
117
118
119 ## Returns the remaining time of the current voice line in seconds.
120 ##
121 ## If there is no voice line playing, returns `0`.
122 func get_remaining_time() -> float:
123         if not voice_player or not voice_player.playing:
124                 return 0.0
125
126         var stream_length := voice_player.stream.get_length()
127         var playback_position := voice_player.get_playback_position()
128         var remaining_seconds := stream_length - playback_position
129
130         return remaining_seconds
131
132
133 ## Whether there is still positive time remaining for the current voiceline.
134 func is_running() -> bool:
135         return get_remaining_time() > 0.0
136
137 #endregion