Created
April 13, 2011 13:05
-
-
Save RyanScottLewis/917499 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
$LOAD_PATH.unshift(File.dirname(__FILE__)) | |
require 'midi-winmm' | |
# tested with midi-winmm, but I assume will work with alsa-rawmidi | |
class Numeric | |
def to_hex_str | |
"%02x" % self | |
end | |
end | |
class String | |
def to_hex_str | |
unpack('U' * length).collect { |x| "%02x" % x }.join | |
end | |
end | |
module MIDIWinMM | |
module Device | |
attr :id, :info, :type, :name, :enabled | |
end | |
end | |
# Every SysEx message sent to the BCR2000 or BCF2000 | |
# uses a language called BCL or B-Control Language.. | |
# Regrettably, Behringer never released the specs | |
# which makes it hard as hell to program. | |
# | |
# From here on, the BCR2000 and BCF2000 will simply | |
# be called "BCR" and "BCF", respectably. | |
# When refering to both devices, I'll simply write "BC". | |
module BControl | |
module Definitions | |
SysExStart = 0xf0 | |
SysExEnd = 0xf7 | |
SysExBehringer = [0x00, 0x20, 0x32] | |
Any = 0x7F | |
BCF2000 = 0x14 | |
BCR2000 = 0x15 | |
end | |
module SysEx | |
include Definitions | |
# Generates an array of bytes that results in a sysex message | |
def self.generate(id, model, command, data) | |
result = [] | |
result << SysExStart | |
result = result + SysExBehringer | |
result << id - 1 << model << command | |
# TODO: if data.is_a?(Array) then ADD the data array, not CONCAT | |
result << data | |
result << SysExEnd | |
end | |
end | |
# Cached list of devices. Use DeviceList#refresh! to ..well.. refresh the list. | |
class DeviceList < Array | |
def initialize; refresh!; end | |
def refresh!; replace(MIDIWinMM::Device.all); end | |
def all_of_type(type); find_all { |d| d.type == type }; end | |
end | |
Devices = DeviceList.new | |
class Device | |
attr :id, :model, :opened | |
def initialize(&blk) | |
@input_device = nil | |
@output_device = nil | |
@opened = false | |
@id = Definitions::Any | |
@model = Definitions::Any | |
end | |
def input_device(&blk) | |
raise("Cannot change input device when opened") if @open | |
block_given? ? @input_device = Devices.all_of_type(:input).find(&blk) : @input_device | |
end | |
def output_device(&blk) | |
raise("Cannot change output device when opened") if @open | |
block_given? ? @output_device = Devices.all_of_type(:output).find(&blk) : @output_device | |
end | |
def input_device?; !!@input_device; end | |
def output_device?; !!@output_device; end | |
def open?; @opened; end | |
alias :opened? :open | |
def id=(val) | |
@id = (1..16).include?(val) ? val : Definitions::Any | |
end | |
def model=(val) | |
is_valid_model = [Definitions::BCR2000, Definitions::BCF2000].include?(val) | |
@model = is_valid_model ? val : Definitions::Any | |
end | |
def open | |
@opened = true | |
@input_device.open if input_device? | |
@output_device.open if output_device? | |
end | |
def close | |
@opened = false | |
@input_device.close if input_device? | |
@output_device.close if output_device? | |
end | |
private # protected | |
def generate_sysex(command, data) | |
SysEx.generate(@id, @model, command, data) | |
end | |
end | |
class BCR2000 < Device | |
def initialize(id = Definitions::Any) | |
@id = id | |
@model = Definitions::BCR2000 | |
end | |
def select_preset(preset_number) | |
sysex_message = generate_sysex(0x22, preset_number - 1) | |
if output_device? && open? | |
@output_device.puts(sysex_message) | |
else | |
sysex_message | |
end | |
end | |
end | |
end | |
# ====================================================== | |
require 'pp' | |
bcr2000 = BControl::BCR2000.new | |
bcr2000.id = 1 | |
bcr2000.output_device { |d| d.name == "BCR2000" } # { |d| d.id == 0 } | |
bcr2000.open | |
bcr2000.select_preset(5) | |
bcr2000.close |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment