Compare commits
10 commits
24051ef4bb
...
f4d536fd95
| Author | SHA1 | Date | |
|---|---|---|---|
| f4d536fd95 | |||
| e70d0d2547 | |||
| db6b1d3085 | |||
| 816d0e8e43 | |||
| 52405b50f8 | |||
| d282c21cfd | |||
| 38de570162 | |||
| 0c2fc7d192 | |||
|
|
defc59a5d2 | ||
|
|
97a4035115 |
37 changed files with 3131 additions and 316 deletions
|
|
@ -1,37 +1,23 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[sub_resource type="GDScript" id=1]
|
||||
script/source = "extends Control
|
||||
[ext_resource path="res://main.gd" type="Script" id=1]
|
||||
|
||||
var gdpd = load(\"res://addons/gdpd/bin/gdpd.gdns\")
|
||||
#var patch
|
||||
[sub_resource type="PhysicsMaterial" id=3]
|
||||
|
||||
func _ready():
|
||||
[sub_resource type="SphereShape" id=1]
|
||||
|
||||
#the patch path should be the absolute one
|
||||
_load_patch(ProjectSettings.globalize_path(\"res://patch1.pd\"))
|
||||
_load_patch(ProjectSettings.globalize_path(\"res://patch2.pd\"))
|
||||
[sub_resource type="SphereMesh" id=2]
|
||||
resource_local_to_scene = true
|
||||
|
||||
[node name="main" type="RigidBody" groups=["sounders"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
physics_material_override = SubResource( 3 )
|
||||
gravity_scale = 0.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
func _load_patch(pd_patch) :
|
||||
#separate file name from directory
|
||||
var patch_name = pd_patch.split(\"/\")[-1]
|
||||
var patch_dir = pd_patch.trim_suffix(patch_name)
|
||||
|
||||
#initialize pd
|
||||
var patch = gdpd.new()
|
||||
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
#retrieve
|
||||
var inps = patch.get_available_input_devices()
|
||||
var outs = patch.get_available_output_devices()
|
||||
patch.init_devices(inps[0], outs[0])
|
||||
|
||||
|
||||
#load patch
|
||||
patch.openfile(patch_name, patch_dir)
|
||||
"
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = SubResource( 1 )
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
mesh = SubResource( 2 )
|
||||
|
|
|
|||
78
GdpdExample/Player.gd
Normal file
78
GdpdExample/Player.gd
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
extends KinematicBody
|
||||
|
||||
var camera_angle = 0
|
||||
var mouse_sensitivity = 0.3
|
||||
var camera_change = Vector2()
|
||||
|
||||
var velocity = Vector3()
|
||||
var direction = Vector3()
|
||||
|
||||
#fly variables
|
||||
const FLY_SPEED = 20
|
||||
const FLY_ACCEL = 4
|
||||
|
||||
var mouse_captured = true
|
||||
|
||||
func _ready():
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
if mouse_captured:
|
||||
aim()
|
||||
fly(delta)
|
||||
# emit signal - playerinfo_updated
|
||||
var tf = $Head/Camera.get_global_transform_interpolated()
|
||||
if tf != Events.player_tf_old:
|
||||
Events.emit_signal("player_transform_updated", $Head/Camera.get_global_translation(), $Head.global_rotation.y)
|
||||
Events.player_tf_old = tf
|
||||
|
||||
if Input.is_action_just_pressed('toggle_mouse'):
|
||||
if mouse_captured:
|
||||
mouse_captured = false
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
else:
|
||||
mouse_captured = true
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventMouseMotion:
|
||||
camera_change = event.relative
|
||||
|
||||
func fly(delta):
|
||||
# reset the direction of the player
|
||||
direction = Vector3()
|
||||
|
||||
# get the rotation of the camera
|
||||
var aim = $Head/Camera.get_global_transform().basis
|
||||
|
||||
# check input and change direction
|
||||
if Input.is_action_pressed("move_forward"):
|
||||
direction -= aim.z
|
||||
if Input.is_action_pressed("move_backward"):
|
||||
direction += aim.z
|
||||
if Input.is_action_pressed("move_left"):
|
||||
direction -= aim.x
|
||||
if Input.is_action_pressed("move_right"):
|
||||
direction += aim.x
|
||||
|
||||
direction = direction.normalized()
|
||||
|
||||
# where would the player go at max speed
|
||||
var target = direction * FLY_SPEED
|
||||
|
||||
# calculate a portion of the distance to go
|
||||
velocity = velocity.linear_interpolate(target, FLY_ACCEL * delta)
|
||||
|
||||
# move
|
||||
move_and_slide(velocity)
|
||||
|
||||
func aim():
|
||||
if camera_change.length() > 0:
|
||||
$Head.rotate_y(deg2rad(-camera_change.x * mouse_sensitivity))
|
||||
|
||||
var change = -camera_change.y * mouse_sensitivity
|
||||
if change + camera_angle < 90 and change + camera_angle > -90:
|
||||
$Head/Camera.rotate_x(deg2rad(change))
|
||||
camera_angle += change
|
||||
camera_change = Vector2()
|
||||
21
GdpdExample/Player.tscn
Normal file
21
GdpdExample/Player.tscn
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://Player.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="CapsuleShape" id=1]
|
||||
radius = 0.6
|
||||
height = 2.0
|
||||
|
||||
[node name="Player" type="KinematicBody"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.52113, 0.98772 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Capsule" type="CollisionShape" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Head" type="Spatial" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0 )
|
||||
|
||||
[node name="Camera" type="Camera" parent="Head"]
|
||||
far = 10000.0
|
||||
24
GdpdExample/Region.gd
Normal file
24
GdpdExample/Region.gd
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
extends Spatial
|
||||
|
||||
var main = load("res://main.tscn")
|
||||
var sub = load("res://osc.tscn")
|
||||
|
||||
func _ready():
|
||||
# 'main' at center.
|
||||
var m = main.instance()
|
||||
add_child(m)
|
||||
m.set_size(rand_range(10, 15))
|
||||
m.audible_range_max = 80
|
||||
m.set_freq(rand_range(100, 300))
|
||||
m.set_gain(40)
|
||||
|
||||
# many 'sub' surrounds 'main' like satellites
|
||||
for i in range(18):
|
||||
var s = sub.instance()
|
||||
add_child(s)
|
||||
s.set_size(rand_range(0.2, 1.2))
|
||||
s.set_color(Color.black)
|
||||
var d = polar2cartesian(rand_range(20, 24), rand_range(0, 2*PI))
|
||||
s.translate(Vector3(d.x, rand_range(-2, 2), d.y))
|
||||
s.set_freq(rand_range(200, 2000))
|
||||
s.set_gain(0.1)
|
||||
6
GdpdExample/Region.tscn
Normal file
6
GdpdExample/Region.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://Region.gd" type="Script" id=1]
|
||||
|
||||
[node name="Region" type="Spatial"]
|
||||
script = ExtResource( 1 )
|
||||
11
GdpdExample/Scene.gd
Normal file
11
GdpdExample/Scene.gd
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
extends Node
|
||||
|
||||
#var region = load("res://Region.tscn")
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
# for i in range(18):
|
||||
# var oscnode = osctscn.instance()
|
||||
# oscnode.set_size(randf()*5 + 0.2)
|
||||
# oscnode.set_freq(randf()*800 + 200)
|
||||
# add_child(oscnode)
|
||||
44
GdpdExample/Scene.tscn
Normal file
44
GdpdExample/Scene.tscn
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://Region.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://Player.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://Scene.gd" type="Script" id=3]
|
||||
|
||||
[sub_resource type="BoxShape" id=1]
|
||||
extents = Vector3( 300, 1, 300 )
|
||||
|
||||
[sub_resource type="CubeMesh" id=2]
|
||||
size = Vector3( 600, 2, 600 )
|
||||
|
||||
[sub_resource type="Environment" id=3]
|
||||
fog_enabled = true
|
||||
|
||||
[node name="Scene" type="Node"]
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody" type="StaticBody" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="StaticBody"]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="StaticBody"]
|
||||
mesh = SubResource( 2 )
|
||||
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 0.158589, 0.987345, 0, -0.987345, 0.158589, 0, 57.3999, 0 )
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="Player" parent="." instance=ExtResource( 2 )]
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource( 3 )
|
||||
|
||||
[node name="Region" parent="." instance=ExtResource( 1 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 30, 0 )
|
||||
|
||||
[node name="Region2" parent="." instance=ExtResource( 1 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -193.573, 78.9511, 112.625 )
|
||||
|
||||
[node name="Region3" parent="." instance=ExtResource( 1 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 67.7793, 64.9703, -27.1477 )
|
||||
|
|
@ -6,4 +6,3 @@
|
|||
resource_name = "gdpd"
|
||||
class_name = "Gdpd"
|
||||
library = ExtResource( 1 )
|
||||
_sections_unfolded = [ "Resource" ]
|
||||
|
|
|
|||
BIN
GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib
Executable file
BIN
GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib
Executable file
Binary file not shown.
6
GdpdExample/autoload/Events.gd
Normal file
6
GdpdExample/autoload/Events.gd
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
extends Node
|
||||
|
||||
var player_tf_old = Transform()
|
||||
signal player_transform_updated(position, heading)
|
||||
# position : Vector3
|
||||
# heading : Vector2 (projected x-z plane, and normalized)
|
||||
6
GdpdExample/autoload/Events.tscn
Normal file
6
GdpdExample/autoload/Events.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://autoload/Events.gd" type="Script" id=1]
|
||||
|
||||
[node name="Events" type="Node"]
|
||||
script = ExtResource( 1 )
|
||||
93
GdpdExample/autoload/Global.gd
Normal file
93
GdpdExample/autoload/Global.gd
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
extends Node
|
||||
|
||||
|
||||
#gdpd (pd interface with godot)
|
||||
var _gdpd
|
||||
var _patches = []
|
||||
|
||||
export (bool) var _enable_gui = false
|
||||
export (String) var _gui_path = "/Applications/Pd-0.53-1.app/Contents/Resources"
|
||||
export (bool) var _verbose = false
|
||||
export (float) var _sample_rate = 48000
|
||||
export (int) var _blocksize = 256
|
||||
|
||||
func _ready():
|
||||
_gdpd = load("res://addons/gdpd/bin/gdpd.gdns").new()
|
||||
if _enable_gui:
|
||||
# set gui path to activate gui window (otherwise, nogui)
|
||||
_gdpd.set_gui_path(_gui_path)
|
||||
_gdpd.set_volume(1) # by default, volume(gain) == 0
|
||||
_gdpd.set_verbose(_verbose) # by default, suppress 'print'
|
||||
_gdpd.init(0, 2, _sample_rate, _blocksize)
|
||||
_gdpd.computeAudio(true) # [; pd dsp 1 (
|
||||
_gdpd.subscribe("toGodot")
|
||||
# delayed 'stream start' to prevent start-up 'pop' noise.
|
||||
yield(get_tree().create_timer(0.3), "timeout")
|
||||
_gdpd.streamstart()
|
||||
|
||||
func _exit_tree():
|
||||
if _patches.size() != 0:
|
||||
print()
|
||||
print("! ======== * purging leftover opened patches ... * ======== !")
|
||||
print()
|
||||
for id in _patches:
|
||||
_gdpd.closePatch(id)
|
||||
_patches.clear()
|
||||
_gdpd.stop()
|
||||
|
||||
func load_patch(pd_patch) -> int:
|
||||
#the patch path should be the absolute one
|
||||
#separate file name from directory
|
||||
var patch_name = pd_patch.split("/")[-1]
|
||||
var patch_dir = pd_patch.trim_suffix(patch_name)
|
||||
var id = _gdpd.openPatch(patch_name, patch_dir)
|
||||
_patches.append(id)
|
||||
return id
|
||||
|
||||
func close_patch(id):
|
||||
if id in _patches:
|
||||
_gdpd.closePatch(id)
|
||||
_patches.erase(id)
|
||||
|
||||
func _process(_delta) :
|
||||
while _gdpd.has_message():
|
||||
var msg = _gdpd.get_next()
|
||||
print(msg)
|
||||
# if msg[0] == "random":
|
||||
# print("r")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ==== archived. ====
|
||||
|
||||
|
||||
# duplicate "res://" into 'user://' ==> we need godot 4 for this approach..
|
||||
# _copydirectory_recursive("res://", "user://")
|
||||
|
||||
|
||||
## copy directory recursively ==> we need godot 4 for this approach..
|
||||
#func _copydirectory_recursive(src, dst):
|
||||
# var dotfolders = RegEx.new()
|
||||
# dotfolders.compile("^\\.\\w*")
|
||||
# var pdfiles = RegEx.new()
|
||||
# pdfiles.compile("\\w+\\.pd$")
|
||||
# var dir = Directory.new()
|
||||
# if dir.open(src) == OK:
|
||||
# dir.list_dir_begin()
|
||||
# var file_name = dir.get_next()
|
||||
# while file_name != "":
|
||||
# if dir.current_is_dir():
|
||||
# print("Found directory: " + file_name)
|
||||
# if not dotfolders.search(file_name):
|
||||
# dir.make_dir(dst + "/" + file_name)
|
||||
# _copydirectory_recursive(dir.get_current_dir() + "/" + file_name, dst + "/" + file_name)
|
||||
# else:
|
||||
# if pdfiles.search(file_name):
|
||||
# print("Found puredata file: " + file_name)
|
||||
# dir.copy(src + "/" + file_name, dst + "/" + file_name)
|
||||
#
|
||||
# file_name = dir.get_next()
|
||||
# else:
|
||||
# print("An error occurred when trying to access the path. : " + src)
|
||||
6
GdpdExample/autoload/Global.tscn
Normal file
6
GdpdExample/autoload/Global.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://autoload/Global.gd" type="Script" id=1]
|
||||
|
||||
[node name="Global" type="Node"]
|
||||
script = ExtResource( 1 )
|
||||
73
GdpdExample/export_presets.cfg
Normal file
73
GdpdExample/export_presets.cfg
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
[preset.0]
|
||||
|
||||
name="Mac OSX"
|
||||
platform="Mac OSX"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="./Sands and Waves (worldscene1).dmg"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
application/name=""
|
||||
application/info="Made with Godot Engine"
|
||||
application/icon=""
|
||||
application/identifier="in.dianaband.worldscene1"
|
||||
application/signature=""
|
||||
application/app_category="Games"
|
||||
application/short_version="1.0"
|
||||
application/version="1.0"
|
||||
application/copyright=""
|
||||
display/high_res=false
|
||||
privacy/microphone_usage_description=""
|
||||
privacy/camera_usage_description=""
|
||||
privacy/location_usage_description=""
|
||||
privacy/address_book_usage_description=""
|
||||
privacy/calendar_usage_description=""
|
||||
privacy/photos_library_usage_description=""
|
||||
privacy/desktop_folder_usage_description=""
|
||||
privacy/documents_folder_usage_description=""
|
||||
privacy/downloads_folder_usage_description=""
|
||||
privacy/network_volumes_usage_description=""
|
||||
privacy/removable_volumes_usage_description=""
|
||||
codesign/enable=true
|
||||
codesign/identity=""
|
||||
codesign/timestamp=false
|
||||
codesign/hardened_runtime=false
|
||||
codesign/replace_existing_signature=true
|
||||
codesign/entitlements/custom_file=""
|
||||
codesign/entitlements/allow_jit_code_execution=false
|
||||
codesign/entitlements/allow_unsigned_executable_memory=false
|
||||
codesign/entitlements/allow_dyld_environment_variables=false
|
||||
codesign/entitlements/disable_library_validation=true
|
||||
codesign/entitlements/audio_input=false
|
||||
codesign/entitlements/camera=false
|
||||
codesign/entitlements/location=false
|
||||
codesign/entitlements/address_book=false
|
||||
codesign/entitlements/calendars=false
|
||||
codesign/entitlements/photos_library=false
|
||||
codesign/entitlements/apple_events=false
|
||||
codesign/entitlements/debugging=false
|
||||
codesign/entitlements/app_sandbox/enabled=false
|
||||
codesign/entitlements/app_sandbox/network_server=false
|
||||
codesign/entitlements/app_sandbox/network_client=false
|
||||
codesign/entitlements/app_sandbox/device_usb=false
|
||||
codesign/entitlements/app_sandbox/device_bluetooth=false
|
||||
codesign/entitlements/app_sandbox/files_downloads=0
|
||||
codesign/entitlements/app_sandbox/files_pictures=0
|
||||
codesign/entitlements/app_sandbox/files_music=0
|
||||
codesign/entitlements/app_sandbox/files_movies=0
|
||||
codesign/custom_options=PoolStringArray( )
|
||||
notarization/enable=false
|
||||
notarization/apple_id_name=""
|
||||
notarization/apple_id_password=""
|
||||
notarization/apple_team_id=""
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3.2 KiB |
|
|
@ -28,6 +28,7 @@ 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
|
||||
|
|
|
|||
55
GdpdExample/main-earplug.pd
Normal file
55
GdpdExample/main-earplug.pd
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#N canvas 108 222 456 518 12;
|
||||
#X obj 361 21 loadbang;
|
||||
#X msg 361 51 \; pd dsp 1;
|
||||
#X floatatom 21 198 5 0 0 0 - - - 0;
|
||||
#X obj 21 22 r fromGodot\$0;
|
||||
#X obj 21 46 list trim;
|
||||
#X obj 199 467 dac~ 1 2;
|
||||
#X obj 199 407 *~;
|
||||
#X obj 189 264 line~;
|
||||
#X msg 189 240 \$1 100;
|
||||
#X obj 189 127 unpack f f;
|
||||
#X floatatom 189 177 5 0 0 0 - - - 0;
|
||||
#X obj 21 256 noise~;
|
||||
#X obj 21 286 bp~ 500 1000;
|
||||
#X obj 21 70 route freq gain panvol;
|
||||
#X obj 21 316 *~;
|
||||
#X msg 296 338 \$1 100;
|
||||
#X floatatom 296 159 5 0 0 0 - - - 0;
|
||||
#X obj 199 437 earplug~ 0 0;
|
||||
#X obj 296 362 line;
|
||||
#X obj 132 310 switch~;
|
||||
#X obj 132 286 tgl 19 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 132 262 change;
|
||||
#X text 89 155 switch on/off before 0 to stop startup pops, f 12;
|
||||
#X obj 189 216 max 0;
|
||||
#X obj 132 238 > -0.3;
|
||||
#X obj 296 248 expr 360-$f1;
|
||||
#X obj 296 182 expr $f1*180/3.141592;
|
||||
#X connect 2 0 12 1;
|
||||
#X connect 3 0 4 0;
|
||||
#X connect 4 0 13 0;
|
||||
#X connect 6 0 17 0;
|
||||
#X connect 7 0 6 1;
|
||||
#X connect 8 0 7 0;
|
||||
#X connect 9 0 10 0;
|
||||
#X connect 9 1 16 0;
|
||||
#X connect 10 0 23 0;
|
||||
#X connect 10 0 24 0;
|
||||
#X connect 11 0 12 0;
|
||||
#X connect 12 0 14 0;
|
||||
#X connect 13 0 2 0;
|
||||
#X connect 13 1 14 1;
|
||||
#X connect 13 2 9 0;
|
||||
#X connect 14 0 6 0;
|
||||
#X connect 15 0 18 0;
|
||||
#X connect 16 0 26 0;
|
||||
#X connect 17 0 5 0;
|
||||
#X connect 17 1 5 1;
|
||||
#X connect 18 0 17 1;
|
||||
#X connect 20 0 19 0;
|
||||
#X connect 21 0 20 0;
|
||||
#X connect 23 0 8 0;
|
||||
#X connect 24 0 21 0;
|
||||
#X connect 25 0 15 0;
|
||||
#X connect 26 0 25 0;
|
||||
100
GdpdExample/main.gd
Normal file
100
GdpdExample/main.gd
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
extends RigidBody
|
||||
|
||||
export (float, 0, 100) var audible_range_max = 10.0
|
||||
export (float, 1, 12) var preset = 1
|
||||
|
||||
export (bool) var use_embeded_patch = false
|
||||
export (String, MULTILINE) var patch = ""
|
||||
|
||||
var _my_patch = "res://main.pd"
|
||||
#var _my_patch = "res://main-earplug.pd"
|
||||
var _my_id = 0
|
||||
|
||||
func set_size(size):
|
||||
$CollisionShape.shape.radius = size
|
||||
$MeshInstance.mesh.radius = size
|
||||
$MeshInstance.mesh.height = size * 2
|
||||
|
||||
func set_freq(freq):
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol('freq')
|
||||
Global._gdpd.add_float(freq)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_gain(gain):
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol('gain')
|
||||
Global._gdpd.add_float(gain)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_param(param):
|
||||
Global._gdpd.start_message(param.size()+1)
|
||||
Global._gdpd.add_symbol("param")
|
||||
for i in range(param.size()):
|
||||
Global._gdpd.add_float(param[i])
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_preset(prs):
|
||||
preset = prs
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol("preset")
|
||||
Global._gdpd.add_float(prs)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_color(color):
|
||||
$MeshInstance.material_override = SpatialMaterial.new()
|
||||
$MeshInstance.material_override.albedo_color = color
|
||||
|
||||
func _ready():
|
||||
# save patch (for export)
|
||||
if use_embeded_patch:
|
||||
assert(_my_patch.substr(0, 7) == "user://", "use userpath with embeded_patch enabled !")
|
||||
assert(patch != "", "patch is empty?")
|
||||
_save_patch()
|
||||
|
||||
# load patch
|
||||
_my_id = Global.load_patch(ProjectSettings.globalize_path(_my_patch))
|
||||
|
||||
# listen 'player_transform_updated' event
|
||||
Events.connect("player_transform_updated", self, "_on_Events_player_transform_updated")
|
||||
|
||||
# send 'preset'
|
||||
set_preset(preset)
|
||||
|
||||
func _on_Events_player_transform_updated(playerpos, playerheading):
|
||||
var mypos = get_global_translation()
|
||||
var mypos2d = Vector2(mypos.x, mypos.z)
|
||||
var playerpos2d = Vector2(playerpos.x, playerpos.z)
|
||||
# calculate distance
|
||||
var distance = mypos.distance_to(playerpos)
|
||||
# calculate angle
|
||||
var angle = fmod(fmod(playerpos2d.angle_to_point(mypos2d) + playerheading - PI/2, PI*2) + PI*2, PI*2)
|
||||
if angle > PI:
|
||||
angle = angle - PI*2
|
||||
# (check)
|
||||
# print(str(_my_id) +" : ("+ str(distance) +","+ str(angle) +")")
|
||||
# calculate gain
|
||||
var gain = 1 - distance/audible_range_max
|
||||
# send to the patch
|
||||
Global._gdpd.start_message(3)
|
||||
Global._gdpd.add_symbol("panvol")
|
||||
Global._gdpd.add_float(gain)
|
||||
Global._gdpd.add_float(angle)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
Global.close_patch(_my_id)
|
||||
|
||||
func _save_patch():
|
||||
# save patch
|
||||
# prepare directory
|
||||
var patch_name = _my_patch.split("/")[-1]
|
||||
var patch_dir = _my_patch.trim_suffix(patch_name)
|
||||
var dir = Directory.new()
|
||||
dir.make_dir_recursive(patch_dir)
|
||||
# save to file
|
||||
var file = File.new()
|
||||
file.open(_my_patch, File.WRITE)
|
||||
file.store_string(patch)
|
||||
file.close()
|
||||
80
GdpdExample/main.pd
Normal file
80
GdpdExample/main.pd
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#N canvas 126 281 456 518 12;
|
||||
#X obj 361 21 loadbang;
|
||||
#X msg 361 51 \; pd dsp 1;
|
||||
#X floatatom 21 198 5 0 0 0 - - - 0;
|
||||
#X obj 21 22 r fromGodot\$0;
|
||||
#X obj 21 46 list trim;
|
||||
#X obj 199 467 dac~ 1 2;
|
||||
#X obj 199 407 *~;
|
||||
#X obj 189 264 line~;
|
||||
#X msg 189 240 \$1 100;
|
||||
#X obj 189 127 unpack f f;
|
||||
#X floatatom 189 177 5 0 0 0 - - - 0;
|
||||
#X obj 21 256 noise~;
|
||||
#X obj 21 286 bp~ 500 1000;
|
||||
#X obj 21 70 route freq gain panvol;
|
||||
#X obj 21 316 *~;
|
||||
#X obj 132 310 switch~;
|
||||
#X obj 132 286 tgl 19 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 132 262 change;
|
||||
#X text 89 155 switch on/off before 0 to stop startup pops, f 12;
|
||||
#X obj 189 216 max 0;
|
||||
#X obj 132 238 > -0.3;
|
||||
#X obj 303 253 hsl 100 20 -1 1 0 0 empty empty empty -2 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 300 349 line~;
|
||||
#X msg 300 325 \$1 100;
|
||||
#X obj 300 278 expr ($f1 + 1)/8;
|
||||
#X floatatom 300 302 5 0 0 0 - - - 0;
|
||||
#N canvas 68 97 450 300 pan2~ 0;
|
||||
#X obj 51 98 cos~;
|
||||
#X obj 111 98 cos~;
|
||||
#X obj 33 128 *~;
|
||||
#X obj 93 128 *~;
|
||||
#X obj 33 158 outlet~;
|
||||
#X obj 93 158 outlet~;
|
||||
#X obj 33 24 inlet~;
|
||||
#X obj 111 24 inlet~;
|
||||
#X obj 111 74 +~ 0.75;
|
||||
#X connect 0 0 2 1;
|
||||
#X connect 1 0 3 1;
|
||||
#X connect 2 0 4 0;
|
||||
#X connect 3 0 5 0;
|
||||
#X connect 6 0 2 0;
|
||||
#X connect 6 0 3 0;
|
||||
#X connect 7 0 8 0;
|
||||
#X connect 7 0 0 0;
|
||||
#X connect 8 0 1 0;
|
||||
#X restore 199 437 pd pan2~;
|
||||
#X floatatom 296 159 5 0 0 0 - - - 0;
|
||||
#X obj 296 182 sin;
|
||||
#X floatatom 296 206 5 0 0 0 - - - 0;
|
||||
#X connect 2 0 12 1;
|
||||
#X connect 3 0 4 0;
|
||||
#X connect 4 0 13 0;
|
||||
#X connect 6 0 26 0;
|
||||
#X connect 7 0 6 1;
|
||||
#X connect 8 0 7 0;
|
||||
#X connect 9 0 10 0;
|
||||
#X connect 9 1 27 0;
|
||||
#X connect 10 0 19 0;
|
||||
#X connect 10 0 20 0;
|
||||
#X connect 11 0 12 0;
|
||||
#X connect 12 0 14 0;
|
||||
#X connect 13 0 2 0;
|
||||
#X connect 13 1 14 1;
|
||||
#X connect 13 2 9 0;
|
||||
#X connect 14 0 6 0;
|
||||
#X connect 16 0 15 0;
|
||||
#X connect 17 0 16 0;
|
||||
#X connect 19 0 8 0;
|
||||
#X connect 20 0 17 0;
|
||||
#X connect 21 0 24 0;
|
||||
#X connect 22 0 26 1;
|
||||
#X connect 23 0 22 0;
|
||||
#X connect 24 0 25 0;
|
||||
#X connect 25 0 23 0;
|
||||
#X connect 26 0 5 0;
|
||||
#X connect 26 1 5 1;
|
||||
#X connect 27 0 28 0;
|
||||
#X connect 28 0 29 0;
|
||||
#X connect 29 0 21 0;
|
||||
53
GdpdExample/osc-earplug.pd
Normal file
53
GdpdExample/osc-earplug.pd
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#N canvas 650 226 456 518 12;
|
||||
#X obj 361 21 loadbang;
|
||||
#X msg 361 51 \; pd dsp 1;
|
||||
#X obj 50 277 osc~ 440;
|
||||
#X floatatom 21 198 5 0 0 0 - - - 0;
|
||||
#X obj 21 22 r fromGodot\$0;
|
||||
#X obj 21 46 list trim;
|
||||
#X obj 199 467 dac~ 1 2;
|
||||
#X obj 199 407 *~;
|
||||
#X obj 189 127 unpack f f;
|
||||
#X obj 21 70 route freq gain panvol;
|
||||
#X obj 50 301 *~;
|
||||
#X msg 296 338 \$1 100;
|
||||
#X floatatom 296 159 5 0 0 0 - - - 0;
|
||||
#X obj 199 437 earplug~ 0 0;
|
||||
#X obj 296 362 line;
|
||||
#X obj 189 264 line~;
|
||||
#X msg 189 240 \$1 100;
|
||||
#X floatatom 189 177 5 0 0 0 - - - 0;
|
||||
#X obj 132 310 switch~;
|
||||
#X obj 132 286 tgl 19 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 132 262 change;
|
||||
#X text 89 155 switch on/off before 0 to stop startup pops, f 12;
|
||||
#X obj 189 216 max 0;
|
||||
#X obj 132 238 > -0.3;
|
||||
#X obj 296 248 expr 360-$f1;
|
||||
#X obj 296 182 expr $f1*180/3.141592;
|
||||
#X connect 2 0 10 0;
|
||||
#X connect 3 0 2 0;
|
||||
#X connect 4 0 5 0;
|
||||
#X connect 5 0 9 0;
|
||||
#X connect 7 0 13 0;
|
||||
#X connect 8 0 17 0;
|
||||
#X connect 8 1 12 0;
|
||||
#X connect 9 0 3 0;
|
||||
#X connect 9 1 10 1;
|
||||
#X connect 9 2 8 0;
|
||||
#X connect 10 0 7 0;
|
||||
#X connect 11 0 14 0;
|
||||
#X connect 12 0 25 0;
|
||||
#X connect 13 0 6 0;
|
||||
#X connect 13 1 6 1;
|
||||
#X connect 14 0 13 1;
|
||||
#X connect 15 0 7 1;
|
||||
#X connect 16 0 15 0;
|
||||
#X connect 17 0 22 0;
|
||||
#X connect 17 0 23 0;
|
||||
#X connect 19 0 18 0;
|
||||
#X connect 20 0 19 0;
|
||||
#X connect 22 0 16 0;
|
||||
#X connect 23 0 20 0;
|
||||
#X connect 24 0 11 0;
|
||||
#X connect 25 0 24 0;
|
||||
100
GdpdExample/osc.gd
Normal file
100
GdpdExample/osc.gd
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
extends RigidBody
|
||||
|
||||
export (float, 0, 100) var audible_range_max = 10.0
|
||||
export (float, 1, 12) var preset = 1
|
||||
|
||||
export (bool) var use_embeded_patch = false
|
||||
export (String, MULTILINE) var patch = ""
|
||||
|
||||
var _my_patch = "res://osc.pd"
|
||||
#var _my_patch = "res://osc-earplug.pd"
|
||||
var _my_id = 0
|
||||
|
||||
func set_size(size):
|
||||
$CollisionShape.shape.radius = size
|
||||
$MeshInstance.mesh.radius = size
|
||||
$MeshInstance.mesh.height = size * 2
|
||||
|
||||
func set_freq(freq):
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol('freq')
|
||||
Global._gdpd.add_float(freq)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_gain(gain):
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol('gain')
|
||||
Global._gdpd.add_float(gain)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_param(param):
|
||||
Global._gdpd.start_message(param.size()+1)
|
||||
Global._gdpd.add_symbol("param")
|
||||
for i in range(param.size()):
|
||||
Global._gdpd.add_float(param[i])
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_preset(prs):
|
||||
preset = prs
|
||||
Global._gdpd.start_message(2)
|
||||
Global._gdpd.add_symbol("preset")
|
||||
Global._gdpd.add_float(prs)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
func set_color(color):
|
||||
$MeshInstance.material_override = SpatialMaterial.new()
|
||||
$MeshInstance.material_override.albedo_color = color
|
||||
|
||||
func _ready():
|
||||
# save patch (for export)
|
||||
if use_embeded_patch:
|
||||
assert(_my_patch.substr(0, 7) == "user://", "use userpath with embeded_patch enabled !")
|
||||
assert(patch != "", "patch is empty?")
|
||||
_save_patch()
|
||||
|
||||
# load patch
|
||||
_my_id = Global.load_patch(ProjectSettings.globalize_path(_my_patch))
|
||||
|
||||
# listen 'player_transform_updated' event
|
||||
Events.connect("player_transform_updated", self, "_on_Events_player_transform_updated")
|
||||
|
||||
# send 'preset'
|
||||
set_preset(preset)
|
||||
|
||||
func _on_Events_player_transform_updated(playerpos, playerheading):
|
||||
var mypos = get_global_translation()
|
||||
var mypos2d = Vector2(mypos.x, mypos.z)
|
||||
var playerpos2d = Vector2(playerpos.x, playerpos.z)
|
||||
# calculate distance
|
||||
var distance = mypos.distance_to(playerpos)
|
||||
# calculate angle
|
||||
var angle = fmod(fmod(playerpos2d.angle_to_point(mypos2d) + playerheading - PI/2, PI*2) + PI*2, PI*2)
|
||||
if angle > PI:
|
||||
angle = angle - PI*2
|
||||
# (check)
|
||||
# print(str(_my_id) +" : ("+ str(distance) +","+ str(angle) +")")
|
||||
# calculate gain
|
||||
var gain = 1 - distance/audible_range_max
|
||||
# send to the patch
|
||||
Global._gdpd.start_message(3)
|
||||
Global._gdpd.add_symbol("panvol")
|
||||
Global._gdpd.add_float(gain)
|
||||
Global._gdpd.add_float(angle)
|
||||
Global._gdpd.finish_list("fromGodot" + String(_my_id))
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
Global.close_patch(_my_id)
|
||||
|
||||
func _save_patch():
|
||||
# save patch
|
||||
# prepare directory
|
||||
var patch_name = _my_patch.split("/")[-1]
|
||||
var patch_dir = _my_patch.trim_suffix(patch_name)
|
||||
var dir = Directory.new()
|
||||
dir.make_dir_recursive(patch_dir)
|
||||
# save to file
|
||||
var file = File.new()
|
||||
file.open(_my_patch, File.WRITE)
|
||||
file.store_string(patch)
|
||||
file.close()
|
||||
78
GdpdExample/osc.pd
Normal file
78
GdpdExample/osc.pd
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#N canvas 659 277 456 518 12;
|
||||
#X obj 361 21 loadbang;
|
||||
#X msg 361 51 \; pd dsp 1;
|
||||
#X obj 50 277 osc~ 440;
|
||||
#X floatatom 21 198 5 0 0 0 - - - 0;
|
||||
#X obj 21 22 r fromGodot\$0;
|
||||
#X obj 21 46 list trim;
|
||||
#X obj 199 467 dac~ 1 2;
|
||||
#X obj 199 407 *~;
|
||||
#X obj 189 127 unpack f f;
|
||||
#X obj 21 70 route freq gain panvol;
|
||||
#X obj 50 301 *~;
|
||||
#X obj 189 264 line~;
|
||||
#X msg 189 240 \$1 100;
|
||||
#X floatatom 189 177 5 0 0 0 - - - 0;
|
||||
#X obj 132 310 switch~;
|
||||
#X obj 132 286 tgl 19 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 132 262 change;
|
||||
#X text 89 155 switch on/off before 0 to stop startup pops, f 12;
|
||||
#X obj 189 216 max 0;
|
||||
#X obj 132 238 > -0.3;
|
||||
#X obj 303 253 hsl 100 20 -1 1 0 0 empty empty empty -2 -10 0 12 #fcfcfc #000000 #000000 0 1;
|
||||
#X obj 300 349 line~;
|
||||
#X msg 300 325 \$1 100;
|
||||
#X obj 300 278 expr ($f1 + 1)/8;
|
||||
#X floatatom 300 302 5 0 0 0 - - - 0;
|
||||
#N canvas 68 97 450 300 pan2~ 0;
|
||||
#X obj 51 98 cos~;
|
||||
#X obj 111 98 cos~;
|
||||
#X obj 33 128 *~;
|
||||
#X obj 93 128 *~;
|
||||
#X obj 33 158 outlet~;
|
||||
#X obj 93 158 outlet~;
|
||||
#X obj 33 24 inlet~;
|
||||
#X obj 111 24 inlet~;
|
||||
#X obj 111 74 +~ 0.75;
|
||||
#X connect 0 0 2 1;
|
||||
#X connect 1 0 3 1;
|
||||
#X connect 2 0 4 0;
|
||||
#X connect 3 0 5 0;
|
||||
#X connect 6 0 2 0;
|
||||
#X connect 6 0 3 0;
|
||||
#X connect 7 0 8 0;
|
||||
#X connect 7 0 0 0;
|
||||
#X connect 8 0 1 0;
|
||||
#X restore 199 437 pd pan2~;
|
||||
#X floatatom 296 159 5 0 0 0 - - - 0;
|
||||
#X obj 296 182 sin;
|
||||
#X floatatom 296 206 5 0 0 0 - - - 0;
|
||||
#X connect 2 0 10 0;
|
||||
#X connect 3 0 2 0;
|
||||
#X connect 4 0 5 0;
|
||||
#X connect 5 0 9 0;
|
||||
#X connect 7 0 25 0;
|
||||
#X connect 8 0 13 0;
|
||||
#X connect 8 1 26 0;
|
||||
#X connect 9 0 3 0;
|
||||
#X connect 9 1 10 1;
|
||||
#X connect 9 2 8 0;
|
||||
#X connect 10 0 7 0;
|
||||
#X connect 11 0 7 1;
|
||||
#X connect 12 0 11 0;
|
||||
#X connect 13 0 18 0;
|
||||
#X connect 13 0 19 0;
|
||||
#X connect 15 0 14 0;
|
||||
#X connect 16 0 15 0;
|
||||
#X connect 18 0 12 0;
|
||||
#X connect 19 0 16 0;
|
||||
#X connect 20 0 23 0;
|
||||
#X connect 21 0 25 1;
|
||||
#X connect 22 0 21 0;
|
||||
#X connect 23 0 24 0;
|
||||
#X connect 24 0 22 0;
|
||||
#X connect 25 0 6 0;
|
||||
#X connect 25 1 6 1;
|
||||
#X connect 26 0 27 0;
|
||||
#X connect 27 0 28 0;
|
||||
#X connect 28 0 20 0;
|
||||
23
GdpdExample/osc.tscn
Normal file
23
GdpdExample/osc.tscn
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://osc.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id=3]
|
||||
|
||||
[sub_resource type="SphereShape" id=1]
|
||||
|
||||
[sub_resource type="SphereMesh" id=2]
|
||||
resource_local_to_scene = true
|
||||
|
||||
[node name="osc" type="RigidBody" groups=["sounders"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
physics_material_override = SubResource( 3 )
|
||||
gravity_scale = 0.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
mesh = SubResource( 2 )
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#N canvas 2 88 450 300 12;
|
||||
#X obj 344 82 s pd;
|
||||
#X obj 344 31 loadbang;
|
||||
#X msg 344 55 dsp 1;
|
||||
#X obj 152 134 dac~;
|
||||
#X obj 152 86 osc~ 440;
|
||||
#X obj 152 110 *~ 0.1;
|
||||
#X connect 1 0 2 0;
|
||||
#X connect 2 0 0 0;
|
||||
#X connect 4 0 5 0;
|
||||
#X connect 5 0 3 0;
|
||||
#X connect 5 0 3 1;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#N canvas 2 88 450 300 12;
|
||||
#X obj 344 82 s pd;
|
||||
#X obj 344 31 loadbang;
|
||||
#X msg 344 55 dsp 1;
|
||||
#X obj 152 134 dac~;
|
||||
#X obj 152 110 *~ 0.1;
|
||||
#X obj 152 86 osc~ 600;
|
||||
#X connect 1 0 2 0;
|
||||
#X connect 2 0 0 0;
|
||||
#X connect 4 0 3 0;
|
||||
#X connect 4 0 3 1;
|
||||
#X connect 5 0 4 0;
|
||||
|
|
@ -8,20 +8,59 @@
|
|||
|
||||
config_version=4
|
||||
|
||||
_global_script_classes=[ ]
|
||||
_global_script_class_icons={
|
||||
|
||||
}
|
||||
|
||||
[application]
|
||||
|
||||
config/name="GdpdExample"
|
||||
run/main_scene="res://Main.tscn"
|
||||
config/name="Sands and Waves (worldscene1)"
|
||||
run/main_scene="res://Scene.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[autoload]
|
||||
|
||||
Global="*res://autoload/Global.tscn"
|
||||
Events="*res://autoload/Events.tscn"
|
||||
|
||||
[gui]
|
||||
|
||||
common/drop_mouse_on_gui_input_disabled=true
|
||||
|
||||
[input]
|
||||
|
||||
move_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_forward={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_backward={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
toggle_mouse={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[layer_names]
|
||||
|
||||
3d_physics/layer_1="world"
|
||||
3d_physics/layer_2="player"
|
||||
3d_physics/layer_3="sounder"
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
||||
[rendering]
|
||||
|
||||
quality/driver/driver_name="GLES2"
|
||||
vram_compression/import_etc=true
|
||||
vram_compression/import_etc2=false
|
||||
environment/default_environment="res://default_env.tres"
|
||||
|
|
|
|||
170
SConstruct
170
SConstruct
|
|
@ -7,18 +7,20 @@ opts = Variables([], ARGUMENTS)
|
|||
env = DefaultEnvironment()
|
||||
|
||||
# Define our options
|
||||
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release']))
|
||||
opts.Add(EnumVariable('target', "Compilation target", 'release', ['d', 'debug', 'r', 'release']))
|
||||
opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
|
||||
opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", '', ['', 'windows', 'x11', 'linux', 'osx']))
|
||||
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
|
||||
opts.Add(BoolVariable('use_mingw', "Use the MingW for cross-compiling", 'no'))
|
||||
opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'GdpdExample/addons/gdpd/bin/'))
|
||||
opts.Add(PathVariable('target_name', 'The library name.', 'libgdpd', PathVariable.PathAccept))
|
||||
opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"]))
|
||||
|
||||
# Local dependency paths, adapt them to your setup
|
||||
godot_headers_path = "src/godot-cpp/godot_headers/"
|
||||
godot_headers_path = "src/godot-cpp/godot-headers/"
|
||||
cpp_bindings_path = "src/godot-cpp/"
|
||||
cpp_library = "libgodot-cpp"
|
||||
earplug_headers_path = "src/externals/earplug/"
|
||||
|
||||
# only support 64 at this time..
|
||||
bits = 64
|
||||
|
|
@ -52,15 +54,24 @@ if env['platform'] == "osx":
|
|||
env['target_path'] += 'osx/'
|
||||
cpp_library += '.osx'
|
||||
env.Append(CPPDEFINES=['__MACOSX_CORE__', 'HAVE_UNISTD_H', 'LIBPD_EXTRA'])
|
||||
env.Append(CXXFLAGS=['-std=c++17'])
|
||||
env.Append(LINKFLAGS=['-arch', 'x86_64','-framework',
|
||||
'CoreAudio', '-framework', 'CoreFoundation'])
|
||||
if env['target'] in ('debug', 'd'):
|
||||
env.Append(CCFLAGS=['-g', '-O2', '-arch', 'x86_64'])
|
||||
|
||||
if env["macos_arch"] == "universal":
|
||||
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
||||
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-g', '-O3', '-arch', 'x86_64'])
|
||||
env.Append(LINKFLAGS=["-arch", env["macos_arch"]])
|
||||
env.Append(CCFLAGS=["-arch", env["macos_arch"]])
|
||||
|
||||
env.Append(LINKFLAGS=['-framework', 'CoreAudio', '-framework', 'CoreFoundation'])
|
||||
env.Append(CXXFLAGS=['-std=c++17'])
|
||||
if env['target'] in ('debug', 'd'):
|
||||
env.Append(CCFLAGS=['-g', '-O2'])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-g', '-O3'])
|
||||
|
||||
elif env['platform'] in ('x11', 'linux'):
|
||||
env['CC'] = 'gcc-7'
|
||||
env['CXX'] = 'g++-7'
|
||||
env['target_path'] += 'x11/'
|
||||
cpp_library += '.linux'
|
||||
env.Append(CPPDEFINES=['__UNIX_JACK__', 'LIBPD_EXTRA'])
|
||||
|
|
@ -70,7 +81,7 @@ elif env['platform'] in ('x11', 'linux'):
|
|||
env.Append(CFLAGS=['-std=c11'])
|
||||
env.Append(CXXFLAGS=['-std=c++17'])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-fPIC', '-g', '-O3'])
|
||||
env.Append(CCFLAGS=['-fPIC', '-O3'])
|
||||
env.Append(CFLAGS=['-std=c11'])
|
||||
env.Append(CXXFLAGS=['-std=c++17'])
|
||||
|
||||
|
|
@ -83,34 +94,40 @@ elif env['platform'] == "windows":
|
|||
# MSVC
|
||||
env.Append(LINKFLAGS=['/WX'])
|
||||
if env['target'] == 'debug':
|
||||
env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MDd'])
|
||||
env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MTd'])
|
||||
elif env['target'] == 'release':
|
||||
env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
|
||||
else:
|
||||
# MinGW
|
||||
env['CXX'] = 'x86_64-w64-mingw32-g++-win32'
|
||||
env['CC'] = 'x86_64-w64-mingw32-gcc-win32'
|
||||
env.Append(CCFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings', '-fpermissive'])
|
||||
#env.Append(CXXFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings', '-fpermissive'])
|
||||
env.Append(CXXFLAGS=['-O3', '-std=c++14', '-Wwrite-strings', '-fpermissive'])
|
||||
#env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
|
||||
#env.Append(CPPDEFINES=['WIN32', '_WIN32', '_MSC_VER', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
|
||||
env.Append(CFLAGS=['-DWINVER=0x502','-DWIN32','-D_WIN32','-Wno-int-to-pointer-cast',
|
||||
'-Wno-pointer-to-int-cast'])
|
||||
env.Append(CPPDEFINES=['HAVE_UNISTD_H=1','LIBPD_EXTRA=1','PD=1',
|
||||
'PD_INTERNAL','USEAPI_DUMMY=1','libpd_EXPORTS'])
|
||||
#env.Append(CPPDEFINES=['__WINDOWS_DS__', 'LIBPD_EXTRA'])
|
||||
env.Append(CPPDEFINES=['__RTAUDIO_DUMMY__', 'LIBPD_EXTRA'])
|
||||
env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
|
||||
env.Append(CFLAGS=['-DWINVER=0x502', '-DWIN32', '-D_WIN32',
|
||||
'-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast'])
|
||||
#env.Append(CPPDEFINES=['HAVE_UNISTD_H=1','LIBPD_EXTRA=1','PD=1',
|
||||
#'PD_INTERNAL','USEAPI_DUMMY=1','libpd_EXPORTS'])
|
||||
env.Append(CPPDEFINES=['PD_INTERNAL', 'libpd_EXPORTS'])
|
||||
env.Append(CPPDEFINES=['__WINDOWS_DS__'])
|
||||
#env.Append(CPPDEFINES=['__WINDOWS_WASAPI__'])
|
||||
#env.Append(CPPDEFINES=['__RTAUDIO_DUMMY__', 'LIBPD_EXTRA'])
|
||||
#env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
|
||||
env.Append(LDPATH=['/usr/x86_64-w64-mingw32/lib/'])
|
||||
env.Append(LINKFLAGS=['-Wl,--export-all-symbols',
|
||||
'-static-libgcc','/usr/x86_64-w64-mingw32/lib/libm.a'])
|
||||
|
||||
#env.Append(LINKFLAGS=['-lkernel32','-luser32', '-lgdi32',
|
||||
# '-lwinspool', '-lshell32', '-lole32',
|
||||
# '-loleaut32', '-luuid', '-lcomdlg32',
|
||||
# '-ladvapi32','-lws2_32', '-lwsock32'])
|
||||
env.Append(LINKFLAGS=['/usr/x86_64-w64-mingw32/lib/libws2_32.a',
|
||||
'/usr/x86_64-w64-mingw32/lib/libwsock32.a'])
|
||||
|
||||
#env.Append(LIBS=['-lkernel32','-luser32', '-lgdi32',
|
||||
# '-lwinspool', '-lshell32', '-lole32',
|
||||
# '-loleaut32', '-luuid', '-lcomdlg32',
|
||||
# '-ladvapi32','-lws2_32', '-lwsock32',
|
||||
# '-ldsound', '-lwinmm'])
|
||||
env.Append(LIBS=['-lws2_32', '-lwsock32','-loleaut32', '-luuid',
|
||||
'-lole32', '-ldsound', '-lwinmm'])
|
||||
#env.Append(LIBS=['-lws2_32', '-lwsock32','-loleaut32', '-lmfplat','-lmfuuid',
|
||||
# '-lole32', '-lwmcodecdspuuid' ,'-luuid','-lksuser'])
|
||||
env['SHLIBSUFFIX'] = '.dll'
|
||||
|
||||
#env.Append(CPPDEFINES=['WINVER=0x502'])
|
||||
#env.Append(CCFLAGS=['-W3', '-GR'])
|
||||
|
|
@ -134,7 +151,7 @@ else:
|
|||
cpp_library += '.' + str(bits)
|
||||
|
||||
# make sure our binding library is properly included
|
||||
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', 'src/libpd/cpp','src/libpd/pure-data/src', 'src/libpd/libpd_wrapper', 'src/libpd/libpd_wrapper/util', 'src/rtaudio'])
|
||||
env.Append(CPPPATH=['.', earplug_headers_path, godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', 'src/libpd/cpp', 'src/libpd/libpd_wrapper', 'src/libpd/pure-data/src', 'src/libpd/libpd_wrapper/util', 'src/rtaudio'])
|
||||
env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
|
||||
env.Append(LIBS=[cpp_library])
|
||||
env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
|
||||
|
|
@ -142,7 +159,106 @@ env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE']
|
|||
# tweak this if you want to use different folders, or more folders, to store your source code in.
|
||||
env.Append(CPPPATH=['src/'])
|
||||
|
||||
sources = Glob('src/*.cpp') + Glob('src/rtaudio/*.cpp') + Glob('src/libpd/libpd_wrapper/*.c') + Glob('src/libpd/libpd_wrapper/util/*.c') + Glob('src/libpd/pure-data/extra/**/*.c') + Glob('src/libpd/pure-data/src/[xmgz]_*.c') + Glob('src/libpd/pure-data/src/d_[acgmorsu]*.c') + Glob('src/libpd/pure-data/src/d_dac.c') + Glob('src/libpd/pure-data/src/d_delay.c') + Glob('src/libpd/pure-data/src/d_fft.c') + Glob('src/libpd/pure-data/src/d_fft_fftsg.c') + Glob('src/libpd/pure-data/src/d_filter.c') + Glob('src/libpd/pure-data/src/s_audio.c') + Glob('src/libpd/pure-data/src/s_audio_dummy.c') + Glob('src/libpd/pure-data/src/s_print.c') + Glob('src/libpd/pure-data/src/s_path.c') + Glob('src/libpd/pure-data/src/s_main.c') + Glob('src/libpd/pure-data/src/s_inter.c') + Glob('src/libpd/pure-data/src/s_utf8.c') + Glob('src/libpd/pure-data/src/s_loader.c') + Glob('src/libpd/pure-data/extra/*.c')
|
||||
# libpd src list: https://github.com/libpd/libpd/blob/d46caa4918bfe07eec08999146e496eb0f744b95/Makefile#L71
|
||||
sources = Glob('src/*.cpp') \
|
||||
+ Glob('src/externals/earplug/*.c') \
|
||||
+ Glob('src/rtaudio/*.cpp') \
|
||||
+ Glob('src/libpd/pure-data/src/d_arithmetic.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_array.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_ctl.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_dac.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_delay.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_fft.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_fft_fftsg.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_filter.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_global.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_math.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_misc.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_osc.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_resample.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_soundfile.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_soundfile_aiff.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_soundfile_caf.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_soundfile_next.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_soundfile_wave.c') \
|
||||
+ Glob('src/libpd/pure-data/src/d_ugen.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_all_guis.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_array.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_bang.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_canvas.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_clone.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_editor.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_editor_extras.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_graph.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_guiconnect.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_io.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_mycanvas.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_numbox.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_radio.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_readwrite.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_rtext.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_scalar.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_slider.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_template.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_text.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_toggle.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_traversal.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_undo.c') \
|
||||
+ Glob('src/libpd/pure-data/src/g_vumeter.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_atom.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_binbuf.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_class.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_conf.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_glob.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_memory.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_obj.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_pd.c') \
|
||||
+ Glob('src/libpd/pure-data/src/m_sched.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_audio.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_audio_dummy.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_inter.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_inter_gui.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_loader.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_main.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_net.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_path.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_print.c') \
|
||||
+ Glob('src/libpd/pure-data/src/s_utf8.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_acoustics.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_arithmetic.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_array.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_connective.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_file.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_gui.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_interface.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_list.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_midi.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_misc.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_net.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_scalar.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_text.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_time.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_vexp.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_vexp_if.c') \
|
||||
+ Glob('src/libpd/pure-data/src/x_vexp_fun.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/s_libpdmidi.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/x_libpdreceive.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/z_hooks.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/z_libpd.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/bob~/bob~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/bonk~/bonk~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/choice/choice.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/fiddle~/fiddle~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/loop~/loop~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/lrshift~/lrshift~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/pique/pique.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/pd~/pdsched.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/pd~/pd~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/sigmund~/sigmund~.c') \
|
||||
+ Glob('src/libpd/pure-data/extra/stdout/stdout.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/util/z_print_util.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/util/z_queued.c') \
|
||||
+ Glob('src/libpd/libpd_wrapper/util/ringbuffer.c')
|
||||
|
||||
library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
|
||||
|
||||
|
|
|
|||
0
main
Normal file
0
main
Normal file
1475
src/externals/earplug/earplug_data.h
vendored
Normal file
1475
src/externals/earplug/earplug_data.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
281
src/externals/earplug/earplug~.c
vendored
Normal file
281
src/externals/earplug/earplug~.c
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/* RT binaural filter: earplug~ */
|
||||
/* based on KEMAR impulse measurement */
|
||||
/* Pei Xiang, summer 2004 */
|
||||
/* Revised in fall 2006 by Jorge Castellanos */
|
||||
/* Revised in spring 2009 by Hans-Christoph Steiner to compile in the data file */
|
||||
/* Updated in 2020-2021 by Dan Wilcox & Chikashi Miyama */
|
||||
|
||||
#include "m_pd.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "earplug~.h"
|
||||
|
||||
/* impulse response data */
|
||||
#ifdef EARPLUG_DATA_NO_EMBED
|
||||
t_float earplug_impulses[368][2][128] = {{{0.0f}}};
|
||||
#else
|
||||
#include "earplug_data.h"
|
||||
#endif
|
||||
|
||||
#define VERSION "0.3.0"
|
||||
|
||||
/* these pragmas only apply to Microsoft's compiler */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */
|
||||
#pragma warning( disable : 4305 ) /* uncast const double to float */
|
||||
#endif
|
||||
|
||||
/* elevation degree: -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 */
|
||||
/* index array: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 */
|
||||
/* impulse response number: 29 31 37 37 37 37 37 31 29 23 19 13 7 1 */
|
||||
/* 0 degree response index: 0 29 60 97 134 171 208 245 276 305 328 347 360 367 */
|
||||
|
||||
static t_class *earplug_class;
|
||||
|
||||
typedef struct _earplug
|
||||
{
|
||||
t_object x_obj;
|
||||
t_outlet *left_channel;
|
||||
t_outlet *right_channel;
|
||||
|
||||
t_float azi;
|
||||
t_float ele;
|
||||
unsigned ch_L;
|
||||
unsigned ch_R;
|
||||
|
||||
t_float azimScale[13];
|
||||
unsigned int azimOffset[13];
|
||||
|
||||
t_float ir[2][128];
|
||||
t_float convBuffer[128];
|
||||
t_float (*impulses)[2][128]; /* a 3D array of 368x2x128 */
|
||||
t_float f; /* dummy float for dsp */
|
||||
int bufferPin;
|
||||
} t_earplug;
|
||||
|
||||
static t_int *earplug_perform(t_int *w)
|
||||
{
|
||||
t_earplug *x = (t_earplug *)(w[1]);
|
||||
t_float *in = (t_float *)(w[2]);
|
||||
t_float *right_out = (t_float *)(w[3]);
|
||||
t_float *left_out = (t_float *)(w[4]);
|
||||
int blocksize = (int)(w[5]);
|
||||
unsigned i;
|
||||
|
||||
|
||||
if (x->ele < 8.0) /* if elevation is less than 80 degrees... */
|
||||
{
|
||||
/* a quantized version of the elevation */
|
||||
int elevInt = (int)floor(x->ele);
|
||||
/* used as the index to the array of scaling factors for the azimuth
|
||||
(adding 4 because the lowest elevation is -4, so it starts at 0) */
|
||||
unsigned elevGridIndex = elevInt + 4;
|
||||
unsigned azimIntUp = (unsigned)(x->azi * x->azimScale[elevGridIndex+1]);
|
||||
float azimFracUp = azimIntUp + 1.0 - x->azi * x->azimScale[elevGridIndex+1];
|
||||
float azimFracUpInv = 1.0 - azimFracUp;
|
||||
float elevFracUp = x->ele - elevInt * 1.0;
|
||||
unsigned azimIntDown = (unsigned)(x->azi * x->azimScale[elevGridIndex]);
|
||||
float azimFracDown = azimIntDown + 1.0 - x->azi * x->azimScale[elevGridIndex];
|
||||
float azimFracDownInv = 1.0 - azimFracDown;
|
||||
float elevFracDown = 1.0 - elevFracUp;
|
||||
unsigned lowerIdx = x->azimOffset[elevGridIndex] + azimIntDown;
|
||||
unsigned upperIdx = x->azimOffset[elevGridIndex + 1] + azimIntUp;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
/* elevFracDown: interpolate the lower two HRIRs and multiply them by their "fraction"
|
||||
elevFracUp: interpolate the upper two HRIRs and multiply them by their "fraction" */
|
||||
x->ir[x->ch_L][i] = elevFracDown *
|
||||
(azimFracDown * x->impulses[lowerIdx][0][i] +
|
||||
azimFracDownInv * x->impulses[lowerIdx + 1][0][i]) +
|
||||
elevFracUp *
|
||||
(azimFracUp * x->impulses[upperIdx][0][i] +
|
||||
azimFracUpInv * x->impulses[upperIdx + 1][0][i]);
|
||||
|
||||
x->ir[x->ch_R][i] = elevFracDown *
|
||||
(azimFracDown * x->impulses[lowerIdx][1][i] +
|
||||
azimFracDownInv * x->impulses[lowerIdx + 1][1][i]) +
|
||||
elevFracUp *
|
||||
(azimFracUp * x->impulses[upperIdx][1][i] +
|
||||
azimFracUpInv * x->impulses[upperIdx + 1][1][i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if elevation is 80 degrees or more the interpolation requires only
|
||||
three points (because there's only one HRIR at 90 deg) */
|
||||
|
||||
/* scale the azimuth to 12 (the number of HRIRs at 80 deg) discreet points */
|
||||
unsigned azimIntDown = (unsigned)(x->azi * 0.033333);
|
||||
float azimFracDown = azimIntDown + 1.0 - x->azi * 0.033333;
|
||||
float elevFracUp = x->ele - 8.0;
|
||||
float elevFracDown = 9.0 - x->ele;
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
/* elevFracDown: these two lines interpolate the lower two HRIRs
|
||||
elevFracUp: multiply the 90 degree HRIR with its corresponding fraction */
|
||||
x->ir[x->ch_L][i] = elevFracDown *
|
||||
(azimFracDown * x->impulses[360+azimIntDown][0][i] +
|
||||
(1.0 - azimFracDown) * x->impulses[361+azimIntDown][0][i])
|
||||
+ elevFracUp * x->impulses[367][0][i];
|
||||
x->ir[x->ch_R][i] = elevFracDown *
|
||||
(azimFracDown * x->impulses[360+azimIntDown][1][i] +
|
||||
(1.0 - azimFracDown) * x->impulses[361+azimIntDown][1][i])
|
||||
+ elevFracUp * x->impulses[367][1][i];
|
||||
}
|
||||
}
|
||||
|
||||
float inSample;
|
||||
float convSum[2]; /* to accumulate the sum during convolution */
|
||||
|
||||
/* convolve the interpolated HRIRs (left and right) with the input signal */
|
||||
while (blocksize--)
|
||||
{
|
||||
convSum[0] = 0;
|
||||
convSum[1] = 0;
|
||||
|
||||
inSample = *(in++);
|
||||
|
||||
x->convBuffer[x->bufferPin] = inSample;
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
convSum[0] += x->ir[0][i] * x->convBuffer[(x->bufferPin - i) &127];
|
||||
convSum[1] += x->ir[1][i] * x->convBuffer[(x->bufferPin - i) &127];
|
||||
}
|
||||
|
||||
x->bufferPin = (x->bufferPin + 1) & 127;
|
||||
|
||||
*left_out++ = convSum[0];
|
||||
*right_out++ = convSum[1];
|
||||
}
|
||||
return w + 6;
|
||||
}
|
||||
|
||||
static void earplug_azimuth(t_earplug *x, float value) {
|
||||
if (value < 0 || value > 360)
|
||||
value = 0;
|
||||
if (value <= 180){
|
||||
x->ch_L = 0;
|
||||
x->ch_R = 1;
|
||||
}
|
||||
else{
|
||||
x->ch_L = 1;
|
||||
x->ch_R = 0;
|
||||
value = 360.0 - value;
|
||||
}
|
||||
x->azi = value;
|
||||
}
|
||||
|
||||
static void earplug_elevation(t_earplug *x, float value) {
|
||||
|
||||
if (value < -40)
|
||||
value = -40;
|
||||
if (value > 90)
|
||||
value = 90;
|
||||
/* divided by 10 since each elevation is 10 degrees apart */
|
||||
x->ele = value * 0.1;
|
||||
}
|
||||
|
||||
static void earplug_dsp(t_earplug *x, t_signal **sp)
|
||||
{
|
||||
/* callback, params, userdata, in_samples, out_L, out_R, blocksize */
|
||||
dsp_add(earplug_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void *earplug_new(t_floatarg azimArg, t_floatarg elevArg)
|
||||
{
|
||||
t_earplug *x = (t_earplug *)pd_new(earplug_class);
|
||||
x->left_channel = outlet_new(&x->x_obj, gensym("signal"));
|
||||
x->right_channel = outlet_new(&x->x_obj, gensym("signal"));
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("azimuth"));
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("elevation"));
|
||||
|
||||
x->azi = azimArg;
|
||||
x->ele = elevArg;
|
||||
x->ch_L = 0;
|
||||
x->ch_R = 1;
|
||||
|
||||
int i, j;
|
||||
FILE *fp;
|
||||
t_symbol *canvasdir = canvas_getdir(canvas_getcurrent());
|
||||
char buff[MAXPDSTRING], *bufptr;
|
||||
int filedesc;
|
||||
|
||||
filedesc = open_via_path(canvasdir->s_name, "earplug_data.txt", "", buff, &bufptr, MAXPDSTRING, 0);
|
||||
if (filedesc >= 0) /* if there was no error opening the text file... */
|
||||
{
|
||||
int ret;
|
||||
fp = fdopen(filedesc, "r");
|
||||
for (i = 0; i < 368; i++)
|
||||
{
|
||||
do {ret = fgetc(fp);}
|
||||
while (ret != 10 && ret != EOF);
|
||||
if (ret != EOF)
|
||||
{
|
||||
for (j = 0; j < 128; j++)
|
||||
{
|
||||
ret = fscanf(fp, "%f %f ", &earplug_impulses[i][0][j],
|
||||
&earplug_impulses[i][1][j]);
|
||||
if (ret == EOF) {break;}
|
||||
}
|
||||
}
|
||||
if (ret == EOF)
|
||||
{
|
||||
pd_error(x, "earplug~: could not load %s/earplug_data.txt, check format?", buff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
if (ret != EOF) {logpost(x, 3, "earplug~: loaded %s/earplug_data.txt", buff);}
|
||||
}
|
||||
x->impulses = earplug_impulses;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
x->convBuffer[i] = 0.f;
|
||||
x->bufferPin = 0;
|
||||
|
||||
/* this is the scaling factor for the azimuth so that it
|
||||
corresponds to an HRTF in the KEMAR database */
|
||||
x->azimScale[0] = x->azimScale[8] = 0.153846153; /* -40 and 40 degree */
|
||||
x->azimScale[1] = x->azimScale[7] = 0.166666666; /* -30 and 30 degree */
|
||||
x->azimScale[2] = x->azimScale[3] = x->azimScale[4]
|
||||
= x->azimScale[5] = x->azimScale[6] = 0.2; /* -20 to 20 degree */
|
||||
x->azimScale[9] = 0.125; /* 50 degree */
|
||||
x->azimScale[10] = 0.1; /* 60 degree */
|
||||
x->azimScale[11] = 0.066666666; /* 70 degree */
|
||||
x->azimScale[12] = 0.033333333; /* 80 degree */
|
||||
|
||||
x->azimOffset[0] = 0;
|
||||
x->azimOffset[1] = 29;
|
||||
x->azimOffset[2] = 60;
|
||||
x->azimOffset[3] = 97;
|
||||
x->azimOffset[4] = 134;
|
||||
x->azimOffset[5] = 171;
|
||||
x->azimOffset[6] = 208;
|
||||
x->azimOffset[7] = 245;
|
||||
x->azimOffset[8] = 276;
|
||||
x->azimOffset[9] = 305;
|
||||
x->azimOffset[10] = 328;
|
||||
x->azimOffset[11] = 347;
|
||||
x->azimOffset[12] = 360;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void earplug_tilde_setup(void)
|
||||
{
|
||||
earplug_class = class_new(gensym("earplug~"), (t_newmethod)earplug_new, 0,
|
||||
sizeof(t_earplug), CLASS_DEFAULT, A_DEFFLOAT, A_DEFFLOAT, 0);
|
||||
|
||||
CLASS_MAINSIGNALIN(earplug_class, t_earplug, f);
|
||||
|
||||
class_addmethod(earplug_class, (t_method)earplug_dsp, gensym("dsp"), A_CANT, 0);
|
||||
class_addmethod(earplug_class, (t_method)earplug_azimuth, gensym("azimuth"), A_FLOAT, 0);
|
||||
class_addmethod(earplug_class, (t_method)earplug_elevation, gensym("elevation"), A_FLOAT, 0);
|
||||
|
||||
post("earplug~ %s: binaural filter with measured responses", VERSION);
|
||||
post(" elevation: -40 to 90 degrees, azimuth: 360 degrees");
|
||||
post(" do not use a blocksize > 8192");
|
||||
}
|
||||
16
src/externals/earplug/earplug~.h
vendored
Normal file
16
src/externals/earplug/earplug~.h
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __EARPLUG_H__
|
||||
#define __EARPLUG_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
EXTERN void earplug_tilde_setup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
398
src/gdpd.cpp
398
src/gdpd.cpp
|
|
@ -3,35 +3,40 @@
|
|||
using namespace godot;
|
||||
|
||||
void Gdpd::_register_methods() {
|
||||
register_method("get_available_input_devices",
|
||||
&Gdpd::get_available_input_devices);
|
||||
register_method("get_available_output_devices",
|
||||
&Gdpd::get_available_output_devices);
|
||||
register_method("init_devices", &Gdpd::init_devices);
|
||||
register_method("init", &Gdpd::init);
|
||||
register_method("stop", &Gdpd::stop);
|
||||
register_method("openfile", &Gdpd::openfile);
|
||||
register_method("closefile", &Gdpd::closefile);
|
||||
register_method("subscribe", &Gdpd::subscribe);
|
||||
register_method("has_message", &Gdpd::has_message);
|
||||
register_method("get_next", &Gdpd::get_next);
|
||||
register_method("start_message", &Gdpd::start_message);
|
||||
register_method("add_symbol", &Gdpd::add_symbol);
|
||||
register_method("add_float", &Gdpd::add_float);
|
||||
register_method("finish_list", &Gdpd::finish_list);
|
||||
register_method("set_volume", &Gdpd::set_volume);
|
||||
register_method("get_available_input_devices", &Gdpd::get_available_input_devices);
|
||||
register_method("get_available_output_devices", &Gdpd::get_available_output_devices);
|
||||
register_method("init_devices", &Gdpd::init_devices);
|
||||
register_method("init", &Gdpd::init);
|
||||
register_method("streamstart", &Gdpd::streamstart);
|
||||
register_method("stop", &Gdpd::stop);
|
||||
register_method("openPatch", &Gdpd::openPatch);
|
||||
register_method("closePatch", &Gdpd::closePatch);
|
||||
register_method("subscribe", &Gdpd::subscribe);
|
||||
register_method("has_message", &Gdpd::has_message);
|
||||
register_method("get_next", &Gdpd::get_next);
|
||||
register_method("start_message", &Gdpd::start_message);
|
||||
register_method("add_symbol", &Gdpd::add_symbol);
|
||||
register_method("add_float", &Gdpd::add_float);
|
||||
register_method("finish_list", &Gdpd::finish_list);
|
||||
register_method("computeAudio", &Gdpd::computeAudio);
|
||||
register_method("set_volume", &Gdpd::set_volume);
|
||||
register_method("set_gui_path", &Gdpd::set_gui_path);
|
||||
register_method("set_verbose", &Gdpd::set_verbose);
|
||||
}
|
||||
|
||||
int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData){
|
||||
Gdpd* gdpd = static_cast<Gdpd*>(userData);
|
||||
gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime,
|
||||
status, userData);
|
||||
return 0;
|
||||
int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData){
|
||||
Gdpd* gdpd = static_cast<Gdpd*>(userData);
|
||||
gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime,
|
||||
status, userData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Gdpd::Gdpd(): m_vol(1) {
|
||||
Gdpd::Gdpd() : m_vol(0), m_gui_path(""), m_verbose(false) {
|
||||
//create message array
|
||||
m_messages = new Array();
|
||||
m_init=false;
|
||||
}
|
||||
|
||||
void Gdpd::_init() {
|
||||
|
|
@ -39,229 +44,280 @@ void Gdpd::_init() {
|
|||
}
|
||||
|
||||
Gdpd::~Gdpd() {
|
||||
|
||||
}
|
||||
|
||||
Array Gdpd::get_available_input_devices() {
|
||||
Array gdlist;
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
if(m_audio.getDeviceInfo(d).inputChannels>0) {
|
||||
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
|
||||
}
|
||||
}
|
||||
return gdlist;
|
||||
Array gdlist;
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
if(m_audio.getDeviceInfo(d).inputChannels>0) {
|
||||
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
|
||||
}
|
||||
}
|
||||
return gdlist;
|
||||
}
|
||||
|
||||
Array Gdpd::get_available_output_devices() {
|
||||
Array gdlist;
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
if(m_audio.getDeviceInfo(d).outputChannels>0) {
|
||||
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
|
||||
}
|
||||
}
|
||||
return gdlist;
|
||||
Array gdlist;
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
if(m_audio.getDeviceInfo(d).outputChannels>0) {
|
||||
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
|
||||
}
|
||||
}
|
||||
return gdlist;
|
||||
}
|
||||
|
||||
|
||||
int Gdpd::init_devices(String inputDevice, String outputDevice) {
|
||||
std::wstring inpWs = inputDevice.unicode_str();
|
||||
std::string inpStr(inpWs.begin(), inpWs.end());
|
||||
std::wstring outWs = outputDevice.unicode_str();
|
||||
std::string outStr(outWs.begin(), outWs.end());
|
||||
std::wstring inpWs = inputDevice.unicode_str();
|
||||
std::string inpStr(inpWs.begin(), inpWs.end());
|
||||
std::wstring outWs = outputDevice.unicode_str();
|
||||
std::string outStr(outWs.begin(), outWs.end());
|
||||
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
std::string n = m_audio.getDeviceInfo(d).name;
|
||||
if(n.compare(inpStr)==0) {
|
||||
m_inputDevice = d;
|
||||
}
|
||||
if(n.compare(outStr)==0) {
|
||||
m_outputDevice = d;
|
||||
}
|
||||
}
|
||||
for(int d=0; d<m_audio.getDeviceCount(); d++) {
|
||||
std::string n = m_audio.getDeviceInfo(d).name;
|
||||
if(n.compare(inpStr)==0) {
|
||||
m_inputDevice = d;
|
||||
}
|
||||
if(n.compare(outStr)==0) {
|
||||
m_outputDevice = d;
|
||||
}
|
||||
}
|
||||
|
||||
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
|
||||
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
|
||||
m_nbInputs = inpInfo.inputChannels;
|
||||
m_nbOutputs = outInfo.outputChannels;
|
||||
m_sampleRate = outInfo.preferredSampleRate;
|
||||
m_bufferFrames = 128;
|
||||
return start();
|
||||
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
|
||||
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
|
||||
m_nbInputs = inpInfo.inputChannels;
|
||||
m_nbOutputs = outInfo.outputChannels;
|
||||
m_sampleRate = outInfo.preferredSampleRate;
|
||||
m_bufferFrames = 128;
|
||||
return start();
|
||||
}
|
||||
|
||||
int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
|
||||
m_inputDevice = m_audio.getDefaultInputDevice();
|
||||
m_outputDevice = m_audio.getDefaultOutputDevice();
|
||||
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
|
||||
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
|
||||
m_nbInputs = std::min<int>(nbInputs, inpInfo.inputChannels);
|
||||
m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels);
|
||||
m_sampleRate = sampleRate;
|
||||
m_bufferFrames = std::max<int>(64, bufferSize);
|
||||
return start();
|
||||
m_inputDevice = m_audio.getDefaultInputDevice();
|
||||
m_outputDevice = m_audio.getDefaultOutputDevice();
|
||||
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
|
||||
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
|
||||
m_nbInputs = std::min<int>(nbInputs, inpInfo.inputChannels);
|
||||
m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels);
|
||||
m_sampleRate = sampleRate;
|
||||
m_bufferFrames = std::max<int>(64, bufferSize);
|
||||
return start();
|
||||
}
|
||||
|
||||
int Gdpd::start() {
|
||||
RtAudio::StreamParameters outParams, inpParams;
|
||||
inpParams.deviceId = m_inputDevice;
|
||||
inpParams.nChannels = m_nbInputs;
|
||||
outParams.deviceId = m_outputDevice;
|
||||
outParams.nChannels = m_nbOutputs;
|
||||
print("Output channels = "+std::to_string(outParams.nChannels));
|
||||
print("Input channels = "+std::to_string(inpParams.nChannels));
|
||||
RtAudio::StreamParameters outParams, inpParams;
|
||||
inpParams.deviceId = m_inputDevice;
|
||||
inpParams.nChannels = m_nbInputs;
|
||||
outParams.deviceId = m_outputDevice;
|
||||
outParams.nChannels = m_nbOutputs;
|
||||
print("Output channels = "+std::to_string(outParams.nChannels));
|
||||
print("Input channels = "+std::to_string(inpParams.nChannels));
|
||||
|
||||
if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) {
|
||||
print("GDPD : Error starting libpd");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) {
|
||||
Godot::print("GDPD : Error starting libpd");
|
||||
return 1;
|
||||
}
|
||||
//libpd_set_verbose(1);
|
||||
|
||||
//libpd_set_verbose(1);
|
||||
if (m_gui_path != "") {
|
||||
libpd_start_gui((char*)m_gui_path.c_str());
|
||||
}
|
||||
|
||||
//create message array
|
||||
m_messages = new Array();
|
||||
//load externals
|
||||
//earplug~
|
||||
earplug_tilde_setup();
|
||||
|
||||
//create message hook
|
||||
m_pd.subscribe("to_gdpd");
|
||||
m_pd.setReceiver(this);
|
||||
//start dsp
|
||||
// m_pd.computeAudio(true);
|
||||
|
||||
//start dsp
|
||||
m_pd.computeAudio(true);
|
||||
//intialize rtaudio
|
||||
if(m_audio.getDeviceCount()==0){
|
||||
Godot::print("There are no available sound devices.");
|
||||
}
|
||||
|
||||
//intialize rtaudio
|
||||
if(m_audio.getDeviceCount()==0){
|
||||
Godot::print("There are no available sound devices.");
|
||||
}
|
||||
RtAudio::StreamOptions options;
|
||||
options.streamName = "gdpd";
|
||||
options.flags = RTAUDIO_SCHEDULE_REALTIME;
|
||||
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
|
||||
options.flags |= RTAUDIO_MINIMIZE_LATENCY;
|
||||
}
|
||||
if (m_nbInputs == 0) {
|
||||
try {
|
||||
m_audio.openStream(&outParams, NULL, RTAUDIO_FLOAT32,
|
||||
m_sampleRate, &m_bufferFrames, &audioCallback,
|
||||
this, &options);
|
||||
// m_audio.startStream();
|
||||
// print("Stream started");
|
||||
}
|
||||
catch(RtAudioError& e) {
|
||||
Godot::print(e.getMessage().c_str());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32,
|
||||
m_sampleRate, &m_bufferFrames, &audioCallback,
|
||||
this, &options);
|
||||
// m_audio.startStream();
|
||||
// print("Stream started");
|
||||
}
|
||||
catch(RtAudioError& e) {
|
||||
Godot::print(e.getMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
RtAudio::StreamOptions options;
|
||||
options.streamName = "gdpd";
|
||||
options.flags = RTAUDIO_SCHEDULE_REALTIME;
|
||||
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
|
||||
options.flags |= RTAUDIO_MINIMIZE_LATENCY;
|
||||
}
|
||||
try {
|
||||
m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32,
|
||||
m_sampleRate, &m_bufferFrames, &audioCallback,
|
||||
this, &options);
|
||||
m_audio.startStream();
|
||||
}
|
||||
catch(RtAudioError& e) {
|
||||
Godot::print(e.getMessage().c_str());
|
||||
}
|
||||
//create message hook
|
||||
m_pd.subscribe("to_gdpd");
|
||||
m_pd.setReceiver(this);
|
||||
m_init=true;
|
||||
|
||||
print("Initialized");
|
||||
|
||||
print("Initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
void Gdpd::streamstart() {
|
||||
m_audio.startStream();
|
||||
print("Stream started");
|
||||
}
|
||||
|
||||
void Gdpd::stop() {
|
||||
m_audio.stopStream();
|
||||
m_audio.closeStream();
|
||||
m_pd.clear();
|
||||
m_pd.computeAudio(false);
|
||||
print("Stopped");
|
||||
m_audio.stopStream();
|
||||
m_audio.closeStream();
|
||||
m_pd.computeAudio(false);
|
||||
print("Stopped");
|
||||
|
||||
if (m_gui_path != "") {
|
||||
libpd_stop_gui();
|
||||
}
|
||||
}
|
||||
|
||||
void Gdpd::processAudio(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData) {
|
||||
int ticks = nBufferFrames / libpd_blocksize();
|
||||
void Gdpd::processAudio(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData) {
|
||||
int ticks = nBufferFrames / libpd_blocksize();
|
||||
|
||||
m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer);
|
||||
m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer);
|
||||
|
||||
//volume control on the output
|
||||
for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) {
|
||||
((float*)outputBuffer)[b]*=m_vol;
|
||||
}
|
||||
//volume control on the output
|
||||
for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) {
|
||||
((float*)outputBuffer)[b]*=m_vol;
|
||||
}
|
||||
}
|
||||
|
||||
void Gdpd::openfile(godot::String baseStr, godot::String dirStr) {
|
||||
std::wstring baseWs = baseStr.unicode_str();
|
||||
std::string baseS(baseWs.begin(), baseWs.end());
|
||||
std::wstring dirWs = dirStr.unicode_str();
|
||||
std::string dirS(dirWs.begin(), dirWs.end());
|
||||
int Gdpd::openPatch(godot::String baseStr, godot::String dirStr) {
|
||||
std::wstring baseWs = baseStr.unicode_str();
|
||||
std::string baseS(baseWs.begin(), baseWs.end());
|
||||
std::wstring dirWs = dirStr.unicode_str();
|
||||
std::string dirS(dirWs.begin(), dirWs.end());
|
||||
|
||||
//libpd_openfile(baseS.c_str(), dirS.c_str());
|
||||
//m_patch = m_pd.openPatch(baseS.c_str(), dirS.c_str());
|
||||
m_pd.openPatch(baseS.c_str(), dirS.c_str());
|
||||
pd::Patch p1 = m_pd.openPatch(baseS.c_str(), dirS.c_str());
|
||||
if(!p1.isValid()) {
|
||||
print("Could not open patch "+baseS);
|
||||
}
|
||||
else {
|
||||
print("Opened patch "+baseS+ " [" + std::to_string(p1.dollarZero()) + "]");
|
||||
m_patchsMap[p1.dollarZero()] = p1;
|
||||
}
|
||||
|
||||
print("Opened patch");
|
||||
return p1.dollarZero();
|
||||
}
|
||||
|
||||
void Gdpd::closefile(godot::String baseStr) {
|
||||
std::wstring baseWs = baseStr.unicode_str();
|
||||
std::string baseS(baseWs.begin(), baseWs.end());
|
||||
m_pd.closePatch(baseS.c_str());
|
||||
void Gdpd::closePatch(int id) {
|
||||
if(m_patchsMap.find(id) != m_patchsMap.end()) {
|
||||
// print("Closing patch, id: "+ std::to_string(id));
|
||||
std::string baseS = m_patchsMap[id].filename();
|
||||
m_pd.closePatch(m_patchsMap[id]);
|
||||
m_patchsMap.erase(id);
|
||||
print("Closed patch "+baseS+ " ["+ std::to_string(id) + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void Gdpd::subscribe(String symbStr) {
|
||||
std::wstring symbWs = symbStr.unicode_str();
|
||||
std::string symbS(symbWs.begin(), symbWs.end());
|
||||
m_pd.subscribe(symbS.c_str());
|
||||
std::wstring symbWs = symbStr.unicode_str();
|
||||
std::string symbS(symbWs.begin(), symbWs.end());
|
||||
m_pd.subscribe(symbS.c_str());
|
||||
}
|
||||
|
||||
bool Gdpd::has_message() {
|
||||
//receive new messages
|
||||
m_pd.receiveMessages();
|
||||
//receive new messages
|
||||
m_pd.receiveMessages();
|
||||
|
||||
//return if more than one message
|
||||
int size = m_messages->size();
|
||||
return size>0;
|
||||
//return if more than one message
|
||||
int size = m_messages->size();
|
||||
return size>0;
|
||||
}
|
||||
|
||||
Array Gdpd::get_next() {
|
||||
Array msg = m_messages->pop_front();
|
||||
return msg;
|
||||
Array msg = m_messages->pop_front();
|
||||
return msg;
|
||||
}
|
||||
|
||||
int Gdpd::blocksize() {
|
||||
int blocksize = libpd_blocksize();
|
||||
return blocksize;
|
||||
int blocksize = libpd_blocksize();
|
||||
return blocksize;
|
||||
}
|
||||
|
||||
int Gdpd::start_message(int nbValues) {
|
||||
int res = libpd_start_message(nbValues);
|
||||
return res;
|
||||
int res = libpd_start_message(nbValues);
|
||||
return res;
|
||||
}
|
||||
|
||||
void Gdpd::add_symbol(String symbStr) {
|
||||
std::wstring symbWs = symbStr.unicode_str();
|
||||
std::string symbS(symbWs.begin(), symbWs.end());
|
||||
libpd_add_symbol(symbS.c_str());
|
||||
std::wstring symbWs = symbStr.unicode_str();
|
||||
std::string symbS(symbWs.begin(), symbWs.end());
|
||||
libpd_add_symbol(symbS.c_str());
|
||||
}
|
||||
|
||||
void Gdpd::add_float(float val) {
|
||||
libpd_add_float(val);
|
||||
libpd_add_float(val);
|
||||
}
|
||||
|
||||
int Gdpd::finish_list(String destStr) {
|
||||
std::wstring destWs = destStr.unicode_str();
|
||||
std::string destS(destWs.begin(), destWs.end());
|
||||
int res = libpd_finish_list(destS.c_str());
|
||||
return res;
|
||||
std::wstring destWs = destStr.unicode_str();
|
||||
std::string destS(destWs.begin(), destWs.end());
|
||||
int res = libpd_finish_list(destS.c_str());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void Gdpd::print(const std::string& message) {
|
||||
Godot::print((std::string("GDPD : ")+message).c_str());
|
||||
if (m_verbose) {
|
||||
Godot::print((std::string("GDPD : ")+message).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Gdpd::receiveList(const std::string& dest, const pd::List& list) {
|
||||
Array gdlist;
|
||||
Array gdlist;
|
||||
|
||||
for(int i = 0; i < list.len(); ++i) {
|
||||
if(list.isFloat(i)) {
|
||||
gdlist.push_back(list.getFloat(i));
|
||||
}
|
||||
else if(list.isSymbol(i)) {
|
||||
String symbStr(list.getSymbol(i).c_str());
|
||||
gdlist.push_back(symbStr);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < list.len(); ++i) {
|
||||
if(list.isFloat(i)) {
|
||||
gdlist.push_back(list.getFloat(i));
|
||||
}
|
||||
else if(list.isSymbol(i)) {
|
||||
String symbStr(list.getSymbol(i).c_str());
|
||||
gdlist.push_back(symbStr);
|
||||
}
|
||||
}
|
||||
|
||||
m_messages->push_back(gdlist);
|
||||
m_messages->push_back(gdlist);
|
||||
}
|
||||
|
||||
void Gdpd::set_volume(float vol) {
|
||||
m_vol=vol;
|
||||
m_vol=vol;
|
||||
}
|
||||
|
||||
void Gdpd::set_gui_path(godot::String pathStr) {
|
||||
std::wstring pathWs = pathStr.unicode_str();
|
||||
std::string pathS(pathWs.begin(), pathWs.end());
|
||||
|
||||
m_gui_path = pathS;
|
||||
}
|
||||
|
||||
void Gdpd::computeAudio(bool state) { //[; pd dsp 0/1 (
|
||||
m_pd.computeAudio(state);
|
||||
}
|
||||
|
||||
void Gdpd::set_verbose(bool verbose) {
|
||||
m_verbose = verbose;
|
||||
}
|
||||
|
|
|
|||
111
src/gdpd.hpp
111
src/gdpd.hpp
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#include <Godot.hpp>
|
||||
#include <AudioStreamPlayer.hpp>
|
||||
|
|
@ -12,68 +13,80 @@
|
|||
#include "PdReceiver.hpp"
|
||||
#include "RtAudio.h"
|
||||
|
||||
#include "earplug~.h"
|
||||
|
||||
namespace godot {
|
||||
|
||||
class Gdpd : public godot::AudioStreamPlayer, public pd::PdReceiver {
|
||||
GODOT_CLASS(Gdpd, AudioStreamPlayer)
|
||||
GODOT_CLASS(Gdpd, AudioStreamPlayer)
|
||||
|
||||
private:
|
||||
float *m_inBuf;
|
||||
float *m_outBuf;
|
||||
Array* m_messages;
|
||||
pd::PdBase m_pd;
|
||||
pd::Patch m_patch;
|
||||
RtAudio m_audio;
|
||||
unsigned int m_bufferFrames;
|
||||
float m_vol;
|
||||
int m_nbInputs;
|
||||
int m_nbOutputs;
|
||||
int m_sampleRate;
|
||||
int m_inputDevice;
|
||||
int m_outputDevice;
|
||||
float *m_inBuf;
|
||||
float *m_outBuf;
|
||||
Array* m_messages;
|
||||
pd::PdBase m_pd;
|
||||
pd::Patch m_patch;
|
||||
RtAudio m_audio;
|
||||
unsigned int m_bufferFrames;
|
||||
float m_vol;
|
||||
int m_nbInputs;
|
||||
int m_nbOutputs;
|
||||
int m_sampleRate;
|
||||
int m_inputDevice;
|
||||
int m_outputDevice;
|
||||
std::map<int, pd::Patch> m_patchsMap;
|
||||
std::string m_gui_path;
|
||||
bool m_verbose;
|
||||
|
||||
bool m_init;
|
||||
|
||||
public:
|
||||
static void _register_methods();
|
||||
static void _register_methods();
|
||||
|
||||
Gdpd();
|
||||
~Gdpd();
|
||||
Gdpd();
|
||||
~Gdpd();
|
||||
|
||||
void _init();
|
||||
void _init();
|
||||
|
||||
//libpd functions
|
||||
Array get_available_input_devices();
|
||||
Array get_available_output_devices();
|
||||
int init_devices(String inputDevice, String outputDevice);
|
||||
int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize);
|
||||
int start();
|
||||
void stop();
|
||||
void openfile(String basename, String dirname);
|
||||
void closefile(String basename);
|
||||
bool has_message();
|
||||
Array get_next();
|
||||
int blocksize();
|
||||
void subscribe(String symbStr);
|
||||
int start_message(int nbValues);
|
||||
void add_symbol(String symbStr);
|
||||
void add_float(float val);
|
||||
int finish_list(String destStr);
|
||||
//libpd functions
|
||||
Array get_available_input_devices();
|
||||
Array get_available_output_devices();
|
||||
int init_devices(String inputDevice, String outputDevice);
|
||||
int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize);
|
||||
int start();
|
||||
void streamstart();
|
||||
void stop();
|
||||
int openPatch(String basename, String dirname);
|
||||
void closePatch(int id);
|
||||
bool has_message();
|
||||
Array get_next();
|
||||
int blocksize();
|
||||
void subscribe(String symbStr);
|
||||
int start_message(int nbValues);
|
||||
void add_symbol(String symbStr);
|
||||
void add_float(float val);
|
||||
int finish_list(String destStr);
|
||||
|
||||
//libpd hooks
|
||||
virtual void print(const std::string& message);
|
||||
void receiveList(const std::string& dest, const pd::List& list);
|
||||
//libpd hooks
|
||||
virtual void print(const std::string& message);
|
||||
void receiveList(const std::string& dest, const pd::List& list);
|
||||
|
||||
//godot functions
|
||||
void set_volume(float vol);
|
||||
inline const float& get_volume(){return m_vol;}
|
||||
//godot functions
|
||||
void computeAudio(bool state); //[; pd dsp 0/1 (
|
||||
void set_gui_path(godot::String path);
|
||||
void set_volume(float vol);
|
||||
inline const float& get_volume(){
|
||||
return m_vol;
|
||||
}
|
||||
void set_verbose(bool verbose);
|
||||
|
||||
|
||||
//rtaudio
|
||||
static int audioCallback(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData);
|
||||
void processAudio(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData);
|
||||
//rtaudio
|
||||
static int audioCallback(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData);
|
||||
void processAudio(void *outputBuffer, void *inputBuffer,
|
||||
unsigned int nBufferFrames, double streamTime,
|
||||
RtAudioStreamStatus status, void *userData);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3ee07f652bbbe91630a8346e3fe39a05f0f1d76a
|
||||
Subproject commit 76d6ad5d8db23b086b175d785812744d2bacf62a
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit e07d211d7b7e5f8dd6d2e3ddce557ae453161a14
|
||||
Subproject commit f1f8967e663027937e7934a357aff5fb116367c4
|
||||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
git submodule update --init --recursive
|
||||
cd src/godot-cpp
|
||||
scons platform=$1 generate_bindings=yes
|
||||
scons platform=$1 target=$2 macos_arch=$3 generate_bindings=yes
|
||||
cd ../..
|
||||
scons platform=$1
|
||||
scons platform=$1 target=$2 macos_arch=$3
|
||||
|
|
|
|||
Loading…
Reference in a new issue