puredata 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5019cc763303059953a987b3987e9841bf6e3ad
4
+ data.tar.gz: 12158322048cc28ae8b83425b9a75c40915b01b8
5
+ SHA512:
6
+ metadata.gz: 2909322b6f9c15dac7f1f49c09680bbc96166ae78931ae4a6a271a3a00c7a3ce42aff1ebdcba5c3f9a3cbc8402fbf766bd4ae3d5f329d165edd10845120600e4
7
+ data.tar.gz: 61935a92985785f15c9c5ee1afb6da5460eb2db389082a261489bebc02f6b8c1e401faf1c6d4d06d9a1eae3d92cbd270d357933f185ab1e0130366fac1fbab2b
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in puredata.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Tomoyuki Chikanaga
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,33 @@
1
+ = Ruby/PureData
2
+ Ruby library to manipulate PureData (Pd-extended) via socket.
3
+
4
+ == Requirements
5
+ Mac OS X
6
+ Pd-extended
7
+
8
+ == Synopsis
9
+
10
+ require "puredata"
11
+
12
+ Pd.start do |pd|
13
+ canvas = pd.canvas("sample")
14
+
15
+ osc = canvas.obj("osc~", 440)
16
+ mul = canvas.obj("*~", 0.1)
17
+ dac = canvas.obj("dac~")
18
+ osc >> mul
19
+ dac.left << mul
20
+ dac.right << mul
21
+
22
+ pd.dsp = true
23
+ sleep 5
24
+ pd.dsp = false
25
+ end
26
+
27
+ == Description
28
+
29
+ == Installation
30
+
31
+ == License
32
+
33
+ This software is released under the MIT License, see LICENSE.txt.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ require "puredata"
2
+
3
+ Pd.start do |pd|
4
+ # create abstraction "osc440.pd"
5
+ sample = pd.abstraction("osc440") do |abst|
6
+ abst.add_outlet(true)
7
+ osc = abst.obj("osc~", 440)
8
+ mul = abst.obj("*~", 0.3)
9
+ osc >> mul
10
+ abst.outlet(0) << mul
11
+ end
12
+
13
+ canvas = pd.canvas("sample")
14
+ osc440 = canvas.obj("osc440")
15
+ dac = canvas.obj("dac~")
16
+ osc440 >> dac.left
17
+ osc440 >> dac.right
18
+ canvas.save
19
+
20
+ pd.dsp = true
21
+ sleep 3
22
+ pd.dsp = false
23
+ end
@@ -0,0 +1,2 @@
1
+ #N canvas 0 22 450 300 10;
2
+ #X obj 40 40 netreceive 10002 0 old;
@@ -0,0 +1,39 @@
1
+ require "puredata"
2
+
3
+ PureData.start(:port => 10002) do |pd|
4
+ # create canvas "sample.pd"
5
+ canvas = pd.canvas("sample")
6
+
7
+ # osc~ => *~ 0.1 => dac~
8
+ osc = canvas.obj("osc~", 440)
9
+ mul = canvas.obj("*~", 0.3)
10
+ dac = canvas.obj("dac~")
11
+ canvas.connect(osc.outlet, mul.inlet(0))
12
+ canvas.connect(mul.outlet, dac.left)
13
+ canvas.connect(mul.outlet, dac.right)
14
+
15
+ pd.dsp = true
16
+ sleep 3
17
+ pd.dsp = false
18
+
19
+ # add receive object for modify frequency of osc~
20
+ freq = canvas.obj("r", "freq")
21
+ line = canvas.obj("line")
22
+ canvas.connect(freq.outlet, line.inlet)
23
+ canvas.connect(line.outlet, osc.freq)
24
+
25
+ pd.dsp = true
26
+ pd.msg(:freq, 500, 4000)
27
+ puts "freq 500 4000"
28
+ sleep 3
29
+ pd.msg(:freq, 220, 5000)
30
+ puts "freq 220 5000"
31
+ sleep 5
32
+ pd.msg(:freq, 1000, 1000)
33
+ puts "freq 1000 1000"
34
+ sleep 1
35
+ pd.msg(:freq, 100, 50)
36
+ puts "freq 100 50"
37
+ sleep 1
38
+ pd.dsp = false
39
+ end
@@ -0,0 +1,21 @@
1
+ require "puredata"
2
+
3
+ Pd.start do |pd|
4
+ # create canvas "sample.pd"
5
+ canvas = pd.canvas("sample")
6
+
7
+ # osc~ => *~ 0.1 => dac~
8
+ osc = canvas.obj("osc~", 440)
9
+ mul = canvas.obj("*~", 0.3)
10
+ dac = canvas.obj("dac~")
11
+ canvas.connect(osc.outlet, mul.inlet(0))
12
+ canvas.connect(mul.outlet, dac.left)
13
+ canvas.connect(mul.outlet, dac.right)
14
+
15
+ # save canvas
16
+ canvas.save
17
+
18
+ # Canvas#save only messaging to Pd and there's no reply.
19
+ # So we can't confirm Pd save patch to file.
20
+ sleep 1
21
+ end
@@ -0,0 +1,8 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # Ruby/PureData early scrach version.
4
+
5
+ require "puredata/pd"
6
+ require "puredata/canvas"
7
+ require "puredata/connection"
8
+ require "puredata/pdobject"
@@ -0,0 +1,98 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # Ruby/PureData Canvas, Abstraction class
4
+
5
+ class PureData
6
+ class Canvas
7
+ def initialize(pd, name, opt={})
8
+ @pd = pd
9
+ @name = name.dup
10
+ unless /\.pd\Z/ =~ @name
11
+ @name += ".pd"
12
+ end
13
+ @dir = File.expand_path(opt[:dir] || Dir.pwd)
14
+ @pdobjid = 0
15
+ pos = opt[:position] || [100, 100]
16
+ size = opt[:size] || [300, 300]
17
+ font = opt[:font] || 10
18
+ pd.msg("pd", "filename", @name, @dir)
19
+ pd.msg("#N", "canvas #{pos.join(" ")} #{size.join(" ")} #{font}")
20
+ pd.msg("#X", "pop", "1")
21
+ end
22
+
23
+ def msg(*args)
24
+ @pd.msg("pd-#{@name}", *args)
25
+ end
26
+
27
+ def obj(klass, *args)
28
+ self.msg("obj", 10, 10, klass, *args)
29
+ id = @pdobjid
30
+ @pdobjid += 1
31
+ cls = PureData.dispatch_object_class(klass, *args)
32
+ cls.new(@pd, self, id, klass, *args)
33
+ end
34
+
35
+ def connect(outlet, inlet)
36
+ obj1, outletid = outlet.outlet_tuple
37
+ obj2, inletid = inlet.inlet_tuple
38
+ oid1 = obj1.pdobjid
39
+ oid2 = obj2.pdobjid
40
+ self.msg("connect", oid1, outletid, oid2, inletid)
41
+ end
42
+
43
+ def save(path=nil)
44
+ if path
45
+ name = File.basename(path)
46
+ unless /\.pd\Z/ =~ name
47
+ name += ".pd"
48
+ end
49
+ dir = File.expand_path(File.dirname(path))
50
+ else
51
+ name = @name
52
+ dir = @dir
53
+ end
54
+ self.msg("savetofile", name, dir)
55
+ @name = name
56
+ @dir = dir
57
+ nil
58
+ end
59
+ end
60
+
61
+ class Abstraction < Canvas
62
+ def initialize(pd, name, opt={})
63
+ super(pd, name, opt)
64
+ @inlets = []
65
+ @outlets = []
66
+ end
67
+
68
+ def inlet(idx=0)
69
+ @inlets[idx].outlet(0)
70
+ end
71
+
72
+ def outlet(idx=0)
73
+ @outlets[idx].inlet(0)
74
+ end
75
+
76
+ def add_inlet(audio=false)
77
+ if audio
78
+ @inlets << self.obj("inlet~")
79
+ else
80
+ @inlets << self.obj("inlet")
81
+ end
82
+ end
83
+
84
+ def add_outlet(audio=false)
85
+ if audio
86
+ @outlets << self.obj("outlet~")
87
+ else
88
+ @outlets << self.obj("outlet")
89
+ end
90
+ end
91
+
92
+ def self.create(pd, name, opt={})
93
+ abstract = self.new(pd, name, opt)
94
+ yield(abstract)
95
+ abstract.save
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,67 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # PureData connection (inlet/outlet) control
4
+
5
+ class PureData
6
+ class IOlet
7
+ def initialize(obj, idx=0)
8
+ @obj = obj
9
+ @idx = idx
10
+ end
11
+
12
+ attr_reader :idx
13
+
14
+ def canvas
15
+ @obj.canvas
16
+ end
17
+
18
+ def pdobjid
19
+ @obj.pdobjid
20
+ end
21
+
22
+ def name
23
+ @obj.name
24
+ end
25
+
26
+ def check_canvas(other)
27
+ unless @obj.canvas == other.canvas
28
+ raise "#{@obj.name} and #{other.name} must be in same canvas"
29
+ end
30
+ end
31
+
32
+ def pair
33
+ [@obj, @idx]
34
+ end
35
+ end
36
+
37
+ class Inlet < IOlet
38
+ def inlet_tuple
39
+ [@obj, @idx]
40
+ end
41
+
42
+ def <<(other)
43
+ if other.is_a?(PdObject)
44
+ other = other.outlet
45
+ end
46
+ check_canvas(other)
47
+ @obj.canvas.connect(other, self)
48
+ other
49
+ end
50
+ end
51
+
52
+ class Outlet < IOlet
53
+ def outlet_tuple
54
+ [@obj, @idx]
55
+ end
56
+
57
+ def >>(other)
58
+ if other.is_a?(PdObject)
59
+ other = other.inlet
60
+ end
61
+ check_canvas(other)
62
+ @obj.canvas.connect(self, other)
63
+ other
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,132 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # Ruby/PureData early scrach version.
4
+
5
+ require "socket"
6
+
7
+ require "puredata/canvas"
8
+
9
+ class PureData
10
+ case RUBY_PLATFORM
11
+ when /darwin/
12
+ @@pd_app_path = "/Applications/Pd-extended.app/Contents/Resources/bin/pd"
13
+ else
14
+ @@pd_app_path = nil
15
+ end
16
+
17
+ def self.start(opt={}, &blk)
18
+ pd = self.new(opt)
19
+ pd.fork_pd(opt)
20
+ pd.start(opt, &blk)
21
+ end
22
+
23
+ def self.attach(opt={}, &blk)
24
+ pd = self.new(opt)
25
+ pd.start(opt, &blk)
26
+ end
27
+
28
+ def initialize(opt={})
29
+ @portno = (opt[:port] || 10002).to_i
30
+ end
31
+
32
+ def fork_pd(opt={})
33
+ path = opt[:pd_app_path] || @@pd_app_path
34
+ pd_params = opt[:pd_params] || []
35
+ if path.nil? or not File.executable?(path)
36
+ raise "option :pd_app_path (Pd-extended executable) must be specified."
37
+ end
38
+ cmd = [
39
+ path,
40
+ pd_params,
41
+ "-nogui",
42
+ "-send", "pd filename ruby-pd.pd ./;",
43
+ "-send", "#N canvas 10 10 200 200 10;",
44
+ "-send", "#X pop 1;",
45
+ "-send", "pd-ruby-pd.pd obj 50 50 netreceive #{@portno} 0 old;",
46
+ ].flatten
47
+ @pid = fork do
48
+ Process.setsid
49
+ exec(*cmd)
50
+ end
51
+ end
52
+
53
+ def bind(opt={})
54
+ err = nil
55
+ 200.times do
56
+ sleep 0.1
57
+ begin
58
+ @sock = TCPSocket.new("localhost", @portno)
59
+ break
60
+ rescue
61
+ err = $!
62
+ end
63
+ end
64
+ unless @sock
65
+ $stderr.puts("connect to localhost:#{@portno} failed")
66
+ raise err
67
+ end
68
+ end
69
+
70
+ def start(opt={}, &blk)
71
+ begin
72
+ bind(opt)
73
+ if blk
74
+ blk.call(self)
75
+ end
76
+ ensure
77
+ if blk
78
+ stop
79
+ end
80
+ end
81
+ end
82
+
83
+ def stop
84
+ if @sock
85
+ @sock.close unless @sock.closed?
86
+ @sock = nil
87
+ end
88
+
89
+ return if @pid.nil?
90
+
91
+ begin
92
+ Process.kill(:TERM, -@pid)
93
+ rescue Errno::ESRCH
94
+ rescue Errno::EPERM
95
+ raise "fail to kill process(#{@pid}): #{$!}"
96
+ end
97
+ Process.waitpid(@pid)
98
+ ensure
99
+ @sock = nil
100
+ @pid = nil
101
+ end
102
+
103
+ def msg(*args)
104
+ @sock.puts(args.map{|l| l.to_s}.join(" ") + ";")
105
+ end
106
+
107
+ def canvas(name, opt={})
108
+ Canvas.new(self, name, opt)
109
+ end
110
+
111
+ def abstraction(name, opt={}, &blk)
112
+ if blk
113
+ Abstraction.create(self, name, opt, &blk)
114
+ else
115
+ Abstraction.new(self, name, opt)
116
+ end
117
+ end
118
+
119
+ def dsp=(flag)
120
+ if flag
121
+ self.msg("pd", "dsp", 1)
122
+ else
123
+ self.msg("pd", "dsp", 0)
124
+ end
125
+ end
126
+
127
+ def quit
128
+ self.msg("pd", "quit")
129
+ end
130
+ end
131
+
132
+ Pd = PureData
@@ -0,0 +1,9 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # Ruby/PureData Pd object wrapper classes
4
+
5
+ require "puredata/pdobject/pdobject"
6
+ require "puredata/pdobject/osc"
7
+ require "puredata/pdobject/dac"
8
+ require "puredata/pdobject/receive"
9
+
@@ -0,0 +1,16 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # dac~ object class
4
+
5
+ class PureData
6
+ class Dac < PdObject
7
+ def left
8
+ inlet(0)
9
+ end
10
+ def right
11
+ inlet(1)
12
+ end
13
+ end
14
+ end
15
+
16
+ PureData.register_pdobject(PureData::Dac, "dac~")
@@ -0,0 +1,12 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # osc~ object class
4
+
5
+ class PureData
6
+ class Osc < PdObject
7
+ def freq
8
+ inlet(0)
9
+ end
10
+ end
11
+ end
12
+ PureData.register_pdobject(PureData::Osc, "osc~")
@@ -0,0 +1,55 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # Ruby/PureData ojbect wrapper base class
4
+
5
+ class PureData
6
+
7
+ @@pdclass = {}
8
+
9
+ def self.register_pdobject(klass, *names)
10
+ names.each do |n|
11
+ @@pdclass[n] = klass
12
+ end
13
+ end
14
+
15
+ def self.dispatch_object_class(klass, *args)
16
+ cls = @@pdclass[klass.to_s]
17
+ cls ||= PdObject
18
+ cls
19
+ end
20
+
21
+ class PdObject
22
+ def initialize(pd, canvas, pdobjid, name, *args)
23
+ @pd = pd
24
+ @canvas = canvas
25
+ @pdobjid = pdobjid
26
+ @name = name
27
+ @args = args
28
+ end
29
+ attr_reader :canvas, :pdobjid, :name
30
+
31
+ def inlet(idx=0)
32
+ Inlet.new(self, idx)
33
+ end
34
+
35
+ def inlet_pair
36
+ [self, 0]
37
+ end
38
+
39
+ def outlet(idx=0)
40
+ Outlet.new(self, idx)
41
+ end
42
+
43
+ def outlet_pair
44
+ [self, 0]
45
+ end
46
+
47
+ def <<(other)
48
+ self.inlet << other
49
+ end
50
+
51
+ def >>(other)
52
+ self.outlet >> other
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,13 @@
1
+ # vim:encoding=utf-8
2
+ #
3
+ # receive object class
4
+
5
+ class PureData
6
+ class Receive < PdObject
7
+ def msg(*args)
8
+ @pd.msg(@args[0], *args)
9
+ end
10
+ end
11
+ end
12
+
13
+ PureData.register_pdobject(PureData::Receive, "receive", "r")
@@ -0,0 +1,3 @@
1
+ module Puredata
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'puredata/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "puredata"
8
+ spec.version = Puredata::VERSION
9
+ spec.authors = ["CHIKANAGA Tomoyuki"]
10
+ spec.email = ["nagachika00@gmail.com"]
11
+
12
+ spec.summary = "Ruby library to manipulate PureData (Pd-extended) via socket."
13
+ spec.description = "Ruby library to manipulate PureData (Pd-extended) via socket."
14
+ spec.homepage = "https://github.com/nagachika/ruby-puredata"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.12"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puredata
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - CHIKANAGA Tomoyuki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Ruby library to manipulate PureData (Pd-extended) via socket.
42
+ email:
43
+ - nagachika00@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - example/abstraction.rb
54
+ - example/example.pd
55
+ - example/example.rb
56
+ - example/save.rb
57
+ - lib/puredata.rb
58
+ - lib/puredata/canvas.rb
59
+ - lib/puredata/connection.rb
60
+ - lib/puredata/pd.rb
61
+ - lib/puredata/pdobject.rb
62
+ - lib/puredata/pdobject/dac.rb
63
+ - lib/puredata/pdobject/osc.rb
64
+ - lib/puredata/pdobject/pdobject.rb
65
+ - lib/puredata/pdobject/receive.rb
66
+ - lib/puredata/version.rb
67
+ - puredata.gemspec
68
+ homepage: https://github.com/nagachika/ruby-puredata
69
+ licenses: []
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.5.1
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Ruby library to manipulate PureData (Pd-extended) via socket.
91
+ test_files: []