musa-dsl 0.49.1 → 0.49.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
  SHA256:
3
- metadata.gz: b8f19ea8b2adc69b0337938f0db645b11ec6b021781b163f9d9d49bcc95470aa
4
- data.tar.gz: 1fd764ad354f2eba388fb2c74e2689919d4729dd875dfc27f75f4aff7bb1a261
3
+ metadata.gz: 707fe9806d319afc148d08559e3f57bae65802f8015a220c1cf9c65220c79ed2
4
+ data.tar.gz: 2df3f1fcdd21ca6fc5b7fe0f2325d3319033e79a6b09163738b8d18ae2a01850
5
5
  SHA512:
6
- metadata.gz: f7d6453e9842589676863769ecc0c4da051d2d1df76e53e5f65ed301465aa8a3eacb80706f8adb0cc4307bd12a8b889309276916e9e1192299cd3ace3cb9db08
7
- data.tar.gz: a5dd8a6f58085d18c4b572613fe688554bc21553fbf21b730dc118b2edabc92ca09736260655039908a1b42ed60fd477cb56e4fb6f43a0874184c4573d1c46e4
6
+ metadata.gz: 9bbf7c979c54e4dc937ca9172aaba7796fb3597afa29592e3e20d52466d947632c8885906d9de42ae35ce4639d8a49db37fdcaa3a150a452e02a3885d12fdbce
7
+ data.tar.gz: b3e51e89caa3db5fd86bf4f0f172df8b7845050f8ead625d92acf1e7c7926a5ec4c693d6ae945de6b102c8ed99cdc7c9c2b36ec4ee02881b5587de8e61c70590
@@ -220,15 +220,49 @@ clock = Musa::Clock::InputMidiClock.new(midi_input)
220
220
  # Create transport
221
221
  transport = Musa::Transport::Transport.new(clock, 4, 24)
222
222
 
223
- # Schedule events
224
- transport.sequencer.at 1 do
225
- puts "Synchronized start at bar 1!"
223
+ # Schedule events INSIDE on_start, not before transport.start. See below.
224
+ transport.on_start do
225
+ transport.sequencer.at 1 do
226
+ puts "Synchronized start at bar 1!"
227
+ end
226
228
  end
227
229
 
228
230
  # Start and wait for MIDI Clock Start message
229
231
  transport.start
230
232
  ```
231
233
 
234
+ ### Under a DAW's clock, schedule from `on_start` or `before_begin`
235
+
236
+ Anything scheduled before `transport.start` can be gone before the first note
237
+ sounds, and the reason is that pressing Play does not always send a Start.
238
+
239
+ A DAW with Song Position Pointer enabled cannot say "play from here" in one
240
+ message: `Start` means "from the beginning" and carries no position. So it sends
241
+ three -- `Stop`, `Song Position Pointer`, `Continue` -- and that first `Stop` is
242
+ a real stop. A stop resets the sequencer, which discards every `at`, `every` and
243
+ `play` registered on it. The transport then starts and runs an empty sequencer.
244
+
245
+ With Song Position Pointer switched off the same piece plays normally: Play
246
+ sends a plain `Start`, there is no stop, and nothing is reset.
247
+
248
+ Whether it bites depends on how the three messages arrive. They are sent within
249
+ a millisecond of each other, and when a single read returns all three the
250
+ transport repositions without stopping -- nothing is reset and a piece that
251
+ schedules early works. When they arrive apart, it does not.
252
+
253
+ That grouping is decided by the platform and by whatever else the machine is
254
+ doing at that moment, so **a piece written this way can work for years and then
255
+ stop working without anything in it having changed**: a different operating
256
+ system, a busier machine, a Ruby that schedules its threads differently. Working
257
+ today is not evidence that the rule does not apply.
258
+
259
+ **The symptom is silence, not an error**, and it is indistinguishable at a glance
260
+ from a transport that never started. If a piece runs mute under a DAW, read the
261
+ sequencer's position while it runs: advancing position with no notes is this.
262
+
263
+ `before_begin` and `on_start` run after that reset, which is what makes them the
264
+ right place.
265
+
232
266
  ## The lifecycle, run
233
267
 
234
268
  ```ruby
data/docs/vocabulary.md CHANGED
@@ -59,4 +59,4 @@ missing from the documents, and that is where to add it.
59
59
 
60
60
  ## transport
61
61
 
62
- `Clock` · `DummyClock` · `ExternalTickClock` · `InputMidiClock` · `TimerClock` · `Transport` · `after_stop` · `before_begin` · `change_position_to` · `n` · `on_change_position` · `on_start` · `on_stop` · `run` · `sequencer` · `start` · `stop` · `terminate` · `tick`
62
+ `Clock` · `DummyClock` · `ExternalTickClock` · `InputMidiClock` · `TimerClock` · `Transport` · `after_stop` · `at` · `before_begin` · `change_position_to` · `every` · `n` · `on_change_position` · `on_start` · `on_stop` · `play` · `run` · `sequencer` · `start` · `stop` · `terminate` · `tick`
@@ -284,6 +284,28 @@ module Musa
284
284
 
285
285
  when 'Continue'
286
286
  @logger.debug('InputMidiClock') { 'processing Continue...' }
287
+
288
+ # A Continue means "carry on playing", and carrying on from a stop is
289
+ # starting. Doing nothing here made the special case above -- Stop,
290
+ # Song Position Pointer and Continue arriving together -- the only
291
+ # path that could ever set @started outside a literal Start, and that
292
+ # path only matches when all three land in the same read.
293
+ #
294
+ # Whether they do is a property of the platform, not of the DAW. Core
295
+ # MIDI delivers packet lists that can carry several messages, so on
296
+ # macOS they usually arrive together; WinMM raises one notification
297
+ # per short message, so on Windows they usually do not. Measured
298
+ # against Bitwig with Song Position Pointer enabled, the Stop arrived
299
+ # alone 0.3 to 0.8 ms before the other two, and the grouping varied
300
+ # between presses of Play. The clock then discarded every tick
301
+ # forever: 1320 of them in one run, in silence.
302
+ #
303
+ # So the pattern above is no longer the only way in. It still earns
304
+ # its place -- when the three do arrive together it repositions
305
+ # without stopping, and a stop resets the sequencer -- but nothing
306
+ # depends on it any more.
307
+ process_start unless @started
308
+
287
309
  @logger.debug('InputMidiClock') { 'processing Continue... done' }
288
310
 
289
311
  when 'Clock'
@@ -1,3 +1,3 @@
1
1
  module Musa
2
- VERSION = '0.49.1'.freeze
2
+ VERSION = '0.49.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musa-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.49.1
4
+ version: 0.49.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Sánchez Yeste