midi-message 0.2.4 → 0.3.0

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/lib/midi-message.rb CHANGED
@@ -5,33 +5,36 @@
5
5
  #
6
6
  module MIDIMessage
7
7
 
8
+ module Event
9
+ end
10
+
8
11
  module Process
9
12
  end
10
13
 
11
- VERSION = "0.2.4"
14
+ VERSION = "0.3.0"
12
15
 
13
16
  end
14
17
 
15
- require 'yaml'
16
-
17
- # messages
18
-
19
- require 'midi-message/short_message'
20
- require 'midi-message/channel_message'
21
- require 'midi-message/constant'
22
- require 'midi-message/context'
23
- require 'midi-message/note_message'
24
- require 'midi-message/parser'
25
- require 'midi-message/system_message'
26
- require 'midi-message/system_exclusive'
27
- require 'midi-message/type_conversion'
18
+ # libs
19
+ require "forwardable"
20
+ require "yaml"
28
21
 
29
- # message processors
22
+ # messages (mixed format)
23
+ require "midi-message/short_message"
24
+ require "midi-message/channel_message"
25
+ require "midi-message/constant"
26
+ require "midi-message/context"
27
+ require "midi-message/note_message"
28
+ require "midi-message/parser"
29
+ require "midi-message/system_message"
30
+ require "midi-message/system_exclusive"
31
+ require "midi-message/type_conversion"
30
32
 
31
33
  # modules
32
34
  require "midi-message/process/processor"
33
35
 
34
36
  # classes
37
+ require "midi-message/event/note"
35
38
  require "midi-message/process/filter"
36
39
  require "midi-message/process/limit"
37
40
  require "midi-message/process/transpose"
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ module MIDIMessage
3
+
4
+ module Event
5
+
6
+ # an Event::Note is a pairing of a MIDI NoteOn and NoteOff message
7
+ # has a length that corresponds to sequencer ticks
8
+ class Note
9
+
10
+ extend Forwardable
11
+
12
+ attr_reader :start,
13
+ :finish,
14
+ :length
15
+
16
+ alias_method :duration, :length
17
+
18
+ def_delegators :start, :note
19
+
20
+ def initialize(start_message, duration, options = {})
21
+ @start = start_message
22
+ @length = duration
23
+
24
+ @finish = options[:finish] || start_message.to_note_off
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -11,45 +11,45 @@ module MIDIMessage
11
11
 
12
12
  attr_reader :bandwidth, :property, :reject
13
13
 
14
- def initialize(message, prop, bandwidth, options = {})
14
+ def initialize(prop, bandwidth, options = {})
15
15
  @bandwidth = [bandwidth].flatten
16
- @message = message
17
16
  @property = prop
18
17
  @reject = options[:reject] || false
19
- initialize_processor(message)
18
+
19
+ initialize_processor(options)
20
20
  end
21
21
 
22
- def process
23
- val = @message.send(@property)
24
- result = @bandwidth.map { |bw| val >= bw.min && val <= bw.max ? @message : nil }
25
- result.include?(@message) ^ @reject ? @message : nil
22
+ def process_single(message)
23
+ val = message.send(@property)
24
+ result = @bandwidth.map { |bw| val >= bw.min && val <= bw.max ? message : nil }
25
+ result.include?(message) ^ @reject ? message : nil
26
26
  end
27
27
 
28
28
  end
29
29
 
30
30
  class LowPassFilter < Filter
31
- def initialize(message, prop, max, options = {})
32
- super(message, prop, (0..max), options)
31
+ def initialize(prop, max, options = {})
32
+ super(prop, (0..max), options)
33
33
  end
34
34
  end
35
35
 
36
36
  class HighPassFilter < Filter
37
- def initialize(message, prop, min, options = {})
38
- super(message, prop, (min..127), options)
37
+ def initialize(prop, min, options = {})
38
+ super(prop, (min..127), options)
39
39
  end
40
40
  end
41
41
 
42
42
  class BandPassFilter < Filter
43
- def initialize(message, prop, accept_range, options = {})
43
+ def initialize(prop, accept_range, options = {})
44
44
  options[:reject] = false
45
- super(message, prop, accept_range, options)
45
+ super(prop, accept_range, options)
46
46
  end
47
47
  end
48
48
 
49
49
  class BandRejectFilter < Filter
50
- def initialize(message, prop, reject_range, options = {})
50
+ def initialize(prop, reject_range, options = {})
51
51
  options[:reject] = true
52
- super(message, prop, reject_range, options)
52
+ super(prop, reject_range, options)
53
53
  end
54
54
  end
55
55
  NotchFilter = BandRejectFilter
@@ -8,20 +8,25 @@ module MIDIMessage
8
8
 
9
9
  include Processor
10
10
 
11
- attr_reader :property, :range
11
+ attr_reader :property, :limit_to
12
+ alias_method :range, :limit_to
12
13
 
13
- def initialize(message, prop, range, options = {})
14
- @range = range
15
- @message = message
14
+ def initialize(prop, limit_to, options = {})
15
+ @limit_to = limit_to
16
16
  @property = prop
17
- initialize_processor(message)
17
+
18
+ initialize_processor(options)
18
19
  end
19
20
 
20
- def process
21
- val = @message.send(@property)
22
- @message.send("#{@property}=", @range.min) if val < @range.min
23
- @message.send("#{@property}=", @range.max) if val > @range.max
24
- @message
21
+ def process_single(message)
22
+ val = message.send(@property)
23
+ if @limit_to.kind_of?(Range)
24
+ message.send("#{@property}=", @limit_to.min) if val < @limit_to.min
25
+ message.send("#{@property}=", @limit_to.max) if val > @limit_to.max
26
+ elsif @limit_to.kind_of?(Numeric)
27
+ message.send("#{@property}=", @limit_to)
28
+ end
29
+ message
25
30
  end
26
31
 
27
32
  end
@@ -8,19 +8,27 @@ module MIDIMessage
8
8
 
9
9
  def self.included(base)
10
10
  base.extend(ClassMethods)
11
- base.send(:attr_reader, :message)
11
+ #base.send(:attr_reader, :message)
12
+ end
13
+
14
+ def process(messages = nil)
15
+ messages = @message unless @message.nil?
16
+ result = [messages].flatten.map { |message| process_single(message) }
17
+ result.kind_of?(Array) && result.size == 1 ? result.first : result
12
18
  end
13
19
 
14
20
  module ClassMethods
15
- def process(*a, &block)
16
- new(*a).process(&block)
21
+
22
+ def process(msg, *a, &block)
23
+ new(*a).process(msg, &block)
17
24
  end
25
+
18
26
  end
19
27
 
20
28
  private
21
29
 
22
- def initialize_processor(message)
23
- @message = message
30
+ def initialize_processor(options)
31
+ @message = options[:message]
24
32
  end
25
33
 
26
34
  end
@@ -10,17 +10,17 @@ module MIDIMessage
10
10
 
11
11
  attr_reader :factor, :property
12
12
 
13
- def initialize(message, prop, factor, options = {})
13
+ def initialize(prop, factor, options = {})
14
14
  @factor = factor
15
- @message = message
16
15
  @property = prop
17
- initialize_processor(message)
16
+
17
+ initialize_processor(options)
18
18
  end
19
19
 
20
- def process
21
- val = @message.send(@property)
22
- @message.send("#{@property}=", val + @factor)
23
- @message
20
+ def process_single(message)
21
+ val = message.send(@property)
22
+ message.send("#{@property}=", val + @factor)
23
+ message
24
24
  end
25
25
 
26
26
  end
data/test/test_filter.rb CHANGED
@@ -11,84 +11,84 @@ class FilterTest < Test::Unit::TestCase
11
11
  def test_high_pass_note_reject
12
12
  msg = MIDIMessage::NoteOn["C0"].new(0, 100)
13
13
  assert_equal(12, msg.note)
14
- outp = HighPassFilter.new(msg, :note, 20).process
14
+ outp = HighPassFilter.new(:note, 20).process(msg)
15
15
  assert_equal(nil, outp)
16
16
  end
17
17
 
18
18
  def test_high_pass_note_accept
19
19
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
20
20
  assert_equal(60, msg.note)
21
- outp = HighPassFilter.new(msg, :note, 20).process
21
+ outp = HighPassFilter.new(:note, 20).process(msg)
22
22
  assert_equal(msg, outp)
23
23
  end
24
24
 
25
25
  def test_low_pass_note_reject
26
26
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
27
27
  assert_equal(60, msg.note)
28
- outp = LowPassFilter.new(msg, :note, 50).process
28
+ outp = LowPassFilter.new(:note, 50).process(msg)
29
29
  assert_equal(nil, outp)
30
30
  end
31
31
 
32
32
  def test_low_pass_note_accept
33
33
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
34
34
  assert_equal(60, msg.note)
35
- outp = LowPassFilter.new(msg, :note, 100).process
35
+ outp = LowPassFilter.new(:note, 100).process(msg)
36
36
  assert_equal(msg, outp)
37
37
  end
38
38
 
39
39
  def test_band_pass_note_reject
40
40
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
41
41
  assert_equal(60, msg.note)
42
- outp = BandPassFilter.new(msg, :note, (20..50)).process
42
+ outp = BandPassFilter.new(:note, (20..50)).process(msg)
43
43
  assert_equal(nil, outp)
44
44
  end
45
45
 
46
46
  def test_band_pass_note_accept
47
47
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
48
48
  assert_equal(60, msg.note)
49
- outp = BandPassFilter.new(msg, :note, (20..100)).process
49
+ outp = BandPassFilter.new(:note, (20..100)).process(msg)
50
50
  assert_equal(msg, outp)
51
51
  end
52
52
 
53
53
  def test_band_reject_note_reject
54
54
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
55
55
  assert_equal(60, msg.note)
56
- outp = NotchFilter.new(msg, :note, (20..70)).process
56
+ outp = NotchFilter.new(:note, (20..70)).process(msg)
57
57
  assert_equal(nil, outp)
58
58
  end
59
59
 
60
60
  def test_band_reject_note_accept
61
61
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
62
62
  assert_equal(60, msg.note)
63
- outp = NotchFilter.new(msg, :note, (20..50)).process
63
+ outp = NotchFilter.new(:note, (20..50)).process(msg)
64
64
  assert_equal(msg, outp)
65
65
  end
66
66
 
67
67
  def test_multiband_note_reject
68
68
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
69
69
  assert_equal(60, msg.note)
70
- outp = Filter.new(msg, :note, [(20..30), (40..50)]).process
70
+ outp = Filter.new(:note, [(20..30), (40..50)]).process(msg)
71
71
  assert_equal(nil, outp)
72
72
  end
73
73
 
74
74
  def test_multiband_note_accept
75
75
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
76
76
  assert_equal(60, msg.note)
77
- outp = Filter.new(msg, :note, [(20..30), (50..70)]).process
77
+ outp = Filter.new(:note, [(20..30), (50..70)]).process(msg)
78
78
  assert_equal(msg, outp)
79
79
  end
80
80
 
81
81
  def test_multinotch_note_reject
82
82
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
83
83
  assert_equal(60, msg.note)
84
- outp = Filter.new(msg, :note, [(20..30), (55..65)], :reject => true).process
84
+ outp = Filter.new(:note, [(20..30), (55..65)], :reject => true).process(msg)
85
85
  assert_equal(nil, outp)
86
86
  end
87
87
 
88
88
  def test_multinotch_note_accept
89
89
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
90
90
  assert_equal(60, msg.note)
91
- outp = Filter.new(msg, :note, [(20..30), (40..50)], :reject => true).process
91
+ outp = Filter.new(:note, [(20..30), (40..50)], :reject => true).process(msg)
92
92
  assert_equal(msg, outp)
93
93
  end
94
94
 
data/test/test_limit.rb CHANGED
@@ -7,32 +7,39 @@ class LimitTest < Test::Unit::TestCase
7
7
  include MIDIMessage
8
8
  include MIDIMessage::Process
9
9
  include TestHelper
10
+
11
+ def test_numeric_range
12
+ msg = MIDIMessage::NoteOn["C0"].new(0, 100)
13
+ assert_equal(12, msg.note)
14
+ Limit.new(:note, 30).process(msg)
15
+ assert_equal(30, msg.note)
16
+ end
10
17
 
11
18
  def test_low_note
12
19
  msg = MIDIMessage::NoteOn["C0"].new(0, 100)
13
20
  assert_equal(12, msg.note)
14
- Limit.new(msg, :note, (20..50)).process
21
+ Limit.new(:note, (20..50)).process(msg)
15
22
  assert_equal(20, msg.note)
16
23
  end
17
24
 
18
25
  def test_high_note
19
26
  msg = MIDIMessage::NoteOn["C6"].new(0, 100)
20
27
  assert_equal(84, msg.note)
21
- Limit.new(msg, :note, (20..50)).process
28
+ Limit.new(:note, (20..50)).process(msg)
22
29
  assert_equal(50, msg.note)
23
30
  end
24
31
 
25
32
  def test_low_velocity
26
33
  msg = MIDIMessage::NoteOn["C0"].new(0, 10)
27
34
  assert_equal(10, msg.velocity)
28
- Limit.new(msg, :velocity, (30..110)).process
35
+ Limit.new(:velocity, (30..110)).process(msg)
29
36
  assert_equal(30, msg.velocity)
30
37
  end
31
38
 
32
39
  def test_high_velocity
33
40
  msg = MIDIMessage::NoteOn["C6"].new(0, 120)
34
41
  assert_equal(120, msg.velocity)
35
- Limit.new(msg, :velocity, (25..75)).process
42
+ Limit.new(:velocity, (25..75)).process(msg)
36
43
  assert_equal(75, msg.velocity)
37
44
  end
38
45
 
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'helper'
4
+
5
+ class NoteEventTest < Test::Unit::TestCase
6
+
7
+ include MIDIMessage
8
+ include TestHelper
9
+
10
+ def test_create_event
11
+ msg = NoteOn.new(0, 0x40, 0x40)
12
+ event = Event::Note.new(msg, 10)
13
+ assert_equal(msg, event.start)
14
+ assert_equal(10, event.duration)
15
+ assert_equal(NoteOff, event.finish.class)
16
+ assert_equal(msg.note, event.finish.note)
17
+ assert_equal(msg.note, event.note)
18
+ end
19
+
20
+ def test_override_finish
21
+ msg = NoteOn.new(0, 0x40, 0x40)
22
+ msg2 = NoteOff.new(0, 0x40, 127)
23
+ event = Event::Note.new(msg, 5, :finish => msg2)
24
+ assert_equal(msg, event.start)
25
+ assert_equal(5, event.duration)
26
+ assert_equal(0x40, event.start.velocity)
27
+ assert_equal(NoteOff, event.finish.class)
28
+ assert_equal(0x40, event.finish.note)
29
+ assert_equal(127, event.finish.velocity)
30
+ end
31
+
32
+ end
@@ -11,28 +11,28 @@ class TransposeTest < Test::Unit::TestCase
11
11
  def test_transpose_note_up
12
12
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
13
13
  assert_equal(60, msg.note)
14
- Transpose.new(msg, :note, 5).process
14
+ Transpose.new(:note, 5).process(msg)
15
15
  assert_equal(65, msg.note)
16
16
  end
17
17
 
18
18
  def test_transpose_velocity_up
19
19
  msg = MIDIMessage::NoteOn["C4"].new(0, 82)
20
20
  assert_equal(82, msg.velocity)
21
- Transpose.new(msg, :velocity, 10).process
21
+ Transpose.new(:velocity, 10).process(msg)
22
22
  assert_equal(92, msg.velocity)
23
23
  end
24
24
 
25
25
  def test_transpose_note_down
26
26
  msg = MIDIMessage::NoteOn["C4"].new(0, 100)
27
27
  assert_equal(60, msg.note)
28
- Transpose.new(msg, :note, -5).process
28
+ Transpose.new(:note, -5).process(msg)
29
29
  assert_equal(55, msg.note)
30
30
  end
31
31
 
32
32
  def test_transpose_velocity_down
33
33
  msg = MIDIMessage::NoteOn["C4"].new(0, 82)
34
34
  assert_equal(82, msg.velocity)
35
- Transpose.new(msg, :velocity, -10).process
35
+ Transpose.new(:velocity, -10).process(msg)
36
36
  assert_equal(72, msg.velocity)
37
37
  end
38
38
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midi-message
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-12 00:00:00.000000000Z
12
+ date: 2011-09-27 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: MIDI messages, objectified in Ruby
15
15
  email:
@@ -21,6 +21,7 @@ files:
21
21
  - lib/midi-message/channel_message.rb
22
22
  - lib/midi-message/constant.rb
23
23
  - lib/midi-message/context.rb
24
+ - lib/midi-message/event/note.rb
24
25
  - lib/midi-message/note_message.rb
25
26
  - lib/midi-message/parser.rb
26
27
  - lib/midi-message/process/filter.rb
@@ -39,6 +40,7 @@ files:
39
40
  - test/test_filter.rb
40
41
  - test/test_limit.rb
41
42
  - test/test_mutability.rb
43
+ - test/test_note_event.rb
42
44
  - test/test_parser.rb
43
45
  - test/test_processor.rb
44
46
  - test/test_short_message.rb