synthdef 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: