mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-18 20:56:28 +01:00
MCP: remove files no longer used (copies are always available in 2.0-ongoing for historical purposes)
git-svn-id: svn://localhost/ardour2/branches/3.0@11835 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c6c98b6453
commit
6315a979a1
21 changed files with 6 additions and 1342 deletions
|
|
@ -1,18 +0,0 @@
|
||||||
For usage, see
|
|
||||||
|
|
||||||
http://www.ardour.org/files/manual/sn-mackie.html
|
|
||||||
|
|
||||||
unfortunately it's a bit outdated, so to get the latest manual, go to the manual
|
|
||||||
directory in the ardour source tree, and say "make html" to build the latest.
|
|
||||||
Then point your favourite browser at tmp/index.html
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
* support for alsa/sequencer ports is currently broken. We're working on it.
|
|
||||||
|
|
||||||
* you'll need to make port changes in etc/ardour3/ardour_system.rc and
|
|
||||||
etc/ardour3/ardour.rc, otherwise they don't stay changed in ~/.ardour3/ardour.rc
|
|
||||||
|
|
||||||
|
|
||||||
John Anderson
|
|
||||||
panic@semiosix.com
|
|
||||||
|
|
@ -263,23 +263,22 @@ MackieControlProtocol::switch_banks (int initial)
|
||||||
// DON'T prevent bank switch if initial == _current_initial_bank
|
// DON'T prevent bank switch if initial == _current_initial_bank
|
||||||
// because then this method can't be used as a refresh
|
// because then this method can't be used as a refresh
|
||||||
|
|
||||||
// sanity checking
|
|
||||||
Sorted sorted = get_sorted_routes();
|
Sorted sorted = get_sorted_routes();
|
||||||
int delta = sorted.size() - route_table.size();
|
int delta = sorted.size() - route_table.size();
|
||||||
|
|
||||||
if (initial < 0 || (delta > 0 && initial > delta)) {
|
if (initial < 0 || (delta > 0 && initial > delta)) {
|
||||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
|
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("not switching to %1\n", initial));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_current_initial_bank = initial;
|
|
||||||
|
|
||||||
// first clear the signals from old routes
|
_current_initial_bank = initial;
|
||||||
// taken care of by the RouteSignal destructors
|
|
||||||
clear_route_signals();
|
clear_route_signals();
|
||||||
|
|
||||||
// now set the signals for new routes
|
// now set the signals for new routes
|
||||||
if (_current_initial_bank <= sorted.size()) {
|
if (_current_initial_bank <= sorted.size()) {
|
||||||
// fetch the bank start and end to switch to
|
|
||||||
uint32_t end_pos = min (route_table.size(), sorted.size());
|
uint32_t end_pos = min (route_table.size(), sorted.size());
|
||||||
|
uint32_t i = 0;
|
||||||
Sorted::iterator it = sorted.begin() + _current_initial_bank;
|
Sorted::iterator it = sorted.begin() + _current_initial_bank;
|
||||||
Sorted::iterator end = sorted.begin() + _current_initial_bank + end_pos;
|
Sorted::iterator end = sorted.begin() + _current_initial_bank + end_pos;
|
||||||
|
|
||||||
|
|
@ -289,7 +288,7 @@ MackieControlProtocol::switch_banks (int initial)
|
||||||
set_route_table_size (surface().strips.size());
|
set_route_table_size (surface().strips.size());
|
||||||
|
|
||||||
// link routes to strips
|
// link routes to strips
|
||||||
uint32_t i = 0;
|
|
||||||
for (; it != end && it != sorted.end(); ++it, ++i) {
|
for (; it != end && it != sorted.end(); ++it, ++i) {
|
||||||
boost::shared_ptr<Route> route = *it;
|
boost::shared_ptr<Route> route = *it;
|
||||||
|
|
||||||
|
|
@ -301,8 +300,7 @@ MackieControlProtocol::switch_banks (int initial)
|
||||||
set_route_table (i, route);
|
set_route_table (i, route);
|
||||||
RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i));
|
RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i));
|
||||||
route_signals.push_back (rs);
|
route_signals.push_back (rs);
|
||||||
// update strip from route
|
rs->notify_all ();
|
||||||
rs->notify_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create dead strips if there aren't enough routes to
|
// create dead strips if there aren't enough routes to
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
|
|
||||||
class Bank
|
|
||||||
attr_accessor :routes, :strips, :current
|
|
||||||
|
|
||||||
def initialize( routes = 17, strips = 8, current = 0 )
|
|
||||||
@routes = routes
|
|
||||||
@strips = strips
|
|
||||||
@current = current
|
|
||||||
end
|
|
||||||
|
|
||||||
def left
|
|
||||||
new_initial = current - routes
|
|
||||||
if new_initial < 0
|
|
||||||
new_initial = 0
|
|
||||||
end
|
|
||||||
current = new_initial
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def right
|
|
||||||
delta = routes - ( strips + current ) - 1
|
|
||||||
puts "delta: #{delta}"
|
|
||||||
if delta > strips
|
|
||||||
delta = strips
|
|
||||||
end
|
|
||||||
@current += delta
|
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
b=Bank.new
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
type,count,group,name,switch,led,id
|
|
||||||
# faders
|
|
||||||
fader,7,strip,gain,1,0,0x00
|
|
||||||
fader,1,master,gain,1,0,0x07
|
|
||||||
|
|
||||||
# pots
|
|
||||||
pot,7,strip,vpot,1,1,0x10
|
|
||||||
pot,1,,jog,1,0,0x17
|
|
||||||
pot,1,,external,1,0,0x2e
|
|
||||||
|
|
||||||
# strip buttons
|
|
||||||
button,7,strip,recenable,1,1,0x18
|
|
||||||
button,7,strip,solo,1,1,0x20
|
|
||||||
button,7,strip,mute,1,1,0x10
|
|
||||||
button,7,strip,select,1,1,0x0
|
|
||||||
button,7,strip,vselect,1,0,0x08
|
|
||||||
|
|
||||||
# overlay buttons
|
|
||||||
button,1,assignment,io,1,1,0x28
|
|
||||||
button,1,assignment,sends,1,1,0x5a
|
|
||||||
button,1,assignment,pan,1,1,0x59
|
|
||||||
button,1,assignment,plugin,1,1,0x57
|
|
||||||
button,1,functions,drop,1,1,0x58 # was eq
|
|
||||||
button,1,assignment,zoom,1,1,0x2d
|
|
||||||
button,1,bank,left,1,0,0x2e
|
|
||||||
button,1,bank,right,1,0,0x2f
|
|
||||||
button,1,bank,channel_left,1,0,0x30
|
|
||||||
button,1,bank,channel_right,1,0,0x31
|
|
||||||
button,1,,scrub,1,1,0x32
|
|
||||||
button,1,,edit,1,1,0x56
|
|
||||||
|
|
||||||
button,1,display,name_value,1,0,0x34
|
|
||||||
button,1,display,smpte_beats,1,0,0x35
|
|
||||||
button,1,,F1,1,0,0x36
|
|
||||||
button,1,,F2,1,0,0x37
|
|
||||||
button,1,,F3,1,0,0x38
|
|
||||||
button,1,,F4,1,0,0x39
|
|
||||||
button,1,,F5,1,0,0x3a
|
|
||||||
button,1,,F6,1,0,0x3b
|
|
||||||
button,1,,F7,1,0,0x3c
|
|
||||||
button,1,,F8,1,0,0x3d
|
|
||||||
button,1,,F9,1,0,0x3e
|
|
||||||
button,1,,F10,1,0,0x3f
|
|
||||||
button,1,,F11,1,0,0x40
|
|
||||||
button,1,,F12,1,0,0x41
|
|
||||||
button,1,,F13,1,0,0x42
|
|
||||||
button,1,,F14,1,0,0x43
|
|
||||||
button,1,,F15,1,0,0x44
|
|
||||||
button,1,,F16,1,0,0x45
|
|
||||||
# turn on/off all solos
|
|
||||||
button,1,,global_solo,1,0,0x27
|
|
||||||
button,1,modifiers,option,1,0,0x50
|
|
||||||
button,1,modifiers,cmd_alt,1,0,0x49
|
|
||||||
button,1,automation,on,1,1,0x4a
|
|
||||||
button,1,automation,rec_ready,1,1,0x4b
|
|
||||||
button,1,functions,undo,1,1,0x4c
|
|
||||||
button,1,automation,snapshot,1,1,0x5f
|
|
||||||
button,1,functions,redo,1,1,0x4f
|
|
||||||
button,1,functions,marker,1,1,0x47
|
|
||||||
button,1,functions,enter,1,1,0x51
|
|
||||||
button,1,functions,cancel,1,0,0x52
|
|
||||||
button,1,functions,mixer,1,0,0x53
|
|
||||||
button,1,functions,save,1,0,0x4d
|
|
||||||
|
|
||||||
# transport buttons
|
|
||||||
button,1,transport,frm_left,1,1,0x5b
|
|
||||||
button,1,transport,frm_right,1,1,0x5c
|
|
||||||
button,1,transport,loop,1,1,0x46
|
|
||||||
button,1,transport,punch_in,1,1,0x48
|
|
||||||
button,1,transport,punch_out,1,1,0x4e
|
|
||||||
button,1,transport,home,1,1,0x2a
|
|
||||||
button,1,transport,end,1,1,0x29
|
|
||||||
button,1,transport,"rewind",1,1,0x2c
|
|
||||||
button,1,transport,"ffwd",1,1,0x2b
|
|
||||||
button,1,transport,"stop",1,1,0x5d
|
|
||||||
button,1,transport,"play",1,1,0x5e
|
|
||||||
button,1,transport,"record",1,1,0x1f
|
|
||||||
button,1,cursor,"cursor_up",1,0,0x60
|
|
||||||
button,1,cursor,"cursor_down",1,0,0x61
|
|
||||||
button,1,cursor,"cursor_left",1,0,0x62
|
|
||||||
button,1,cursor,"cursor_right",1,0,0x63
|
|
||||||
button,1,,"dyn",1,1,0x64
|
|
||||||
button,1,,"flip",1,1,0x65
|
|
||||||
button,1,user,"user_a",1,0,0x66
|
|
||||||
button,1,user,"user_b",1,0,0x67
|
|
||||||
|
|
||||||
button,7,strip,"fader_touch",1,0,0x68
|
|
||||||
button,1,master,"fader_touch",1,0,0x6f
|
|
||||||
button,1,master,mute,1,0,0x17
|
|
||||||
button,1,,clicking,1,1,0x33
|
|
||||||
|
|
||||||
button,1,,"smpte",0,1,0x71
|
|
||||||
button,1,,"beats",0,1,0x72
|
|
||||||
button,1,,"solo",0,1,0x73
|
|
||||||
button,1,,"relay_click",0,1,0x76
|
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -1,216 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
# Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
this_dir = File.dirname(__FILE__)
|
|
||||||
|
|
||||||
require 'faster_csv'
|
|
||||||
require "#{this_dir}/mackie.rb"
|
|
||||||
|
|
||||||
class Control
|
|
||||||
attr_accessor :id, :led, :group, :name, :ordinal, :switch
|
|
||||||
|
|
||||||
def initialize( obj, group )
|
|
||||||
@id = obj.id
|
|
||||||
@name = obj.name
|
|
||||||
@ordinal = obj.ordinal
|
|
||||||
@switch = obj.switch
|
|
||||||
@group = group
|
|
||||||
end
|
|
||||||
|
|
||||||
def ordinal_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Fader < Control
|
|
||||||
def self.midi_zero_byte
|
|
||||||
0xe0
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.mask_for_id( bytes )
|
|
||||||
bytes[0] & 0b00001111
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Button < Control
|
|
||||||
def self.midi_zero_byte
|
|
||||||
0x90
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.mask_for_id( bytes )
|
|
||||||
bytes[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Led < Control
|
|
||||||
end
|
|
||||||
|
|
||||||
class LedRing < Led
|
|
||||||
end
|
|
||||||
|
|
||||||
class Pot < Control
|
|
||||||
def self.midi_zero_byte
|
|
||||||
0xb0
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.mask_for_id( bytes )
|
|
||||||
bytes[1] & 0b00011111
|
|
||||||
end
|
|
||||||
|
|
||||||
def led=( rhs )
|
|
||||||
@led = LedRing.new( rhs, group )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Group < Array
|
|
||||||
attr_accessor :name, :controls
|
|
||||||
|
|
||||||
def initialize( name )
|
|
||||||
@name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_control( control )
|
|
||||||
@controls ||= Array.new
|
|
||||||
@controls << control
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Strip < Group
|
|
||||||
|
|
||||||
attr_accessor :ordinal
|
|
||||||
def initialize( name, ordinal )
|
|
||||||
super( name )
|
|
||||||
@ordinal = ordinal
|
|
||||||
end
|
|
||||||
|
|
||||||
def name
|
|
||||||
@name == 'master' ? @name : "#{@name}_#{@ordinal}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_master
|
|
||||||
name == 'master'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
types = { 0xe0 => Fader, 0x90 => Button, 0xb0 => Pot }
|
|
||||||
|
|
||||||
# number of controls, name, switch, led, id
|
|
||||||
# anything that doesn't have the correct number
|
|
||||||
# of columns will be ignored
|
|
||||||
# actually, 'switch' means it generates data
|
|
||||||
# whereas 'led' means it receives data
|
|
||||||
|
|
||||||
class Row
|
|
||||||
attr_accessor :count, :name, :switch, :led, :start_id, :type, :group
|
|
||||||
attr_accessor :id, :ordinal_name, :ordinal_group, :ordinal
|
|
||||||
|
|
||||||
def initialize( hash )
|
|
||||||
@count = hash['count'].to_i
|
|
||||||
@name = hash['name']
|
|
||||||
@switch = hash['switch'].to_b
|
|
||||||
@led = hash['led'].to_b
|
|
||||||
@start_id = hash['id'].hex
|
|
||||||
@type = hash['type']
|
|
||||||
@group = hash['group']
|
|
||||||
|
|
||||||
@hash = hash
|
|
||||||
end
|
|
||||||
|
|
||||||
def each_ordinal( &block )
|
|
||||||
for i in 0...count
|
|
||||||
@ordinal = i + 1
|
|
||||||
@ordinal_name = count > 1 ? "#{name}_#{ordinal}" : name
|
|
||||||
@ordinal_group = count > 1 ? "#{group}_#{ordinal}" : group
|
|
||||||
@id = start_id + i
|
|
||||||
|
|
||||||
@hash['ordinal_name'] = @ordinal_name
|
|
||||||
@hash['ordinal_group'] = @ordinal_group
|
|
||||||
|
|
||||||
yield( self )
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_hash
|
|
||||||
@hash
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Surface
|
|
||||||
attr_reader :groups, :controls_by_id, :types, :midis, :controls, :name
|
|
||||||
|
|
||||||
def initialize( name = 'none' )
|
|
||||||
@name = name
|
|
||||||
@types = Hash.new
|
|
||||||
@groups = Hash.new
|
|
||||||
@controls = Array.new
|
|
||||||
@controls_by_id = Hash.new
|
|
||||||
@midis = Hash.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_or_create_group( name, ordinal = nil )
|
|
||||||
if name.nil?
|
|
||||||
@groups['none'] = Group.new('none')
|
|
||||||
else
|
|
||||||
group = name =~ /strip/ || name == 'master' ? Strip.new( name, ordinal ) : Group.new( name )
|
|
||||||
@groups[group.name] ||= group
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse( control_data )
|
|
||||||
FasterCSV.parse( control_data, :headers => true ) do |csv_row|
|
|
||||||
next if csv_row.entries.size < 5 || csv_row[0] =~ /^\s*#/ || csv_row['id'].nil?
|
|
||||||
row = Row.new( csv_row )
|
|
||||||
|
|
||||||
row.each_ordinal do |row|
|
|
||||||
group = add_or_create_group( row.group, row.ordinal )
|
|
||||||
if row.switch
|
|
||||||
# for controls
|
|
||||||
control = eval "#{row.type.capitalize}.new( row, group )"
|
|
||||||
|
|
||||||
# for controls with leds
|
|
||||||
control.led = Led.new( row, group ) if row.led
|
|
||||||
else
|
|
||||||
# for LED-only entries
|
|
||||||
if row.led
|
|
||||||
control = Led.new( row, group )
|
|
||||||
control.led = control
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# add the new control to the various lookups
|
|
||||||
# but first print a warning if the id is duplicated
|
|
||||||
if @controls_by_id.has_key?( row.id ) && control.group.class != Strip
|
|
||||||
duplicated = @controls_by_id[row.id]
|
|
||||||
puts "duplicate id #{control.id}:#{control.name} of #{duplicated.id}:#{duplicated.name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
@controls_by_id[row.id] = control
|
|
||||||
@controls << control
|
|
||||||
group << control
|
|
||||||
|
|
||||||
# add incoming midi bytes
|
|
||||||
if row.switch
|
|
||||||
types[control.class.midi_zero_byte] = control.class
|
|
||||||
midis[control.class.midi_zero_byte] ||= Hash.new
|
|
||||||
midis[control.class.midi_zero_byte][row.id] = control
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
|
|
||||||
while !File.exist? ARGV[0]
|
|
||||||
sleep 0.010
|
|
||||||
end
|
|
||||||
|
|
||||||
file = File.open ARGV[0], 'r'
|
|
||||||
|
|
||||||
while bytes = file.sysread( 3 )
|
|
||||||
puts "%02x %02x %02x" % [ bytes[0], bytes[1], bytes[2] ]
|
|
||||||
end
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
<%#
|
|
||||||
Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
-%>
|
|
||||||
<%-
|
|
||||||
require 'controls.rb'
|
|
||||||
|
|
||||||
sf = Surface.new
|
|
||||||
sf.parse( File.open "mackie-controls.csv" )
|
|
||||||
buttons = sf.controls.find_all{|x| x.class == Button && x.group.class != Strip}
|
|
||||||
-%>
|
|
||||||
/*
|
|
||||||
Generated by scripts/generate-button-handlers.erb
|
|
||||||
*/
|
|
||||||
#include "mackie_button_handler.h"
|
|
||||||
#include "controls.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Mackie;
|
|
||||||
|
|
||||||
LedState MackieButtonHandler::default_button_press( Button & button )
|
|
||||||
{
|
|
||||||
cout << "press: " << button << endl;
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
LedState MackieButtonHandler::default_button_release( Button & button )
|
|
||||||
{
|
|
||||||
cout << "release: " << button << endl;
|
|
||||||
return off;
|
|
||||||
}
|
|
||||||
|
|
||||||
<%-
|
|
||||||
buttons.each do |button|
|
|
||||||
%>
|
|
||||||
LedState MackieButtonHandler::<%=button.name%>_press( Button & button )
|
|
||||||
{
|
|
||||||
return default_button_press( button );
|
|
||||||
}
|
|
||||||
|
|
||||||
LedState MackieButtonHandler::<%=button.name%>_release( Button & button )
|
|
||||||
{
|
|
||||||
return default_button_release( button );
|
|
||||||
}
|
|
||||||
<% end %>
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
<%#
|
|
||||||
Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
-%>
|
|
||||||
<%-
|
|
||||||
require 'controls.rb'
|
|
||||||
|
|
||||||
sf = Surface.new
|
|
||||||
sf.parse( File.open "mackie-controls.csv" )
|
|
||||||
buttons = sf.controls.find_all{|x| x.class == Button && x.group.class != Strip}
|
|
||||||
-%>
|
|
||||||
#ifndef mackie_button_handler_h
|
|
||||||
#define mackie_button_handler_h
|
|
||||||
/*
|
|
||||||
Generated by scripts/generate-button-handlers.erb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
namespace Mackie
|
|
||||||
{
|
|
||||||
|
|
||||||
class MackieButtonHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~MackieButtonHandler() {}
|
|
||||||
|
|
||||||
virtual LedState default_button_press( Button & button );
|
|
||||||
virtual LedState default_button_release( Button & button );
|
|
||||||
|
|
||||||
virtual void update_led( Button & button, LedState ls ) = 0;
|
|
||||||
|
|
||||||
<%- buttons.each do |button| %>
|
|
||||||
virtual LedState <%=button.name%>_press( Button & );
|
|
||||||
virtual LedState <%=button.name%>_release( Button & );
|
|
||||||
<% end %>
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
|
|
||||||
require 'erb'
|
|
||||||
|
|
||||||
require File.dirname(__FILE__) + '/controls.rb'
|
|
||||||
|
|
||||||
cc_template = ''
|
|
||||||
File.open( File.dirname(__FILE__) + "/surface-cc-template.erb", "r" ) { |f| cc_template = f.read }
|
|
||||||
|
|
||||||
h_template = ''
|
|
||||||
File.open( File.dirname(__FILE__) + "/surface-h-template.erb", "r" ) { |f| h_template = f.read }
|
|
||||||
|
|
||||||
sf = Surface.new( ARGV[0] )
|
|
||||||
control_data = ''
|
|
||||||
File.open( File.dirname(__FILE__) + "/#{sf.name.downcase}-controls.csv", "r") { |f| control_data = f.read }
|
|
||||||
sf.parse control_data
|
|
||||||
|
|
||||||
@result = ""
|
|
||||||
erb = ERB.new( cc_template , 0, "%<>-", "@result" )
|
|
||||||
erb.result
|
|
||||||
File.open( "#{sf.name.downcase}_surface.cc", "w" ) { |f| f.write @result }
|
|
||||||
|
|
||||||
erb = ERB.new( h_template , 0, "%<>-", "@result" )
|
|
||||||
erb.result
|
|
||||||
File.open( "#{sf.name.downcase}_surface.h", "w" ) { |f| f.write @result }
|
|
||||||
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
# Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
require 'controls.rb'
|
|
||||||
require 'mackie.rb'
|
|
||||||
|
|
||||||
if ARGV.size != 2
|
|
||||||
puts "#$0 /dev/snd/midiXXXX control-file.csv"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
while !File.exist? ARGV[0]
|
|
||||||
sleep 0.010
|
|
||||||
end
|
|
||||||
|
|
||||||
#mapping_csv = ARGV[1] || "mackie-controls.csv"
|
|
||||||
mapping_csv = ARGV[1]
|
|
||||||
puts "mapping_csv: #{mapping_csv}"
|
|
||||||
puts ""
|
|
||||||
|
|
||||||
file = File.open ARGV[0], 'r+'
|
|
||||||
mck = Mackie.new( file )
|
|
||||||
|
|
||||||
# faders to minimum. bcf2000 doesn't respond
|
|
||||||
mck.write_sysex "\x61"
|
|
||||||
|
|
||||||
# all leds off. bcf2000 doesn't respond
|
|
||||||
mck.write_sysex "\x62"
|
|
||||||
|
|
||||||
# get version. comes back as ASCII bytes
|
|
||||||
version = mck.sysex "\x13\x00"
|
|
||||||
puts "version: #{version.map{|x| x.chr}}"
|
|
||||||
|
|
||||||
# write a welcome message. bcf2000 responds with exact
|
|
||||||
# string but doesn't display anything
|
|
||||||
# 0 offset,
|
|
||||||
#~ file.write hdr + "\x12\x3fLCDE\xf7"
|
|
||||||
#~ file.flush
|
|
||||||
#~ answer = read_sysex file
|
|
||||||
#~ puts "answer: #{answer[hdr.length..-1].map{|x| x.chr}}"
|
|
||||||
|
|
||||||
# write to BBT display
|
|
||||||
#~ file.write hdr + "\x10LCDE\xf7"
|
|
||||||
#~ file.flush
|
|
||||||
#~ bbt = []
|
|
||||||
#~ while ( nc = file.read( 1 ) )[0] != 0xf7
|
|
||||||
#~ bbt << nc[0]
|
|
||||||
#~ end
|
|
||||||
#~ puts "bbt: #{bbt[hdr.length..-1].map{|x| x.chr}}"
|
|
||||||
|
|
||||||
# write 7-segment display
|
|
||||||
#~ file.write hdr + "\x11LCDE\xf7"
|
|
||||||
#~ file.flush
|
|
||||||
|
|
||||||
# go offline. bcf2000 doesn't respond
|
|
||||||
#~ file.write( hdr + "\x0f\x7f\xf7" )
|
|
||||||
#~ file.flush
|
|
||||||
|
|
||||||
sf = Surface.new
|
|
||||||
control_data = ""
|
|
||||||
File.open( mapping_csv ) { |f| control_data = f.read }
|
|
||||||
sf.parse( control_data )
|
|
||||||
|
|
||||||
# send all faders to 0, but bounce them first
|
|
||||||
# otherwise the bcf gets confused
|
|
||||||
sf.midis[0xe0].values.find_all{|x| x.class == Fader}.each do |x|
|
|
||||||
bytes = Array.new
|
|
||||||
bytes[0] = 0xe0 + x.ordinal - 1
|
|
||||||
bytes[1] = 0x1
|
|
||||||
bytes[2] = 0x1
|
|
||||||
file.write bytes.pack( 'C*' )
|
|
||||||
bytes[0] = 0xe0 + x.ordinal - 1
|
|
||||||
bytes[1] = 0x0
|
|
||||||
bytes[2] = 0x0
|
|
||||||
file.write bytes.pack( 'C*' )
|
|
||||||
end
|
|
||||||
file.flush
|
|
||||||
|
|
||||||
# respond to control movements
|
|
||||||
while bytes = mck.file.read( 3 )
|
|
||||||
print "received: %02.x %02.x %02.x" % [ bytes[0], bytes[1], bytes[2] ]
|
|
||||||
midi_type = bytes[0] & 0b11110000
|
|
||||||
|
|
||||||
control_id = sf.types[midi_type].mask_for_id( bytes )
|
|
||||||
control = sf.midis[midi_type][control_id]
|
|
||||||
|
|
||||||
print " Control Type: %-7s, " % sf.types[midi_type]
|
|
||||||
print "id: %4x" % control_id
|
|
||||||
print ", control: %15s" % ( control ? control.name : "nil control" )
|
|
||||||
print ", %15s" % ( control ? control.group.name : "nil group" )
|
|
||||||
print "\n"
|
|
||||||
end
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
type,count,group,name,switch,led,id
|
|
||||||
# faders
|
|
||||||
fader,8,strip,gain,1,0,0x00
|
|
||||||
fader,1,master,gain,1,0,0x08
|
|
||||||
|
|
||||||
# pots
|
|
||||||
pot,8,strip,vpot,1,1,0x10
|
|
||||||
pot,1,,jog,1,0,0x3c
|
|
||||||
pot,1,,external,1,0,0x2e
|
|
||||||
|
|
||||||
# strip buttons
|
|
||||||
button,8,strip,recenable,1,1,0x0
|
|
||||||
button,8,strip,solo,1,1,0x08
|
|
||||||
button,8,strip,mute,1,1,0x10
|
|
||||||
button,8,strip,select,1,1,0x18
|
|
||||||
button,8,strip,vselect,1,0,0x20
|
|
||||||
|
|
||||||
# overlay buttons
|
|
||||||
button,1,assignment,io,1,1,0x28
|
|
||||||
button,1,assignment,sends,1,1,0x29
|
|
||||||
button,1,assignment,pan,1,1,0x2a
|
|
||||||
button,1,assignment,plugin,1,1,0x2b
|
|
||||||
button,1,assignment,eq,1,1,0x2c
|
|
||||||
button,1,assignment,dyn,1,1,0x2d
|
|
||||||
button,1,bank,left,1,0,0x2e
|
|
||||||
button,1,bank,right,1,0,0x2f
|
|
||||||
button,1,bank,channel_left,1,0,0x30
|
|
||||||
button,1,bank,channel_right,1,0,0x31
|
|
||||||
button,1,,flip,1,1,0x32
|
|
||||||
button,1,,edit,1,1,0x33
|
|
||||||
|
|
||||||
button,1,display,name_value,1,0,0x34
|
|
||||||
button,1,display,smpte_beats,1,0,0x35
|
|
||||||
button,1,,F1,1,0,0x36
|
|
||||||
button,1,,F2,1,0,0x37
|
|
||||||
button,1,,F3,1,0,0x38
|
|
||||||
button,1,,F4,1,0,0x39
|
|
||||||
button,1,,F5,1,0,0x3a
|
|
||||||
button,1,,F6,1,0,0x3b
|
|
||||||
button,1,,F7,1,0,0x3c
|
|
||||||
button,1,,F8,1,0,0x3d
|
|
||||||
button,1,,F9,1,0,0x3e
|
|
||||||
button,1,,F10,1,0,0x3f
|
|
||||||
button,1,,F11,1,0,0x40
|
|
||||||
button,1,,F12,1,0,0x41
|
|
||||||
button,1,,F13,1,0,0x42
|
|
||||||
button,1,,F14,1,0,0x43
|
|
||||||
button,1,,F15,1,0,0x44
|
|
||||||
button,1,,F16,1,0,0x45
|
|
||||||
button,1,modifiers,shift,1,0,0x46
|
|
||||||
button,1,modifiers,option,1,0,0x47
|
|
||||||
button,1,modifiers,control,1,0,0x48
|
|
||||||
button,1,modifiers,cmd_alt,1,0,0x49
|
|
||||||
button,1,automation,on,1,1,0x4a
|
|
||||||
button,1,automation,rec_ready,1,1,0x4b
|
|
||||||
button,1,functions,undo,1,1,0x4c
|
|
||||||
button,1,automation,snapshot,1,1,0x4d
|
|
||||||
button,1,automation,touch,1,1,0x4e
|
|
||||||
button,1,functions,redo,1,1,0x4f
|
|
||||||
button,1,functions,marker,1,1,0x50
|
|
||||||
button,1,functions,enter,1,1,0x51
|
|
||||||
button,1,functions,cancel,1,0,0x52
|
|
||||||
button,1,functions,mixer,1,0,0x53
|
|
||||||
button,1,transport,frm_left,1,1,0x54
|
|
||||||
button,1,transport,frm_right,1,1,0x55
|
|
||||||
button,1,transport,loop,1,1,0x56
|
|
||||||
button,1,transport,punch_in,1,1,0x57
|
|
||||||
button,1,transport,punch_out,1,1,0x58
|
|
||||||
button,1,transport,home,1,1,0x59
|
|
||||||
button,1,transport,end,1,1,0x5a
|
|
||||||
|
|
||||||
# transport buttons
|
|
||||||
button,1,transport,"rewind",1,1,0x5b
|
|
||||||
button,1,transport,"ffwd",1,1,0x5c
|
|
||||||
button,1,transport,"stop",1,1,0x5d
|
|
||||||
button,1,transport,"play",1,1,0x5e
|
|
||||||
button,1,transport,"record",1,1,0x5f
|
|
||||||
button,1,cursor,"cursor_up",1,0,0x60
|
|
||||||
button,1,cursor,"cursor_down",1,0,0x61
|
|
||||||
button,1,cursor,"cursor_left",1,0,0x62
|
|
||||||
button,1,cursor,"cursor_right",1,0,0x63
|
|
||||||
button,1,,"zoom",1,1,0x64
|
|
||||||
button,1,,"scrub",1,1,0x65
|
|
||||||
button,1,user,"user_a",1,0,0x66
|
|
||||||
button,1,user,"user_b",1,0,0x67
|
|
||||||
|
|
||||||
button,8,strip,"fader_touch",1,0,0x68
|
|
||||||
button,1,master,"fader_touch",1,0,0x70
|
|
||||||
|
|
||||||
button,1,,"smpte",0,1,0x71
|
|
||||||
button,1,,"beats",0,1,0x72
|
|
||||||
button,1,,"solo",0,1,0x73
|
|
||||||
button,1,,"relay_click",0,1,0x76
|
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Binary file not shown.
|
|
@ -1,119 +0,0 @@
|
||||||
class String
|
|
||||||
def to_bytes
|
|
||||||
arr = []
|
|
||||||
each_byte{|x| arr << x}
|
|
||||||
arr
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Array
|
|
||||||
def to_hex
|
|
||||||
map{|x| "%2.0x" % x}
|
|
||||||
end
|
|
||||||
|
|
||||||
alias as_hex to_hex
|
|
||||||
end
|
|
||||||
|
|
||||||
class String
|
|
||||||
def to_b
|
|
||||||
to_i != 0 || %w{true t yes y}.include?( self.downcase )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Fixnum
|
|
||||||
def to_hex
|
|
||||||
"%02x" % self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Mackie
|
|
||||||
attr_accessor :file
|
|
||||||
|
|
||||||
def initialize( file )
|
|
||||||
@file = file
|
|
||||||
end
|
|
||||||
|
|
||||||
# send and receive a sysex message
|
|
||||||
# after wrapping in the header and the eox byte
|
|
||||||
def sysex( msg )
|
|
||||||
puts "Mackie write: #{msg.unpack('C*').to_hex.inspect}"
|
|
||||||
write_sysex( msg )
|
|
||||||
response = read_sysex
|
|
||||||
puts "Mackie response: #{response.to_hex.inspect}"
|
|
||||||
response[5..-1]
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns an array of bytes
|
|
||||||
def read_sysex
|
|
||||||
buf = []
|
|
||||||
while ( nc = @file.read( 1 ) )[0] != 0xf7
|
|
||||||
buf << nc[0]
|
|
||||||
end
|
|
||||||
buf
|
|
||||||
end
|
|
||||||
|
|
||||||
# send and flush a sysex message
|
|
||||||
# after wrapping in the header and the eox byte
|
|
||||||
def write_sysex( msg )
|
|
||||||
@file.write( hdrlc + msg + "\xf7" )
|
|
||||||
@file.flush
|
|
||||||
end
|
|
||||||
|
|
||||||
def write( msg )
|
|
||||||
@file.write msg
|
|
||||||
@file.flush
|
|
||||||
end
|
|
||||||
|
|
||||||
def translate_seven_segment( char )
|
|
||||||
case char
|
|
||||||
when 0x40..0x60
|
|
||||||
char - 0x40
|
|
||||||
when 0x21..0x3f
|
|
||||||
char
|
|
||||||
else
|
|
||||||
0x00
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# display the msg (which can be only 2 characters)
|
|
||||||
# append the number of stops. Options are '..', '. ', '. ', ' '
|
|
||||||
def two_char( msg, stops = ' ' )
|
|
||||||
two = Array.new
|
|
||||||
two << translate_seven_segment( msg.upcase[0] )
|
|
||||||
two << translate_seven_segment( msg.upcase[1] )
|
|
||||||
|
|
||||||
two[0] += 0x40 if stops[0] == '.'[0]
|
|
||||||
two[1] += 0x40 if stops[1] == '.'[0]
|
|
||||||
|
|
||||||
midi_msg = [0xb0, 0x4a, two[1], 0x4b, two[0] ]
|
|
||||||
write midi_msg.pack( 'C*' )
|
|
||||||
end
|
|
||||||
|
|
||||||
# send and receive the device initialisation
|
|
||||||
def init
|
|
||||||
response = sysex( "\x00" )
|
|
||||||
|
|
||||||
# decode host connection query
|
|
||||||
status = response[0]
|
|
||||||
raise( "expected 01, got " + response.inspect ) if status != 1
|
|
||||||
|
|
||||||
serial = response[1..7]
|
|
||||||
challenge = response[8..11]
|
|
||||||
|
|
||||||
# send host connection reply
|
|
||||||
reply = "\x02" + serial.pack('C*') + challenge.pack('C*')
|
|
||||||
response = sysex reply
|
|
||||||
|
|
||||||
# decode host connection confirmation
|
|
||||||
status = response[0]
|
|
||||||
raise ( "expected 03, got " + response.inspect ) if status != 3
|
|
||||||
end
|
|
||||||
|
|
||||||
def hdrlc
|
|
||||||
"\xf0\x00\x00\x66\x10"
|
|
||||||
end
|
|
||||||
|
|
||||||
def hdrlcxt
|
|
||||||
"\xf0\x00\x00\x66\x11"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
# Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
require "rexml/document"
|
|
||||||
file = File.new( ARGV[0] )
|
|
||||||
doc = REXML::Document.new file
|
|
||||||
|
|
||||||
# fetch the node containing the controls
|
|
||||||
controls = XPath.first( doc, 'Session/ControlProtocols/Protocol[@name="Generic MIDI"]/controls' )
|
|
||||||
|
|
||||||
channel = 1
|
|
||||||
|
|
||||||
# A Control is a button or slider. It has an internal ID
|
|
||||||
# an incoming MIDI message, and an outgoing midi message
|
|
||||||
class Control
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Strips have solo,rec,mute,pan,fader
|
|
||||||
# Strips have midi input
|
|
||||||
# Strips have midi output
|
|
||||||
# Strips have an XML representation, or something like that
|
|
||||||
class Strip
|
|
||||||
def initialize( node )
|
|
||||||
@solo = node.elements['solo']
|
|
||||||
@mute = node.elements['mute']
|
|
||||||
@rec = node.elements['recenable']
|
|
||||||
@fader = node.elements['IO/gaincontrol']
|
|
||||||
@panner = node.elements['IO/Panner/StreamPanner/panner']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This knows how to extract a set of controls from a Route
|
|
||||||
|
|
||||||
doc.elements.each( 'Session/Routes/Route' ) do |node|
|
|
||||||
strip = Strip.new( node )
|
|
||||||
|
|
||||||
controls.add_element( 'mute',
|
|
||||||
'id' => mute.attribute('id').value,
|
|
||||||
'event' => "0xb0",
|
|
||||||
'channel' => channel.to_s,
|
|
||||||
'additional' => "0x41"
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
pp controls.elements
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
#~ /usr/bin/ruby
|
|
||||||
# Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
require 'erb'
|
|
||||||
|
|
||||||
signals = %w{
|
|
||||||
solo_changed
|
|
||||||
mute_changed
|
|
||||||
record_enable_changed
|
|
||||||
gain_changed
|
|
||||||
name_changed
|
|
||||||
panner_changed
|
|
||||||
}
|
|
||||||
|
|
||||||
@signal_calls = { 'panner_changed' => 'panner()[0]->Changed' }
|
|
||||||
|
|
||||||
def connection_call( x )
|
|
||||||
if @signal_calls.include? x
|
|
||||||
@signal_calls[x]
|
|
||||||
else
|
|
||||||
x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
signals.each do |x|
|
|
||||||
puts <<EOF
|
|
||||||
void MackieControlProtocol::notify_#{x}( void *, ARDOUR::Route * route )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
strip_from_route( route ).#{x.gsub( /_changed/, '' )}();
|
|
||||||
}
|
|
||||||
catch( exception & e )
|
|
||||||
{
|
|
||||||
cout << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
end
|
|
||||||
|
|
||||||
class_def = <<EOF
|
|
||||||
#ifndef route_signal_h
|
|
||||||
#define route_signal_h
|
|
||||||
|
|
||||||
#include <sigc++/sigc++.h>
|
|
||||||
|
|
||||||
class MackieControlProtocol;
|
|
||||||
|
|
||||||
namespace ARDOUR {
|
|
||||||
class Route;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Mackie
|
|
||||||
{
|
|
||||||
|
|
||||||
class Strip;
|
|
||||||
|
|
||||||
/**
|
|
||||||
This class is intended to easily create and destroy the set of
|
|
||||||
connections from a route to a control surface strip. Instanting
|
|
||||||
it will connect the signals, and destructing it will disconnect
|
|
||||||
the signals.
|
|
||||||
*/
|
|
||||||
class RouteSignal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RouteSignal( ARDOUR::Route & route, MackieControlProtocol & mcp, Strip & strip )
|
|
||||||
: _route( route ), _mcp( mcp ), _strip( strip )
|
|
||||||
{
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
~RouteSignal()
|
|
||||||
{
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ARDOUR::Route & _route;
|
|
||||||
MackieControlProtocol & _mcp;
|
|
||||||
Strip & _strip;
|
|
||||||
|
|
||||||
<% signals.each do |x| -%>
|
|
||||||
sigc::connection _<%= x %>_connection;
|
|
||||||
<% end -%>
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
|
|
||||||
erb = ERB.new( class_def, 0, ">-" )
|
|
||||||
erb.run
|
|
||||||
|
|
||||||
impl_def = <<EOF
|
|
||||||
#include "route_signal.h"
|
|
||||||
|
|
||||||
#include "ardour/route.h"
|
|
||||||
#include "ardour/panner.h"
|
|
||||||
|
|
||||||
#include "mackie_control_protocol.h"
|
|
||||||
|
|
||||||
using namespace Mackie;
|
|
||||||
|
|
||||||
void RouteSignal::connect()
|
|
||||||
{
|
|
||||||
<% signals.each do |x| -%>
|
|
||||||
_<%=x%>_connection = _route.<%=connection_call(x)%>.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_<%=x%> ), &_route ) );
|
|
||||||
<% end -%>
|
|
||||||
}
|
|
||||||
|
|
||||||
void RouteSignal::disconnect()
|
|
||||||
{
|
|
||||||
<% signals.each do |x| -%>
|
|
||||||
_<%= x %>_connection.disconnect();
|
|
||||||
<% end -%>
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
erb = ERB.new( impl_def, 0, ">-" )
|
|
||||||
erb.run
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
# Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
require 'mackie'
|
|
||||||
|
|
||||||
buttons = {}
|
|
||||||
pots = {}
|
|
||||||
|
|
||||||
while !File.exist? ARGV[0]
|
|
||||||
sleep 0.010
|
|
||||||
end
|
|
||||||
|
|
||||||
file = File.open( ARGV[0], 'r+' )
|
|
||||||
#mck = Mackie.new( file )
|
|
||||||
device = false
|
|
||||||
|
|
||||||
# respond to control movements
|
|
||||||
while bytes = file.read( 3 )
|
|
||||||
puts "received: %02.x %02.x %02.x" % [ bytes[0], bytes[1], bytes[2] ]
|
|
||||||
output = nil
|
|
||||||
case bytes[0] & 0b11110000
|
|
||||||
when 0xe0
|
|
||||||
# fader moved, so respond if move is OK
|
|
||||||
output = bytes
|
|
||||||
when 0x90
|
|
||||||
# button pressed
|
|
||||||
case bytes[1]
|
|
||||||
when 0x68..0x6f
|
|
||||||
# do nothing - touch detection
|
|
||||||
puts "touch detect: %02.x" % bytes[2]
|
|
||||||
else
|
|
||||||
# treat all buttons as toggles
|
|
||||||
button_id = bytes[1]
|
|
||||||
|
|
||||||
# only toggle on release. Not working. All buttons send press
|
|
||||||
# and then release signals
|
|
||||||
if bytes[2] == 0
|
|
||||||
if buttons.include?( button_id )
|
|
||||||
# toggle button state
|
|
||||||
puts "button id #{buttons[button_id]} to #{!buttons[button_id]}"
|
|
||||||
buttons[button_id] = !buttons[button_id]
|
|
||||||
else
|
|
||||||
# create a new button as on
|
|
||||||
puts "adding button id #{button_id}"
|
|
||||||
buttons[button_id] = true
|
|
||||||
end
|
|
||||||
bytes[2] = buttons[button_id] ? 0x7f : 0
|
|
||||||
output = bytes
|
|
||||||
end
|
|
||||||
end
|
|
||||||
when 0xb0
|
|
||||||
# pots, jog wheel, external
|
|
||||||
case bytes[1]
|
|
||||||
when 0x10..0x17
|
|
||||||
#pot turned
|
|
||||||
pot_id = bytes[1] & 0b00000111
|
|
||||||
direction = bytes[2] & 0b01000000
|
|
||||||
delta = bytes[2] & 0b00111111
|
|
||||||
sign = direction == 0 ? 1 : -1
|
|
||||||
|
|
||||||
if pots.include? pot_id
|
|
||||||
current_led_pos = pots[pot_id]
|
|
||||||
else
|
|
||||||
current_led_pos = pots[pot_id] = 6
|
|
||||||
end
|
|
||||||
new_led_pos = current_led_pos + sign
|
|
||||||
new_led_pos = case
|
|
||||||
when new_led_pos <= 0
|
|
||||||
0
|
|
||||||
when new_led_pos >= 11
|
|
||||||
11
|
|
||||||
else
|
|
||||||
new_led_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
pots[pot_id] = new_led_pos
|
|
||||||
|
|
||||||
puts "pot #{pot_id} turned #{sign} #{direction == 0 ? 'clockwise' : 'widdershins'}: %02.x to #{new_led_pos}" % delta
|
|
||||||
|
|
||||||
output = bytes
|
|
||||||
output[1] += 0x20
|
|
||||||
output[2] = 0b01000000
|
|
||||||
#~ modes:
|
|
||||||
#~ 0 - single dot
|
|
||||||
#~ 1 - boost/cut
|
|
||||||
#~ 2 - wrap
|
|
||||||
#~ 3 - spread
|
|
||||||
mode = pot_id < 4 ? pot_id : 0
|
|
||||||
output[2] |= ( mode << 4 )
|
|
||||||
output[2] += ( new_led_pos ) & 0b00001111
|
|
||||||
when 0x2e
|
|
||||||
# external controller
|
|
||||||
when 0x3c
|
|
||||||
# jog wheel
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts "don't know what this means"
|
|
||||||
end
|
|
||||||
|
|
||||||
# output bytes
|
|
||||||
if device && output
|
|
||||||
#sleep 0.1
|
|
||||||
puts "sending: %02.x %02.x %02.x" % [ output[0], output[1], output[2] ]
|
|
||||||
begin
|
|
||||||
res = file.write output
|
|
||||||
puts "res: #{res}"
|
|
||||||
file.flush
|
|
||||||
rescue => e
|
|
||||||
puts "oops #{e}"
|
|
||||||
file.close
|
|
||||||
file = File.open ARGV[0], 'r+'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
<%#
|
|
||||||
Copyright (C) 2006,2007 John Anderson
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
-%>
|
|
||||||
/*
|
|
||||||
Generated by scripts/generate-surface.rb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "<%= sf.name.downcase %>_surface.h"
|
|
||||||
|
|
||||||
#include "controls.h"
|
|
||||||
#include "mackie_button_handler.h"
|
|
||||||
|
|
||||||
using namespace Mackie;
|
|
||||||
|
|
||||||
void Mackie::<%= sf.name %>Surface::init_controls()
|
|
||||||
{
|
|
||||||
// intialise groups and strips
|
|
||||||
Group * group = 0;
|
|
||||||
|
|
||||||
// make sure there are enough strips
|
|
||||||
strips.resize( <%= sf.groups.values.find_all{|x| x.name =~ /strip/}.size %> );
|
|
||||||
|
|
||||||
% sf.groups.values.each do |group|
|
|
||||||
<%- if group.class == Strip -%>
|
|
||||||
<%- if group.name == 'master' -%>
|
|
||||||
group = new MasterStrip ( "<%=group.name%>", 0 );
|
|
||||||
<%- else -%>
|
|
||||||
group = new <%= group.class.name %> ( "<%=group.name%>", <%=group.ordinal - 1%> );
|
|
||||||
<%- end -%>
|
|
||||||
<%- else -%>
|
|
||||||
group = new <%= group.class.name %> ( "<%=group.name%>" );
|
|
||||||
<%- end -%>
|
|
||||||
groups["<%=group.name%>"] = group;
|
|
||||||
<%- if group.class == Strip -%>
|
|
||||||
strips[<%=group.ordinal - 1%>] = dynamic_cast<Strip*>( group );
|
|
||||||
<%- end -%>
|
|
||||||
|
|
||||||
% end
|
|
||||||
|
|
||||||
// initialise controls
|
|
||||||
Fader * fader = 0;
|
|
||||||
Pot * pot = 0;
|
|
||||||
Button * button = 0;
|
|
||||||
Led * led = 0;
|
|
||||||
|
|
||||||
% sf.controls.each do |control|
|
|
||||||
<%-
|
|
||||||
variable_name = control.class.name.downcase
|
|
||||||
class_name =
|
|
||||||
if control.name == 'jog'
|
|
||||||
'Jog'
|
|
||||||
else
|
|
||||||
control.class.name
|
|
||||||
end
|
|
||||||
-%>
|
|
||||||
group = groups["<%=control.group.name%>"];
|
|
||||||
<%= variable_name %> = new <%= class_name %> ( <%= control.id %>, <%= control.ordinal %>, "<%=control.name%>", *group );
|
|
||||||
<%= variable_name %>s[0x<%=control.id.to_hex %>] = <%= variable_name %>;
|
|
||||||
controls.push_back( <%= variable_name %> );
|
|
||||||
<%- if control.group.class != Strip -%>
|
|
||||||
controls_by_name["<%= control.name %>"] = <%= variable_name %>;
|
|
||||||
<%- end -%>
|
|
||||||
group->add( *<%= variable_name %> );
|
|
||||||
|
|
||||||
% end
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mackie::<%= sf.name %>Surface::handle_button( MackieButtonHandler & mbh, ButtonState bs, Button & button )
|
|
||||||
{
|
|
||||||
if ( bs != press && bs != release )
|
|
||||||
{
|
|
||||||
mbh.update_led( button, none );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LedState ls;
|
|
||||||
switch ( button.id() )
|
|
||||||
{
|
|
||||||
<%-
|
|
||||||
buttons = sf.controls.find_all{|x| x.class == Button && x.group.class != Strip}
|
|
||||||
buttons.each do |button|
|
|
||||||
%>
|
|
||||||
case 0x<%= ( button.class.midi_zero_byte << 8 | button.id ).to_hex %>: // <%= button.name %>
|
|
||||||
switch ( bs ) {
|
|
||||||
case press: ls = mbh.<%= button.name %>_press( button ); break;
|
|
||||||
case release: ls = mbh.<%= button.name %>_release( button ); break;
|
|
||||||
case neither: break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
<% end %>
|
|
||||||
}
|
|
||||||
mbh.update_led( button, ls );
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef mackie_surface_<%= sf.name.downcase %>_h
|
|
||||||
#define mackie_surface_<%= sf.name.downcase %>_h
|
|
||||||
/*
|
|
||||||
Generated by scripts/generate-surface.rb
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "surface.h"
|
|
||||||
|
|
||||||
namespace Mackie
|
|
||||||
{
|
|
||||||
|
|
||||||
class MackieButtonHandler;
|
|
||||||
|
|
||||||
class <%= sf.name %>Surface : public Surface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
<%= sf.name %>Surface( uint32_t max_strips ) : Surface( max_strips )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void handle_button( MackieButtonHandler & mbh, ButtonState bs, Button & button );
|
|
||||||
virtual void init_controls();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
|
|
||||||
require 'controls.rb'
|
|
||||||
require 'pp'
|
|
||||||
|
|
||||||
sf = Surface.new
|
|
||||||
sf.parse( ARGV[0] )
|
|
||||||
sf.types.each{|k,v| puts "%02.x #{v}" % k}
|
|
||||||
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
class ElementHandler
|
|
||||||
|
|
||||||
def apply( anElement )
|
|
||||||
anElement.each {|e| handle(e)} if anElement
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle( aNode )
|
|
||||||
if aNode.kind_of? REXML::Text
|
|
||||||
handleTextNode(aNode)
|
|
||||||
elsif aNode.kind_of? REXML::Element
|
|
||||||
handle_element aNode
|
|
||||||
else
|
|
||||||
return #ignore comments and processing instructions
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_element( anElement )
|
|
||||||
handler_method = "handle_" + anElement.name.tr("-","_")
|
|
||||||
if self.respond_to? handler_method
|
|
||||||
self.send(handler_method, anElement)
|
|
||||||
else
|
|
||||||
default_handler(anElement)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#! /usr/bin/ruby
|
|
||||||
|
|
||||||
require 'mackie.rb'
|
|
||||||
|
|
||||||
@file = File.open '/dev/snd/midiC2D0', 'r+'
|
|
||||||
|
|
||||||
@led_8_on = [ 0x90, 0x18, 0x7f ]
|
|
||||||
@hci = [ 0, 0xf7 ]
|
|
||||||
@version_req = [ 0x13, 0, 0xf7 ]
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue