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