midi-nibbler 0.0.3
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.
- data/LICENSE +13 -0
- data/README.rdoc +106 -0
- data/lib/nibbler/hex_char_array_filter.rb +37 -0
- data/lib/nibbler/midi-message_factory.rb +54 -0
- data/lib/nibbler/midilib_factory.rb +66 -0
- data/lib/nibbler/nibbler.rb +66 -0
- data/lib/nibbler/parser.rb +154 -0
- data/lib/nibbler/type_conversion.rb +33 -0
- data/lib/nibbler.rb +27 -0
- metadata +86 -0
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2010-2011 Ari Russo
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.rdoc
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
= nibbler
|
2
|
+
|
3
|
+
{cat on arp}[http://images.treetrouble.net/images/dog_with_synth.jpg]
|
4
|
+
|
5
|
+
Parse MIDI Messages
|
6
|
+
|
7
|
+
== Requirements
|
8
|
+
|
9
|
+
* {midi-message}[http://github.com/arirusso/midi-message]
|
10
|
+
|
11
|
+
== Install
|
12
|
+
|
13
|
+
gem install midi-nibbler
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
require 'nibbler'
|
18
|
+
|
19
|
+
nibbler = Nibbler.new
|
20
|
+
|
21
|
+
Enter a message piece by piece
|
22
|
+
|
23
|
+
p nibbler.parse("90")
|
24
|
+
nil
|
25
|
+
|
26
|
+
p nibbler.parse("40")
|
27
|
+
nil
|
28
|
+
|
29
|
+
p nibbler.parse("40")
|
30
|
+
# #<MIDIMessage::NoteOn:0x98c9818
|
31
|
+
# @channel=0,
|
32
|
+
# @data=[64, 100],
|
33
|
+
# @name="C3",
|
34
|
+
# @note=64,
|
35
|
+
# @status=[9, 0],
|
36
|
+
# @velocity=100,
|
37
|
+
# @verbose_name="Note On: C3">
|
38
|
+
|
39
|
+
Enter a message all at once
|
40
|
+
|
41
|
+
p nibbler.parse("904040")
|
42
|
+
|
43
|
+
# #<MIDIMessage::NoteOn:0x98c9818
|
44
|
+
# @channel=0,
|
45
|
+
# @data=[64, 100],
|
46
|
+
# @name="C3",
|
47
|
+
# @note=64,
|
48
|
+
# @status=[9, 0],
|
49
|
+
# @velocity=100,
|
50
|
+
# @verbose_name="Note On: C3">
|
51
|
+
|
52
|
+
Use bytes
|
53
|
+
|
54
|
+
p nibbler.parse(0x90, 0x40, 0x40)
|
55
|
+
#<MIDIMessage::NoteOn:0x98c9818 ...>
|
56
|
+
|
57
|
+
You can use nibbles in string format
|
58
|
+
|
59
|
+
p nibbler.parse("9", "0", "4", "0", "4", "0")
|
60
|
+
#<MIDIMessage::NoteOn:0x98c9818 ...>
|
61
|
+
|
62
|
+
Interchange the different types
|
63
|
+
|
64
|
+
p nibbler.parse("9", "0", 0x40, 64)
|
65
|
+
#<MIDIMessage::NoteOn:0x98c9818 ...>
|
66
|
+
|
67
|
+
Use running status
|
68
|
+
|
69
|
+
p nibbler.parse(0x40, 64)
|
70
|
+
#<MIDIMessage::NoteOn:0x98c9818 ...>
|
71
|
+
|
72
|
+
Look at the messages we've parsed
|
73
|
+
|
74
|
+
p nibbler.messages
|
75
|
+
[#<MIDIMessage::NoteOn:0x98c9804 ...>
|
76
|
+
#<MIDIMessage::NoteOn:0x98c9811 ...>]
|
77
|
+
|
78
|
+
Add an incomplete message
|
79
|
+
|
80
|
+
p nibbler.parse("9")
|
81
|
+
p nibbler.parse("40")
|
82
|
+
|
83
|
+
See progress
|
84
|
+
|
85
|
+
p nibbler.buffer
|
86
|
+
["9", "4", "0"]
|
87
|
+
|
88
|
+
p nibbler.buffer_hex
|
89
|
+
"940"
|
90
|
+
|
91
|
+
Nibbler defaults to generate {midi-message}[http://github.com/arirusso/midi-message] objects, but it is also possible to use {midilib}[https://github.com/jimm/midilib]
|
92
|
+
|
93
|
+
Nibbler.new(:message_lib => :midilib)
|
94
|
+
|
95
|
+
p nibbler.parse("9", "0", 0x40, "40")
|
96
|
+
"0: ch 00 on 40 40"
|
97
|
+
|
98
|
+
== Author
|
99
|
+
|
100
|
+
* {Ari Russo}[http://github.com/arirusso] <ari.russo at gmail.com>
|
101
|
+
|
102
|
+
== License
|
103
|
+
|
104
|
+
Apache 2.0, See the file LICENSE
|
105
|
+
|
106
|
+
Copyright (c) 2011 Ari Russo
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
# Turns various types of input in to an array of hex digit chars
|
6
|
+
class HexCharArrayFilter
|
7
|
+
|
8
|
+
# returns an array of hex string nibbles
|
9
|
+
def process(*a)
|
10
|
+
a.flatten!
|
11
|
+
buf = []
|
12
|
+
a.each do |thing|
|
13
|
+
buf += case thing
|
14
|
+
when Array then thing.map { |arr| to_nibbles(*arr) }.inject { |a,b| a + b }
|
15
|
+
when String then TypeConversion.hex_str_to_hex_chars(filter_string(thing))
|
16
|
+
when Numeric then TypeConversion.numeric_byte_to_hex_chars(filter_numeric(thing))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
buf.compact.map { |n| n.upcase }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# limit <em>num</em> to bytes usable in MIDI ie values (0..240)
|
25
|
+
# returns nil if the byte is outside of that range
|
26
|
+
def filter_numeric(num)
|
27
|
+
(0x00..0xFF).include?(num) ? num : nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# get rid of non-hex string characters
|
31
|
+
def filter_string(str)
|
32
|
+
str.gsub(/[^0-9a-fA-F]/, '').upcase
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
# factory for constructing messages with {midi-message}(http://github.com/arirusso/midi-message)
|
6
|
+
class MIDIMessageFactory
|
7
|
+
|
8
|
+
include MIDIMessage
|
9
|
+
|
10
|
+
def note_off(second_nibble, data_byte_1, data_byte_2)
|
11
|
+
NoteOff.new(second_nibble, data_byte_1, data_byte_2)
|
12
|
+
end
|
13
|
+
|
14
|
+
def note_on(second_nibble, data_byte_1, data_byte_2)
|
15
|
+
NoteOn.new(second_nibble, data_byte_1, data_byte_2)
|
16
|
+
end
|
17
|
+
|
18
|
+
def polyphonic_aftertouch(second_nibble, data_byte_1, data_byte_2)
|
19
|
+
PolyphonicAftertouch.new(second_nibble, data_byte_1, data_byte_2)
|
20
|
+
end
|
21
|
+
|
22
|
+
def control_change(second_nibble, data_byte_1, data_byte_2)
|
23
|
+
ControlChange.new(second_nibble, data_byte_1, data_byte_2)
|
24
|
+
end
|
25
|
+
|
26
|
+
def program_change(second_nibble, data_byte)
|
27
|
+
ProgramChange.new(second_nibble, data_byte)
|
28
|
+
end
|
29
|
+
|
30
|
+
def channel_aftertouch(second_nibble, data_byte)
|
31
|
+
ChannelAftertouch.new(second_nibble, data_byte)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pitch_bend(second_nibble, data_byte_1, data_byte_2)
|
35
|
+
PitchBend.new(second_nibble, data_byte_1, data_byte_2)
|
36
|
+
end
|
37
|
+
|
38
|
+
def system_exclusive(*a)
|
39
|
+
SystemExclusive.new(*a)
|
40
|
+
end
|
41
|
+
|
42
|
+
def system_common(second_nibble, data_byte_1 = nil, data_byte_2 = nil)
|
43
|
+
SystemCommon.new(second_nibble, data_byte_1, data_byte_2)
|
44
|
+
end
|
45
|
+
|
46
|
+
def system_realtime(second_nibble)
|
47
|
+
SystemRealtime.new(second_nibble)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
# factory for constructing messages with {midilib}(https://github.com/jimm/midilib)
|
6
|
+
# midilib is copyright © 2003-2010 Jim Menard
|
7
|
+
class MidilibFactory
|
8
|
+
|
9
|
+
include MIDI
|
10
|
+
|
11
|
+
def note_off(second_nibble, data_byte_1, data_byte_2)
|
12
|
+
NoteOff.new(second_nibble, data_byte_1, data_byte_2)
|
13
|
+
end
|
14
|
+
|
15
|
+
def note_on(second_nibble, data_byte_1, data_byte_2)
|
16
|
+
NoteOn.new(second_nibble, data_byte_1, data_byte_2)
|
17
|
+
end
|
18
|
+
|
19
|
+
def polyphonic_aftertouch(second_nibble, data_byte_1, data_byte_2)
|
20
|
+
PolyPressure.new(second_nibble, data_byte_1, data_byte_2)
|
21
|
+
end
|
22
|
+
|
23
|
+
def control_change(second_nibble, data_byte_1, data_byte_2)
|
24
|
+
Controller.new(second_nibble, data_byte_1, data_byte_2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def program_change(second_nibble, data_byte)
|
28
|
+
ProgramChange.new(second_nibble, data_byte)
|
29
|
+
end
|
30
|
+
|
31
|
+
def channel_aftertouch(second_nibble, data_byte)
|
32
|
+
ChannelPressure.new(second_nibble, data_byte)
|
33
|
+
end
|
34
|
+
|
35
|
+
def pitch_bend(second_nibble, data_byte_1, data_byte_2)
|
36
|
+
# to-do handle the midilib lsb/msb
|
37
|
+
# right now the second data byte is being thrown away
|
38
|
+
PitchBend.new(second_nibble, data_byte_1, data_byte_2)
|
39
|
+
end
|
40
|
+
|
41
|
+
def system_exclusive(*a)
|
42
|
+
SystemExclusive.new(a)
|
43
|
+
end
|
44
|
+
|
45
|
+
def system_common(second_nibble, data_byte_1 = nil, data_byte_2 = nil)
|
46
|
+
case second_nibble
|
47
|
+
when 0x2 then SongPointer.new(data_byte_1) # similar issue to pitch bend here
|
48
|
+
when 0x3 then SongSelect.new(data_byte_1)
|
49
|
+
when 0x6 then TuneRequest.new
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def system_realtime(second_nibble)
|
54
|
+
case second_nibble
|
55
|
+
when 0x8 then Clock.new
|
56
|
+
when 0xA then Start.new
|
57
|
+
when 0xB then Continue.new
|
58
|
+
when 0xC then Stop.new
|
59
|
+
when 0xE then ActiveSense.new
|
60
|
+
when 0xF then SystemReset.new
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
# this is the entry point to the app
|
6
|
+
class Nibbler
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
attr_reader :messages,
|
11
|
+
:processed,
|
12
|
+
:rejected
|
13
|
+
|
14
|
+
# this class holds on to all output except for the buffer because the data in the buffer
|
15
|
+
# is the only data that's relevant between calls of Parser.process
|
16
|
+
def_delegators :@parser, :buffer
|
17
|
+
def_delegator :clear_buffer, :buffer, :clear
|
18
|
+
def_delegator :clear_processed, :processed, :clear
|
19
|
+
def_delegator :clear_rejected, :rejected, :clear
|
20
|
+
def_delegator :clear_messages, :messages, :clear
|
21
|
+
|
22
|
+
def initialize(options = {}, &block)
|
23
|
+
@processed, @rejected, @messages = [], [], []
|
24
|
+
@parser = Parser.new(options)
|
25
|
+
@typefilter = HexCharArrayFilter.new
|
26
|
+
block.call unless block.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def all_messages
|
30
|
+
@messages | @fragmented_messages
|
31
|
+
end
|
32
|
+
|
33
|
+
def buffer_hex
|
34
|
+
buffer.join
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_buffer
|
38
|
+
buffer.clear
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear_messages
|
42
|
+
@messages.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse(*a)
|
46
|
+
queue = @typefilter.process(a)
|
47
|
+
result = @parser.process(queue)
|
48
|
+
@messages += result[:messages]
|
49
|
+
@processed += result[:processed]
|
50
|
+
@rejected += result[:rejected]
|
51
|
+
#@buffer = result[:remaining]
|
52
|
+
# return type
|
53
|
+
# 0 messages: nil
|
54
|
+
# 1 message: the message
|
55
|
+
# >1 message: an array of messages
|
56
|
+
# might make sense to make this an array no matter what...
|
57
|
+
if result[:messages].length < 2
|
58
|
+
(result[:messages].empty? ? nil : result[:messages][0])
|
59
|
+
else
|
60
|
+
result[:messages]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
|
6
|
+
# this is where messages go
|
7
|
+
class Parser
|
8
|
+
|
9
|
+
attr_reader :buffer
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@running_status = nil
|
13
|
+
@buffer = []
|
14
|
+
@iterator = 0
|
15
|
+
|
16
|
+
case options[:message_lib]
|
17
|
+
when :midilib then
|
18
|
+
require 'midilib'
|
19
|
+
require 'nibbler/midilib_factory'
|
20
|
+
@message_factory = MidilibFactory.new
|
21
|
+
else
|
22
|
+
require 'midi-message'
|
23
|
+
require 'nibbler/midi-message_factory'
|
24
|
+
@message_factory = MIDIMessageFactory.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def process(nibbles)
|
29
|
+
output = {
|
30
|
+
:messages => [],
|
31
|
+
:processed => [],
|
32
|
+
:rejected => []
|
33
|
+
}
|
34
|
+
@iterator = 0
|
35
|
+
@buffer += nibbles
|
36
|
+
while @iterator <= (@buffer.length - 1)
|
37
|
+
# iterate through nibbles until a status message is found
|
38
|
+
# see if there really is a message there
|
39
|
+
populate_current
|
40
|
+
# current is the current piece of the buffer we're dealing with
|
41
|
+
processed = nibbles_to_message
|
42
|
+
unless processed[:message].nil?
|
43
|
+
# if it's a real message, reject previous nibbles
|
44
|
+
output[:rejected] += @buffer.slice(0, @iterator)
|
45
|
+
# and record it
|
46
|
+
@buffer = @current # current now has the remaining nibbles for next pass
|
47
|
+
@current = nil # reset current
|
48
|
+
@iterator = 0 # reset iterator
|
49
|
+
output[:messages] << processed[:message]
|
50
|
+
output[:processed] += processed[:processed]
|
51
|
+
else
|
52
|
+
@running_status = nil
|
53
|
+
@iterator += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
output
|
57
|
+
end
|
58
|
+
|
59
|
+
def nibbles_to_message
|
60
|
+
output = {
|
61
|
+
:message => nil,
|
62
|
+
:processed => [],
|
63
|
+
:remaining => nil
|
64
|
+
}
|
65
|
+
return output if @current.length < 2
|
66
|
+
first = @current[0].hex
|
67
|
+
second = @current[1].hex
|
68
|
+
|
69
|
+
output[:message], output[:processed] = *case first
|
70
|
+
when 0x8 then lookahead(6) { |status_2, bytes| @message_factory.note_off(status_2, bytes[1], bytes[2]) }
|
71
|
+
when 0x9 then lookahead(6) { |status_2, bytes| @message_factory.note_on(status_2, bytes[1], bytes[2]) }
|
72
|
+
when 0xA then lookahead(6) { |status_2, bytes| @message_factory.polyphonic_aftertouch(status_2, bytes[1], bytes[2]) }
|
73
|
+
when 0xB then lookahead(6) { |status_2, bytes| @message_factory.control_change(status_2, bytes[1], bytes[2]) }
|
74
|
+
when 0xC then lookahead(4) { |status_2, bytes| @message_factory.program_change(status_2, bytes[1]) }
|
75
|
+
when 0xD then lookahead(4) { |status_2, bytes| @message_factory.channel_aftertouch(status_2, bytes[1]) }
|
76
|
+
when 0xE then lookahead(6) { |status_2, bytes| @message_factory.pitch_bend(status_2, bytes[1], bytes[2]) }
|
77
|
+
when 0xF then case second
|
78
|
+
when 0x0 then lookahead_sysex { |bytes| @message_factory.system_exclusive(*bytes) }
|
79
|
+
when 0x1..0x6 then lookahead(6, :recursive => true) { |status_2, bytes| @message_factory.system_common(status_2, bytes[1], bytes[2]) }
|
80
|
+
when 0x8..0xF then lookahead(2) { |status_2, bytes| @message_factory.system_realtime(status_2) }
|
81
|
+
end
|
82
|
+
else
|
83
|
+
use_running_status if running_status_possible?
|
84
|
+
end
|
85
|
+
output
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def running_status_possible?
|
91
|
+
!@running_status.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
def use_running_status
|
95
|
+
lookahead(@running_status[:num], :status_nibble => @running_status[:status_nibble], &@running_status[:block])
|
96
|
+
end
|
97
|
+
|
98
|
+
def populate_current
|
99
|
+
@current = (@buffer[@iterator, (@buffer.length - @iterator)])
|
100
|
+
end
|
101
|
+
|
102
|
+
def lookahead(num, options = {}, &block)
|
103
|
+
recursive = !options[:recursive].nil? && options[:recursive]
|
104
|
+
status_nibble = options[:status_nibble]
|
105
|
+
processed = []
|
106
|
+
msg = nil
|
107
|
+
# do we have enough nibbles for num bytes?
|
108
|
+
if @current.slice(0, num).length >= num
|
109
|
+
|
110
|
+
# if so shift those nibbles off of the array and call block with them
|
111
|
+
processed += @current.slice!(0, num)
|
112
|
+
status_nibble ||= processed[1]
|
113
|
+
# send the nibbles to the block as bytes
|
114
|
+
# return the evaluated block and the remaining nibbles
|
115
|
+
bytes = TypeConversion.hex_chars_to_numeric_bytes(processed)
|
116
|
+
# record the current situation in case running status comes up next round
|
117
|
+
@running_status = {
|
118
|
+
:block => block,
|
119
|
+
:num => num - 2,
|
120
|
+
:status_nibble => status_nibble
|
121
|
+
}
|
122
|
+
msg = block.call(status_nibble.hex, bytes)
|
123
|
+
elsif num > 0 && recursive
|
124
|
+
msg, processed = *lookahead(num-2, options, &block)
|
125
|
+
end
|
126
|
+
[msg, processed]
|
127
|
+
end
|
128
|
+
|
129
|
+
def lookahead_sysex(&block)
|
130
|
+
processed = []
|
131
|
+
msg = nil
|
132
|
+
@running_status = nil
|
133
|
+
|
134
|
+
bytes = TypeConversion.hex_chars_to_numeric_bytes(@current)
|
135
|
+
ind = bytes.index(0xF7)
|
136
|
+
unless ind.nil?
|
137
|
+
msg = block.call(bytes.slice!(0, ind + 1))
|
138
|
+
processed += @current.slice!(0, (ind + 1) * 2)
|
139
|
+
end
|
140
|
+
[msg, processed]
|
141
|
+
end
|
142
|
+
|
143
|
+
# for testing
|
144
|
+
def buffer=(val)
|
145
|
+
@buffer=val
|
146
|
+
end
|
147
|
+
|
148
|
+
def current
|
149
|
+
@current
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module Nibbler
|
4
|
+
|
5
|
+
# this is a helper for converting nibbles and bytes
|
6
|
+
module TypeConversion
|
7
|
+
|
8
|
+
def self.hex_chars_to_numeric_bytes(nibbles)
|
9
|
+
nibbles = nibbles.dup
|
10
|
+
# get rid of last nibble if there's an odd number
|
11
|
+
# it will be processed later anyway
|
12
|
+
nibbles.slice!(nibbles.length-2, 1) if nibbles.length.odd?
|
13
|
+
bytes = []
|
14
|
+
while !(nibs = nibbles.slice!(0,2)).empty?
|
15
|
+
byte = (nibs[0].hex << 4) + nibs[1].hex
|
16
|
+
bytes << byte
|
17
|
+
end
|
18
|
+
bytes
|
19
|
+
end
|
20
|
+
|
21
|
+
# converts a string of hex digits to bytes
|
22
|
+
def self.hex_str_to_hex_chars(str)
|
23
|
+
str.split(//)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.numeric_byte_to_hex_chars(num)
|
27
|
+
[((num & 0xF0) >> 4), (num & 0x0F)].map { |n| n.to_s(16) }
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/nibbler.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Parse MIDI Messages
|
4
|
+
# (c)2011 Ari Russo and licensed under the Apache 2.0 License
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'forwardable'
|
8
|
+
|
9
|
+
require 'nibbler/nibbler'
|
10
|
+
require 'nibbler/parser'
|
11
|
+
require 'nibbler/type_conversion'
|
12
|
+
require 'nibbler/hex_char_array_filter'
|
13
|
+
|
14
|
+
#
|
15
|
+
# Parse MIDI Messages
|
16
|
+
#
|
17
|
+
module Nibbler
|
18
|
+
|
19
|
+
VERSION = "0.0.3"
|
20
|
+
|
21
|
+
# shortcut to Parser.new
|
22
|
+
def self.new(*a, &block)
|
23
|
+
Nibbler.new(*a, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midi-nibbler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.3
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ari Russo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-04 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: midi-message
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: midilib
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
description: Parse MIDI Messages.
|
39
|
+
email:
|
40
|
+
- ari.russo@gmail.com
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
files:
|
48
|
+
- lib/nibbler.rb
|
49
|
+
- lib/nibbler/nibbler.rb
|
50
|
+
- lib/nibbler/midi-message_factory.rb
|
51
|
+
- lib/nibbler/parser.rb
|
52
|
+
- lib/nibbler/midilib_factory.rb
|
53
|
+
- lib/nibbler/hex_char_array_filter.rb
|
54
|
+
- lib/nibbler/type_conversion.rb
|
55
|
+
- LICENSE
|
56
|
+
- README.rdoc
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://github.com/arirusso/nibbler
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.3.6
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project: nibbler
|
81
|
+
rubygems_version: 1.6.2
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Parse MIDI Messages.
|
85
|
+
test_files: []
|
86
|
+
|