midi-instrument 0.4.1 → 0.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4dc9ef33817d2595aa97bec2239f28f1b1779bb4
4
- data.tar.gz: 05d6227e8b18d1a7a36b439661ea0d7204ec2770
3
+ metadata.gz: 978dc80ea49edc2731e8f13901b836b097f0d2c8
4
+ data.tar.gz: b994a8bc8087ed8e7137bbd4104eb1cbb2a9b6b5
5
5
  SHA512:
6
- metadata.gz: b377e4696a2ab9f80d0c76a10287891883a1ab04162d78b0b0d5c88ba6981f384577ee0b82a1a8fab8da1c8780797699b9cb3f3e3896eb57369354da1cade4cf
7
- data.tar.gz: c3c7bf02d6ab64895a10b0319bd7ecf387d40885b0c0c184fd79922149eda6edc776d26715f573d83afa6006448b87d86ec7e24453715d44155d1c5eea6c38be
6
+ metadata.gz: fb094c3701f256fbebfbca1f8123757c67a16bcbcba813848ab13e1258dd30c8d73af8ce4fb76a0a463d36ebe9d265996dce9654caf9526e39fa30a455d157df
7
+ data.tar.gz: 7d9f7a393fb61e3001f340f5a0d99ea428792a50f9c990c6cdf0e57d2f6417fef25fc97f6ac9c86520f15516cc8d448907b0aaaa26fd48b3f88cc83127ea40c2
@@ -27,6 +27,6 @@ require "midi-instrument/output"
27
27
 
28
28
  module MIDIInstrument
29
29
 
30
- VERSION = "0.4.1"
30
+ VERSION = "0.4.2"
31
31
 
32
32
  end
@@ -1,11 +1,66 @@
1
1
  module MIDIInstrument
2
2
 
3
+ # Adds convenience methods when included by Node
3
4
  module API
4
5
 
5
- def self.included(base)
6
- base.send(:extend, Forwardable)
7
- base.send(:def_delegators, :@input, :omni_on)
8
- base.send(:def_delegators, :@output, :mute, :toggle_mute, :mute=, :muted?, :mute?)
6
+ # Input convenience methods
7
+ module Input
8
+
9
+ def self.included(base)
10
+ base.send(:extend, Forwardable)
11
+ base.send(:def_delegators, :@input, :omni_on)
12
+ end
13
+
14
+ # MIDI input devices
15
+ # @return [Array<UniMIDI::Input>]
16
+ def inputs
17
+ @input.devices
18
+ end
19
+
20
+ # MIDI channel messages will only be acknowledged if they have this optional specified channel
21
+ # @return [Fixnum, nil]
22
+ def receive_channel
23
+ @input.channel
24
+ end
25
+ alias_method :rx_channel, :receive_channel
26
+
27
+ # Set the receive channel
28
+ # @return [Fixnum, nil]
29
+ def receive_channel=(channel)
30
+ @input.channel = channel
31
+ end
32
+ alias_method :rx_channel=, :receive_channel=
33
+
34
+ end
35
+
36
+ # Output convenience methods
37
+ module Output
38
+
39
+ def self.included(base)
40
+ base.send(:extend, Forwardable)
41
+ base.send(:def_delegators, :@output, :mute, :toggle_mute, :mute=, :muted?, :mute?)
42
+ end
43
+
44
+ # MIDI output devices
45
+ # @return [Array<UniMIDI::Output>]
46
+ def outputs
47
+ @output.devices
48
+ end
49
+
50
+ # MIDI channel messages will be optionally forced to have this channel when outputted
51
+ # @return [Fixnum, nil]
52
+ def transmit_channel
53
+ @output.channel
54
+ end
55
+ alias_method :tx_channel, :transmit_channel
56
+
57
+ # Set an optional MIDI channel to force channel notes into when outputted
58
+ # @return [Fixnum, nil]
59
+ def transmit_channel=(channel)
60
+ @output.channel = channel
61
+ end
62
+ alias_method :tx_channel=, :transmit_channel=
63
+
9
64
  end
10
65
 
11
66
  end
@@ -32,6 +32,9 @@ module MIDIInstrument
32
32
  self
33
33
  end
34
34
 
35
+ # Manually add messages to the input
36
+ # @param [Array<MIDIMessage>, MIDIMessage, *MIDIMessage] messages
37
+ # @return [Array<MIDIMessage>]
35
38
  def add(*messages)
36
39
  messages = Message.to_messages([messages].flatten)
37
40
  messages = messages.map { |message| filter_message(message) }.compact
@@ -68,6 +71,9 @@ module MIDIInstrument
68
71
 
69
72
  private
70
73
 
74
+ # Filter an event based on the message contained in it
75
+ # @param [Hash] event
76
+ # @return [Hash, nil]
71
77
  def filter_event(event)
72
78
  if !@channel_filter.nil?
73
79
  if !(message = filter_message(event[:message])).nil?
@@ -79,6 +85,9 @@ module MIDIInstrument
79
85
  end
80
86
  end
81
87
 
88
+ # If there's a channel filter, use it to filter the given message.
89
+ # @param [MIDIMessage] message
90
+ # @return [MIDIMessage]
82
91
  def filter_message(message)
83
92
  message = @channel_filter.process(message) unless @channel_filter.nil?
84
93
  message
@@ -29,6 +29,24 @@ module MIDIInstrument
29
29
  end
30
30
  end
31
31
 
32
+ # Convert the input to MIDI note off messages
33
+ # @param [*MIDIMessage::NoteOff, *MIDIMessage::NoteOn, *String] args
34
+ # @param [Hash] options
35
+ # @option options [Fixnum] :default_channel
36
+ # @option options [Fixnum] :default_velocity
37
+ # @return [Array<MIDIMessage::NoteOn, nil>]
38
+ def to_note_offs(*args)
39
+ notes = [args.dup].flatten
40
+ options = notes.last.kind_of?(Hash) ? notes.pop : {}
41
+ notes.map do |note|
42
+ case note
43
+ when String then string_to_note_off(note, options) if note?(note)
44
+ when MIDIMessage::NoteOff then note
45
+ when MIDIMessage::NoteOn then note.to_note_off
46
+ end
47
+ end
48
+ end
49
+
32
50
  # Convert the input to MIDI note on messages
33
51
  # @param [*MIDIMessage::NoteOn, *String] args
34
52
  # @param [Hash] options
@@ -76,9 +94,30 @@ module MIDIInstrument
76
94
  # @option options [Fixnum] :default_velocity
77
95
  # @return [MIDIMessage::NoteOn]
78
96
  def string_to_note_on(string, options = {})
97
+ string_to_note(string, MIDIMessage::NoteOn, options)
98
+ end
99
+
100
+ # Convert the given string (eg "A4") to a note off message object
101
+ # @param [String] string
102
+ # @param [Hash] options
103
+ # @option options [Fixnum] :default_channel
104
+ # @option options [Fixnum] :default_velocity
105
+ # @return [MIDIMessage::NoteOn]
106
+ def string_to_note_off(string, options = {})
107
+ string_to_note(string, MIDIMessage::NoteOff, options)
108
+ end
109
+
110
+ # Convert the given string (eg "A4") to the given note message class
111
+ # @param [String] string
112
+ # @param [MIDIMessage::NoteOn, MIDIMessage::NoteOff] klass
113
+ # @param [Hash] options
114
+ # @option options [Fixnum] :default_channel
115
+ # @option options [Fixnum] :default_velocity
116
+ # @return [MIDIMessage::NoteOn]
117
+ def string_to_note(string, klass, options = {})
79
118
  channel = options.fetch(:default_channel, 0)
80
119
  velocity = options.fetch(:default_velocity, 100)
81
- MIDIMessage::NoteOn[string].new(channel, velocity)
120
+ klass[string].new(channel, velocity)
82
121
  end
83
122
 
84
123
  end
@@ -3,7 +3,8 @@ module MIDIInstrument
3
3
  # Can listen for and send MIDI messages
4
4
  class Node
5
5
 
6
- include API
6
+ include API::Input
7
+ include API::Output
7
8
 
8
9
  attr_reader :input, :output
9
10
 
@@ -14,34 +15,6 @@ module MIDIInstrument
14
15
  @output = Output.new
15
16
  end
16
17
 
17
- def inputs
18
- @input.devices
19
- end
20
-
21
- def outputs
22
- @output.devices
23
- end
24
-
25
- def receive_channel
26
- @input.channel
27
- end
28
- alias_method :rx_channel, :receive_channel
29
-
30
- def receive_channel=(channel)
31
- @input.channel = channel
32
- end
33
- alias_method :rx_channel=, :receive_channel=
34
-
35
- def transmit_channel
36
- @output.channel
37
- end
38
- alias_method :tx_channel, :transmit_channel
39
-
40
- def transmit_channel=(channel)
41
- @output.channel = channel
42
- end
43
- alias_method :tx_channel=, :transmit_channel=
44
-
45
18
  end
46
19
 
47
20
  end
data/test/message_test.rb CHANGED
@@ -22,6 +22,7 @@ class MIDIInstrument::MessageTest < Test::Unit::TestCase
22
22
  result = MIDIInstrument::Message.to_messages(*messages)
23
23
  assert_not_nil result
24
24
  assert_not_empty result
25
+ assert result.all? { |message| message.is_a?(MIDIMessage::NoteOn) }
25
26
  messages.each_with_index { |message,i| assert_equal message.note, result[i].note }
26
27
  end
27
28
 
@@ -68,6 +69,37 @@ class MIDIInstrument::MessageTest < Test::Unit::TestCase
68
69
 
69
70
  end
70
71
 
72
+ context ".to_note_offs" do
73
+
74
+ should "convert strings to note off" do
75
+ names = ["A-1", "C#4", "F#5", "D6"]
76
+ result = MIDIInstrument::Message.to_note_offs(*names)
77
+ assert_not_nil result
78
+ assert_not_empty result
79
+ assert_equal names.size, result.size
80
+ assert result.all? { |item| item.is_a?(MIDIMessage::NoteOff) }
81
+ names.each_with_index { |name, i| assert_equal name, result[i].name }
82
+ end
83
+
84
+ should "convert on to off" do
85
+ names = ["A-1", "C#4", "F#5", "D6"]
86
+ messages = MIDIInstrument::Message.to_messages(*names)
87
+ result = MIDIInstrument::Message.to_note_offs(*messages)
88
+ assert_not_nil result
89
+ assert_not_empty result
90
+ assert result.all? { |message| message.is_a?(MIDIMessage::NoteOff) }
91
+ messages.each_with_index { |message,i| assert_equal message.note, result[i].note }
92
+ end
93
+
94
+ should "return nil for unknowns" do
95
+ result = MIDIInstrument::Message.to_note_offs("blah", "blah", 56904)
96
+ assert_not_nil result
97
+ assert_equal 3, result.size
98
+ assert_empty result.compact
99
+ end
100
+
101
+ end
102
+
71
103
  context ".to_note_ons" do
72
104
 
73
105
  should "convert strings to note ons" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midi-instrument
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Russo