Merged with trunk R1705.
[ardour.git] / libs / surfaces / mackie / scripts / simple_host.rb
1 #! /usr/bin/ruby
2 # Copyright (C) 2006,2007 John Anderson
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 require 'mackie'
19
20 buttons = {}
21 pots = {}
22
23 while !File.exist? ARGV[0]
24   sleep 0.010
25 end
26
27 file = File.open( ARGV[0], 'r+' )
28 mck = Mackie.new( file )
29
30 # faders to minimum. bcf2000 doesn't respond
31 mck.write_sysex "\x61"
32
33 # all leds off. bcf2000 doesn't respond
34 mck.write_sysex "\x62"
35
36 # get version. comes back as ASCII bytes
37 version = mck.sysex "\x13\x00"
38 puts "version: #{version.map{|x| x.chr}}"
39
40 # respond to control movements
41 while bytes = file.read( 3 )
42   puts "received: %02.x %02.x %02.x" % [ bytes[0], bytes[1], bytes[2] ]
43   output = nil
44   case bytes[0] & 0b11110000
45   when 0xe0
46     # fader moved, so respond if move is OK
47     output = bytes
48   when 0x90
49     # button pressed
50     case bytes[1]
51     when 0x68..0x6f
52       # do nothing - touch detection
53       puts "touch detect: %02.x" % bytes[2]
54     else
55       # treat all buttons as toggles
56       button_id = bytes[1]
57       
58       # only toggle on release. Not working. All buttons send press
59       # and then release signals
60       if bytes[2] == 0
61         if buttons.include?( button_id )
62           # toggle button state
63           puts "button id #{buttons[button_id]} to #{!buttons[button_id]}"
64           buttons[button_id] = !buttons[button_id]
65         else
66           # create a new button as on
67           puts "adding button id #{button_id}"
68           buttons[button_id] = true
69         end
70         bytes[2] = buttons[button_id] ? 0x7f : 0
71         output = bytes
72       end
73     end
74   when 0xb0
75     # pots, jog wheel, external
76     case bytes[1]
77     when 0x10..0x17
78       #pot turned
79       pot_id = bytes[1] & 0b00000111
80       direction = bytes[2] & 0b01000000
81       delta = bytes[2] & 0b00111111
82       sign = direction == 0 ? 1 : -1
83       
84       if pots.include? pot_id
85         current_led_pos = pots[pot_id]
86       else
87         current_led_pos = pots[pot_id] = 6
88       end
89       new_led_pos = current_led_pos + sign
90       new_led_pos = case
91         when new_led_pos <= 0
92           0
93         when new_led_pos >= 11
94           11
95         else
96           new_led_pos
97       end
98         
99       pots[pot_id] = new_led_pos
100       
101       puts "pot #{pot_id} turned #{sign} #{direction == 0 ? 'clockwise' : 'widdershins'}: %02.x to #{new_led_pos}" % delta
102       
103       output = bytes
104       output[1] += 0x20
105       output[2] = 0b01000000
106       #~ modes:
107       #~ 0 - single dot
108       #~ 1 - boost/cut
109       #~ 2 - wrap
110       #~ 3 - spread
111       mode = pot_id < 4 ? pot_id : 0
112       output[2] |= ( mode << 4 )
113       output[2] += ( new_led_pos ) & 0b00001111
114     when 0x2e
115       # external controller
116     when 0x3c
117       # jog wheel
118     end
119   else
120     puts "don't know what this means"
121   end
122   
123   # output bytes
124   if output
125     #sleep 0.1
126     puts "sending: %02.x %02.x %02.x" % [ output[0], output[1], output[2] ]
127     begin
128       res = file.write output
129       puts "res: #{res}"
130       file.flush
131     rescue => e
132       puts "oops #{e}"
133       file.close
134       file = File.open ARGV[0], 'r+'
135     end
136   end
137 end