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 +4 -4
- data/README.md +115 -4
- data/lib/synthdef.rb +21 -12
- data/lib/synthdef/version.rb +1 -1
- data/spec/data/hoover.scsyndef +0 -0
- data/spec/data/recorder.scsyndef +0 -0
- data/spec/data/stereo_player.scsyndef +0 -0
- data/spec/synthdef_spec.rb +19 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 665422f13978b9e8381467e67573a50fb522f768
|
4
|
+
data.tar.gz: c2110f4a9fbfa0a0791ed3ce7b559e3f39263bf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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",
|
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
|
data/lib/synthdef.rb
CHANGED
@@ -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
|
-
|
17
|
-
|
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
|
-
|
23
|
-
array
|
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
|
-
|
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
|
-
|
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
|
40
|
+
choice :param_index, :selection => :check_version, :choices => {0 => :int16, 1 => :int32}
|
36
41
|
end
|
37
42
|
|
38
|
-
|
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
|
43
|
-
int16
|
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 :
|
47
|
-
|
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
|
data/lib/synthdef/version.rb
CHANGED
Binary file
|
data/spec/data/recorder.scsyndef
CHANGED
Binary file
|
Binary file
|
data/spec/synthdef_spec.rb
CHANGED
@@ -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.
|
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-
|
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:
|