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 +4 -4
- data/lib/midi-instrument.rb +1 -1
- data/lib/midi-instrument/api.rb +59 -4
- data/lib/midi-instrument/input.rb +9 -0
- data/lib/midi-instrument/message.rb +40 -1
- data/lib/midi-instrument/node.rb +2 -29
- data/test/message_test.rb +32 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 978dc80ea49edc2731e8f13901b836b097f0d2c8
|
4
|
+
data.tar.gz: b994a8bc8087ed8e7137bbd4104eb1cbb2a9b6b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb094c3701f256fbebfbca1f8123757c67a16bcbcba813848ab13e1258dd30c8d73af8ce4fb76a0a463d36ebe9d265996dce9654caf9526e39fa30a455d157df
|
7
|
+
data.tar.gz: 7d9f7a393fb61e3001f340f5a0d99ea428792a50f9c990c6cdf0e57d2f6417fef25fc97f6ac9c86520f15516cc8d448907b0aaaa26fd48b3f88cc83127ea40c2
|
data/lib/midi-instrument.rb
CHANGED
data/lib/midi-instrument/api.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
120
|
+
klass[string].new(channel, velocity)
|
82
121
|
end
|
83
122
|
|
84
123
|
end
|
data/lib/midi-instrument/node.rb
CHANGED
@@ -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
|