surface_master 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/examples/orbit_playground.rb +2 -2
- data/lib/surface_master/device.rb +5 -2
- data/lib/surface_master/logging.rb +1 -1
- data/lib/surface_master/orbit/device.rb +92 -47
- data/lib/surface_master/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 186d651bbe04a8255ccc6d5d85b7faf13c7e1345
|
4
|
+
data.tar.gz: 1b4b9684879c2c01703301979ffba653e11811ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba465d6123b0d6c9547e31b13f548e03bf795c8b727c296e144651cce84d13d82f47d65cf94c58942245d23c688e06e4810569ed7c34c50d26ec4dd59835202f
|
7
|
+
data.tar.gz: 5d65cc3500a1e1cdf4b29c3114bd3561548b32ded2c2ac00726a1404b4a74f6c26693f83847fc25193efd5f3229df60045d81aaaa88060395c752bdf078511c9
|
data/CHANGELOG.md
CHANGED
@@ -125,10 +125,10 @@ loop do
|
|
125
125
|
indices.each do |i|
|
126
126
|
MAPPINGS[i] = (MAPPINGS[i] + offset) % 0x3F
|
127
127
|
end
|
128
|
-
device.sysex
|
128
|
+
device.send(:sysex!, *MAPPINGS)
|
129
129
|
if use_read
|
130
130
|
sleep read_delay
|
131
|
-
device.sysex
|
131
|
+
device.send(:sysex!, *READ_STATE)
|
132
132
|
end
|
133
133
|
printf "."
|
134
134
|
sleep delay
|
@@ -50,14 +50,17 @@ module SurfaceMaster
|
|
50
50
|
def sysex!(*payload)
|
51
51
|
fail NoOutputAllowedError unless output_enabled?
|
52
52
|
msg = sysex_msg(payload)
|
53
|
-
logger.debug { "#{msg.length}: 0x#{msg.map { |b| '%02X' % b }.join(' ')}" }
|
54
53
|
result = @output.write_sysex(msg)
|
55
54
|
if result != 0
|
56
|
-
|
55
|
+
logger.error { "Sysex Error: #{Portmidi::PM_Map.Pm_GetErrorText(result)}" }
|
57
56
|
end
|
58
57
|
result
|
59
58
|
end
|
60
59
|
|
60
|
+
def format_msg(msg)
|
61
|
+
"0x#{msg.map { |b| '%02X' % b }.join(' ')} (len = #{msg.length})"
|
62
|
+
end
|
63
|
+
|
61
64
|
def create_input_device(opts)
|
62
65
|
return nil unless opts[:input]
|
63
66
|
create_device(Portmidi.input_devices,
|
@@ -7,10 +7,12 @@ module SurfaceMaster
|
|
7
7
|
def initialize(opts = nil)
|
8
8
|
@name = "Numark ORBIT"
|
9
9
|
super(opts)
|
10
|
-
|
10
|
+
init!
|
11
11
|
end
|
12
12
|
|
13
|
-
def reset
|
13
|
+
def reset!; end
|
14
|
+
|
15
|
+
def init!
|
14
16
|
# Hack to get around apparent portmidi message truncation.
|
15
17
|
return
|
16
18
|
|
@@ -18,48 +20,63 @@ module SurfaceMaster
|
|
18
20
|
# this will let us compare command vs. response payloads to determine
|
19
21
|
# if the state of the device is what we want. Of course, sometimes it
|
20
22
|
# lies, but we can't do much about that.
|
21
|
-
# expected_state = MAPPINGS[
|
23
|
+
# expected_state = MAPPINGS[1..-1]
|
22
24
|
# sysex!(MAPPINGS)
|
23
25
|
# sleep 0.1
|
24
26
|
# sysex!(READ_STATE)
|
25
|
-
# current_state
|
26
|
-
# started_at
|
27
|
-
# attempts
|
27
|
+
# current_state = []
|
28
|
+
# started_at = Time.now.to_f
|
29
|
+
# attempts = 1
|
30
|
+
# state = :looking_for_start
|
28
31
|
# loop do
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# # TODO: method before they begin clamoring for input, but that's just
|
32
|
-
# # TODO: a guess right now.
|
33
|
-
# if @input.buffer.length == 0
|
32
|
+
# raw = @input.read
|
33
|
+
# unless raw
|
34
34
|
# elapsed = Time.now.to_f - started_at
|
35
35
|
# if elapsed > 4.0
|
36
|
-
# logger.
|
36
|
+
# logger.error { "Timeout fetching state of Numark Orbit!" }
|
37
37
|
# break
|
38
38
|
# elsif elapsed > (1.0 * attempts)
|
39
|
-
# logger.
|
40
|
-
# attempts
|
41
|
-
#
|
39
|
+
# logger.error { "Asking for current state of Numark Orbit again!" }
|
40
|
+
# attempts += 1
|
41
|
+
# current_state = []
|
42
|
+
# state = :looking_for_start
|
43
|
+
# sysex!(READ_STATE)
|
42
44
|
# next
|
43
45
|
# end
|
44
46
|
# sleep 0.01
|
45
47
|
# next
|
46
48
|
# end
|
47
|
-
# raw = @input.gets
|
48
|
-
# current_state = raw.find { |ii| ii[:data][0] == 0xF0 }
|
49
|
-
# break unless current_state.nil?
|
50
|
-
# end
|
51
|
-
|
52
|
-
# return unless current_state
|
53
49
|
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
50
|
+
# case state
|
51
|
+
# when :looking_for_start
|
52
|
+
# idx = raw.find_index { |ii| ii[:message][0] == 0xF0 }
|
53
|
+
# if idx
|
54
|
+
# state = :looking_for_end
|
55
|
+
# raw = raw[idx..-1]
|
56
|
+
# current_state += raw.map { |ii| ii[:message] }.flatten
|
57
|
+
# end
|
58
|
+
# when :looking_for_end
|
59
|
+
# idx = raw.find_index { |ii| ii[:message][0] == 0xF7 }
|
60
|
+
# if idx
|
61
|
+
# # TODO: Now what?
|
62
|
+
# current_state = current_state[6..-1]
|
63
|
+
# if expected_state != current_state
|
64
|
+
# logger.error { "UH OH! Numark Orbit state didn't match what we sent!" }
|
65
|
+
# logger.error { "Expected: #{format_msg(expected_state)}" }
|
66
|
+
# logger.error { "Got: #{format_msg(current_state)}" }
|
67
|
+
# else
|
68
|
+
# logger.debug { "Your Numark Orbit should be in the right state now." }
|
69
|
+
# return
|
70
|
+
# end
|
71
|
+
# else
|
72
|
+
# idx = -1
|
73
|
+
# end
|
74
|
+
# raw = raw[0..idx]
|
75
|
+
# current_state += raw.map { |ii| ii[:message] }.flatten
|
76
|
+
# end
|
62
77
|
# end
|
78
|
+
|
79
|
+
# logger.error { "Didn't get state from Numark Orbit!" }
|
63
80
|
end
|
64
81
|
|
65
82
|
def read
|
@@ -70,8 +87,13 @@ module SurfaceMaster
|
|
70
87
|
|
71
88
|
protected
|
72
89
|
|
73
|
-
MAPPINGS = [0x03,
|
90
|
+
MAPPINGS = [0x03, # Command byte.
|
91
|
+
|
92
|
+
# Some aspect of internal state I don't understand...
|
93
|
+
0x01, 0x70,
|
74
94
|
|
95
|
+
# Pad mappings. (Channel, Note, Color) for banks 1-4.
|
96
|
+
# These are addressed left-to-right, top-to-bottom.
|
75
97
|
0x00, 0x00, 0x00,
|
76
98
|
0x00, 0x04, 0x00,
|
77
99
|
0x00, 0x08, 0x00,
|
@@ -88,6 +110,7 @@ module SurfaceMaster
|
|
88
110
|
0x00, 0x07, 0x00,
|
89
111
|
0x00, 0x0B, 0x00,
|
90
112
|
0x00, 0x0F, 0x00,
|
113
|
+
|
91
114
|
0x01, 0x00, 0x00,
|
92
115
|
0x01, 0x04, 0x00,
|
93
116
|
0x01, 0x08, 0x00,
|
@@ -104,6 +127,7 @@ module SurfaceMaster
|
|
104
127
|
0x01, 0x07, 0x00,
|
105
128
|
0x01, 0x0B, 0x00,
|
106
129
|
0x01, 0x0F, 0x00,
|
130
|
+
|
107
131
|
0x02, 0x00, 0x00,
|
108
132
|
0x02, 0x04, 0x00,
|
109
133
|
0x02, 0x08, 0x00,
|
@@ -111,7 +135,7 @@ module SurfaceMaster
|
|
111
135
|
0x02, 0x01, 0x00,
|
112
136
|
0x02, 0x05, 0x00,
|
113
137
|
0x02, 0x09, 0x00,
|
114
|
-
0x02, 0x0D, 0x00,
|
138
|
+
0x02, 0x0D, 0x00, # After here is where shit goes sideways...
|
115
139
|
0x02, 0x02, 0x00,
|
116
140
|
0x02, 0x06, 0x00,
|
117
141
|
0x02, 0x0A, 0x00,
|
@@ -120,6 +144,7 @@ module SurfaceMaster
|
|
120
144
|
0x02, 0x07, 0x00,
|
121
145
|
0x02, 0x0B, 0x00,
|
122
146
|
0x02, 0x0F, 0x00,
|
147
|
+
|
123
148
|
0x03, 0x00, 0x00,
|
124
149
|
0x03, 0x04, 0x00,
|
125
150
|
0x03, 0x08, 0x00,
|
@@ -137,22 +162,42 @@ module SurfaceMaster
|
|
137
162
|
0x03, 0x0B, 0x00,
|
138
163
|
0x03, 0x0F, 0x00,
|
139
164
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
0x00,
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
0x00,
|
154
|
-
|
155
|
-
|
165
|
+
# VKnob buttons, I think. Ordered by bank, then vknob.
|
166
|
+
# High nybble of first byte is 0x0 for abslute, 0x1 for
|
167
|
+
# relative. Low nybble is channel. Second byte is CC.
|
168
|
+
0x00, 0x00,
|
169
|
+
0x01, 0x00,
|
170
|
+
0x02, 0x00,
|
171
|
+
0x03, 0x00,
|
172
|
+
|
173
|
+
0x00, 0x01,
|
174
|
+
0x01, 0x01,
|
175
|
+
0x02, 0x01,
|
176
|
+
0x03, 0x01,
|
177
|
+
|
178
|
+
0x00, 0x02,
|
179
|
+
0x01, 0x02,
|
180
|
+
0x02, 0x02,
|
181
|
+
0x03, 0x02,
|
182
|
+
|
183
|
+
0x00, 0x03,
|
184
|
+
0x01, 0x03,
|
185
|
+
0x02, 0x03,
|
186
|
+
0x03, 0x03,
|
187
|
+
|
188
|
+
# Shoulder buttons. Channel/CC pairs for left, then right
|
189
|
+
# through each of the four banks.
|
190
|
+
0x0C, 0x00,
|
191
|
+
0x0D, 0x00,
|
192
|
+
|
193
|
+
0x0C, 0x00,
|
194
|
+
0x0D, 0x00,
|
195
|
+
|
196
|
+
0x0C, 0x00,
|
197
|
+
0x0D, 0x00,
|
198
|
+
|
199
|
+
0x0C, 0x00,
|
200
|
+
0x0D, 0x00]
|
156
201
|
READ_STATE = [0x01, 0x00, 0x00]
|
157
202
|
|
158
203
|
def sysex_prefix; @sysex_prefix ||= super + [0x00, 0x01, 0x3F, 0x2B]; end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surface_master
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Frisby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: portmidi
|