module SynthBlocks::Sequencer::SequencerDSL

A module that implements a sequencer DSL

Usage

include SequencerDSL
def_pattern(:pattern_name, 16) do
  drum_pattern kickdrum, '*---*---*---*---'
end

my_song = song(bpm: 125) do
  pattern(:pattern_name, at: 0, repeat: 4)
end

output = my_song.render(44100) do |sample|
  kickdrum.run(sample)
end
print output.pack('e*')

Public Instance Methods

def_pattern(name, steps, &block) click to toggle source

Define a note pattern

# File lib/synth_blocks/sequencer/sequencer_dsl.rb, line 112
def def_pattern(name, steps, &block)
  @patterns ||= {}
  p = Pattern.new(steps)
  p.run(block)
  @patterns[name] = p
end
render(sfreq, start=0, len=nil) { |sample| ... } click to toggle source

render the song the actual rendering needs to be done manually in the block passed start & length in bars block gets an offset in samples it should render

# File lib/synth_blocks/sequencer/sequencer_dsl.rb, line 202
def render(sfreq, start=0, len=nil)
  start_time = start * @per_bar
  end_time = len ? start_time + len * @per_bar : length
  start_sample = (sfreq * start_time).floor
  end_sample = (sfreq * end_time).ceil
  sample = start_sample
  sample_len = end_sample - start_sample
  output = Array.new(sample_len)
  loop do
    output[sample - start_sample] = yield sample
    break if sample > end_sample
    sample += 1
  end
  output
end
song(bpm: 120, &block) click to toggle source

Define a song in the given tempo (in BPM) using the Song#pattern method

# File lib/synth_blocks/sequencer/sequencer_dsl.rb, line 187
def song(bpm: 120, &block)
  song = Song.new(bpm, @patterns)
  song.run(block)
  song.play
  # File.open("DEBUG.txt", 'wb') do |f|
  #   f.print song.events.inspect
  # end
  song
end