step_sequencer 1.0.0 → 1.0.1
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 +26 -31
- data/lib/step_sequencer/sound_player.rb +6 -20
- data/lib/step_sequencer/tests/test_cases.rb +1 -1
- data/lib/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d054ce0fbe6cde52f1e23da9ca98b9b45769d05
|
4
|
+
data.tar.gz: 01fb805e03d44e0f5c7aa6dbb40a4b72bec9c7c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b410a219bc1270e3e6ed728c5dc304169d1c23f7627190f38a6b6bac19281dcaa50ef08ec9daffc4ae3767f2242b3cb30fafbe98ed7735361a7f91a22b7cb35
|
7
|
+
data.tar.gz: a640503ed21c0079c08502ad06f9cd3eaeb7118a78b1d12420ba92ead42f56f6e70341a8e40b99fd64a9ca2be1ad9e3758df2ffc93ba0de53b13600e1a578376
|
data/README.md
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
|
5
5
|
This is a Ruby tool to play mp3 files in a step sequencer.
|
6
6
|
|
7
|
-
It also handles polyrhythmic playback and
|
7
|
+
It also handles polyrhythmic playback and building sounds using effects like
|
8
8
|
|
9
9
|
#### Depedencies
|
10
10
|
|
11
|
-
Some external programs need to be installed
|
11
|
+
Some external programs need to be installed:
|
12
12
|
|
13
13
|
`mpg123 ffmpeg sox libsox-fmt-mp3`
|
14
14
|
|
@@ -27,17 +27,19 @@ require 'step_sequencer'
|
|
27
27
|
#### Usage
|
28
28
|
|
29
29
|
There are two main components: `StepSequencer::SoundBuilder` and
|
30
|
-
`StepSequencer::SoundPlayer
|
31
|
-
`StepSequencer::SoundAnalyser`, can also be useful.
|
30
|
+
`StepSequencer::SoundPlayer`
|
32
31
|
|
33
32
|
##### 1. **`StepSequencer::SoundBuilder`**
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
`
|
39
|
-
|
40
|
-
`StepSequencer::SoundBuilder
|
34
|
+
This offers only one public method, `.build`, which is drastically overloaded
|
35
|
+
and dispatches to a number of other classes (each of which is responsible for
|
36
|
+
a single effect). The definitions of these can be found in the source code at
|
37
|
+
`lib/step_sequencer/sound_builder/default_effects/`. To add a custom effect,
|
38
|
+
use one of the existing ones as a template and then add a reference to the class
|
39
|
+
in the `StepSequencer::SoundBuilder::EffectsComponents` hash.
|
40
|
+
|
41
|
+
Here is an example. It takes a single input mp3 and creates 12 new ones,
|
42
|
+
spanning the "equal temperament" tuning.
|
41
43
|
|
42
44
|
```rb
|
43
45
|
# returns nested array (array of generated sounds for each source)
|
@@ -81,10 +83,10 @@ _change pitch_ (returns array of paths, one for each source)
|
|
81
83
|
new_filenames = builder.build(
|
82
84
|
sources: filenames,
|
83
85
|
effect: :Pitch,
|
84
|
-
args: [{value: 2}]
|
86
|
+
args: [{value: 2}]
|
85
87
|
)
|
86
88
|
# By default this will adjust the speed so that only the pitch changes.
|
87
|
-
# However the `speed_correction: false` arg
|
89
|
+
# However the `speed_correction: false` arg will prevent this.
|
88
90
|
```
|
89
91
|
|
90
92
|
_loop_ (returns array of paths, one for each source)
|
@@ -118,7 +120,7 @@ new_filenames = builder.build(
|
|
118
120
|
args: [{filename: "foo.mp3"}], # filename arg is optional,
|
119
121
|
# and one will be auto-generated otherwise.
|
120
122
|
)
|
121
|
-
|
123
|
+
```
|
122
124
|
|
123
125
|
_overlay_ (returns single path)
|
124
126
|
|
@@ -129,7 +131,7 @@ new_filenames = builder.build(
|
|
129
131
|
args: [{filename: "foo.mp3"}], # filename arg is optional,
|
130
132
|
# and one will be auto-generated otherwise.
|
131
133
|
)
|
132
|
-
|
134
|
+
```
|
133
135
|
|
134
136
|
As the above examples illustrate, `#build` is always given an array of sources
|
135
137
|
(audio paths). `effect` is always a symbol, and although it can be ommitted if
|
@@ -143,7 +145,7 @@ which is when the sounds are mapped to rows.
|
|
143
145
|
|
144
146
|
For example, say I want to plug in the sounds I created earlier using
|
145
147
|
`StepSequencer::SoundBuilder#build`. I have 12 sounds and I want to give each
|
146
|
-
of them their own row in the sequencer. This pretty easy to do:
|
148
|
+
of them their own row in the sequencer. This is pretty easy to do:
|
147
149
|
|
148
150
|
```rb
|
149
151
|
player = StepSequencer::SoundPlayer.new(filenames)
|
@@ -173,12 +175,12 @@ player.play(
|
|
173
175
|
)
|
174
176
|
```
|
175
177
|
|
176
|
-
To use something other than `x` or `_`,
|
177
|
-
|
178
|
+
To use something other than `x` or `_`, set the options `:hit_char` and `:rest_char`.
|
179
|
+
|
180
|
+
The following plays the same notes, but with nested arrays and the `:matrix` option.
|
181
|
+
The hits/rests here are denoted by 1 and nil, respectively
|
178
182
|
|
179
183
|
```rb
|
180
|
-
# plays the same notes, but with nested arrays.
|
181
|
-
# the note/rest are denoted by 1 and nil, respectively
|
182
184
|
player.play(
|
183
185
|
tempo: 240,
|
184
186
|
matrix: 0.upto(11).reduce([]) do |rows, i|
|
@@ -201,13 +203,12 @@ play the aformentioned 12-step grid 4 times, I'd pass a limit of 48.
|
|
201
203
|
something like `sleep 0.5 while player.playing`
|
202
204
|
- the tempo can be understood as BPM in quarter notes. So to get the same speed
|
203
205
|
as 16th notes at 120 BPM, use a tempo of 480. The default is 120.
|
204
|
-
- The player isn't
|
206
|
+
- The player isn't set up to be manipulated while playing. Use a new instance instead.
|
205
207
|
|
206
208
|
#### Todos
|
207
209
|
|
208
210
|
- precompile the grid into a single mp3. this will result in optimal playback
|
209
|
-
|
210
|
-
and a single sound can be played over itself.
|
211
|
+
- make a nice REPL
|
211
212
|
|
212
213
|
#### Tests
|
213
214
|
|
@@ -217,17 +218,11 @@ Rather, it generates sounds and then plays them back for manual aural
|
|
217
218
|
validation.
|
218
219
|
|
219
220
|
A couple small (1 second) mp3s are bundled with the gem and are used in the tests.
|
220
|
-
To run the tests from the command line
|
221
|
+
To run the tests from the command line, use the executable included with the gem:
|
221
222
|
|
222
223
|
```rb
|
223
224
|
step_sequencer test
|
224
225
|
```
|
225
226
|
|
226
|
-
They
|
227
|
-
|
228
|
-
the class methods of `Builder` and `Player` in `StepSequencer::Tests::TestCases`.
|
229
|
-
|
230
|
-
There is one extra dependency required to use the tests, and that's the
|
231
|
-
`espeak-ruby` gem. which will indicate what sounds are playing.
|
232
|
-
This requires the external tool to be installed as well,
|
233
|
-
e.g. `brew install espeak` or `sudo apt-get install espeak`.
|
227
|
+
They can also be run from code: `require 'step_sequencer'` then
|
228
|
+
`StepSequencer::Tests.run`.
|
@@ -2,13 +2,6 @@ class StepSequencer::SoundPlayer
|
|
2
2
|
|
3
3
|
using StepSequencer.refinement(:StringBlank)
|
4
4
|
|
5
|
-
HitChar = ENV.fetch("STEP_SEQUENCER_GRID_HIT_CHAR", "x")
|
6
|
-
RestChar = ENV.fetch("STEP_SEQUENCER_GRID_REST_CHAR", "_")
|
7
|
-
|
8
|
-
if [HitChar, RestChar].any? &:blank?
|
9
|
-
raise StandardError, "HitChar or RestChar cannot be just whitespace"
|
10
|
-
end
|
11
|
-
|
12
5
|
attr_reader :playing
|
13
6
|
|
14
7
|
def initialize(sources)
|
@@ -16,8 +9,9 @@ class StepSequencer::SoundPlayer
|
|
16
9
|
reset_state
|
17
10
|
end
|
18
11
|
|
19
|
-
def play(tempo: 120, string: nil, matrix: nil, limit: nil)
|
12
|
+
def play(tempo: 120, string: nil, matrix: nil, limit: nil, hit_char: 'x', rest_char: '_')
|
20
13
|
@limit = limit
|
14
|
+
@hit_char, @rest_char = hit_char, rest_char
|
21
15
|
if @playing
|
22
16
|
raise( StandardError,
|
23
17
|
"A sound player received #play when it was not in a stopped state.
|
@@ -51,15 +45,15 @@ class StepSequencer::SoundPlayer
|
|
51
45
|
private
|
52
46
|
|
53
47
|
def build_matrix_from_string(string)
|
54
|
-
string.tr(" ", '').split("\n").map(&:chars).map do |chars|
|
48
|
+
string.tr(" ", '').gsub(/\#.+$/, '').split("\n").map(&:chars).map do |chars|
|
55
49
|
chars.map do |char|
|
56
|
-
if char == hit_char then 1
|
57
|
-
elsif char == rest_char then nil
|
50
|
+
if char == @hit_char then 1
|
51
|
+
elsif char == @rest_char then nil
|
58
52
|
else
|
59
53
|
raise( StandardError,
|
60
54
|
"
|
61
55
|
Error playing from string. Found char #{char} which is not
|
62
|
-
one of '#{hit_char}' or '#{rest_char}'.
|
56
|
+
one of '#{@hit_char}' or '#{@rest_char}'.
|
63
57
|
"
|
64
58
|
)
|
65
59
|
end
|
@@ -121,12 +115,4 @@ class StepSequencer::SoundPlayer
|
|
121
115
|
@active_steps = Array.new((matrix.length), 0)
|
122
116
|
end
|
123
117
|
|
124
|
-
def hit_char
|
125
|
-
self.class::HitChar
|
126
|
-
end
|
127
|
-
|
128
|
-
def rest_char
|
129
|
-
self.class::RestChar
|
130
|
-
end
|
131
|
-
|
132
118
|
end
|
data/lib/version.rb
CHANGED