Created
August 15, 2010 11:06
-
-
Save alltom/525366 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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