synthdef 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 606df2662e08ada182088202a35eac3d4371288f
4
- data.tar.gz: 7e0639b1b86fe4f9555081db52fb7d691f78097c
3
+ metadata.gz: 665422f13978b9e8381467e67573a50fb522f768
4
+ data.tar.gz: c2110f4a9fbfa0a0791ed3ce7b559e3f39263bf3
5
5
  SHA512:
6
- metadata.gz: 178481c0bde1bda955b256fb5d57f0b8d87517d909c13009fb36f941c84ec0438eb6f35c0c4396db5217971fcf90986fef51f8e2f12770eb3b0f584d083c91fa
7
- data.tar.gz: 0867d1e926b801e40c21fe2bb03814955ab724e0e69d30c7fe226b1da0e1ea0daf5eaa337cface9942017ef46263eb43738e9e35b0393f30d77a72795daf195c
6
+ metadata.gz: 539a3e6d7691f19a939c1cb311d250c7fdfffc0187c59874f1e523861da3cbf978271b1a84f08f3aa82def73e5d8e8260faa940c68f259d20082c0d65e9a25a5
7
+ data.tar.gz: 61d36bda458ead263f7b5c7c309c20d1e9ea483092c97d9e74c5acf8d581b133e998d6580ba15d704c158e33ea1a7c5d432e0b223d6d5e93b5e2bdde2e3ae7dc
data/README.md CHANGED
@@ -2,9 +2,15 @@
2
2
 
3
3
  ## pre-Alpha
4
4
 
5
- A gem to work with SuperCollider's binary synthdef format. This uses the excellent [`bindata`](https://github.com/dmendel/bindata) gem to define the spec in a very readable way. The implementation is less than 60 lines of code.
5
+ A gem to work with SuperCollider's binary synthdef format. This uses the excellent [`bindata`](https://github.com/dmendel/bindata) gem to define the spec in a very readable way. The implementation is around than 60 lines of code.
6
6
 
7
- Inspiration for the spec was taken from the following links:
7
+ It works with both SynthDef and SynthDef2 formats.
8
+
9
+ I found the actual spec here:
10
+
11
+ [http://doc.sccode.org/Reference/Synth-Definition-File-Format.html](http://doc.sccode.org/Reference/Synth-Definition-File-Format.html)
12
+
13
+ Before I found the spec(!), inspiration was taken from the following links:
8
14
 
9
15
  - [Clojure - Overtone - synthdef.clj](https://github.com/overtone/overtone/blob/master/src/overtone/sc/machinery/synthdef.clj)
10
16
 
@@ -39,11 +45,116 @@ Take a binary scsyndef file (you can find an example in `spec/data/recorder.scsy
39
45
  ```
40
46
  $ bundle exec irb
41
47
 
48
+ # pp is just to pretty print the output, not essential
49
+ >> require 'pp'
50
+ => true
42
51
  >> require 'synthdef'
43
52
  => true
44
53
  >> raw = open("spec/data/recorder.scsyndef").read
45
- >> Synthdef.read(raw)
46
- => {:file_type_id=>"SCgf", :file_version=>1, :no_of_synthdefs=>1, :synthdefs=>[{:name=>"sonic-pi-recorder", :no_of_constants=>0, :constants=>[], :no_of_params=>2, :params=>[0.0, 0.0], :no_of_param_names=>2, :param_names=>[{:param_name=>"out-buf", :param_index=>0}, {:param_name=>"in_bus", :param_index=>1}], :no_of_ugens=>3, :ugens=>[{:ugen_name=>"Control", :rate=>1, :no_of_inputs=>0, :no_of_outputs=>2, :special=>0, :inputs=>[], :outputs=>[1, 1]}, {:ugen_name=>"InFeedback", :rate=>2, :no_of_inputs=>1, :no_of_outputs=>2, :special=>0, :inputs=>[{:src=>0, :input_index=>1}], :outputs=>[2, 2]}, {:ugen_name=>"DiskOut", :rate=>2, :no_of_inputs=>3, :no_of_outputs=>1, :special=>0, :inputs=>[{:src=>0, :input_index=>0}, {:src=>1, :input_index=>0}, {:src=>1, :input_index=>1}], :outputs=>[2]}], :no_of_variants=>0, :variants=>[]}]}
54
+ >> pp Synthdef.read(raw)
55
+ => {:file_type_id=>"SCgf",
56
+ :file_version=>1,
57
+ :no_of_synthdefs=>1,
58
+ :synthdefs=>
59
+ [{:name=>"sonic-pi-recorder",
60
+ :no_of_constants=>0,
61
+ :constants=>[],
62
+ :no_of_params=>2,
63
+ :params=>[0.0, 0.0],
64
+ :no_of_param_names=>2,
65
+ :param_names=>
66
+ [{:param_name=>"out-buf", :param_index=>0},
67
+ {:param_name=>"in_bus", :param_index=>1}],
68
+ :no_of_ugens=>3,
69
+ :ugens=>
70
+ [{:ugen_name=>"Control",
71
+ :rate=>1,
72
+ :no_of_inputs=>0,
73
+ :no_of_outputs=>2,
74
+ :special=>0,
75
+ :inputs=>[],
76
+ :outputs=>[1, 1]},
77
+ {:ugen_name=>"In",
78
+ :rate=>2,
79
+ :no_of_inputs=>1,
80
+ :no_of_outputs=>2,
81
+ :special=>0,
82
+ :inputs=>[{:src=>0, :input_constant_index=>1}],
83
+ :outputs=>[2, 2]},
84
+ {:ugen_name=>"DiskOut",
85
+ :rate=>2,
86
+ :no_of_inputs=>3,
87
+ :no_of_outputs=>1,
88
+ :special=>0,
89
+ :inputs=>
90
+ [{:src=>0, :input_constant_index=>0},
91
+ {:src=>1, :input_constant_index=>0},
92
+ {:src=>1, :input_constant_index=>1}],
93
+ :outputs=>[2]}],
94
+ :no_of_variants=>0,
95
+ :variants=>[]}]}
96
+ ```
97
+
98
+ ## Differences between SynthDef versions 1 and 2
99
+
100
+ ```
101
+ # Taken from spec
102
+ # synth-definition-file for version 2
103
+
104
+ int32 - four byte file type id containing the ASCII characters: "SCgf"
105
+ int32 - file version, currently 2.
106
+ int16 - number of synth definitions in this file (D).
107
+ [ synth-definition ] * D
108
+ pstring - the name of the synth definition
109
+ int32 - number of constants (K)
110
+ [float32] * K - constant values
111
+ int32 - number of parameters (P)
112
+ [float32] * P - initial parameter values
113
+ int32 - number of parameter names (N)
114
+ [ param-name ] * N
115
+ pstring - the name of the parameter
116
+ int32 - its index in the parameter array
117
+ int32 - number of unit generators (U)
118
+ [ ugen-spec ] * U
119
+ pstring - the name of the SC unit generator class
120
+ int8 - calculation rate
121
+ int32 - number of inputs (I)
122
+ int32 - number of outputs (O)
123
+ int16 - special index
124
+ [ input-spec ] * I
125
+ int32 - index of unit generator or -1 for a constant
126
+ if (unit generator index == -1)
127
+ int32 - index of constant
128
+ else
129
+ int32 - index of unit generator output
130
+ [ output-spec ] * O
131
+ int8 - calculation rate
132
+ int16 - number of variants (V)
133
+ [ variant-spec ] * V
134
+ pstring - the name of the variant
135
+ [float32] * P - variant initial parameter values
136
+ ```
137
+
138
+ Again, taken from the spec
139
+
140
+ ```
141
+ The original SynthDef format differs in that the following items are int16 instead of int32.
142
+ NOTE: The following list describes what has changed between SynthDef and SynthDef2. It is not a complete description of the the original SynthDef file format.
143
+ int32 - file version, currently 1. (This is 2 for the new format.)
144
+ a synth-definition is :
145
+ int16 - number of constants (K)
146
+ int16 - number of parameters (P)
147
+ int16 - number of parameter names (N)
148
+ int16 - number of unit generators (U)
149
+ a param-name is :
150
+ int16 - its index in the parameter array
151
+ a ugen-spec is :
152
+ int16 - number of inputs (I)
153
+ int16 - number of outputs (O)
154
+ an input-spec is :
155
+ int16 - index of unit generator or -1 for a constant
156
+ int16 - index of constant
157
+ int16 - index of unit generator output
47
158
  ```
48
159
 
49
160
  ## Contributing
@@ -10,41 +10,50 @@ class PascalString < BinData::Primitive
10
10
  end
11
11
 
12
12
  class Synthdef < BinData::Record
13
+ def check_version
14
+ # Returns zero based index for choices
15
+ file_version == 1 ? 0 : 1
16
+ end
17
+
13
18
  endian :big
14
19
 
15
20
  string :file_type_id, read_length: 4
16
- uint32 :file_version
17
- uint16 :no_of_synthdefs
21
+ int32 :file_version
22
+ int16 :no_of_synthdefs
18
23
 
19
24
  array :synthdefs, initial_length: lambda { no_of_synthdefs } do
20
25
  pascal_string :name
21
26
 
22
- int16 :no_of_constants
23
- array :constants, initial_length: lambda { no_of_constants } do
27
+ choice :no_of_constants, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
28
+ array :constants, initial_length: lambda { no_of_constants } do
24
29
  float :constant
25
30
  end
26
31
 
27
- int16 :no_of_params
32
+ choice :no_of_params, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
28
33
  array :params, initial_length: lambda { no_of_params } do
29
34
  float :initial_parameter_value
30
35
  end
31
36
 
32
- int16 :no_of_param_names
37
+ choice :no_of_param_names, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
33
38
  array :param_names, initial_length: lambda { no_of_param_names } do
34
39
  pascal_string :param_name
35
- int16 :param_index
40
+ choice :param_index, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
36
41
  end
37
42
 
38
- int16 :no_of_ugens
43
+ choice :no_of_ugens, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
39
44
  array :ugens, initial_length: lambda { no_of_ugens } do
40
45
  pascal_string :ugen_name
41
46
  int8 :rate
42
- int16 :no_of_inputs
43
- int16 :no_of_outputs
47
+ choice :no_of_inputs, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
48
+ choice :no_of_outputs, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
44
49
  int16 :special, initial_value: 0
45
50
  array :inputs, initial_length: lambda { no_of_inputs } do
46
- int16 :src
47
- int16 :input_index
51
+ choice :src, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
52
+ if lambda { src == -1 }
53
+ choice :input_constant_index, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
54
+ else
55
+ choice :input_ugen_index, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
56
+ end
48
57
  end
49
58
  array :outputs, initial_length: lambda { no_of_outputs } do
50
59
  int8 :calculation_rate
@@ -1,5 +1,5 @@
1
1
  require 'bindata'
2
2
 
3
3
  class Synthdef < BinData::Record
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
Binary file
Binary file
@@ -2,11 +2,29 @@ require 'spec_helper'
2
2
 
3
3
  describe Synthdef do
4
4
  let(:synthdef_binary) { IO.read(File.expand_path("../data/recorder.scsyndef", __FILE__)) }
5
+ let(:complex_synthdef_binary) { IO.read(File.expand_path("../data/hoover.scsyndef", __FILE__)) }
5
6
 
6
- it 'reads a basic synthdef' do
7
+ it 'reads a basic version 1 synthdef' do
7
8
  parsed_synthdef = Synthdef.read(synthdef_binary).snapshot
8
9
 
9
10
  expect(parsed_synthdef).to be_a(Hash)
10
11
  expect(parsed_synthdef).not_to be_empty
12
+ expect(parsed_synthdef[:synthdefs].first[:no_of_constants]).to eq(0)
13
+ expect(parsed_synthdef[:synthdefs].first[:no_of_params]).to eq(2)
14
+ end
15
+
16
+ it 'reads a complex version 2 synthdef' do
17
+ parsed_synthdef = Synthdef.read(complex_synthdef_binary).snapshot
18
+
19
+ expect(parsed_synthdef).to be_a(Hash)
20
+ expect(parsed_synthdef[:file_version]).to eq(2)
21
+ expect(parsed_synthdef[:no_of_synthdefs]).to eq(1)
22
+ expect(parsed_synthdef[:synthdefs].first[:no_of_constants]).to eq(32)
23
+ expect(parsed_synthdef[:synthdefs].first[:constants].last).to eq(-4.0)
24
+ expect(parsed_synthdef[:synthdefs].first[:no_of_params]).to eq(5)
25
+ expect(parsed_synthdef[:synthdefs].first[:param_names].last).to eq({param_name: "gate", param_index: 4})
26
+ expect(parsed_synthdef[:synthdefs].first[:no_of_ugens]).to eq(104)
27
+ expect(parsed_synthdef[:synthdefs].first[:ugens].last[:ugen_name]).to eq("Out")
28
+ expect(parsed_synthdef[:synthdefs].first[:no_of_variants]).to eq(0)
11
29
  end
12
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synthdef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xavier Riley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-24 00:00:00.000000000 Z
11
+ date: 2015-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -151,7 +151,9 @@ files:
151
151
  - Rakefile
152
152
  - lib/synthdef.rb
153
153
  - lib/synthdef/version.rb
154
+ - spec/data/hoover.scsyndef
154
155
  - spec/data/recorder.scsyndef
156
+ - spec/data/stereo_player.scsyndef
155
157
  - spec/spec_helper.rb
156
158
  - spec/synthdef_spec.rb
157
159
  - synthdef.gemspec
@@ -180,7 +182,9 @@ signing_key:
180
182
  specification_version: 4
181
183
  summary: Work with SuperCollider's binary synthdef format
182
184
  test_files:
185
+ - spec/data/hoover.scsyndef
183
186
  - spec/data/recorder.scsyndef
187
+ - spec/data/stereo_player.scsyndef
184
188
  - spec/spec_helper.rb
185
189
  - spec/synthdef_spec.rb
186
190
  has_rdoc: