Added basic audio support

This commit is contained in:
RodZill4 2020-02-24 08:32:11 +01:00
parent e6281915af
commit da1a26b895
12 changed files with 478 additions and 4 deletions

View File

@ -0,0 +1,20 @@
tool
extends MMGenBase
class_name MMGenAudio
"""
Dummy generator to get audio shaders from UI
"""
func get_type() -> String:
return "audio"
func get_type_name() -> String:
return "Audio"
func get_input_defs() -> Array:
return [ { name="in", type="sound" } ]
func _serialize(data: Dictionary) -> Dictionary:
return data

View File

@ -72,7 +72,8 @@ func create_gen(data) -> MMGenBase:
switch = MMGenSwitch, switch = MMGenSwitch,
export = MMGenExport, export = MMGenExport,
comment = MMGenComment, comment = MMGenComment,
debug = MMGenDebug debug = MMGenDebug,
audio = MMGenAudio
} }
var generator = null var generator = null
for g in guess: for g in guess:

View File

@ -79,6 +79,15 @@
"params":"p", "params":"p",
"slot_type":3, "slot_type":3,
"color":{ "r":1.0, "g":0.0, "b":1.0, "a":1.0 } "color":{ "r":1.0, "g":0.0, "b":1.0, "a":1.0 }
},
{
"name":"sound",
"label":"Sound",
"type":"vec2",
"paramdefs":"vec3 t",
"params":"t",
"slot_type":4,
"color":{ "r":1.0, "g":1.0, "b":0.0, "a":1.0 }
}, },
{ {
"name":"any", "name":"any",

View File

@ -0,0 +1,18 @@
vec2 __sound(vec3 uv) {
$(code)
return $(value);
}
void fragment() {
vec3 uv = UV.xxx;
vec2 smin = vec2(1.0);
vec2 smax = vec2(-1.0);
for (int i = -5; i <=5; ++i) {
vec2 s = __sound(vec3(UV.x+float(i)/5.0/preview_size));
smin = min(s, smin);
smax = max(s, smax);
}
vec2 y = vec2((0.5-UV.y)*2.1);
vec2 color = step(smin, y+4.0/preview_size)*step(y-4.0/preview_size, smax);
COLOR = vec4(color, max(color.x, color.y), 1.0);
}

View File

@ -0,0 +1,264 @@
{
"connections": [
{
"from": "206_2",
"from_port": 0,
"to": "206_2_2",
"to_port": 0
},
{
"from": "206_2_2",
"from_port": 0,
"to": "206",
"to_port": 0
},
{
"from": "206_2_2",
"from_port": 0,
"to": "audio",
"to_port": 0
}
],
"label": "Graph",
"name": "59",
"node_position": {
"x": 0,
"y": 0
},
"nodes": [
{
"name": "Material",
"node_position": {
"x": 184,
"y": -37
},
"parameters": {
"albedo_color": {
"a": 1,
"b": 1,
"g": 1,
"r": 1,
"type": "Color"
},
"ao_light_affect": 1,
"depth_scale": 1,
"emission_energy": 1,
"metallic": 1,
"normal_scale": 1,
"roughness": 1,
"size": 11,
"subsurf_scatter_strength": 0
},
"type": "material"
},
{
"name": "206",
"node_position": {
"x": -438.5,
"y": -376
},
"parameters": {
"attack": 0,
"decay": 0.4,
"release": 0.4,
"sustain": 0.25
},
"shader_model": {
"code": "",
"global": "float enveloppe(float time, float attack, float decay, float sustain, float release) {\n\tfloat rv = 0.0;\n\tif (time < attack) {\n\t\trv = time/attack;\n\t} else if (time < attack+decay) {\n\t\trv = 1.0-(1.0-sustain)*(time-attack)/(decay);\n\t} else {\n\t\trv = sustain-sustain*(time-attack-decay)/(release);\n\t}\n\treturn clamp(rv, 0.0, 1.0);\n}",
"inputs": [
{
"default": "vec2(0.0)",
"label": "",
"name": "in",
"type": "sound"
}
],
"instance": "",
"name": "Enveloppe",
"outputs": [
{
"sound": "$in($uv)*enveloppe($uv.y, $attack, $decay, $sustain, $release)",
"type": "sound"
}
],
"parameters": [
{
"control": "None",
"default": 0.2,
"label": "Attack",
"max": 10,
"min": 0,
"name": "attack",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 0.5,
"label": "Decay",
"max": 10,
"min": 0,
"name": "decay",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 0.5,
"label": "Sustain",
"max": 1,
"min": 0,
"name": "sustain",
"step": 0.01,
"type": "float"
},
{
"control": "None",
"default": 2,
"label": "Release",
"max": 10,
"min": 0,
"name": "release",
"step": 0.01,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "206_2",
"node_position": {
"x": -432.5,
"y": -488
},
"parameters": {
"frequency": 930.2,
"type": 0
},
"shader_model": {
"code": "",
"global": "",
"inputs": [
],
"instance": "",
"name": "Wave",
"outputs": [
{
"sound": "vec2($type)",
"type": "sound"
}
],
"parameters": [
{
"default": 3,
"label": "Type",
"name": "type",
"type": "enum",
"values": [
{
"name": "Sine",
"value": "sin($frequency*$uv.x*6.28)"
},
{
"name": "Rect",
"value": "2.0*step(fract($frequency*$uv.x), 0.5)-1.0"
},
{
"name": "Sawtooth",
"value": "2.0*fract($frequency*$uv.x)-1.0"
},
{
"name": "Triangle",
"value": "4.0*abs(fract($frequency*$uv.x)-0.5)-1.0"
}
]
},
{
"control": "None",
"default": 440,
"label": "Frequency",
"max": 22000,
"min": 0,
"name": "frequency",
"step": 0.1,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "audio",
"node_position": {
"x": -380.958374,
"y": -205.208374
},
"parameters": {
},
"seed_value": 8978,
"type": "audio"
},
{
"name": "206_2_2",
"node_position": {
"x": -143.958374,
"y": -463.508362
},
"parameters": {
"amplitude": 0.056,
"speed": 0.98
},
"shader_model": {
"code": "",
"global": "",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in",
"type": "sound"
}
],
"instance": "",
"name": "Sine",
"outputs": [
{
"sound": "$in(vec3($uv.x*(1.0+$amplitude*sin($uv.y*$speed*6.28318530718)/$uv.y), $uv.yz))",
"type": "sound"
}
],
"parameters": [
{
"control": "None",
"default": 0.1,
"label": "Amplitude",
"max": 0.5,
"min": 0,
"name": "amplitude",
"step": 0.001,
"type": "float"
},
{
"control": "None",
"default": 2,
"label": "Speed",
"max": 20,
"min": 0,
"name": "speed",
"step": 0.01,
"type": "float"
}
]
},
"type": "shader"
}
],
"parameters": {
},
"type": "graph"
}

View File

@ -0,0 +1,15 @@
[remap]
importer="material_maker.import"
type="SpatialMaterial"
path="res://.import/audio.ptex-9e2c2e20f2d1e2d6957feaedacaf2a96.tres"
[deps]
source_file="res://material_maker/examples/audio.ptex"
dest_files=[ "res://.import/audio.ptex-9e2c2e20f2d1e2d6957feaedacaf2a96.tres" ]
[params]
render=false
scale=1.0

View File

@ -0,0 +1,66 @@
extends MMGraphNodeBase
onready var playback = $AudioStreamPlayer.get_stream_playback()
var samples_played = 0
func _ready():
set_process(false)
func set_generator(g) -> void:
.set_generator(g)
generator.connect("parameter_changed", self, "on_parameter_changed")
on_parameter_changed(null, null)
func on_parameter_changed(p, v):
$Timer.start()
func update_shader():
var src = generator.get_source(0)
var result = { code="", sound="vec2(0.0)", globals=[] }
if src != null:
var context : MMGenContext = MMGenContext.new()
result = src.generator.get_shader_code("vec3(s2ttime(UV))", src.output_index, context)
while result is GDScriptFunctionState:
result = yield(result, "completed")
var code : String = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n"
code += "uniform float start_time = 0.0;\n"
code += "const float buffer_size = 64.0;\n"
code += "float s2ttime(vec2 uv) {\nreturn start_time+(floor(uv.x*buffer_size)+buffer_size*floor(uv.y*buffer_size))/44100.0;\n}\n"
code += "vec4 au2tex(vec2 s) {\nvec2 v = floor((0.5+0.5*s)*65536.0);\nvec2 vl = mod(v, 256.0)/255.0;\nvec2 vh = floor(v/256.0)/255.0;\nreturn vec4(vh.x, vl.x, vh.y, vl.y);\n}\n"
for g in result.globals:
code += g
code += "void fragment() {\n"
code += result.code;
code += "COLOR = au2tex("+result.sound+");"
code += "}"
$ViewportContainer/Viewport/ColorRect.material.shader.code = code
samples_played = 0
$ViewportContainer/Viewport/ColorRect.material.set_shader_param("start_time", 0.0)
func _on_Button_pressed():
if $AudioStreamPlayer.playing:
$AudioStreamPlayer.stop()
set_process(false)
$Button.text = "Play"
else:
update_shader()
samples_played = 0
$ViewportContainer/Viewport/ColorRect.material.set_shader_param("start_time", 0.0)
$AudioStreamPlayer.play()
set_process(true)
$Button.text = "Stop"
func _process(delta):
var image = $ViewportContainer/Viewport.get_texture().get_data()
var to_fill = min(playback.get_frames_available(), image.data.width*image.data.height)
var i : int = 0
for j in range(to_fill):
var left = (image.data.data[i]+image.data.data[i+1]/256.0)/128.0-1.0
var right = (image.data.data[i+2]+image.data.data[i+3]/256.0)/128.0-1.0
playback.push_frame(Vector2(left, right))
i += 4
samples_played += to_fill
$ViewportContainer/Viewport/ColorRect.material.set_shader_param("start_time", samples_played/44100.0)

View File

@ -0,0 +1,74 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://material_maker/nodes/audio.gd" type="Script" id=1]
[sub_resource type="AudioStreamGenerator" id=1]
buffer_length = 0.1
[sub_resource type="Shader" id=2]
resource_local_to_scene = true
[sub_resource type="ShaderMaterial" id=3]
resource_local_to_scene = true
shader = SubResource( 2 )
[node name="Audio" type="GraphNode"]
margin_right = 96.0
margin_bottom = 115.0
title = "Audio"
show_close = true
slot/0/left_enabled = true
slot/0/left_type = 4
slot/0/left_color = Color( 1, 1, 0, 1 )
slot/0/right_enabled = false
slot/0/right_type = 0
slot/0/right_color = Color( 1, 1, 1, 1 )
slot/1/left_enabled = false
slot/1/left_type = 0
slot/1/left_color = Color( 1, 1, 1, 1 )
slot/1/right_enabled = false
slot/1/right_type = 0
slot/1/right_color = Color( 1, 1, 1, 1 )
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false,
"_editor_description_": ""
}
[node name="Button" type="Button" parent="."]
margin_left = 16.0
margin_top = 24.0
margin_right = 80.0
margin_bottom = 44.0
text = "Play"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = SubResource( 1 )
[node name="ViewportContainer" type="ViewportContainer" parent="."]
margin_left = 16.0
margin_top = 45.0
margin_right = 80.0
margin_bottom = 109.0
rect_min_size = Vector2( 64, 64 )
mouse_filter = 2
[node name="Viewport" type="Viewport" parent="ViewportContainer"]
size = Vector2( 64, 64 )
transparent_bg = true
handle_input_locally = false
usage = 0
render_target_v_flip = true
render_target_update_mode = 3
[node name="ColorRect" type="ColorRect" parent="ViewportContainer/Viewport"]
material = SubResource( 3 )
margin_right = 64.0
margin_bottom = 64.0
rect_min_size = Vector2( 64, 64 )
[node name="Timer" type="Timer" parent="."]
wait_time = 0.1
one_shot = true
[connection signal="pressed" from="Button" to="." method="_on_Button_pressed"]
[connection signal="timeout" from="Timer" to="." method="update_shader"]

View File

@ -2,7 +2,6 @@
[ext_resource path="res://material_maker/nodes/debug.gd" type="Script" id=1] [ext_resource path="res://material_maker/nodes/debug.gd" type="Script" id=1]
[node name="Debug" type="GraphNode"] [node name="Debug" type="GraphNode"]
margin_right = 124.0 margin_right = 124.0
margin_bottom = 49.0 margin_bottom = 49.0
@ -15,6 +14,9 @@ slot/0/right_enabled = false
slot/0/right_type = 0 slot/0/right_type = 0
slot/0/right_color = Color( 1, 1, 1, 1 ) slot/0/right_color = Color( 1, 1, 1, 1 )
script = ExtResource( 1 ) script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Button" type="Button" parent="."] [node name="Button" type="Button" parent="."]
margin_left = 16.0 margin_left = 16.0

View File

@ -86,6 +86,7 @@ func _on_Apply_pressed() -> void:
emit_signal("node_changed", get_model_data()) emit_signal("node_changed", get_model_data())
func _on_OK_pressed() -> void: func _on_OK_pressed() -> void:
print("OK pressed")
emit_signal("node_changed", get_model_data()) emit_signal("node_changed", get_model_data())
queue_free() queue_free()

View File

@ -4,8 +4,6 @@
[ext_resource path="res://material_maker/widgets/node_editor/node_editor_item_list.gd" type="Script" id=2] [ext_resource path="res://material_maker/widgets/node_editor/node_editor_item_list.gd" type="Script" id=2]
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=3] [ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=3]
[sub_resource type="AtlasTexture" id=1] [sub_resource type="AtlasTexture" id=1]
flags = 4 flags = 4
atlas = ExtResource( 3 ) atlas = ExtResource( 3 )

View File

@ -14,6 +14,11 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://material_maker/widgets/float_edit.gd" "path": "res://material_maker/widgets/float_edit.gd"
}, { }, {
"base": "MMGenBase",
"class": "MMGenAudio",
"language": "GDScript",
"path": "res://addons/material_maker/engine/gen_audio.gd"
}, {
"base": "Node", "base": "Node",
"class": "MMGenBase", "class": "MMGenBase",
"language": "GDScript", "language": "GDScript",
@ -141,6 +146,7 @@ _global_script_classes=[ {
} ] } ]
_global_script_class_icons={ _global_script_class_icons={
"MMFloatEdit": "", "MMFloatEdit": "",
"MMGenAudio": "",
"MMGenBase": "", "MMGenBase": "",
"MMGenBuffer": "", "MMGenBuffer": "",
"MMGenComment": "", "MMGenComment": "",