Created
May 20, 2017 13:55
-
-
Save antonhornquist/ce549a61caf076466f9ffa5e76435b64 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'tempfile' | |
# pure data patching dsl for ruby hack | |
file = Tempfile.new | |
begin | |
my_patch = patch # 1. create patch | |
my_patch + 'declare -stdpath creb' # 2. add object | |
mod = my_patch + 'loadbang' >> 'list 200 10000' >> 'line~' >> 'osc~ 2' >> '*~ 800' >> '+~ 1000' # 3. connect | |
sine = mod >> 'osc~ 429' >> '*~ 0.5' | |
saw = mod >> 'blosc~ saw' >> '*~ 0.7' | |
vol = my_patch + 'vol~ 80' | |
sine >> vol | |
saw >> vol | |
writesf = my_patch + 'writesf~ 2' | |
trim = my_patch + 'list trim' | |
my_patch + 'list append open out.wav' >> trim | |
my_patch + 'list append start' >> trim | |
connect(my_patch, trim, 0, writesf, 0) | |
dac = my_patch + 'dac~' | |
connect(my_patch, vol, 0, dac, 0) | |
connect(my_patch, vol, 0, dac, 1) | |
connect(my_patch, vol, 0, writesf, 0) | |
connect(my_patch, vol, 0, writesf, 1) | |
=begin | |
p = patch | |
$p = p | |
object(p, 'declare', '-stdpath', 'creb') | |
test = 'osc~ 429' >> '*~ 0.8' >> 'dac~' | |
puts test | |
object(p, 'declare', '-stdpath', 'creb') | |
mod = object(p, 'osc~', 2) | |
mul = object(p, '*~', 400) | |
add = object(p, '+~', 1000) | |
# mod = patch('osc~ 2' >> '*~ 400' >> '+~ 1000') | |
osc = object(p, 'blosc~', 'saw') | |
connect(p, mod, 0, mul, 0) | |
connect(p, mul, 0, add, 0) | |
connect(p, add, 0, osc, 0) | |
vol = object(p, 'vol~', 80) | |
connect(p, osc, 0, vol, 0) | |
dac = object(p, 'dac~') | |
connect(p, vol, 0, dac, 0) | |
connect(p, vol, 0, dac, 1) | |
=end | |
file.write(patch_to_s(ze_patch)) | |
file.close | |
# pid = run_pd(file, ["-nogui", "-send \"pd dsp 1;\""]) | |
pid = run_pd(file, ["-send \"pd dsp 1;\""]) | |
gets | |
ensure | |
if pid | |
puts "close pd..." | |
Process.kill("KILL", pid) | |
end | |
file.unlink if file | |
end | |
BEGIN { | |
module CoreExtensions | |
module String | |
module Patching | |
def to_object(patch) | |
strs = self.split | |
name = strs.first | |
args = strs.drop(1) | |
# [name, args] | |
object(patch, name, *args) | |
end | |
end | |
end | |
module Hash | |
module Patching | |
def +(something) | |
patch = self | |
something.to_object(patch) | |
end | |
def >>(something) | |
patch = self[:patch] | |
if something.respond_to? :keys | |
# assume Hash | |
connect(patch, self, 0, something, 0) | |
something | |
else | |
# assume String | |
obj = something.to_object(patch) | |
connect(patch, self, 0, obj, 0) | |
obj | |
end | |
end | |
end | |
end | |
end | |
String.include CoreExtensions::String::Patching # monkey patching, beware | |
Hash.include CoreExtensions::Hash::Patching # monkey patching, beware | |
def patch(name=nil) | |
{ :name => name, :declarations => [], :objects => [], :connections => [] } | |
end | |
def object(patch, name, *args) | |
object = { :patch => patch, :name => name, :args => args } | |
patch[:objects] << object | |
if name.to_sym == :declare | |
(args.size/2).times do |i| | |
flag, value = *args[(i*2)..(i*2+1)] | |
patch[:declarations] << { :flag => flag, :value => value } | |
end | |
end | |
object | |
end | |
def connect(patch, from, outlet_no, to, inlet_no) | |
connection = { :from => from, :outlet => outlet_no, :to => to, :inlet => inlet_no } | |
patch[:connections] << connection | |
connection | |
end | |
def object_name_args_to_s(object) | |
"#{object[:name]}#{object[:args].empty? ? "" : " " + object[:args].join(" ")}" | |
end | |
def declaration_to_s(declaration) | |
"#X declare #{declaration[:flag]} #{declaration[:value]};" | |
end | |
def object_to_s(object, index) | |
"#X obj 10 #{10+index*30} #{object_name_args_to_s(object)};" | |
end | |
def connection_to_s(patch, connection) | |
objects = patch[:objects] | |
from = objects.find_index(connection[:from]) | |
to = objects.find_index(connection[:to]) | |
"#X connect #{from} #{connection[:outlet]} #{to} #{connection[:inlet]};" | |
end | |
def patch_to_s(patch) | |
declarations = patch[:declarations] | |
objects = patch[:objects] | |
connections = patch[:connections] | |
arr = ["#N canvas 50 50 450 300 10;"] + declarations.map do |declaration| | |
declaration_to_s(declaration) | |
end + objects.each_with_index.map do |object, i| | |
object_to_s(object, i) | |
end + connections.map do |connection| | |
connection_to_s(patch, connection) | |
end | |
arr.join("\n") | |
end | |
def run_pd(file, opts=[], fork=true) | |
pd_path = case RUBY_PLATFORM | |
when /darwin/ then "/Applications/Pd-0.47-1-64bit.app/Contents/Resources/bin/pd" # assumes pd installed on this path | |
when /mingw32/ then "pd.exe" # assumes pd.exe is in PATH | |
end | |
cmd = pd_path | |
cmd = cmd + " #{opts.join(" ")}" unless opts.empty? | |
cmd = cmd + " \"#{file.path}\"" if file | |
puts "cmd: #{cmd}" | |
if fork | |
pid = case RUBY_PLATFORM | |
when /darwin/ then fork { exec(cmd) } | |
when /mingw32/ then Process.spawn(cmd) | |
end | |
pid | |
else | |
exec(cmd) | |
end | |
end | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment