module ZXUtils::MusicBox::MultitrackCommands
MusicBox
MultitrackCommands
¶ ↑
Commands for multi-tracks.
For the other available commands see: TrackConfigCommands
.
Public Class Methods
Returns a channel index: 0 to 2 for the given channel
name.
A channel
can be an integer: 0 to 2 or one of the symbols or strings: :a
, :b
, :c
.
# File lib/zxutils/music_box/multitrack.rb, line 30 def self.channel_name_to_index(channel) case channel when 0, 'a'.freeze, 'A'.freeze, :a, :A then 0 when 1, 'b'.freeze, 'B'.freeze, :b, :B then 1 when 2, 'c'.freeze, 'C'.freeze, :c, :C then 2 else raise ArgumentError, "Couldn't guess which channel you've had in mind: #{channel.inspect}" end end
Public Instance Methods
Creates a track fragments with the same commands for all the channels.
Provide a block with commands suitable for MusicBox::Track
.
The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 114 def all_channels(&block) (0..2).each {|ch| channel(ch, &block) } end
Creates a track fragment for the A channel.
Provide a block with commands suitable for MusicBox::Track
. The track will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 125 def ch_a(&block) channel 0, &block end
Creates a track fragment for the B channel.
Provide a block with commands suitable for MusicBox::Track
. The track will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 135 def ch_b(&block) channel 1, &block end
Creates a track fragment for the C channel.
Provide a block with commands suitable for MusicBox::Track
. The track will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 145 def ch_c(&block) channel 2, &block end
Creates a track fragment for the given channel_name
.
Provide a block with commands suitable for MusicBox::Track
.
A channel_name
can be an integer: 0 to 2 or one of the symbols or strings: :a
, :b
, :c
.
The track will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 73 def channel(ch_name, &block) ch_index = MultitrackCommands.channel_name_to_index ch_name tracks = if (last_entry = @channels.last) and TracksEntry === last_entry and last_entry[ch_index].nil? last_entry else TracksEntry.new.tap {|t| @channels << t } end first_octave_note_ = @first_octave_note tempo_ = @tempo tracks[ch_index] = Class.new do |klass| include Track first_octave_note(first_octave_note_) tempo(tempo_) klass.module_eval(&block) end end
Creates a track fragments with the same commands for the channels indicated by channel_names
.
Provide a block with commands suitable for MusicBox::Track
.
A channel_names
can be integers: 0 to 2 or the symbols or strings: :a
, :b
, :c
.
The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 100 def for_channels(*chs, &block) chs.map {|ch| MultitrackCommands.channel_name_to_index ch }. each {|ch| channel(ch, &block) } end
Loops execution from the marked point name
. Repeats repeat
times. If repeat
is nil
or missing loops forever.
See also MultitrackCommands.mark
and MultitrackCommands.repeat
. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 216 def loop_to(mark_name, repeat=nil) @channels << LoopCommand.new(mark_name, repeat) @channels.length end
Marks a point in tracks and gives it a name
as a symbol or a string. You can later use MultitrackCommands.loop_to
with a marked point name. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 202 def mark(name) @channels << MarkCommand.new(name) @channels.length end
Pauses tracks execution for a length
period. The length
value should be a positive integer.
The number of ticks
paused is being calculated based on the TrackConfigCommands.tempo
value.
ticks = tempo / length
For the tempo unrelated pause see MultitrackCommands.wait
. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 187 def pause(length, *length_exts) ticks = Rational(@tempo, length) length_exts.each do |len_ext| ticks += Rational(@tempo, len_ext) end wait(ticks) end
Repeats the execution of the commands in the given block repeat
times. If repeat
is nil
or missing repeats forever.
See also MultitrackCommands.mark
and MultitrackCommands.loop_to
. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 230 def repeat(times=nil, mark:nil, &block) mark_cmd = MarkCommand.new(mark) @channels << mark_cmd if times != 0 yield unless @channels.last.equal?(mark_cmd) or times == 1 loop_to mark_cmd.mark_name, times end end @channels.length end
Yields execution of the tracks to another multi-track with the given multitrack_name
as a symbol or a string. When the sub-tracks execution is finished, the yielding multi-track will resume execution. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 155 def sub_track(multitrack_name) @channels << SubMultitrackEntry.new(multitrack_name) @channels.length end
Specify ranges of allowed ticks for each channel's track synchronization. If the given track is behind the most advanced track N ticks it will be synchronized only if the N matches the given range. However if the upper bound of the range is given, when exceeded a compilation error will occur.
If the value is nil
the previous range, set for the channel is not being changed.
Example:
synchronize_channels a:2..10, b:0.., c:5...5
The above command will allow channel A to fall behind by no more than 10 ticks and will be synchronized only if it lags 2 or more ticks behind. It will also allow channel B to fall behind by any number of ticks and will always be synchronized. It will also restrict channel C to fall behind by a maximum 4 number of ticks and will never be synchronized.
- NOTE
-
For Ruby < 2.6 (where endless range was introduced) instead of 0.. use 0…2**16.
By default a:0.., b:0.., c:0.. is set.
# File lib/zxutils/music_box/multitrack.rb, line 59 def synchronize_channels(a:nil, b:nil, c:nil) @channels << SynchronizeChannelsEntry.new(a, b, c) @channels.length end
Pauses tracks execution for ticks
number of ticks. The ticks
value should be a positive integer as an Integer or a Rational.
For the TrackConfigCommands.tempo
related pause see MultitrackCommands.pause
. The tracks will be synchronized accordingly with the other channel's tracks.
# File lib/zxutils/music_box/multitrack.rb, line 169 def wait(ticks) @channels << PauseCommand.new(ticks) @channels.length end