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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f05e5833d38340144b70f118284273333692da7
4
- data.tar.gz: f1f28455b5272f7dff4a7d2d3aa578bcf64fec49
3
+ metadata.gz: 5d054ce0fbe6cde52f1e23da9ca98b9b45769d05
4
+ data.tar.gz: 01fb805e03d44e0f5c7aa6dbb40a4b72bec9c7c5
5
5
  SHA512:
6
- metadata.gz: 4b600c61efe15377b72893b484b020894e7aba4cd4e902da2f0d46d99146bf98aea810624b23d0d603cf4020724d95188ca8cd21eb1d3cfe3663cecbb44f7281
7
- data.tar.gz: 170de1a63b8618181f7536fcfdcb8687602eaea3dd9e62ac07a3b68995188c32307f6edb2c432cf54542e5c734dcfa61be1049cbc124c29ea5d310f8ba294537
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 (via `apt-get`, `brew`, `yum`, etc)
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`. A third component,
31
- `StepSequencer::SoundAnalyser`, can also be useful.
30
+ `StepSequencer::SoundPlayer`
32
31
 
33
32
  ##### 1. **`StepSequencer::SoundBuilder`**
34
33
 
35
- There are number of `StepSequencer::SoundBuilder::EffectsComponents`
36
- (this constant refers to a hash, the values of which are classes).
37
- All of them inherit from and implement the protocol of
38
- `StepSequencer::SoundBuilder::EffectsComponentProtocol`. To use a custom effect,
39
- add the class to this list. Through the protocol, they're connected to the
40
- `StepSequencer::SoundBuilder.build` method.
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}] # doubling pitch to account for 0.5 speed
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 prevents this.
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 `_`, use the environment variables
177
- `STEP_SEQUENCER_GRID_HIT_CHAR` and `STEP_SEQUENCER_GRID_REST_CHAR`
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 configured to be manipulated while playing. Use a new instance instead.
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
- but may be slightly difficult considering many sounds can be played at once,
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 after installing the gem:
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 are packaged with the distributed gem, so after `require 'step_sequencer'`
227
- just use `StepSequencer::Tests.run`. Individual cases can also be run by calling
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
@@ -10,7 +10,7 @@ class StepSequencer::Tests::TestCases
10
10
  tempo: 240,
11
11
  limit: 16,
12
12
  string: <<-TXT,
13
- x _ x _
13
+ x _ x _ # with a comment
14
14
  _ _ x _
15
15
  TXT
16
16
  )
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module StepSequencer
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: step_sequencer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - max pleaner