Skip to content

Instantly share code, notes, and snippets.

@alltom
Created August 15, 2010 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alltom/525366 to your computer and use it in GitHub Desktop.
Save alltom/525366 to your computer and use it in GitHub Desktop.
require "rubygems"
require "osc"
require "midiator"
require "ruck"
require "rstyx"
include Ruck
include MIDIator::Drums
SERVER_HOST = "localhost"
SERVER_PORT = 5000
class RealTimeShreduler < Shreduler
def initialize
super
@shred_queue = []
@shreds_by_id = {}
@next_shred_id = 1
end
def start_time
@start_time ||= Time.now
end
def actual_now
Time.now - start_time
end
def enqueue(code)
@shred_queue << code
end
def kill(shred_id)
shred = @shreds_by_id[shred_id] || return
shred.kill
end
def catch_up
if @shred_queue.length > 0
to_add = @shred_queue.dup
@shred_queue.clear
to_add.each do |code|
puts "loading shred #{@next_shred_id}..."
@shreds_by_id[@next_shred_id] = spork { Module.new.instance_eval(code) }
@next_shred_id += 1
end
end
run_until actual_now
end
def run
loop { catch_up }
end
end
### GOGOGOGOGOGOGO!
Thread.new do
server = OSC::UDPServer.new
server.bind SERVER_HOST, SERVER_PORT
server.add_method "/live/add", "s" do |msg|
$shreduler.enqueue(msg.args[0])
end
server.serve
end
$midi = MIDIator::Interface.new
# $midi.autodetect_driver
$midi.use :dls_synth # OS X built-in synth
def instrument(channel, program, bank_msb, bank_lsb)
# 32: bank select
$midi.control_change 32, channel, bank_lsb
$midi.program_change channel, program
# TODO: msb
end
# TR-808 is Program 26 in LSB bank 1
# $midi.control_change 32, 10, 1 # number, channel, value
# $midi.program_change 10, 26 # channel, program
instrument(10, 25, 0, 1)
# $midi.control_change 32, 10, 0 # number, channel, value
# $midi.program_change 10, 128 # channel, program
class Object
def drum(note = BassDrum1, velocity = 127)
$midi.note_on(note, 10, velocity)
spork { Shred.yield(0.1); $midi.note_off(note, 10) }
end
def piano(note, velocity = 127)
$midi.note_on(note, 0, velocity)
end
def piano_off(note)
piano(note, 0)
end
def beat_sync(offset = 0.0, clock = $bc)
Shred.yield(1.0 - ($bc.now % 1.0) + offset, clock)
end
def measure_sync(offset = 0.0, clock = $bc)
Shred.yield(4.0 - ($bc.now % 4.0) + offset, clock)
end
end
class Fixnum
alias :old_mod :%
def %(o)
if Range === o
(self - o.first) % (o.last - o.first) + o.first
else
old_mod(o)
end
end
end
shreduler = RealTimeShreduler.new
shreduler.make_convenient
$bc = Clock.new(130.0 / 60.0)
$shreduler.clock.add_child_clock($bc)
# drum BassDrum1
# drum CrashCymbal1
# piano 40
# piano_off 40
shreduler.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment