Added Mixing Desk (for better music and sound support

This commit is contained in:
Paul Black 2022-03-20 20:35:37 -06:00
parent b636a261bb
commit 98d425dad1
59 changed files with 2298 additions and 0 deletions

BIN
addons/mixing-desk/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-6073e7f53ad5eec561c4bc50d715b0dd.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/icon.png"
dest_files=[ "res://.import/icon.png-6073e7f53ad5eec561c4bc50d715b0dd.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View file

@ -0,0 +1,69 @@
tool
extends EditorPlugin
func _enter_tree():
#music nodes
add_custom_type("MixingDeskMusic", "Node", preload("music/mixing_desk_music.gd"), preload("music/mdm_icon.png"))
add_custom_type("Song", "Node", preload("music/song.gd"), preload("music/icons/song_icon.png"))
add_custom_type("TransitionSong", "Node", preload("music/transition_song.gd"), preload("music/icons/tran_song_icon.png"))
add_custom_type("CoreContainer", "Node", preload("music/containers/core_cont.gd"), preload("music/icons/core_cont_icon.png"))
add_custom_type("RandomContainer", "Node", preload("music/containers/ran_cont.gd"), preload("music/icons/ran_cont_icon.png"))
add_custom_type("SeqContainer", "Node", preload("music/containers/seq_cont.gd"), preload("music/icons/seq_cont_icon.png"))
add_custom_type("ConcatContainer", "Node", preload("music/containers/concat_cont.gd"), preload("music/icons/concat_cont_icon.png"))
add_custom_type("RolloverContainer", "Node", preload("music/containers/rollover_cont.gd"), preload("music/icons/rollover_cont_icon.png"))
add_custom_type("AutoFadeContainer", "Node", preload("music/containers/autofade_cont.gd"), preload("music/icons/autofade_cont_icon.png"))
add_custom_type("AutoLayerContainer", "Node", preload("music/containers/autolayer_cont.gd"), preload("music/icons/autolayer_cont_icon.png"))
#sound nodes - nonspatial
add_custom_type("MultiSoundContainer", "Node", preload("sound/nonspatial/multi_sound.gd"), preload("sound/snd_icon.png"))
add_custom_type("PolySoundContainer", "Node", preload("sound/nonspatial/polysound.gd"), preload("sound/snd_icon.png"))
add_custom_type("RanSoundContainer", "Node", preload("sound/nonspatial/ran_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ScatterSoundContainer", "Node", preload("sound/nonspatial/scatter_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ConcatSoundContainer", "Node", preload("sound/nonspatial/concat_cont.gd"), preload("sound/snd_icon.png"))
#sound nodes - 2d
add_custom_type("MultiSoundContainer2D", "Node2D", preload("sound/2d/multi_sound.gd"), preload("sound/snd_icon.png"))
add_custom_type("PolySoundContainer2D", "Node2D", preload("sound/2d/polysound.gd"), preload("sound/snd_icon.png"))
add_custom_type("RanSoundContainer2D", "Node2D", preload("sound/2d/ran_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ScatterSoundContainer2D", "Node2D", preload("sound/2d/scatter_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ConcatSoundContainer2D", "Node2D", preload("sound/2d/concat_cont.gd"), preload("sound/snd_icon.png"))
#sound nodes - 3d
add_custom_type("MultiSoundContainer3D", "Spatial", preload("sound/3d/multi_sound.gd"), preload("sound/snd_icon.png"))
add_custom_type("PolySoundContainer3D", "Spatial", preload("sound/3d/polysound.gd"), preload("sound/snd_icon.png"))
add_custom_type("RanSoundContainer3D", "Spatial", preload("sound/3d/ran_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ScatterSoundContainer3D", "Spatial", preload("sound/3d/scatter_cont.gd"), preload("sound/snd_icon.png"))
add_custom_type("ConcatSoundContainer3D", "Spatial", preload("sound/3d/concat_cont.gd"), preload("sound/snd_icon.png"))
func _exit_tree():
#music nodes
remove_custom_type("MixingDeskMusic")
remove_custom_type("Song")
remove_custom_type("TransitionSong")
remove_custom_type("CoreContainer")
remove_custom_type("RandomContainer")
remove_custom_type("SeqContainer")
remove_custom_type("ConcatContainer")
remove_custom_type("RolloverContainer")
remove_custom_type("AutofadeContainer")
#sound nodes - nonspatial
remove_custom_type("MultiSoundContainer")
remove_custom_type("PolysoundContainer")
remove_custom_type("RanSoundContainer")
remove_custom_type("ScatterSoundContainer")
remove_custom_type("ConcatSoundContainer")
#sound nodes - 2d
remove_custom_type("MultiSoundContainer2D")
remove_custom_type("PolysoundContainer2D")
remove_custom_type("RanSoundContainer2D")
remove_custom_type("ScatterSoundContainer2D")
remove_custom_type("ConcatSoundContainer2D")
#sound nodes - 3d
remove_custom_type("MultiSoundContainer3D")
remove_custom_type("PolysoundContainer3D")
remove_custom_type("RanSoundContainer3D")
remove_custom_type("ScatterSoundContainer3D")
remove_custom_type("ConcatSoundContainer3D")

View file

@ -0,0 +1,82 @@
extends Node
var cont = "autofade"
enum play_type {random, all}
export(play_type) var play_style
export var toggle : bool = false
export(NodePath) var target_node
export(String) var target_property
export(float) var min_range = 0.0
export(float) var max_range = 1.0
export(bool) var invert
export(float, 0.0, 1.0) var track_speed
var param
var target
func _ready():
get_node("../..").connect("beat", self, "_update")
target = get_node(target_node)
init_volume()
func _update(beat):
param = target.get(target_property)
if !toggle:
var vol := _get_range_vol()
for i in get_children():
_fade_to(i, vol)
else:
for i in get_children():
if param:
_fade_to(i, 0)
else:
_fade_to(i, -65)
func init_volume():
param = target.get(target_property)
if !toggle:
var vol := _get_range_vol()
for i in get_children():
i.volume_db = vol
else:
for i in get_children():
if param:
i.volume_db = 0
else:
i.volume_db = -65
func _get_range_vol() -> float:
var vol: float = param
if !invert:
vol -= min_range
else:
vol *= -1
vol += max_range
vol /= abs(max_range - min_range)
vol = (vol*65) - 65
vol = clamp(vol,-65,0)
return vol
func is_equal(a : float,b : float):
return int(a) == int(b)
func _fade_to(target, vol):
var is_match
var cvol = target.volume_db
is_match = is_equal(cvol,vol)
if !is_match:
if cvol > vol:
if track_speed < 1.0:
cvol -= 1.5 / (1.0 - track_speed )
else:
cvol = vol
else:
cvol = lerp(cvol,vol,track_speed)
target.volume_db = cvol
else:
if vol == 0:
if cvol != vol:
target.volume_db = 0
elif cvol != vol:
target.volume_db = vol

View file

@ -0,0 +1,95 @@
extends Node
enum play_mode {additive, single, pad}
export(play_mode) var play_style
export(int) var layer_min
export(int) var layer_max
export(bool) var automate = false
export(NodePath) var target_node
export(String) var target_property
export(float) var min_range = 0.0
export(float) var max_range = 1.0
export(int) var pad = 0
export(bool) var invert
export(float) var track_speed
var target
var num = 0.0
var t_layer
var cont = "autolayer"
func _ready():
get_node("../..").connect("beat", self, "_update")
target = get_node(target_node)
init_layers()
func _update(beat):
_set_layers_values()
_fade_layers()
func init_layers():
_set_layers_values()
for i in range(get_child_count()):
var child = get_child(i)
if i != -1:
if i < layer_min or i > layer_max:
child.volume_db = -65
else:
child.volume_db = 0
func _set_layers_values():
t_layer = layer_max
if automate:
num = target.get(target_property)
if !invert:
num -= min_range
else:
num *= -1
num += max_range
num /= abs(max_range - min_range)
num *= (get_child_count())
t_layer = clamp(floor(num), -1, get_child_count() - 1)
match play_style:
play_mode.additive:
layer_min = -1
layer_max = t_layer
play_mode.single:
layer_min = t_layer
layer_max = t_layer
play_mode.pad:
if pad != 0:
layer_min = t_layer - pad
layer_max = t_layer + pad
func _fade_layers():
for i in range(get_child_count()):
var child = get_child(i)
if i != -1:
if i < layer_min or i > layer_max:
_fade_to(child,-65)
else:
_fade_to(child,0)
func is_equal(a : float,b : float):
return int(a) == int(b)
func _fade_to(target, vol):
var is_match
var cvol = target.volume_db
var sum = vol - cvol
is_match = is_equal(vol,cvol)
if !is_match:
if cvol > vol:
if track_speed < 1.0:
cvol -= 1.5 / (1.0 - track_speed )
else:
cvol = vol
else:
cvol = lerp(cvol,vol,track_speed)
target.volume_db = cvol
else:
if vol == 0:
if cvol != vol:
target.volume_db = 0
elif cvol != vol:
target.volume_db = vol

View file

@ -0,0 +1,3 @@
extends Node
var cont = "concat"

View file

@ -0,0 +1,3 @@
extends Node
var cont = "core"

View file

@ -0,0 +1,4 @@
extends Node
var cont = "ran"
export var random_chance : float = 0.0

View file

@ -0,0 +1,4 @@
extends Node
var cont = "roll"
export var crossover_beat : int = 0

View file

@ -0,0 +1,3 @@
extends Node
var cont = "seq"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/autofade_cont_icon.png-da81f6972570f9a36de2cce2814b7c1c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/autofade_cont_icon.png"
dest_files=[ "res://.import/autofade_cont_icon.png-da81f6972570f9a36de2cce2814b7c1c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/autolayer_cont_icon.png-ddda8d804752c299feb978565aae44a3.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/autolayer_cont_icon.png"
dest_files=[ "res://.import/autolayer_cont_icon.png-ddda8d804752c299feb978565aae44a3.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/concat_cont_icon.png-46ab913d8bb6ad3dfbdace17286a892d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/concat_cont_icon.png"
dest_files=[ "res://.import/concat_cont_icon.png-46ab913d8bb6ad3dfbdace17286a892d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/core_cont_icon.png-16b0b847901e33dd6ee3a8b9e7d3f675.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/core_cont_icon.png"
dest_files=[ "res://.import/core_cont_icon.png-16b0b847901e33dd6ee3a8b9e7d3f675.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/mdm_icon.png-1c8d773edbccb19a201bcd288a3b607d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/mdm_icon.png"
dest_files=[ "res://.import/mdm_icon.png-1c8d773edbccb19a201bcd288a3b607d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/ran_cont_icon.png-a22416379792358117344f94403db0fa.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/ran_cont_icon.png"
dest_files=[ "res://.import/ran_cont_icon.png-a22416379792358117344f94403db0fa.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/rollover_cont_icon.png-5c1a5b59fcd51787526e86442c4f5dde.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/rollover_cont_icon.png"
dest_files=[ "res://.import/rollover_cont_icon.png-5c1a5b59fcd51787526e86442c4f5dde.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/seq_cont_icon.png-eb3d70d7ee41bdcc2247393fe6239efd.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/seq_cont_icon.png"
dest_files=[ "res://.import/seq_cont_icon.png-eb3d70d7ee41bdcc2247393fe6239efd.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/song_icon.png-b30f643a8bc8af94404a9fd2f73a8213.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/song_icon.png"
dest_files=[ "res://.import/song_icon.png-b30f643a8bc8af94404a9fd2f73a8213.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/tran_song_icon.png-e63c474d0791bfed8702e128861f174f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/icons/tran_song_icon.png"
dest_files=[ "res://.import/tran_song_icon.png-e63c474d0791bfed8702e128861f174f.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/mdm_icon.png-472fc57740e9d463b3e07f80b7cd7ff4.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/mdm_icon.png"
dest_files=[ "res://.import/mdm_icon.png-472fc57740e9d463b3e07f80b7cd7ff4.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View file

@ -0,0 +1,501 @@
extends Node
var tempo
var bars
var beats_in_bar
var transition_beats
var can_shuffle = true
enum play_style {play_once, loop_one, shuffle, endless_shuffle, endless_loop}
export(play_style) var play_mode
export(bool) var autoplay = false
export(NodePath) var autoplay_song
onready var songs = get_children()
const default_vol = 0
var ref_track : Object
var playing_tracks = []
var time = 0.0
var beat = 1.0
var last_beat = -1
var suppress_beat = 0.0
var b2bar = 0
var bar = 1.0
var beats_in_sec = 0.0
var can_bar = true
var playing = false
var current_song_num = 0
var current_song
var beat_tran = false
var bar_tran = false
var old_song
var new_song = 0
var repeats = 0
var rollover = null
var rollover_point : int = 0
signal beat
signal bar
signal end
signal shuffle
signal song_changed
func _ready():
for i in songs:
if i.ignore:
songs.remove(songs.find(i))
var shuff = Timer.new()
shuff.name = 'shuffle_timer'
add_child(shuff)
shuff.one_shot = true
var root = Node.new()
root.name = "root"
add_child(root)
shuff.connect("timeout", self, "shuffle_songs")
for song in songs:
for i in song.get_children():
if i.cont == "core":
for o in i.get_children():
var tween = Tween.new()
tween.name = 'Tween'
o.add_child(tween)
if autoplay:
if !playing:
quickplay(str(autoplay_song))
if AudioServer.get_bus_index("Music") == -1:
AudioServer.add_bus(AudioServer.bus_count)
AudioServer.set_bus_name(AudioServer.bus_count - 1, "Music")
#loads a song and gets ready to play
func init_song(track):
if playing:
get_child(current_song_num).playing = false
playing_tracks.clear()
track = _songname_to_int(track)
var song = songs[track]
var root = song._get_core()
current_song_num = track
current_song = songs[track]._get_core()
repeats= 0
for i in root.get_children():
if song.fading_out:
i.get_child(0).stop(i)
song.fading_out = false
i.set_volume_db(default_vol)
if song.muted_tracks.size() > 0:
for i in song.muted_tracks:
mute(current_song_num, i)
tempo = song.tempo
bars = song.bars
beats_in_bar = song.beats_in_bar
beats_in_sec = 60000.0/tempo
transition_beats = (beats_in_sec*song.transition_beats)/1000
for i in song.get_children():
if i.cont == "roll":
rollover = i
rollover_point = ((song.bars * song.beats_in_bar) - (i.crossover_beat - 1))
break
else:
rollover = null
#updates place in song and detects beats/bars
func _process(delta):
if suppress_beat > 0:
suppress_beat -= delta
return
if playing:
time = ref_track.get_playback_position()
beat = int(floor(((time/beats_in_sec) * 1000.0) + 1.0))
if beat != last_beat && (beat - 1) % int(bars * beats_in_bar) + 1 != last_beat:
_beat()
last_beat = beat
#start a song with only one track playing
func start_alone(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
current_song_num = song
current_song = songs[song]._get_core()
for i in current_song.get_children():
i.set_volume_db(-60.0)
current_song.get_child(layer).set_volume_db(default_vol)
play(song)
#play in isolation
func _iplay(track):
var trk = track.duplicate()
get_node("root").add_child(trk)
var twe = Tween.new()
twe.name = "Tween"
trk.add_child(twe)
trk.play()
trk.connect("finished", self, "_track_finished", [trk])
return trk
#kills overlays when finished
func _track_finished(trk):
trk.queue_free()
#fade out overlays
func _stop_overlays():
for i in get_node("root").get_children():
i.get_node("Tween").interpolate_property(i, "volume_db", i.volume_db, -60, transition_beats, Tween.TRANS_LINEAR, Tween.EASE_IN)
i.get_node("Tween").start()
i.get_node("Tween").connect("tween_completed", self, "_overlay_faded", [i])
#delete overlay on fade
func _overlay_faded(object, key, overlay):
overlay.queue_free()
#initialise and play the song immediately
func quickplay(song):
init_song(song)
play(song)
#check if ref is string or int
func _songname_to_int(ref):
if typeof(ref) == TYPE_STRING: return get_node(ref).get_index()
else:
return ref
func _trackname_to_int(song, ref):
if typeof(ref) == TYPE_STRING:
return songs[song]._get_core().get_node(ref).get_index()
else:
return ref
#play a song
func play(song):
song = _songname_to_int(song)
get_child(song).playing = true
time = 0
bar = 1
beat = 1
last_beat = -1
suppress_beat = beats_in_sec / 1000.0 * 0.5
for i in songs[song].get_children():
if i.cont == "core":
var first = true
for o in i.get_children():
var newtrk = _iplay(o)
playing_tracks.append(newtrk)
if first:
ref_track = newtrk
first = false
if !playing:
last_beat = 1
emit_signal("bar", bar)
_beat()
playing = true
_play_overlays(song)
func _play_overlays(song):
for i in songs[song].get_children():
if i.cont == "ran":
randomize()
var rantrk = _get_rantrk(i)
if rand_range(0,1) <= i.random_chance:
_iplay(rantrk)
if i.cont == "seq":
var seqtrk = repeats
if repeats == i.get_child_count():
seqtrk = 0
repeats = 0
_iplay(.get_child(seqtrk))
if i.cont == "concat":
if repeats < 1:
_play_concat(i)
songs[song].concats.append(i)
if i.cont == "autofade":
match i.play_style:
0:
var chance = randi() % i.get_child_count()
i.get_child(chance).play()
1:
for o in i.get_children():
o.play()
if i.cont == "autolayer":
for o in i.get_children():
o.play()
if bar_tran:
bar_tran = false
if beat_tran:
beat_tran = false
#play short random tracks in sequence in 'song'
func _play_concat(concat):
var rantrk = _get_rantrk(concat)
rantrk.play()
rantrk.connect("finished", self, "concat_fin", [concat])
func _concat_fin(concat):
for i in concat.get_children():
if i.is_connected("finished", self, "concat_fin") :
i.disconnect("finished", self, "concat_fin")
_play_concat(concat)
#mute all layers above specified layer, and fade in all below
func fadeout_above_layer(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
if songs[song]._get_core().get_child_count() < 2:
return
for i in range(0, layer + 1):
fade_in(song, i)
for i in range(layer + 1, songs[song]._get_core().get_child_count()):
fade_out(song, i)
#mute all layers below specified layer, and fade in all below
#use mute_below_layer(0) to fade all tracks in
func fadeout_below_layer(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
for i in range(layer, songs[song]._get_core().get_child_count()):
fade_in(song, i)
if layer > 0:
for i in range(0, layer - 1):
fade_out(song, i)
if layer == 1:
fade_out(song, 0)
#mute all layers aside from specified layer
func solo(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
for i in range(layer + 1, songs[song]._get_core().get_child_count()):
fade_out(song, i)
if layer > 0:
for i in range(0, layer - 1):
fade_out(song, i)
if layer == 1:
fade_out(song, 0)
#mute only the specified layer
func mute(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
songs[song]._get_core().get_child(layer).volume_db = -65.0
var target = playing_tracks[layer]
target.set_volume_db(-60.0)
var pos = songs[song].muted_tracks.find(layer)
if pos == null:
songs[song].muted_tracks.append(layer)
#unmute only the specified layer
func unmute(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
songs[song]._get_core().get_child(layer).volume_db = 0
var target = playing_tracks[layer]
target.set_volume_db(default_vol)
var pos = songs[song].muted_tracks.find(layer)
if pos != -1:
songs[song].muted_tracks.remove(pos)
#mutes a track if not muted, or vice versa
func toggle_mute(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
var target = songs[song]._get_core().get_child(layer)
if target.volume_db < 0:
unmute(song, layer)
else:
mute(song, layer)
#slowly bring in the specified layer
func fade_in(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
songs[song]._get_core().get_child(layer).volume_db = default_vol
var target = playing_tracks[layer]
var tween = target.get_node("Tween")
var in_from = target.get_volume_db()
tween.interpolate_property(target, 'volume_db', in_from, default_vol, transition_beats, Tween.TRANS_QUAD, Tween.EASE_OUT)
tween.start()
var pos = songs[song].muted_tracks.find(layer)
if pos != -1:
songs[song].muted_tracks.remove(pos)
#slowly take out the specified layer
func fade_out(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
songs[song]._get_core().get_child(layer).volume_db = -65.0
var target = playing_tracks[layer]
var tween = target.get_node("Tween")
var in_from = target.get_volume_db()
tween.interpolate_property(target, 'volume_db', in_from, -65.0, transition_beats, Tween.TRANS_SINE, Tween.EASE_OUT)
tween.start()
#fades a track in if silent, fades out if not
func toggle_fade(song, layer):
song = _songname_to_int(song)
layer = _trackname_to_int(song, layer)
var target = songs[song]._get_core().get_child(layer)
if target.volume_db < 0:
fade_in(song, layer)
else:
fade_out(song, layer)
#change to the specified song at the next bar
func queue_bar_transition(song):
song = _songname_to_int(song)
old_song = current_song_num
songs[old_song].fading_out = true
new_song = song
bar_tran = true
#change to the specified song at the next beat
func queue_beat_transition(song):
song = _songname_to_int(song)
old_song = current_song_num
songs[old_song].fading_out = true
new_song = song
beat_tran = true
#play two tracks in order, either ending, looping or shuffling on the second
func queue_sequence(sequence : Array, type : String, on_end : String):
match type:
"beat":
queue_beat_transition(sequence[0])
"bar":
queue_bar_transition(sequence[0])
play_mode = 0
yield(self,"song_changed")
yield(self,"end")
init_song(sequence[1])
play(sequence[1])
match on_end:
"play_once":
play_mode = 0
"loop":
play_mode = 1
"shuffle":
play_mode = 2
"endless":
play_mode = 3
#unload and stops the current song, then initialises and plays the new one
func _change_song(song):
old_song = current_song_num
song = _songname_to_int(song)
if song != current_song_num:
emit_signal("song_changed", [old_song, song])
init_song(song)
for i in songs[old_song].get_children():
if i.cont == "core":
if songs[old_song].transition_beats >= 1:
for o in i.get_child_count():
fade_out(old_song, o)
elif i.cont != "rollover":
for o in i.get_children():
if o.playing:
o.stop()
_stop_overlays()
play(song)
#stops playing
func stop(song):
song = _songname_to_int(song)
get_child(song).playing = false
if playing:
playing = false
for i in songs[song]._get_core().get_children():
i.stop()
i.stream.loop = false
_stop_overlays()
#when the core loop finishes its loop
func _core_finished():
songs[current_song_num].concats.clear()
emit_signal("end", current_song_num)
match get_current_song().song_type:
"standard":
match play_mode:
1:
bar = 1
beat = 1
last_beat = -1
repeats += 1
play(current_song_num)
2:
$shuffle_timer.start(rand_range(2,4))
3:
shuffle_songs()
4:
var new_song
if current_song_num == (get_child_count() - 3):
new_song = 0
else:
new_song = current_song_num + 1
_change_song(new_song)
"transition":
var t = get_current_song().target_song
var desk = t.get_parent()
if desk == self:
_change_song(t.name)
else:
stop(current_song_num)
desk.quickplay(t.name)
#called every bar
func _bar():
if can_bar:
can_bar = false
if bar_tran:
if current_song_num != new_song:
_change_song(new_song)
else:
play(new_song)
yield(get_tree().create_timer(0.5), "timeout")
can_bar = true
#called every beat
func _beat():
if beat_tran:
if current_song_num != new_song:
_change_song(new_song)
else:
play(new_song)
if b2bar == beats_in_bar:
b2bar = 1
bar += 1
_bar()
emit_signal("bar", bar)
else:
b2bar += 1
if rollover != null:
if beat == rollover_point:
if rollover.get_child_count() > 1:
var roll = rollover.get_child(randi() % rollover.get_child_count())
roll.play()
else:
rollover.get_child(0).play()
if beat == (bars*beats_in_bar + 1):
_core_finished()
emit_signal("beat", (beat - 1) % int(bars * beats_in_bar) + 1)
func get_current_song():
return get_child(current_song_num)
#gets a random track from a song and returns it
func _get_rantrk(song):
song = _songname_to_int(song)
var chance = randi() % song.get_child_count()
var rantrk = song.get_child(chance)
return rantrk
#choose new song randomly
func shuffle_songs():
randomize()
var list = songs
list.remove(list.find(get_child(current_song_num)))
var song_num = randi() % (list.size() - 1)
var song = get_child(song_num).name
emit_signal("shuffle", [current_song_num, get_node(song).get_index()])
new_song = get_node(song).get_index()
_change_song(song)

View file

@ -0,0 +1,48 @@
extends Node
#internal vars
var song_type = "standard"
var fading_out : bool = false
var fading_in : bool = false
var muted_tracks = []
var concats : Array
var playing = false
#external properties
export(int) var tempo
export(int) var bars
export(int) var beats_in_bar
export(float) var transition_beats
export(bool) var ignore = false
export(bool) var auto_transition
export(NodePath) var auto_signal_node
export(String) var auto_signal
export(String, "Beat", "Bar") var transition_type
export(String) var bus = "Music"
func _ready():
if auto_transition:
var sig_node = get_node(auto_signal_node)
sig_node.connect(auto_signal, self, "_transition", [transition_type])
var busnum = AudioServer.get_bus_index(bus)
if busnum == -1:
var new_bus = AudioServer.add_bus(AudioServer.bus_count)
AudioServer.set_bus_name(AudioServer.bus_count - 1, bus)
if bus != "Music":
AudioServer.set_bus_send(AudioServer.get_bus_index(bus),"Music")
for i in get_children():
for o in i.get_children():
o.set_bus(bus)
func _transition(type):
match type:
"Beat":
get_parent().queue_beat_transition(name)
"Bar":
get_parent().queue_bar_transition(name)
func _get_core():
for i in get_children():
if i.cont == "core":
return i

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/song_icon.png-47a049549935361c5fbfe56d26ffc2bd.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/music/song_icon.png"
dest_files=[ "res://.import/song_icon.png-47a049549935361c5fbfe56d26ffc2bd.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View file

@ -0,0 +1,47 @@
extends Node
#internal vars
var song_type = "transition"
var fading_out : bool = false
var fading_in : bool = false
var muted_tracks = []
var concats : Array
var ignore = true
#external properties
export(int) var tempo
export(int) var bars
export(int) var beats_in_bar
export(NodePath) var target_song
export(float) var transition_beats
export(bool) var auto_transition
export(NodePath) var auto_signal_node
export(String) var auto_signal
export(String, "Beat", "Bar") var transition_type
export(String) var bus = "Music"
func _ready():
if auto_transition:
var sig_node = get_node(auto_signal_node)
sig_node.connect(auto_signal, self, "_transition", [transition_type])
var busnum = AudioServer.get_bus_index(bus)
if busnum == -1:
var new_bus = AudioServer.add_bus(AudioServer.bus_count)
AudioServer.set_bus_name(AudioServer.bus_count - 1, bus)
if bus != "Music":
AudioServer.set_bus_send(AudioServer.get_bus_index(bus),"Music")
for i in get_children():
for o in i.get_children():
o.set_bus(bus)
func _transition(type):
match type:
"Beat":
get_parent().queue_beat_transition(name)
"Bar":
get_parent().queue_bar_transition(name)
func _get_core():
for i in get_children():
if i.cont == "core":
return i

View file

@ -0,0 +1,8 @@
[plugin]
name="Mixing Desk"
description="A plugin that adds nodes making it easier to create
procedural sound or adaptive music."
author="Kyle Harmieson"
version="2.13.3"
script="mixing_desk.gd"

View file

@ -0,0 +1,65 @@
extends Node2D
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.position = global_position
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/2d/spawn_sound.gd"))
snd.setup()
func play(num=0):
if num == 0:
num = sound_number
randomize()
for i in range(0, num):
var ransnd = _get_ransnd()
ransnd.play()
yield(ransnd, "finished")
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,18 @@
extends Node2D
export var autoplay : bool
export(NodePath) var spawn_node
func _ready():
for i in get_children():
i.spawn_node = spawn_node
if autoplay:
play()
func play():
for i in get_children():
i.play()
func stop():
for i in get_children():
i.stop()

View file

@ -0,0 +1,56 @@
extends Node2D
var dvols = []
var dpitches = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.position = global_position
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/2d/spawn_sound.gd"))
snd.setup()
func play(ran=true):
for i in get_children():
if i.name == "root": return
if ran:
_randomise(i)
_iplay(i)
func _randomise(sound):
var dvol = dvols[sound.get_index()]
var dpitch = dpitches[sound.get_index()]
var newvol = (dvol + _range(volume_range))
var newpitch = (dpitch + _range(pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch
func _range(item : float) -> float:
return rand_range(-item,item)

View file

@ -0,0 +1,67 @@
extends Node2D
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.position = global_position
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/2d/spawn_sound.gd"))
snd.setup()
func play(num=0, ran=true):
if num == 0:
num = sound_number
if num > 1:
for i in range(0, num):
var ransnd = _get_ransnd()
_iplay(ransnd)
else:
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,102 @@
extends Node2D
var dvols = []
var dpitches = []
var soundlist = []
var dlocs = []
var timeroot
var root
var scattering : bool = false
export(NodePath) var spawn_node
export var autostart : bool = true
export var volume_range : float = 1.0
export var pitch_range : float= 1.0
export var scatter_range : float = 1.0
export var voices : int = 5
export var min_time : float = 1
export var max_time : float = 5
export var timeout : float = 7
export var randomise : bool = true
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
dlocs.append(i.position)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autostart:
play()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.position = global_position
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/2d/spawn_sound.gd"))
snd.setup()
func play():
if scattering:
return
scattering = true
var timeroot = Node.new()
timeroot.name = 'timeroot'
add_child(timeroot)
for i in voices:
var timer = Timer.new()
timer.name = str('scat_timer_' + str(i))
timeroot.add_child(timer)
timer.start(rand_range(min_time,max_time))
timer.connect("timeout", self, "_scatter_timeout", [timer, min_time, max_time])
if rand_range(0,1) > 0.7:
_scatter()
if timeout != 0:
var timeouttimer = Timer.new()
timeouttimer.wait_time= timeout
add_child(timeouttimer)
timeouttimer.start()
timeouttimer.connect("timeout", self, "stop")
func _scatter_timeout(timer, min_time, max_time):
_scatter()
timer.start(rand_range(min_time, max_time))
func stop():
scattering = false
if has_node("timeroot"):
$timeroot.queue_free()
func _scatter():
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise(ransnd)
return ransnd
func _randomise(sound):
var dvol = dvols[sound.get_index()]
var dpitch = dpitches[sound.get_index()]
var dloc = dlocs[sound.get_index()]
var newvol = (dvol + _range(volume_range))
var newpitch = (dpitch + _range(pitch_range))
var newloc = (dloc + Vector2(_range(scatter_range), _range(scatter_range)))
sound.volume_db = newvol
sound.pitch_scale = newpitch
sound.position = newloc
func _range(item : float) -> float:
return rand_range(-item,item)

View file

@ -0,0 +1,7 @@
extends AudioStreamPlayer2D
func setup():
connect("finished", self, "finished")
func finished():
queue_free()

View file

@ -0,0 +1,65 @@
extends Spatial
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.unit_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.translation = global_transform.origin
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/3d/spawn_sound.gd"))
snd.setup()
func play(num=0):
if num == 0:
num = sound_number
randomize()
for i in range(0, num):
var ransnd = _get_ransnd()
ransnd.play()
yield(ransnd, "finished")
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.unit_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,19 @@
extends Spatial
export var autoplay : bool
export(NodePath) var spawn_node
func _ready():
for i in get_children():
if spawn_node:
i.spawn_node = spawn_node
if autoplay:
play()
func play():
for i in get_children():
i.play()
func stop():
for i in get_children():
i.stop()

View file

@ -0,0 +1,54 @@
extends Spatial
var dvols = []
var dpitches = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
func _ready():
for i in get_children():
if i.get("unit_db") != null:
dvols.append(i.unit_db)
dpitches.append(i.pitch_scale)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Spatial.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.global_transform.origin = global_transform.origin
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/3d/spawn_sound.gd"))
snd.setup()
func play(ran=true):
for i in get_children():
if i.name == "root": return
if ran:
_randomise_pitch_and_vol(i)
_iplay(i)
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.unit_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,70 @@
extends Spatial
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.unit_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Spatial.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.global_transform.origin = global_transform.origin
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/3d/spawn_sound.gd"))
snd.setup()
func play(num=0, ran=true):
if num == 0:
num = sound_number
if num > 1:
for i in range(0, num):
var ransnd = _get_ransnd()
_iplay(ransnd)
else:
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise(ransnd)
return ransnd
func _randomise(sound):
var dvol = dvols[sound.get_index()]
var dpitch = dpitches[sound.get_index()]
var newvol = (dvol + _range(volume_range))
var newpitch = (dpitch + _range(pitch_range))
sound.unit_db = newvol
sound.pitch_scale = newpitch
func _range(item : float) -> float:
return rand_range(-item,item)

View file

@ -0,0 +1,106 @@
extends Spatial
var dvols = []
var dpitches = []
var dlocs = []
var soundlist = []
var timeroot
var root
var scattering : bool = false
export(NodePath) var spawn_node
export var autostart : bool = true
export var volume_range : float = 1.0
export var pitch_range : float= 1.0
export var scatter_range : float = 1.0
export var voices : int = 5
export var min_time : float = 1
export var max_time : float = 5
export var timeout : float = 7
export var randomise : bool = true
func _ready():
for i in get_children():
dvols.append(i.unit_db)
dpitches.append(i.pitch_scale)
dlocs.append(i.global_transform.origin)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Spatial.new()
add_child(root)
root.name = "root"
if autostart:
play()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
if spawn_node:
snd.global_transform.origin = sound.global_transform.origin
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/3d/spawn_sound.gd"))
snd.setup()
func play():
if scattering:
return
scattering = true
timeroot = Node.new()
timeroot.name = 'timeroot' + str(get_index())
add_child(timeroot)
for i in voices:
var timer = Timer.new()
timer.name = str('scat_timer_' + str(i))
timeroot.add_child(timer)
timer.start(rand_range(min_time,max_time))
timer.connect("timeout", self, "_scatter_timeout", [timer, min_time, max_time])
if rand_range(0,1) > 0.7:
_scatter()
if timeout != 0:
var timeouttimer = Timer.new()
timeouttimer.wait_time= timeout
timeouttimer.name = "Timeout"
add_child(timeouttimer)
timeouttimer.start()
timeouttimer.connect("timeout", self, "stop")
func _scatter_timeout(timer, min_time, max_time):
_scatter()
timer.start(rand_range(min_time, max_time))
func stop():
if scattering:
scattering = false
timeroot.call_deferred("queue_free")
func _scatter():
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise(ransnd)
return ransnd
func _randomise(sound):
var dvol = dvols[sound.get_index()]
var dpitch = dpitches[sound.get_index()]
var dloc
if dlocs[sound.get_index()] != sound.global_transform.origin:
dlocs[sound.get_index()] = sound.global_transform.origin
dloc = dlocs[sound.get_index()]
var newvol = (dvol + _range(volume_range))
var newpitch = (dpitch + _range(pitch_range))
var newloc = (dloc + Vector3(_range(scatter_range), _range(scatter_range),_range(scatter_range)))
sound.unit_db = newvol
sound.pitch_scale = newpitch
sound.global_transform.origin = newloc
func _range(item : float) -> float:
return rand_range(-item,item)

View file

@ -0,0 +1,7 @@
extends AudioStreamPlayer3D
func setup():
connect("finished", self, "finished")
func finished():
queue_free()

View file

@ -0,0 +1,5 @@
extends Node
func play():
for i in get_children():
i.play()

View file

@ -0,0 +1,63 @@
extends Node
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/nonspatial/spawn_sound.gd"))
snd.setup()
func play(num=0):
if num == 0:
num = sound_number
randomize()
for i in range(0, num):
var ransnd = _get_ransnd()
ransnd.play()
yield(ransnd, "finished")
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,20 @@
extends Node
export var autoplay : bool
export(NodePath) var spawn_node
func _ready():
for i in get_children():
if spawn_node:
if spawn_node in i:
i.spawn_node = spawn_node
if autoplay:
play()
func play():
for i in get_children():
i.play()
func stop():
for i in get_children():
i.stop()

View file

@ -0,0 +1,51 @@
extends Node
var dvols = []
var dpitches = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/nonspatial/spawn_sound.gd"))
snd.setup()
func play(ran=true):
for i in get_children():
if i.name == "root": return
if ran:
_randomise_pitch_and_vol(i)
_iplay(i)
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,65 @@
extends Node
var dvols = []
var dpitches = []
var soundlist = []
var root
export(NodePath) var spawn_node
export var autoplay : bool
export var volume_range : float
export var pitch_range : float
export var sound_number : int
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autoplay:
play()
func stop():
for i in root.get_children():
i.queue_free()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/nonspatial/spawn_sound.gd"))
snd.setup()
func play(num=0, ran=true):
if num == 0:
num = sound_number
if num > 1:
for i in range(0, num):
var ransnd = _get_ransnd()
_iplay(ransnd)
else:
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd(ran=true):
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if ran:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch

View file

@ -0,0 +1,94 @@
extends Node
var dvols = []
var dpitches = []
var soundlist = []
var timeroot
var root
var scattering : bool = false
export(NodePath) var spawn_node
export var autostart : bool = true
export var volume_range : float = 1.0
export var pitch_range : float= 1.0
export var voices : int = 5
export var min_time : float = 1
export var max_time : float = 5
export var timeout : float = 7
export var randomise : bool = true
func _ready():
for i in get_children():
dvols.append(i.volume_db)
dpitches.append(i.pitch_scale)
soundlist.append(i)
if spawn_node:
if typeof(spawn_node) == TYPE_NODE_PATH:
root = get_node(spawn_node)
elif typeof(spawn_node) == TYPE_OBJECT:
root = spawn_node
else:
root = Node2D.new()
add_child(root)
root.name = "root"
if autostart:
play()
func _iplay(sound):
var snd = sound.duplicate()
root.add_child(snd)
snd.play()
snd.set_script(preload("res://addons/mixing-desk/sound/nonspatial/spawn_sound.gd"))
snd.setup()
func play():
if scattering:
return
scattering = true
var timeroot = Node.new()
timeroot.name = 'timeroot'
add_child(timeroot)
for i in voices:
var timer = Timer.new()
timer.name = str('scat_timer_' + str(i))
timeroot.add_child(timer)
timer.start(rand_range(min_time,max_time))
timer.connect("timeout", self, "_scatter_timeout", [timer, min_time, max_time])
if rand_range(0,1) > 0.7:
_scatter()
if timeout != 0:
var timeouttimer = Timer.new()
timeouttimer.wait_time= timeout
add_child(timeouttimer)
timeouttimer.start()
timeouttimer.connect("timeout", self, "stop")
func _scatter_timeout(timer, min_time, max_time):
_scatter()
timer.start(rand_range(min_time, max_time))
func stop():
scattering = false
if has_node("timeroot"):
$timeroot.queue_free()
func _scatter():
var ransnd = _get_ransnd()
_iplay(ransnd)
func _get_ransnd():
var chance = randi() % soundlist.size()
var ransnd = soundlist[chance]
if randomise:
_randomise_pitch_and_vol(ransnd)
return ransnd
func _randomise_pitch_and_vol(sound):
var dvol = sound.get_parent().dvols[sound.get_index()]
var dpitch = sound.get_parent().dpitches[sound.get_index()]
var newvol = (dvol + rand_range(-volume_range,volume_range))
var newpitch = (dpitch + rand_range(-pitch_range,pitch_range))
sound.volume_db = newvol
sound.pitch_scale = newpitch
func _range(item : float) -> float:
return rand_range(-item,item)

View file

@ -0,0 +1,7 @@
extends AudioStreamPlayer
func setup():
connect("finished", self, "finished")
func finished():
queue_free()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/snd_icon.png-44f572aa53b2a4c72c88f282577b4a4f.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/mixing-desk/sound/snd_icon.png"
dest_files=[ "res://.import/snd_icon.png-44f572aa53b2a4c72c88f282577b4a4f.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0