Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 72 lines (59 sloc) 1.304 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
# An implementation of Bjorklund's algorithm applied to rhythm.
# Inspired by http://ruinwesen.com/blog?id=216

require 'music'

include Music

module Euclid
  module_function
  def euclid(k, n)
    raise ArgumentError, "`k' must be less than `n'" unless k < n
    bjorklund Array.new(k, [true]) + Array.new(n - k, [false])
  end
  
  def bjorklund(seqs)
    real, rem = split_rem(seqs)
    if rem.size <= 1
      (real + rem).flatten
    else
      bjorklund(interleave(real, rem))
    end
  end
  
  def split_rem(seq)
    rem, real = seq.partition { |x| x == seq.last }
    if rem.size == real.size
      return seq, []
    else
      return real, rem
    end
  end
  
  def interleave(list1, list2)
    res = []
    l1 = list1.dup
    l2 = list2.dup
    until l1.empty? && l2.empty?
      e1 = l1.shift || []
      e2 = l2.shift || []
      res.push(e1 + e2)
    end
    res
  end
end

def kick(*args)
  n(35, *args)
end

def snare(*args)
  n(38, *args)
end

def rhythm(k, n)
  bits = Euclid.euclid(k, n)
  s(bits.map { |pulse| pulse ? kick(SN) : r(SN) }) * 2
end

def tick
  (r & snare(1)) * 2
end

def score
  ks = rhythm(3, 8) & rhythm(7, 8) & rhythm(5, 8) & rhythm(7, 8)
  ss = tick * 4
  ks | ss
end

SMFWriter.new(:tempo => 136).
  track(score, :name => 'Euclidean Etude').
  save('euclid')
Something went wrong with that request. Please try again.