pedalboard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -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
@@ -0,0 +1,11 @@
1
+ module Pedalboard
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ REVISION = 1
6
+ end
7
+
8
+ def self.version
9
+ "#{Version::MAJOR}.#{Version::MINOR}.#{Version::REVISION}"
10
+ end
11
+ end
@@ -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