Skip to content

Instantly share code, notes, and snippets.

@saimonmoore
Forked from ahx/drummachine.rb
Created November 10, 2008 11:21
Show Gist options
  • Save saimonmoore/23475 to your computer and use it in GitHub Desktop.
Save saimonmoore/23475 to your computer and use it in GitHub Desktop.
#
# A try to built a simple drummachine using Shoes and Midiator.
# Unfortunalty animation seems to be quite processor heavy. Things might get slow..
# Because of that, the beats don't get highlighted on beat.
#
# You will need a midi input for this.
# On OSX you could use http://notahat.com/midi_patchbay
# and http://notahat.com/simplesynth or Garage Band
#
# Usage:
# Klick to toggle beat
# Press SPACE to start/stop the loop
#
# Andreas Haller (http://github.com/ahaller)
# enjoy.
# One Square representing a Beat
class Shoes::Beatbutton < Shoes::Widget
attr :options
def initialize(o = {})
# FIXME Move this maybe out of here!? Widget should be "gui-only"!?
# options
@options = {
:selected => false,
:note => 48,
:channel => 0,
:duration => 1.5
}.merge!(o)
@selected = @options[:selected]
# styling
self.style :width => 25, :height => 25 # FIXME delete (?)
strokewidth 4
# draw beat
stack :width => 25, :height => 25 do
draw_boxes
click do
toggle
end
end
end
def selected?
@selected
end
def toggle
@box_selected.toggle
@selected = !@selected
end
private
def draw_boxes
fill gray; nostroke
@box = box
fill white
@box_selected = box
@box_selected.hide
end
# drawing a box
def box
rect(0,0,25,25,4)
end
end
# A row of beats
class Shoes::Track < Shoes::Widget
attr :beats
def initialize(o = {})
@options = {
:beat => {}
}.merge!(o)
@beats = []
flow do
16.times do
@beats << beatbutton(@options[:beat].clone)
end
end
end
end
# Run the Shoes app
Shoes.setup do
gem 'midiator >= 0.2.0'
end
require 'midiator'
# Run the shoes app
Shoes.app :width => 420, :height => 130, :margin => 10, :resizable => false do
# Setup midi driver
@midi = MIDIator::Interface.new
@midi.autodetect_driver
@midi.program_change 0, 25 # Electronic Drumset
# Tempo
@tempo = 8
# Basic styling
background black
border black, :strokewidth => 4
stack :margin => 10 do
# Create tracks
@tracks = [
# You might want out your own notes here
track(:beat => {:note => 34}),
track(:beat => {:note => 46}),
track(:beat => {:note => 38}),
track(:beat => {:note => 36})
]
# position-marker / playhead
stroke yellow; nofill
@marker = rect(0,0,25,100,4)
end
# Main loop / Tick
@loop = animate @tempo do |i|
pos = i % 16 # on which tick are we
@marker.left = pos*25 # One beat-square is 25px # FIXME DRY 25
@tracks.each do |track|
beat = track.beats[pos] # getting current beat in track
if beat.selected?
Thread.new {
@midi.play(beat.options[:note],
beat.options[:duration],
beat.options[:channel]
)
}
end
end
end
# Keys
keypress do |key|
@loop.toggle if key == " "
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment