pedalboard 0.0.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 +7 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +65 -0
- data/README.md +25 -0
- data/bin/pedalboard +6 -0
- data/du/Dino.cpp +257 -0
- data/du/Dino.h +85 -0
- data/du/du.ino +19 -0
- data/examples/main_stage.rb +57 -0
- data/lib/pedalboard.rb +22 -0
- data/lib/pedalboard/cli.rb +21 -0
- data/lib/pedalboard/commands.rb +44 -0
- data/lib/pedalboard/components/base_component.rb +20 -0
- data/lib/pedalboard/components/led.rb +28 -0
- data/lib/pedalboard/components/pedal.rb +52 -0
- data/lib/pedalboard/components/pot.rb +78 -0
- data/lib/pedalboard/device.rb +32 -0
- data/lib/pedalboard/dsl_parser.rb +25 -0
- data/lib/pedalboard/version.rb +11 -0
- data/pedalboard.gemspec +27 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/pedalboard/cli_spec.rb +40 -0
- data/spec/unit/pedalboard/components/led_spec.rb +43 -0
- data/spec/unit/pedalboard/components/pedal_spec.rb +34 -0
- data/spec/unit/pedalboard/components/pot_spec.rb +54 -0
- data/spec/unit/pedalboard/device_spec.rb +47 -0
- data/spec/unit/pedalboard/dsl_parser_spec.rb +64 -0
- data/spec/unit/pedalboard_spec.rb +79 -0
- metadata +165 -0
data/du/du.ino
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "Dino.h"
|
2
|
+
#include <Servo.h>
|
3
|
+
Dino dino;
|
4
|
+
|
5
|
+
// Dino.h doesn't handle TXRX. Setup a function to tell it to write to Serial.
|
6
|
+
void writeResponse(char *response) { Serial.print(response); Serial.print("\n"); }
|
7
|
+
void (*writeCallback)(char *str) = writeResponse;
|
8
|
+
|
9
|
+
void setup() {
|
10
|
+
Serial.begin(115200);
|
11
|
+
dino.setupWrite(writeCallback);
|
12
|
+
}
|
13
|
+
|
14
|
+
void loop() {
|
15
|
+
while(Serial.available() > 0) dino.parse(Serial.read());
|
16
|
+
dino.updateListeners();
|
17
|
+
Serial.flush();
|
18
|
+
}
|
19
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
led1 = nil
|
2
|
+
led2 = nil
|
3
|
+
led3 = nil
|
4
|
+
led4 = nil
|
5
|
+
|
6
|
+
altled1 = nil
|
7
|
+
altled2 = nil
|
8
|
+
altled3 = nil
|
9
|
+
altled4 = nil
|
10
|
+
|
11
|
+
pot pin: 'A0',
|
12
|
+
change: ->(value) { set_volume(value) }
|
13
|
+
|
14
|
+
pedal pin: 2,
|
15
|
+
press: ->{ patch 1 },
|
16
|
+
long_press: ->{ patch 4 }
|
17
|
+
|
18
|
+
pedal pin: 3,
|
19
|
+
press: ->{ patch 2 },
|
20
|
+
long_press: ->{ patch 5 }
|
21
|
+
|
22
|
+
pedal pin: 4,
|
23
|
+
press: ->{ patch 3 },
|
24
|
+
long_press: ->{ patch 6 }
|
25
|
+
|
26
|
+
pedal pin: 5,
|
27
|
+
press: ->{ next_set },
|
28
|
+
long_press: ->{ previous_set }
|
29
|
+
|
30
|
+
led1 = led pin: 6
|
31
|
+
led2 = led pin: 11
|
32
|
+
led3 = led pin: 8
|
33
|
+
led4 = led pin: 9
|
34
|
+
|
35
|
+
altled1 = led pin: 10
|
36
|
+
altled2 = led pin: 7
|
37
|
+
altled3 = led pin: 12
|
38
|
+
altled4 = led pin: 13
|
39
|
+
|
40
|
+
MIDI.using(pedalboard.midi_input, pedalboard.midi_output) do
|
41
|
+
receive do |message|
|
42
|
+
if message.index == 22
|
43
|
+
begin
|
44
|
+
led1.light_if message.value == 1
|
45
|
+
led2.light_if message.value == 2
|
46
|
+
led3.light_if message.value == 3
|
47
|
+
|
48
|
+
altled1.light_if message.value == 4
|
49
|
+
altled2.light_if message.value == 5
|
50
|
+
altled3.light_if message.value == 6
|
51
|
+
rescue Exception => e
|
52
|
+
puts e.message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/lib/pedalboard.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'pedalboard/cli'
|
2
|
+
require_relative 'pedalboard/dsl_parser'
|
3
|
+
require_relative 'pedalboard/device'
|
4
|
+
|
5
|
+
require_relative 'pedalboard/components/led'
|
6
|
+
require_relative 'pedalboard/components/pedal'
|
7
|
+
require_relative 'pedalboard/components/pot'
|
8
|
+
|
9
|
+
module Pedalboard
|
10
|
+
def self.create opts={}, &block
|
11
|
+
device_class = opts.delete(:device_class) { Device }
|
12
|
+
dsl_parser = opts.delete(:dsl_parser) { DSLParser }
|
13
|
+
|
14
|
+
parser = dsl_parser.new(
|
15
|
+
device_class.new(opts)
|
16
|
+
)
|
17
|
+
|
18
|
+
parser.instance_exec(&block) if block_given?
|
19
|
+
|
20
|
+
return parser.pedalboard
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'mixlib/cli'
|
2
|
+
|
3
|
+
require_relative '../pedalboard'
|
4
|
+
|
5
|
+
module Pedalboard
|
6
|
+
class CLI
|
7
|
+
include Mixlib::CLI
|
8
|
+
|
9
|
+
def create_device filename
|
10
|
+
contents = File.open(filename).read
|
11
|
+
Pedalboard.create do
|
12
|
+
eval contents
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def run args
|
17
|
+
options = parse_options(args)
|
18
|
+
options.each { |file| create_device file }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Pedalboard
|
2
|
+
class Commands
|
3
|
+
NOTES = [
|
4
|
+
'c1', 'd1', 'e1',
|
5
|
+
'f1', 'g1', 'a1'
|
6
|
+
]
|
7
|
+
|
8
|
+
attr_reader :pedalboard
|
9
|
+
|
10
|
+
def initialize opts={}
|
11
|
+
@pedalboard = opts.fetch(:pedalboard) { }
|
12
|
+
end
|
13
|
+
|
14
|
+
def patch number
|
15
|
+
midi do
|
16
|
+
note NOTES[number - 1]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def next_set
|
21
|
+
midi do
|
22
|
+
note 'b1'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def previous_set
|
27
|
+
midi do
|
28
|
+
note 'c2'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_volume value
|
33
|
+
midi do
|
34
|
+
cc 7, value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def midi &block
|
39
|
+
MIDI.using(pedalboard.midi_input, pedalboard.midi_output) do
|
40
|
+
instance_exec &block
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../commands'
|
2
|
+
|
3
|
+
module Pedalboard; module Components
|
4
|
+
class BaseComponent
|
5
|
+
attr_reader :pin, :pedalboard
|
6
|
+
|
7
|
+
def initialize opts={}
|
8
|
+
@pin = opts.fetch(:pin) {}
|
9
|
+
@pedalboard = opts.fetch(:pedalboard) {}
|
10
|
+
@dino_component = opts.fetch(:dino_component) {}
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def run_command command, *args
|
15
|
+
Commands.new(
|
16
|
+
pedalboard: pedalboard
|
17
|
+
).instance_exec *args, &command
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end; end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'dino/components/base_component'
|
2
|
+
require 'dino/components/led'
|
3
|
+
|
4
|
+
require_relative 'base_component'
|
5
|
+
|
6
|
+
module Pedalboard; module Components
|
7
|
+
class Led < BaseComponent
|
8
|
+
def light_if condition
|
9
|
+
condition ? on : off
|
10
|
+
end
|
11
|
+
|
12
|
+
def off
|
13
|
+
dino_component.send :off
|
14
|
+
end
|
15
|
+
|
16
|
+
def on
|
17
|
+
dino_component.send :on
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def dino_component
|
22
|
+
@dino_component ||= Dino::Components::Led.new(
|
23
|
+
pin: pin,
|
24
|
+
board: pedalboard.board
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end; end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'dino/components/base_component'
|
2
|
+
require 'dino/components/button'
|
3
|
+
|
4
|
+
require_relative 'base_component'
|
5
|
+
|
6
|
+
module Pedalboard; module Components
|
7
|
+
class Pedal < BaseComponent
|
8
|
+
LONG_TIME = 0.4
|
9
|
+
|
10
|
+
attr_reader :press, :long_press
|
11
|
+
|
12
|
+
def initialize opts={}
|
13
|
+
super opts
|
14
|
+
|
15
|
+
@press = opts.fetch(:press) { ->{} }
|
16
|
+
@long_press = opts.fetch(:long_press) { ->{} }
|
17
|
+
|
18
|
+
configure_dino_component
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure_dino_component
|
22
|
+
dino_component.down do
|
23
|
+
begin
|
24
|
+
@start_time = Time.now
|
25
|
+
rescue Exception => e
|
26
|
+
puts e.message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
dino_component.up do
|
31
|
+
begin
|
32
|
+
interval = Time.now - @start_time
|
33
|
+
if interval > LONG_TIME
|
34
|
+
run_command long_press
|
35
|
+
else
|
36
|
+
run_command press
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
puts e.message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def dino_component
|
46
|
+
@dino_component ||= Dino::Components::Button.new(
|
47
|
+
pin: pin,
|
48
|
+
board: pedalboard.board
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end; end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'dino/components/base_component'
|
2
|
+
require 'dino/components/sensor'
|
3
|
+
|
4
|
+
require_relative 'base_component'
|
5
|
+
|
6
|
+
module Pedalboard; module Components
|
7
|
+
class Pot < BaseComponent
|
8
|
+
TOLERANCE = 2
|
9
|
+
|
10
|
+
UPPER_LIMIT = 127
|
11
|
+
LOWER_LIMIT = 0
|
12
|
+
|
13
|
+
attr_reader :change, :inverted,
|
14
|
+
:lower_limit, :upper_limit,
|
15
|
+
:tolerance
|
16
|
+
|
17
|
+
attr_accessor :value
|
18
|
+
|
19
|
+
def initialize opts={}
|
20
|
+
super opts
|
21
|
+
|
22
|
+
@change = opts.fetch(:change) { ->(value) {} }
|
23
|
+
@lower_limit = opts.fetch(:lower_limit) { LOWER_LIMIT }
|
24
|
+
@upper_limit = opts.fetch(:upper_limit) { UPPER_LIMIT }
|
25
|
+
@tolerance = opts.fetch(:tolerance) { TOLERANCE }
|
26
|
+
@inverted = opts.fetch(:inverted) { false }
|
27
|
+
@value = lower_limit
|
28
|
+
|
29
|
+
configure_dino_component
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def configure_dino_component
|
34
|
+
dino_component.when_data_received do |value|
|
35
|
+
begin
|
36
|
+
new_value = normalised(value)
|
37
|
+
if significant_change?(new_value)
|
38
|
+
@value = new_value
|
39
|
+
run_command(change, new_value)
|
40
|
+
end
|
41
|
+
rescue Exception => e
|
42
|
+
puts e.message
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def dino_component
|
48
|
+
@dino_component ||= Dino::Components::Sensor.new(
|
49
|
+
pin: pin,
|
50
|
+
board: pedalboard.board
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def normalised received_value
|
55
|
+
normalised_value = (
|
56
|
+
(received_value.to_i / 1024.0) *
|
57
|
+
(upper_limit - lower_limit)
|
58
|
+
).to_i + lower_limit
|
59
|
+
normalised_value = upper_limit - normalised_value if inverted
|
60
|
+
normalised_value
|
61
|
+
end
|
62
|
+
|
63
|
+
def range_to_ignore
|
64
|
+
min = value - tolerance
|
65
|
+
max = value + tolerance
|
66
|
+
(min..max).to_a
|
67
|
+
end
|
68
|
+
|
69
|
+
def significant_change? new_value
|
70
|
+
if new_value != value
|
71
|
+
return true if new_value == lower_limit
|
72
|
+
return true if new_value == upper_limit
|
73
|
+
end
|
74
|
+
|
75
|
+
!range_to_ignore.include?(new_value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end; end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'dino'
|
2
|
+
require 'micromidi'
|
3
|
+
|
4
|
+
module Pedalboard
|
5
|
+
class Device
|
6
|
+
|
7
|
+
attr_reader :components, :board, :midi_output, :midi_input
|
8
|
+
|
9
|
+
def initialize opts={}
|
10
|
+
@components = []
|
11
|
+
@connection = opts.fetch(:connection) { Dino::TxRx::Serial.new }
|
12
|
+
@board = opts.fetch(:board) { Dino::Board.new(connection) }
|
13
|
+
@midi_output = opts.fetch(:midi_output) { UniMIDI::Output.gets }
|
14
|
+
@midi_input = opts.fetch(:midi_input) { UniMIDI::Input.gets }
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_component type, opts={}
|
18
|
+
opts[:pedalboard] = self
|
19
|
+
component = eval(component_class(type))
|
20
|
+
.new(opts)
|
21
|
+
components << component
|
22
|
+
component
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
attr_reader :connection
|
27
|
+
|
28
|
+
def component_class type
|
29
|
+
"Pedalboard::Components::#{type.capitalize}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pedalboard
|
2
|
+
class DSLParser
|
3
|
+
attr_reader :pedalboard
|
4
|
+
|
5
|
+
def initialize pedalboard
|
6
|
+
@pedalboard = pedalboard
|
7
|
+
end
|
8
|
+
|
9
|
+
def led *args
|
10
|
+
@pedalboard.add_component :led, *args
|
11
|
+
end
|
12
|
+
|
13
|
+
def pedal *args
|
14
|
+
@pedalboard.add_component :pedal, *args
|
15
|
+
end
|
16
|
+
|
17
|
+
def pot *args
|
18
|
+
@pedalboard.add_component :pot, *args
|
19
|
+
end
|
20
|
+
|
21
|
+
def board
|
22
|
+
self.pedalboard.board
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/pedalboard.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
2
|
+
require 'pedalboard/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'pedalboard'
|
6
|
+
s.version = Pedalboard.version
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.date = '2014-05-04'
|
9
|
+
s.summary = 'Easy Arduino MIDI pedalboard'
|
10
|
+
s.description = 'Quick and easy prototyping for Arduino-based MIDI pedalboards'
|
11
|
+
s.authors = ['Adam Phillips']
|
12
|
+
s.email = 'adam@29ways.co.uk'
|
13
|
+
s.homepage = 'https://github.com/adamphillips/pedalboard'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'dino'
|
21
|
+
s.add_runtime_dependency 'micromidi'
|
22
|
+
s.add_runtime_dependency 'mixlib-cli'
|
23
|
+
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
s.add_development_dependency 'pry'
|
26
|
+
s.add_development_dependency 'codeclimate-test-reporter'
|
27
|
+
end
|