midi-nibbler 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|