midi-nibbler 0.1.1 → 0.2.1
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 +7 -0
- data/LICENSE +2 -2
- data/README.md +139 -0
- data/lib/nibbler.rb +13 -10
- data/lib/nibbler/hex_processor.rb +47 -0
- data/lib/nibbler/midi-message.rb +53 -0
- data/lib/nibbler/midilib.rb +67 -0
- data/lib/nibbler/parser.rb +86 -94
- data/lib/nibbler/session.rb +134 -0
- data/lib/nibbler/type_conversion.rb +17 -10
- data/test/helper.rb +3 -9
- data/test/{test_hex_char_array_filter.rb → hex_processor_test.rb} +18 -23
- data/test/midi_message_test.rb +126 -0
- data/test/midilib_test.rb +131 -0
- data/test/{test_parser_buffer.rb → parser_buffer_test.rb} +3 -8
- data/test/{test_parser_rejected.rb → parser_rejected_test.rb} +9 -14
- data/test/parser_test.rb +188 -0
- data/test/session_test.rb +135 -0
- data/test/{test_type_conversion.rb → type_conversion_test.rb} +6 -11
- metadata +60 -65
- data/README.rdoc +0 -115
- data/lib/nibbler/hex_char_array_filter.rb +0 -37
- data/lib/nibbler/midi-message_factory.rb +0 -54
- data/lib/nibbler/midilib_factory.rb +0 -66
- data/lib/nibbler/nibbler.rb +0 -89
- data/test/test_midi_message_factory.rb +0 -130
- data/test/test_midilib_factory.rb +0 -137
- data/test/test_nibbler.rb +0 -120
- data/test/test_parser.rb +0 -159
metadata
CHANGED
@@ -1,95 +1,90 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: midi-nibbler
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Ari Russo
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2014-08-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
17
14
|
name: midi-message
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: "0"
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
25
20
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: midilib
|
29
21
|
prerelease: false
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: midilib
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
36
34
|
type: :development
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: A utility for parsing MIDI messages from various types of input
|
42
|
+
email:
|
40
43
|
- ari.russo@gmail.com
|
41
44
|
executables: []
|
42
|
-
|
43
45
|
extensions: []
|
44
|
-
|
45
46
|
extra_rdoc_files: []
|
46
|
-
|
47
|
-
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
48
50
|
- lib/nibbler.rb
|
49
|
-
- lib/nibbler/
|
50
|
-
- lib/nibbler/midi-
|
51
|
+
- lib/nibbler/hex_processor.rb
|
52
|
+
- lib/nibbler/midi-message.rb
|
53
|
+
- lib/nibbler/midilib.rb
|
51
54
|
- lib/nibbler/parser.rb
|
52
|
-
- lib/nibbler/
|
53
|
-
- lib/nibbler/hex_char_array_filter.rb
|
55
|
+
- lib/nibbler/session.rb
|
54
56
|
- lib/nibbler/type_conversion.rb
|
55
|
-
- test/test_parser.rb
|
56
57
|
- test/helper.rb
|
57
|
-
- test/
|
58
|
-
- test/
|
59
|
-
- test/
|
60
|
-
- test/
|
61
|
-
- test/
|
62
|
-
- test/
|
63
|
-
- test/
|
64
|
-
-
|
65
|
-
- README.rdoc
|
66
|
-
has_rdoc: true
|
58
|
+
- test/hex_processor_test.rb
|
59
|
+
- test/midi_message_test.rb
|
60
|
+
- test/midilib_test.rb
|
61
|
+
- test/parser_buffer_test.rb
|
62
|
+
- test/parser_rejected_test.rb
|
63
|
+
- test/parser_test.rb
|
64
|
+
- test/session_test.rb
|
65
|
+
- test/type_conversion_test.rb
|
67
66
|
homepage: http://github.com/arirusso/nibbler
|
68
|
-
licenses:
|
69
|
-
|
67
|
+
licenses:
|
68
|
+
- Apache 2.0
|
69
|
+
metadata: {}
|
70
70
|
post_install_message:
|
71
71
|
rdoc_options: []
|
72
|
-
|
73
|
-
require_paths:
|
72
|
+
require_paths:
|
74
73
|
- lib
|
75
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
-
|
77
|
-
requirements:
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
78
76
|
- - ">="
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version:
|
81
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
-
|
83
|
-
requirements:
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
84
81
|
- - ">="
|
85
|
-
- !ruby/object:Gem::Version
|
82
|
+
- !ruby/object:Gem::Version
|
86
83
|
version: 1.3.6
|
87
84
|
requirements: []
|
88
|
-
|
89
85
|
rubyforge_project: nibbler
|
90
|
-
rubygems_version:
|
86
|
+
rubygems_version: 2.2.2
|
91
87
|
signing_key:
|
92
|
-
specification_version:
|
88
|
+
specification_version: 4
|
93
89
|
summary: Parse MIDI Messages.
|
94
90
|
test_files: []
|
95
|
-
|
data/README.rdoc
DELETED
@@ -1,115 +0,0 @@
|
|
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
|
-
nibbler.parse("90")
|
24
|
-
=> nil
|
25
|
-
|
26
|
-
nibbler.parse("40")
|
27
|
-
=> nil
|
28
|
-
|
29
|
-
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
|
-
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
|
-
nibbler.parse(0x90, 0x40, 0x40)
|
55
|
-
=> #<MIDIMessage::NoteOn:0x98c9818 ...>
|
56
|
-
|
57
|
-
You can use nibbles in string format
|
58
|
-
|
59
|
-
nibbler.parse("9", "0", "4", "0", "4", "0")
|
60
|
-
=> #<MIDIMessage::NoteOn:0x98c9818 ...>
|
61
|
-
|
62
|
-
Interchange the different types
|
63
|
-
|
64
|
-
nibbler.parse("9", "0", 0x40, 64)
|
65
|
-
=> #<MIDIMessage::NoteOn:0x98c9818 ...>
|
66
|
-
|
67
|
-
Use running status
|
68
|
-
|
69
|
-
nibbler.parse(0x40, 64)
|
70
|
-
=> #<MIDIMessage::NoteOn:0x98c9818 ...>
|
71
|
-
|
72
|
-
Look at the messages we've parsed
|
73
|
-
|
74
|
-
nibbler.messages
|
75
|
-
=> [#<MIDIMessage::NoteOn:0x98c9804 ...>
|
76
|
-
#<MIDIMessage::NoteOn:0x98c9811 ...>]
|
77
|
-
|
78
|
-
Add an incomplete message
|
79
|
-
|
80
|
-
nibbler.parse("9")
|
81
|
-
nibbler.parse("40")
|
82
|
-
|
83
|
-
See progress
|
84
|
-
|
85
|
-
nibbler.buffer
|
86
|
-
=> ["9", "4", "0"]
|
87
|
-
|
88
|
-
nibbler.buffer_s
|
89
|
-
=> "940"
|
90
|
-
|
91
|
-
Pass in a timestamp
|
92
|
-
|
93
|
-
nibbler.parse("904040", :timestamp => Time.now.to_i)
|
94
|
-
=> { :messages=> #<MIDIMessage::NoteOn:0x92f4564 ..>, :timestamp=>1304488440 }
|
95
|
-
|
96
|
-
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]
|
97
|
-
|
98
|
-
Nibbler.new(:message_lib => :midilib)
|
99
|
-
|
100
|
-
nibbler.parse("9", "0", 0x40, "40")
|
101
|
-
=> "0: ch 00 on 40 40"
|
102
|
-
|
103
|
-
== Also see
|
104
|
-
|
105
|
-
* {midi-eye}[http://github.com/arirusso/midi-eye], a MIDI event listener based on nibbler
|
106
|
-
|
107
|
-
== Author
|
108
|
-
|
109
|
-
* {Ari Russo}[http://github.com/arirusso] <ari.russo at gmail.com>
|
110
|
-
|
111
|
-
== License
|
112
|
-
|
113
|
-
Apache 2.0, See the file LICENSE
|
114
|
-
|
115
|
-
Copyright (c) 2011 Ari Russo
|
@@ -1,37 +0,0 @@
|
|
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
|
@@ -1,54 +0,0 @@
|
|
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
|
@@ -1,66 +0,0 @@
|
|
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
|
data/lib/nibbler/nibbler.rb
DELETED
@@ -1,89 +0,0 @@
|
|
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
|
-
@timestamps = options[:timestamps] || false
|
24
|
-
@callbacks, @processed, @rejected, @messages = [], [], [], []
|
25
|
-
@parser = Parser.new(options)
|
26
|
-
@typefilter = HexCharArrayFilter.new
|
27
|
-
block.call unless block.nil?
|
28
|
-
end
|
29
|
-
|
30
|
-
def all_messages
|
31
|
-
@messages | @fragmented_messages
|
32
|
-
end
|
33
|
-
|
34
|
-
def buffer_s
|
35
|
-
buffer.join
|
36
|
-
end
|
37
|
-
alias_method :buffer_hex, :buffer_s
|
38
|
-
|
39
|
-
def clear_buffer
|
40
|
-
buffer.clear
|
41
|
-
end
|
42
|
-
|
43
|
-
def clear_messages
|
44
|
-
@messages.clear
|
45
|
-
end
|
46
|
-
|
47
|
-
def use_timestamps
|
48
|
-
@messages = @messages.map do |m|
|
49
|
-
{ :messages => m, :timestamp => nil }
|
50
|
-
end
|
51
|
-
@timestamps = true
|
52
|
-
end
|
53
|
-
|
54
|
-
def parse(*a)
|
55
|
-
a.compact!
|
56
|
-
options = a.last.kind_of?(Hash) ? a.pop : nil
|
57
|
-
timestamp = options[:timestamp] if !options.nil? && !options[:timestamp].nil?
|
58
|
-
use_timestamps if !timestamp.nil? && !@timestamps
|
59
|
-
queue = @typefilter.process(a)
|
60
|
-
result = @parser.process(queue)
|
61
|
-
record_message(result[:messages], timestamp)
|
62
|
-
@processed += result[:processed]
|
63
|
-
@rejected += result[:rejected]
|
64
|
-
get_parse_output(result[:messages], options)
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def record_message(msg, timestamp = nil)
|
70
|
-
!@timestamps ? @messages += msg : @messages << {
|
71
|
-
:messages => msg,
|
72
|
-
:timestamp => timestamp
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
def get_parse_output(messages, options = nil)
|
77
|
-
# return type
|
78
|
-
# 0 messages: nil
|
79
|
-
# 1 message: the message
|
80
|
-
# >1 message: an array of messages
|
81
|
-
# might make sense to make this an array no matter what...iii dunnoo
|
82
|
-
output = messages.length < 2 ? (messages.empty? ? nil : messages[0]) : messages
|
83
|
-
output = { :messages => output, :timestamp => options[:timestamp] } if @timestamps && !options.nil?
|
84
|
-
output
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|