lib/launchpad/device.rb in launchpad-0.1.1 vs lib/launchpad/device.rb in launchpad-0.2.0
- old
+ new
@@ -117,11 +117,14 @@
#
# [<tt>:x</tt>] x coordinate
# [<tt>:y</tt>] y coordinate
# [<tt>:red</tt>] brightness of red LED
# [<tt>:green</tt>] brightness of green LED
- # [<tt>:mode</tt>] button mode
+ # [<tt>:mode</tt>] button mode, defaults to <tt>:normal</tt>, one of:
+ # [<tt>:normal/tt>] updates the LED for all circumstances (the new value will be written to both buffers)
+ # [<tt>:flashing/tt>] updates the LED for flashing (the new value will be written to buffer 0 while the LED will be off in buffer 1, see buffering_mode)
+ # [<tt>:buffering/tt>] updates the LED for the current update_buffer only
#
# Errors raised:
#
# [Launchpad::NoValidGridCoordinatesError] when coordinates aren't within the valid range
# [Launchpad::NoValidBrightnessError] when brightness values aren't within the valid range
@@ -155,58 +158,73 @@
# [Launchpad::NoOutputAllowedError] when output is not enabled
def change_all(*colors)
# ensure that colors is at least and most 80 elements long
colors = colors.flatten[0..79]
colors += [0] * (80 - colors.size) if colors.size < 80
- # HACK switch off first grid LED to reset rapid LED change pointer
- output(Status::ON, 0, 0)
+ # send normal MIDI message to reset rapid LED change pointer
+ # in this case, set mapping mode to x-y layout (the default)
+ output(Status::CC, Status::NIL, GridLayout::XY)
# send colors in slices of 2
+ messages = []
colors.each_slice(2) do |c1, c2|
- output(Status::MULTI, velocity(c1), velocity(c2))
+ messages << message(Status::MULTI, velocity(c1), velocity(c2))
end
+ output_messages(messages)
end
# Switches LEDs marked as flashing on when using custom timer for flashing.
#
# Errors raised:
#
# [Launchpad::NoOutputAllowedError] when output is not enabled
def flashing_on
- output(Status::CC, Status::NIL, Velocity::FLASHING_ON)
+ buffering_mode(:display_buffer => 0)
end
# Switches LEDs marked as flashing off when using custom timer for flashing.
#
# Errors raised:
#
# [Launchpad::NoOutputAllowedError] when output is not enabled
def flashing_off
- output(Status::CC, Status::NIL, Velocity::FLASHING_OFF)
+ buffering_mode(:display_buffer => 1)
end
# Starts flashing LEDs marked as flashing automatically.
# Stop flashing by calling flashing_on or flashing_off.
#
# Errors raised:
#
# [Launchpad::NoOutputAllowedError] when output is not enabled
def flashing_auto
- output(Status::CC, Status::NIL, Velocity::FLASHING_AUTO)
+ buffering_mode(:flashing => true)
end
- # def start_buffering
- # output(CC, 0x00, 0x31)
- # @buffering = true
- # end
- #
- # def flush_buffer(end_buffering = true)
- # output(CC, 0x00, 0x34)
- # if end_buffering
- # output(CC, 0x00, 0x30)
- # @buffering = false
- # end
- # end
+ # Controls the two buffers.
+ #
+ # Optional options hash:
+ #
+ # [<tt>:display_buffer</tt>] which buffer to use for display, defaults to +0+
+ # [<tt>:update_buffer</tt>] which buffer to use for updates when <tt>:mode</tt> is set to <tt>:buffering</tt>, defaults to +0+ (see change)
+ # [<tt>:copy</tt>] whether to copy the LEDs states from the new display_buffer over to the new update_buffer, <tt>true/false</tt>, defaults to <tt>false</tt>
+ # [<tt>:flashing</tt>] whether to start flashing by automatically switching between the two buffers for display, <tt>true/false</tt>, defaults to <tt>false</tt>
+ #
+ # Errors raised:
+ #
+ # [Launchpad::NoOutputAllowedError] when output is not enabled
+ def buffering_mode(opts = nil)
+ opts = {
+ :display_buffer => 0,
+ :update_buffer => 0,
+ :copy => false,
+ :flashing => false
+ }.merge(opts || {})
+ data = opts[:display_buffer] + 4 * opts[:update_buffer] + 32
+ data += 16 if opts[:copy]
+ data += 8 if opts[:flashing]
+ output(Status::CC, Status::NIL, data)
+ end
# Reads user actions (button presses/releases) that haven't been handled yet.
#
# Returns:
#
@@ -328,12 +346,26 @@
#
# Errors raised:
#
# [Launchpad::NoOutputAllowedError] when output is not enabled
def output(status, data1, data2)
+ output_messages([message(status, data1, data2)])
+ end
+
+ # Writes several messages to the MIDI device.
+ #
+ # Parameters:
+ #
+ # [+messages+] an array of hashes (usually created with message) with:
+ # [<tt>:message</tt>] an array of
+ # MIDI status code,
+ # MIDI data 1 (note),
+ # MIDI data 2 (velocity)
+ # [<tt>:timestamp</tt>] integer indicating the time when the MIDI message was created
+ def output_messages(messages)
raise NoOutputAllowedError if @output.nil?
- @output.write([{:message => [status, data1, data2], :timestamp => 0}])
+ @output.write(messages)
nil
end
# Calculates the MIDI data 1 value (note) for a button.
#
@@ -383,11 +415,14 @@
#
# Options hash:
#
# [<tt>:red</tt>] brightness of red LED
# [<tt>:green</tt>] brightness of green LED
- # [<tt>:mode</tt>] button mode
+ # [<tt>:mode</tt>] button mode, defaults to <tt>:normal</tt>, one of:
+ # [<tt>:normal/tt>] updates the LED for all circumstances (the new value will be written to both buffers)
+ # [<tt>:flashing/tt>] updates the LED for flashing (the new value will be written to buffer 0 while in buffer 1, the value will be :off, see )
+ # [<tt>:buffering/tt>] updates the LED for the current update_buffer only
#
# Returns:
#
# integer to be used for MIDI data 2
#
@@ -426,9 +461,30 @@
when 2, :medium, :med then 2
when 3, :high, :hi then 3
else
raise NoValidBrightnessError.new("you need to specify the brightness as 0/1/2/3, :off/:low/:medium/:high or :off/:lo/:hi, you specified: #{brightness}")
end
+ end
+
+ # Creates a MIDI message.
+ #
+ # Parameters:
+ #
+ # [+status+] MIDI status code
+ # [+data1+] MIDI data 1 (note)
+ # [+data2+] MIDI data 2 (velocity)
+ #
+ # Returns:
+ #
+ # an array with:
+ #
+ # [<tt>:message</tt>] an array of
+ # MIDI status code,
+ # MIDI data 1 (note),
+ # MIDI data 2 (velocity)
+ # [<tt>:timestamp</tt>] integer indicating the time when the MIDI message was created, in this case 0
+ def message(status, data1, data2)
+ {:message => [status, data1, data2], :timestamp => 0}
end
end
end