micromidi 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,39 +1,60 @@
1
1
  module MicroMIDI
2
2
 
3
3
  module Instructions
4
-
4
+
5
5
  class SysEx
6
6
 
7
- include MIDIMessage
8
-
7
+ # @param [State] state
9
8
  def initialize(state)
10
9
  @state = state
11
10
  end
12
-
13
- # create a sysex command
11
+
12
+ # Create a sysex command message
13
+ # @param [Fixnum] address
14
+ # @param [Array<Fixnum>] data
15
+ # @param [Hash] options
16
+ # @option options [MIDIMessage::SystemExclusive::Node] :node (also :sysex_node)
17
+ # @return [MIDIMessage::SystemExclusive::Command]
14
18
  def sysex_command(address, data, options = {})
15
- options[:sysex_node] ||= options[:node]
16
- props = @state.message_properties(options, :sysex_node)
17
- SystemExclusive::Command.new(address, data, :node => props[:sysex_node])
19
+ properties = sysex_properties(options)
20
+ MIDIMessage::SystemExclusive::Command.new(address, data, :node => properties[:sysex_node])
18
21
  end
19
22
  alias_method :command, :sysex_command
20
-
21
- # create a sysex request
23
+
24
+ # Create a sysex request message
25
+ # @param [Fixnum] address
26
+ # @param [Fixnum] size
27
+ # @param [Hash] options
28
+ # @option options [MIDIMessage::SystemExclusive::Node] :node (also :sysex_node)
29
+ # @return [MIDIMessage::SystemExclusive::Request]
22
30
  def sysex_request(address, size, options = {})
23
- options[:sysex_node] ||= options[:node]
24
- props = @state.message_properties(options, :sysex_node)
25
- SystemExclusive::Request.new(address, size, :node => props[:sysex_node])
31
+ properties = sysex_properties(options)
32
+ MIDIMessage::SystemExclusive::Request.new(address, size, :node => properties[:sysex_node])
26
33
  end
27
34
  alias_method :request, :sysex_request
28
-
29
- # create an indeterminate sysex message
35
+
36
+ # Create a generic sysex message
37
+ # @param [Array<Fixnum>] data
38
+ # @param [Hash] options
39
+ # @option options [MIDIMessage::SystemExclusive::Node] :node (also :sysex_node)
40
+ # @return [MIDIMessage::SystemExclusive::Message]
30
41
  def sysex_message(data, options = {})
31
- options[:sysex_node] ||= options[:node]
32
- props = @state.message_properties(options, :sysex_node)
33
- SystemExclusive::Message.new(data, :node => props[:sysex_node])
42
+ properties = sysex_properties(options)
43
+ MIDIMessage::SystemExclusive::Message.new(data, :node => properties[:sysex_node])
34
44
  end
35
45
  alias_method :sysex, :sysex_message
36
46
 
47
+ private
48
+
49
+ # Get the message properties given the options hash
50
+ # @param [Hash] options
51
+ # @return [Hash]
52
+ def sysex_properties(options)
53
+ sysex_options = options.dup
54
+ sysex_options[:sysex_node] ||= options.delete(:node)
55
+ @state.message_properties(sysex_options, :sysex_node)
56
+ end
57
+
37
58
  end
38
59
 
39
60
  end
@@ -1,34 +1,32 @@
1
1
  module MicroMIDI
2
2
 
3
- def self.new(*args, &block)
4
- message(*args, &block)
3
+ extend self
4
+
5
+ # Shortcut to create a new context
6
+ # @param [*Object] args
7
+ # @param [Proc] block
8
+ # @return [Context]
9
+ def new(*args, &block)
10
+ inputs = Device.get_inputs(args)
11
+ outputs = Device.get_outputs(args)
12
+ Context.new(inputs, outputs, &block)
5
13
  end
6
14
 
7
- def self.message(*args, &block)
8
- inputs = get_inputs(args)
9
- outputs = get_outputs(args)
10
- MicroMIDI::Context.new(inputs, outputs, &block)
11
- end
12
15
  class << self
13
- alias_method :using, :message
16
+ alias_method :message, :new
17
+ alias_method :using, :new
14
18
  end
15
19
 
16
20
  module IO
17
21
 
22
+ # Shortcut to create a new context
23
+ # @param [*Object] args
24
+ # @param [Proc] block
25
+ # @return [Context]
18
26
  def self.new(*args, &block)
19
- MicroMIDI.message(*args, &block)
27
+ MicroMIDI.new(*args, &block)
20
28
  end
21
29
 
22
30
  end
23
31
 
24
- private
25
-
26
- def self.get_inputs(args)
27
- args.find_all { |device| device.respond_to?(:type) && device.type == :input && device.respond_to?(:gets) }
28
- end
29
-
30
- def self.get_outputs(args)
31
- args.find_all { |device| device.respond_to?(:puts) }
32
- end
33
-
34
32
  end
@@ -1,86 +1,129 @@
1
1
  module MicroMIDI
2
2
 
3
+ # The DSL state
3
4
  class State
4
-
5
+
5
6
  DEFAULT = {
6
7
  :channel => 0,
7
8
  :octave => 2,
8
9
  :velocity => 100
9
10
  }
10
-
11
+
11
12
  attr_accessor :auto_output,
12
- :channel,
13
- :last_note,
14
- :octave,
15
- :sysex_node,
16
- :super_sticky,
17
- :velocity
18
-
13
+ :channel,
14
+ :last_note,
15
+ :octave,
16
+ :sysex_node,
17
+ :super_sticky,
18
+ :velocity
19
+
19
20
  attr_reader :inputs,
20
- :last_command,
21
- :listeners,
22
- :outputs,
23
- :output_cache,
24
- :start_time,
25
- :thru_listeners
26
-
21
+ :last_command,
22
+ :listeners,
23
+ :outputs,
24
+ :output_cache,
25
+ :start_time,
26
+ :thru_listeners
27
+
28
+ # @param [Array<UniMIDI::Input>, UniMIDI::Input] inputs
29
+ # @param [Array<UniMIDI::Output, IO>, IO, UniMIDI::Output] outputs
30
+ # @param [Hash] options
31
+ # @option options [Fixnum] :channel
32
+ # @option options [Fixnum] :octave
33
+ # @option options [Fixnum] :velocity
27
34
  def initialize(inputs, outputs, options = {})
28
- @inputs = inputs
29
- @outputs = outputs
35
+ @inputs = [inputs].flatten
36
+ @outputs = [outputs].flatten
30
37
 
31
38
  @channel = options[:channel] || DEFAULT[:channel]
32
39
  @velocity = options[:velocity] || DEFAULT[:velocity]
33
- @octave = options[:octave] || DEFAULT[:octave]
40
+ @octave = options[:octave] || DEFAULT[:octave]
34
41
 
35
42
  @auto_output = true
36
43
  @last_command = nil
37
- @last_note = nil
44
+ @last_note = nil
38
45
  @listeners = []
39
46
  @thru_listeners = []
40
47
  @output_cache = []
41
48
  @start_time = Time.now.to_f
42
49
  @super_sticky = false
43
50
  end
44
-
45
- def record(method, args, block, output)
51
+
52
+ # Record that a command was used
53
+ # @param [Symbol, String] method
54
+ # @param [Array<Object>] args
55
+ # @param [Proc] block
56
+ # @param [Object] result
57
+ def record(method, args, block, result)
46
58
  timestamp = now
47
- message = {
48
- :message => output,
49
- :timestamp => timestamp
59
+ message = {
60
+ :message => result,
61
+ :timestamp => timestamp
50
62
  }
51
63
  @output_cache << message
52
- @last_command = {
53
- :method => method,
54
- :args => args,
55
- :block => block,
56
- :timestamp => timestamp
64
+ @last_command = {
65
+ :method => method,
66
+ :args => args,
67
+ :block => block,
68
+ :timestamp => timestamp
57
69
  }
58
70
  end
59
-
71
+
72
+ #
73
+ # Toggles super_sticky mode, a mode where any explicit values used to create MIDI messages
74
+ # automatically become sticky. Normally the explicit value would only be used for
75
+ # the current message.
76
+ #
77
+ # For example, while in super sticky mode
78
+ #
79
+ # ```ruby
80
+ # note "C4", :channel => 5
81
+ # note "C3"
82
+ # ```
83
+ #
84
+ # will have the same results as
85
+ #
86
+ # ```ruby
87
+ # channel 5
88
+ # note "C4"
89
+ # note "C3"
90
+ # ```
91
+ #
92
+ # @return [Boolean]
60
93
  def toggle_super_sticky
61
94
  @super_sticky = !@super_sticky
62
95
  end
63
-
96
+
97
+ # Toggles auto-output mode. In auto-output mode, any messages that are instantiated are sent to
98
+ # any available MIDI outputs.
99
+ # @return [Boolean]
64
100
  def toggle_auto_output
65
101
  @auto_output = !@auto_output
66
102
  end
67
103
 
104
+ # Return message properties with regard to the current state
105
+ # @param [Hash] options
106
+ # @param [*Symbol] properties
107
+ # @return [Hash]
68
108
  def message_properties(options, *properties)
69
- output = {}
109
+ result = {}
70
110
  properties.each do |property|
71
- output[property] = options[property]
72
- if !output[property].nil? && (send(property).nil? || @super_sticky)
73
- send("#{property.to_s}=", output[property])
111
+ result[property] = options[property]
112
+ if !result[property].nil? && (send(property).nil? || @super_sticky)
113
+ send("#{property.to_s}=", result[property])
74
114
  end
75
- output[property] ||= send(property.to_s)
115
+ result[property] ||= send(property.to_s)
76
116
  end
77
- output
117
+ result
78
118
  end
79
-
119
+
80
120
  private
81
-
121
+
122
+ # A timestamp
123
+ # @return [Float]
82
124
  def now
83
- (Time.now.to_f - @start_time) * 1000
125
+ time = Time.now.to_f - @start_time
126
+ time * 1000
84
127
  end
85
128
 
86
129
  end
data/lib/midi.rb CHANGED
@@ -2,14 +2,15 @@
2
2
  # MicroMIDI
3
3
  # A Ruby DSL for MIDI
4
4
  #
5
- # (c)2011-2014 Ari Russo
6
- # licensed under the Apache 2.0 License
5
+ # (c)2011-2014 Ari Russo
6
+ # Apache 2.0 License
7
7
  #
8
8
 
9
- # The purpose of this file is just to allow both:
9
+ # The purpose of this file is to allow:
10
10
  #
11
- # <em>require "micromidi"</em>
12
- # and
13
11
  # <em>require "midi"</em>
12
+ # in addition to
13
+ # <em>require "micromidi"</em>
14
+ #
14
15
 
15
16
  require "micromidi"
@@ -1,78 +1,73 @@
1
1
  require "helper"
2
2
 
3
- class CompositeTest < Test::Unit::TestCase
4
-
5
- include MicroMIDI
6
- include MIDIMessage
7
- include TestHelper
3
+ class CompositeTest < Minitest::Test
8
4
 
9
5
  def test_play
10
6
  m = MicroMIDI.message
11
7
  start = Time.now
12
8
  msg = m.play "C0", 0.5
13
-
9
+
14
10
  finish = Time.now
15
11
  dif = finish - start
16
12
  assert_equal(true, dif >= 0.5)
17
-
18
- assert_equal(NoteOn, msg.class)
13
+
14
+ assert_equal(MIDIMessage::NoteOn, msg.class)
19
15
  assert_equal(12, msg.note)
20
16
  assert_equal(0, msg.channel)
21
17
  assert_equal(2, m.state.output_cache.size)
22
-
18
+
23
19
  off_msg = m.state.output_cache.last[:message]
24
- assert_equal(NoteOff, off_msg.class)
20
+ assert_equal(MIDIMessage::NoteOff, off_msg.class)
25
21
  assert_equal(12, off_msg.note)
26
22
  assert_equal(0, off_msg.channel)
27
23
  end
28
-
24
+
29
25
  def test_play_chord
30
26
  m = MicroMIDI.message
31
27
  start = Time.now
32
28
  msgs = m.play "C0", "E1", "G2", 0.5
33
-
29
+
34
30
  finish = Time.now
35
31
  dif = finish - start
36
32
  assert_equal(true, dif >= 0.5)
37
-
33
+
38
34
  msg = msgs.first
39
-
40
- assert_equal(NoteOn, msg.class)
35
+
36
+ assert_equal(MIDIMessage::NoteOn, msg.class)
41
37
  assert_equal(12, msg.note)
42
38
  assert_equal(0, msg.channel)
43
39
  assert_equal(6, m.state.output_cache.size)
44
-
40
+
45
41
  off_msg = m.state.output_cache.last[:message]
46
- assert_equal(NoteOff, off_msg.class)
42
+ assert_equal(MIDIMessage::NoteOff, off_msg.class)
47
43
  assert_equal(43, off_msg.note)
48
44
  assert_equal(0, off_msg.channel)
49
45
  end
50
-
46
+
51
47
  def test_play_chord_array
52
48
  m = MicroMIDI.message
53
49
  start = Time.now
54
50
  msgs = m.play ["C0", "E1", "G2"], 0.5
55
-
51
+
56
52
  finish = Time.now
57
53
  dif = finish - start
58
54
  assert_equal(true, dif >= 0.5)
59
-
55
+
60
56
  msg = msgs.first
61
-
62
- assert_equal(NoteOn, msg.class)
57
+
58
+ assert_equal(MIDIMessage::NoteOn, msg.class)
63
59
  assert_equal(12, msg.note)
64
60
  assert_equal(0, msg.channel)
65
61
  assert_equal(6, m.state.output_cache.size)
66
-
62
+
67
63
  off_msg = m.state.output_cache.last[:message]
68
- assert_equal(NoteOff, off_msg.class)
64
+ assert_equal(MIDIMessage::NoteOff, off_msg.class)
69
65
  assert_equal(43, off_msg.note)
70
66
  assert_equal(0, off_msg.channel)
71
67
  end
72
-
68
+
73
69
  def test_all_off
74
-
70
+
75
71
  end
76
-
77
- end
78
72
 
73
+ end
data/test/context_test.rb CHANGED
@@ -1,52 +1,47 @@
1
1
  require "helper"
2
2
 
3
- class ContextTest < Test::Unit::TestCase
3
+ class ContextTest < Minitest::Test
4
4
 
5
- include MicroMIDI
6
- include MIDIMessage
7
- include TestHelper
8
-
9
5
  def test_new_with_block
10
6
  msg = nil
11
7
  MIDI::IO.new do
12
8
  msg = note "C0"
13
9
  end
14
- assert_equal(NoteOn, msg.class)
10
+ assert_equal(MIDIMessage::NoteOn, msg.class)
15
11
  assert_equal(12, msg.note)
16
- assert_equal(0, msg.channel)
12
+ assert_equal(0, msg.channel)
17
13
  end
18
-
14
+
19
15
  def test_new_with_no_block
20
16
  m = MIDI::IO.new
21
17
  msg = m.note "C0"
22
- assert_equal(NoteOn, msg.class)
18
+ assert_equal(MIDIMessage::NoteOn, msg.class)
23
19
  assert_equal(12, msg.note)
24
20
  assert_equal(0, msg.channel)
25
21
  end
26
-
22
+
27
23
  def test_edit
28
24
  msg = nil
29
- m = MIDI::IO.new
25
+ m = MIDI::IO.new
30
26
  m.edit do
31
27
  msg = m.note "C0"
32
28
  end
33
- assert_equal(NoteOn, msg.class)
29
+ assert_equal(MIDIMessage::NoteOn, msg.class)
34
30
  assert_equal(12, msg.note)
35
- assert_equal(0, msg.channel)
31
+ assert_equal(0, msg.channel)
36
32
  end
37
33
 
38
34
  def test_repeat
39
35
  m = MicroMIDI.message
40
36
  msg = m.note "C0"
41
- assert_equal(NoteOn, msg.class)
37
+ assert_equal(MIDIMessage::NoteOn, msg.class)
42
38
  assert_equal(12, msg.note)
43
39
  assert_equal(0, msg.channel)
44
-
40
+
45
41
  r_msg = m.repeat
46
- assert_equal(NoteOn, r_msg.class)
42
+ assert_equal(MIDIMessage::NoteOn, r_msg.class)
47
43
  assert_equal(12, r_msg.note)
48
44
  assert_equal(0, r_msg.channel)
49
45
  end
50
-
51
- end
52
46
 
47
+ end