micromidi 0.1.3 → 0.1.4

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.
@@ -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