micromidi 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ module MicroMIDI
4
+
5
+ class State
6
+
7
+ Default = {
8
+ :channel => 0,
9
+ :octave => 2,
10
+ :velocity => 100
11
+ }
12
+
13
+ attr_accessor :auto_output,
14
+ :channel,
15
+ :last_note,
16
+ :octave,
17
+ :sysex_node,
18
+ :super_sticky,
19
+ :velocity
20
+
21
+ attr_reader :inputs,
22
+ :last_command,
23
+ :listeners,
24
+ :outputs,
25
+ :output_cache,
26
+ :start_time,
27
+ :thru_listeners
28
+
29
+ def initialize(ins, outs, options = {})
30
+ @auto_output = true
31
+ @last_command = nil
32
+ @last_note = nil
33
+ @listeners = []
34
+ @thru_listeners = []
35
+ @output_cache = []
36
+ @start_time = Time.now.to_f
37
+ @super_sticky = false
38
+
39
+ @channel = options[:channel] || Default[:channel]
40
+ @velocity = options[:velocity] || Default[:velocity]
41
+ @octave = options[:octave] || Default[:octave]
42
+
43
+ @inputs = ins
44
+ @outputs = outs
45
+ end
46
+
47
+ def record(m, a, b, outp)
48
+ ts = now
49
+ @output_cache << { :message => outp, :timestamp => ts }
50
+ @last_command = { :method => m, :args => a, :block => b, :timestamp => ts }
51
+ end
52
+
53
+ def toggle_super_sticky
54
+ @super_sticky = !@super_sticky
55
+ end
56
+
57
+ def toggle_auto_output
58
+ @auto_output = !@auto_output
59
+ end
60
+
61
+ def message_properties(opts, *props)
62
+ output = {}
63
+ props.each do |prop|
64
+ output[prop] = opts[prop]
65
+ self.send("#{prop.to_s}=", output[prop]) if !output[prop].nil? && (self.send(prop).nil? || @super_sticky)
66
+ output[prop] ||= self.send(prop.to_s)
67
+ end
68
+ output
69
+ end
70
+
71
+ private
72
+
73
+ def now
74
+ ((Time.now.to_f - @start_time) * 1000)
75
+ end
76
+
77
+ end
78
+
79
+ end
data/lib/micromidi.rb ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # micromidi
4
+ # A Ruby DSL for MIDI
5
+ #
6
+ # (c)2011 Ari Russo
7
+ # licensed under the Apache 2.0 License
8
+ #
9
+
10
+ # libs
11
+ require 'midi-eye'
12
+ require 'midi-message'
13
+ require 'unimidi'
14
+
15
+ module MicroMIDI
16
+
17
+ VERSION = "0.0.7"
18
+
19
+ module Instructions
20
+ end
21
+
22
+ def self.new(*a, &block)
23
+ message(*a, &block)
24
+ end
25
+
26
+ def self.message(*args, &block)
27
+ ins, outs = *process_devices(args)
28
+ MicroMIDI::Context.new(ins, outs, &block)
29
+ end
30
+ class << self
31
+ alias_method :using, :message
32
+ end
33
+
34
+ module IO
35
+
36
+ def self.new(*args)
37
+ MicroMIDI.message(*args)
38
+ end
39
+
40
+ end
41
+
42
+ private
43
+
44
+ def self.process_devices(args)
45
+ ins = args.find_all { |d| d.respond_to?(:type) && d.type == :input && d.respond_to?(:gets) }
46
+ outs = args.find_all { |d| d.respond_to?(:puts) }
47
+ [ins, outs]
48
+ end
49
+
50
+ end
51
+ MIDI = MicroMIDI
52
+
53
+ # modules
54
+ require 'micromidi/instructions/composite'
55
+
56
+ # classes
57
+ require 'micromidi/context'
58
+ require 'micromidi/state'
59
+ require 'micromidi/instructions/process'
60
+ require 'micromidi/instructions/input'
61
+ require 'micromidi/instructions/message'
62
+ require 'micromidi/instructions/output'
63
+ require 'micromidi/instructions/sticky'
64
+ require 'micromidi/instructions/sysex'
65
+
66
+ # re-open
67
+ require 'micromidi/instructions/shorthand'
data/lib/midi.rb ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # micromidi
4
+ # A Ruby DSL for MIDI
5
+ #
6
+ # (c)2011 Ari Russo
7
+ # licensed under the Apache 2.0 License
8
+ #
9
+
10
+ # the purpose of this file is just to allow both
11
+ # <em>require "micromidi"</em>
12
+ # and
13
+ # <em>require "midi"</em>
14
+
15
+ require 'micromidi'
data/test/helper.rb ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ dir = File.dirname(File.expand_path(__FILE__))
4
+ $LOAD_PATH.unshift dir + '/../lib'
5
+
6
+ require 'test/unit'
7
+ require 'midi'
8
+
9
+ module TestHelper
10
+
11
+ def self.select_devices
12
+ $test_device ||= {}
13
+ { :input => UniMIDI::Input.all, :output => UniMIDI::Output.all }.each do |type, devs|
14
+ puts ""
15
+ puts "select an #{type.to_s}..."
16
+ while $test_device[type].nil?
17
+ devs.each do |device|
18
+ puts device.pretty_name
19
+ end
20
+ selection = $stdin.gets.chomp
21
+ if selection != ""
22
+ selection = selection.to_i
23
+ $test_device[type] = devs.find { |d| d.id == selection }
24
+ puts "selected #{selection} for #{type.to_s}" unless $test_device[type]
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ TestHelper.select_devices
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class CompositeTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_play
12
+ m = MicroMIDI.message
13
+ start = Time.now
14
+ msg = m.play "C0", 0.5
15
+
16
+ finish = Time.now
17
+ dif = finish - start
18
+ assert_equal(true, dif >= 0.5)
19
+
20
+ assert_equal(NoteOn, msg.class)
21
+ assert_equal(12, msg.note)
22
+ assert_equal(0, msg.channel)
23
+ assert_equal(2, m.state.output_cache.size)
24
+
25
+ off_msg = m.state.output_cache.last[:message]
26
+ assert_equal(NoteOff, off_msg.class)
27
+ assert_equal(12, off_msg.note)
28
+ assert_equal(0, off_msg.channel)
29
+ end
30
+
31
+ def test_all_off
32
+
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class ContextTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_no_block
12
+ m = MIDI::IO.new
13
+ msg = m.note "C0"
14
+ assert_equal(NoteOn, msg.class)
15
+ assert_equal(12, msg.note)
16
+ assert_equal(0, msg.channel)
17
+ end
18
+
19
+ def test_repeat
20
+ m = MicroMIDI.message
21
+ msg = m.note "C0"
22
+ assert_equal(NoteOn, msg.class)
23
+ assert_equal(12, msg.note)
24
+ assert_equal(0, msg.channel)
25
+
26
+ r_msg = m.repeat
27
+ assert_equal(NoteOn, r_msg.class)
28
+ assert_equal(12, r_msg.note)
29
+ assert_equal(0, r_msg.channel)
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class EffectTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include TestHelper
9
+
10
+ def test_high_pass_note_reject
11
+ m = MicroMIDI.message
12
+ msg = m.note "C0"
13
+ outp = m.hpf msg, :note, 20
14
+ assert_equal(12, msg.note)
15
+ assert_equal(nil, outp)
16
+ end
17
+
18
+ def test_high_pass_note_accept
19
+ m = MicroMIDI.message
20
+ msg = m.note "C4"
21
+ outp = m.hpf msg, :note, 20
22
+ assert_equal(60, msg.note)
23
+ assert_equal(msg, outp)
24
+ end
25
+
26
+ def test_low_pass_note_reject
27
+ m = MicroMIDI.message
28
+ msg = m.note "C4"
29
+ outp = m.lpf msg, :note, 50
30
+ assert_equal(60, msg.note)
31
+ assert_equal(nil, outp)
32
+ end
33
+
34
+ def test_low_pass_note_accept
35
+ m = MicroMIDI.message
36
+ msg = m.note "C4"
37
+ outp = m.lp msg, :note, 100
38
+ assert_equal(60, msg.note)
39
+ assert_equal(msg, outp)
40
+ end
41
+
42
+ def test_band_pass_note_reject
43
+ m = MicroMIDI.message
44
+ msg = m.note "C4"
45
+ outp = m.bpf msg, :note, (20..50)
46
+ assert_equal(60, msg.note)
47
+ assert_equal(nil, outp)
48
+ end
49
+
50
+ def test_band_pass_note_accept
51
+ m = MicroMIDI.message
52
+ msg = m.note "C4"
53
+ outp = m.bp msg, :note, (20..100)
54
+ assert_equal(60, msg.note)
55
+ assert_equal(msg, outp)
56
+ end
57
+
58
+ def test_notch_note_reject
59
+ m = MicroMIDI.message
60
+ msg = m.note "C4"
61
+ outp = m.nf msg, :note, (20..70)
62
+ assert_equal(60, msg.note)
63
+ assert_equal(nil, outp)
64
+ end
65
+
66
+ def test_notch_note_accept
67
+ m = MicroMIDI.message
68
+ msg = m.note "C4"
69
+ outp = m.nf msg, :note, (20..50)
70
+ assert_equal(60, msg.note)
71
+ assert_equal(msg, outp)
72
+ end
73
+
74
+ def test_multiband_note_reject
75
+ m = MicroMIDI.message
76
+ msg = m.note "C4"
77
+ outp = m.f msg, :note, [(20..30), (40..50)]
78
+ assert_equal(60, msg.note)
79
+ assert_equal(nil, outp)
80
+ end
81
+
82
+ def test_multiband_note_accept
83
+ m = MicroMIDI.message
84
+ msg = m.note "C4"
85
+ outp = m.mbf msg, :note, [(20..30), (50..70)]
86
+ assert_equal(60, msg.note)
87
+ assert_equal(msg, outp)
88
+ end
89
+
90
+ def test_multinotch_note_reject
91
+ m = MicroMIDI.message
92
+ msg = m.note "C4"
93
+ outp = m.mbf msg, :note, [(20..30), (55..65)], :reject => true
94
+ assert_equal(60, msg.note)
95
+ assert_equal(nil, outp)
96
+ end
97
+
98
+ def test_multinotch_note_accept
99
+ m = MicroMIDI.message
100
+ msg = m.note "C4"
101
+ outp = m.mbf msg, :note, [(20..30), (40..50)], :reject => true
102
+ assert_equal(60, msg.note)
103
+ assert_equal(msg, outp)
104
+ end
105
+
106
+ def test_limit_low
107
+ m = MicroMIDI.message
108
+ msg = m.note "C0"
109
+ outp = m.limit msg, :note, (20..50)
110
+ assert_equal(20, msg.note)
111
+ end
112
+
113
+ def test_limit_high
114
+ m = MicroMIDI.message
115
+ msg = m.note "C6"
116
+ outp = m.limit msg, :note, (20..50)
117
+ assert_equal(50, msg.note)
118
+ end
119
+
120
+ def test_transpose_note_up
121
+ m = MicroMIDI.message
122
+ msg = m.note "C4"
123
+ outp = m.transpose msg, :note, 5
124
+ assert_equal(65, msg.note)
125
+ end
126
+
127
+ def test_transpose_velocity_down
128
+ m = MicroMIDI.message
129
+ msg = m.note "C4", :velocity => 82
130
+ outp = m.transpose msg, :velocity, -10
131
+ assert_equal(72, msg.velocity)
132
+ end
133
+
134
+ end
135
+
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class InputTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_thru_listeners
12
+ m = MicroMIDI.message($test_device[:input].open)
13
+ m.thru
14
+ assert_equal(0, m.state.listeners.size)
15
+ assert_equal(1, m.state.thru_listeners.size)
16
+ assert_equal(MIDIEye::Listener, m.state.thru_listeners.first.class)
17
+ end
18
+
19
+ def test_thru_unless
20
+ end
21
+
22
+ end
23
+
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class MessageTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_cc
12
+ m = MicroMIDI.message
13
+ msg = m.cc 16, 12
14
+ assert_equal(ControlChange, msg.class)
15
+ assert_equal(16, msg.index)
16
+ assert_equal(12, msg.value)
17
+ end
18
+
19
+ def test_channel_aftertouch
20
+ m = MicroMIDI::IO.new
21
+ msg = m.channel_aftertouch 2, :channel => 1
22
+ assert_equal(ChannelAftertouch, msg.class)
23
+ assert_equal(1, msg.channel)
24
+ assert_equal(2, msg.value)
25
+ end
26
+
27
+ def test_poly_aftertouch
28
+ m = MicroMIDI::IO.new
29
+ msg = m.poly_aftertouch 64, 2, :channel => 1
30
+ assert_equal(PolyphonicAftertouch, msg.class)
31
+ assert_equal(1, msg.channel)
32
+ assert_equal(64, msg.note)
33
+ assert_equal(2, msg.value)
34
+ end
35
+
36
+ def test_pitch_bend
37
+ m = MicroMIDI::IO.new
38
+ msg = m.pitch_bend 64, 2, :channel => 1
39
+ assert_equal(PitchBend, msg.class)
40
+ assert_equal(1, msg.channel)
41
+ assert_equal(64, msg.low)
42
+ assert_equal(2, msg.high)
43
+ end
44
+
45
+ def test_note_off
46
+ m = MicroMIDI.message
47
+ msg = m.note_off 13, :channel => 9, :velocity => 80
48
+ assert_equal(NoteOff, msg.class)
49
+ assert_equal(13, msg.note)
50
+ assert_equal(9, msg.channel)
51
+ assert_equal(80, msg.velocity)
52
+ end
53
+
54
+ def test_note_on_string
55
+ m = MicroMIDI.message
56
+ msg = m.note "C0", :velocity => 94
57
+ assert_equal(NoteOn, msg.class)
58
+ assert_equal(12, msg.note)
59
+ assert_equal(94, msg.velocity)
60
+ end
61
+
62
+ def test_note_on_string_no_octave
63
+ m = MicroMIDI.message
64
+ msg = m.note "C", :velocity => 94
65
+ assert_equal(NoteOn, msg.class)
66
+ assert_equal(36, msg.note)
67
+ assert_equal(94, msg.velocity)
68
+ end
69
+
70
+ def test_note_on_int
71
+ m = MicroMIDI.message
72
+ msg = m.note 12, :channel => 3
73
+ assert_equal(NoteOn, msg.class)
74
+ assert_equal(12, msg.note)
75
+ assert_equal(3, msg.channel)
76
+ end
77
+
78
+ def test_note_on_symbol
79
+ m = MicroMIDI.message
80
+ msg = m.note :C0
81
+ assert_equal(NoteOn, msg.class)
82
+ assert_equal(12, msg.note)
83
+ assert_equal(100, msg.velocity)
84
+ end
85
+
86
+ def test_note_on_symbol_no_octave
87
+ m = MicroMIDI.message
88
+ msg = m.note :C
89
+ assert_equal(NoteOn, msg.class)
90
+ assert_equal(36, msg.note)
91
+ assert_equal(100, msg.velocity)
92
+ end
93
+
94
+ def test_parse
95
+ m = MicroMIDI.message
96
+ msg = m.parse "906040"
97
+ assert_equal(NoteOn, msg.class)
98
+ assert_equal(96, msg.note)
99
+ assert_equal(0, msg.channel)
100
+ assert_equal(64, msg.velocity)
101
+ end
102
+
103
+ def test_program_change
104
+ m = MicroMIDI.message
105
+ msg = m.program_change 15
106
+ assert_equal(ProgramChange, msg.class)
107
+ assert_equal(15, msg.program)
108
+ end
109
+
110
+ def test_off
111
+ m = MicroMIDI.message
112
+ msg = m.note "C0", :channel => 3
113
+ assert_equal(NoteOn, msg.class)
114
+ assert_equal(12, msg.note)
115
+ assert_equal(3, msg.channel)
116
+ off_msg = m.off
117
+ assert_equal(NoteOff, off_msg.class)
118
+ assert_equal(12, off_msg.note)
119
+ assert_equal(3, off_msg.channel)
120
+ end
121
+
122
+ end
123
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class OutputTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_auto_output
12
+ m = MicroMIDI.message($test_device[:output].open)
13
+ assert_equal(true, m.state.auto_output)
14
+ m.output false
15
+ assert_equal(false, m.state.auto_output)
16
+ m.output true
17
+ assert_equal(true, m.state.auto_output)
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class StateTest < Test::Unit::TestCase
6
+
7
+ include MicroMIDI
8
+ include MIDIMessage
9
+ include TestHelper
10
+
11
+ def test_output_cache
12
+ m = MicroMIDI.message
13
+ cache = m.state.output_cache
14
+
15
+ m.note "C0"
16
+ assert_equal(1, cache.size)
17
+
18
+ m.note "C3"
19
+ assert_equal(2, cache.size)
20
+ end
21
+
22
+ def test_start_time
23
+ t1 = Time.now.to_f
24
+ m = MicroMIDI.message
25
+ t2 = Time.now.to_f
26
+ t = m.state.start_time
27
+ assert_equal(true, t1 < t)
28
+ assert_equal(true, t < t2)
29
+ end
30
+
31
+ end
32
+