summaryrefslogtreecommitdiff
path: root/libs/surfaces/mackie/scripts/simple_host.rb
blob: a5c07f2abb4ddbc32cb68231c190ee73fa2f184b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#! /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 )

# 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}}"

# 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 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