midi-fx 0.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 +13 -0
- data/README.md +13 -0
- data/lib/midi-fx.rb +37 -0
- data/lib/midi-fx/filter.rb +55 -0
- data/lib/midi-fx/limit.rb +27 -0
- data/lib/midi-fx/transpose.rb +21 -0
- data/test/filter_test.rb +109 -0
- data/test/helper.rb +5 -0
- data/test/limit_test.rb +40 -0
- data/test/module_test.rb +13 -0
- data/test/transpose_test.rb +33 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 39c028b4fc0b5db17aad8a24058ef3ac94f130f3
|
4
|
+
data.tar.gz: 46e4cdeda5efaf2dce5eb69b26ecc7d6de418652
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 64e9f0fa4e52b8689ec27cf3ce54717cc261fc70ea7c93da463bf25be50fbae7d8bce62671302de72508ac3f67468d9ead56e5c6bf4bd546445c85986bb34982
|
7
|
+
data.tar.gz: c8c96e53af97c3e4746a0d10569524d28e33e1e7470b49d7ca37cbeb6e8f5078c1698f32dc7094636629204cbf2f0c7205740ccbf4c34b85dc23a912433f87e7
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2011-2014 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.md
ADDED
data/lib/midi-fx.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# midi-fx
|
3
|
+
#
|
4
|
+
# MIDI effects in Ruby
|
5
|
+
#
|
6
|
+
# (c)2011-2014 Ari Russo
|
7
|
+
# Apache 2.0 License
|
8
|
+
#
|
9
|
+
|
10
|
+
# libs
|
11
|
+
require "midi-message"
|
12
|
+
|
13
|
+
# classes
|
14
|
+
require "midi-fx/filter"
|
15
|
+
require "midi-fx/limit"
|
16
|
+
require "midi-fx/transpose"
|
17
|
+
|
18
|
+
module MIDIFX
|
19
|
+
|
20
|
+
VERSION = "0.1"
|
21
|
+
|
22
|
+
MAP = {
|
23
|
+
:filter => Filter,
|
24
|
+
:limit => Limit,
|
25
|
+
:transpose => Transpose
|
26
|
+
}
|
27
|
+
|
28
|
+
def self.method_missing(method, *args, &block)
|
29
|
+
if MAP.keys.include?(method)
|
30
|
+
message = args.shift
|
31
|
+
MAP[method].new(*args).process(message, &block)
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module MIDIFX
|
2
|
+
|
3
|
+
# Use the Filter superclass when you need a multi-band filter
|
4
|
+
class Filter
|
5
|
+
|
6
|
+
attr_reader :bandwidth, :property, :reject
|
7
|
+
|
8
|
+
def initialize(property, bandwidth, options = {})
|
9
|
+
@bandwidth = [bandwidth].flatten
|
10
|
+
@property = property
|
11
|
+
@reject = options[:reject] || false
|
12
|
+
@name = options[:name]
|
13
|
+
end
|
14
|
+
|
15
|
+
def process(message)
|
16
|
+
val = message.send(@property)
|
17
|
+
result = @bandwidth.map do |bw|
|
18
|
+
case bw
|
19
|
+
when Range then val >= bw.min && val <= bw.max ? message : nil
|
20
|
+
when Numeric then val == bw ? message : nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
result.include?(message) ^ @reject ? message : nil
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class LowPassFilter < Filter
|
29
|
+
def initialize(prop, max, options = {})
|
30
|
+
super(prop, (0..max), options)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class HighPassFilter < Filter
|
35
|
+
def initialize(prop, min, options = {})
|
36
|
+
super(prop, (min..127), options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class BandPassFilter < Filter
|
41
|
+
def initialize(prop, accept_range, options = {})
|
42
|
+
options[:reject] = false
|
43
|
+
super(prop, accept_range, options)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class BandRejectFilter < Filter
|
48
|
+
def initialize(prop, reject_range, options = {})
|
49
|
+
options[:reject] = true
|
50
|
+
super(prop, reject_range, options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
NotchFilter = BandRejectFilter
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MIDIFX
|
2
|
+
|
3
|
+
class Limit
|
4
|
+
|
5
|
+
attr_reader :property, :limit_to
|
6
|
+
alias_method :range, :limit_to
|
7
|
+
|
8
|
+
def initialize(property, limit_to, options = {})
|
9
|
+
@limit_to = limit_to
|
10
|
+
@property = property
|
11
|
+
@name = options[:name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def process(message)
|
15
|
+
val = message.send(@property)
|
16
|
+
if @limit_to.kind_of?(Range)
|
17
|
+
message.send("#{@property}=", @limit_to.min) if val < @limit_to.min
|
18
|
+
message.send("#{@property}=", @limit_to.max) if val > @limit_to.max
|
19
|
+
elsif @limit_to.kind_of?(Numeric)
|
20
|
+
message.send("#{@property}=", @limit_to)
|
21
|
+
end
|
22
|
+
message
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MIDIFX
|
2
|
+
|
3
|
+
class Transpose
|
4
|
+
|
5
|
+
attr_reader :factor, :property
|
6
|
+
|
7
|
+
def initialize(property, factor, options = {})
|
8
|
+
@factor = factor
|
9
|
+
@property = property
|
10
|
+
@name = options[:name]
|
11
|
+
end
|
12
|
+
|
13
|
+
def process(message)
|
14
|
+
val = message.send(@property)
|
15
|
+
message.send("#{@property}=", val + @factor)
|
16
|
+
message
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/test/filter_test.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class MIDIFX::FilterTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_high_pass_note_reject
|
6
|
+
message = MIDIMessage::NoteOn["C0"].new(0, 100)
|
7
|
+
assert_equal(12, message.note)
|
8
|
+
output = MIDIFX::HighPassFilter.new(:note, 20).process(message)
|
9
|
+
assert_equal(nil, output)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_high_pass_note_accept
|
13
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
14
|
+
assert_equal(60, message.note)
|
15
|
+
output = MIDIFX::HighPassFilter.new(:note, 20).process(message)
|
16
|
+
assert_equal(message, output)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_low_pass_note_reject
|
20
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
21
|
+
assert_equal(60, message.note)
|
22
|
+
output = MIDIFX::LowPassFilter.new(:note, 50).process(message)
|
23
|
+
assert_equal(nil, output)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_low_pass_note_accept
|
27
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
28
|
+
assert_equal(60, message.note)
|
29
|
+
output = MIDIFX::LowPassFilter.new(:note, 100).process(message)
|
30
|
+
assert_equal(message, output)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_band_pass_note_reject
|
34
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
35
|
+
assert_equal(60, message.note)
|
36
|
+
output = MIDIFX::BandPassFilter.new(:note, (20..50)).process(message)
|
37
|
+
assert_equal(nil, output)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_band_pass_note_accept
|
41
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
42
|
+
assert_equal(60, message.note)
|
43
|
+
output = MIDIFX::BandPassFilter.new(:note, (20..100)).process(message)
|
44
|
+
assert_equal(message, output)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_band_reject_note_reject
|
48
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
49
|
+
assert_equal(60, message.note)
|
50
|
+
output = MIDIFX::NotchFilter.new(:note, (20..70)).process(message)
|
51
|
+
assert_equal(nil, output)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_band_reject_note_accept
|
55
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
56
|
+
assert_equal(60, message.note)
|
57
|
+
output = MIDIFX::NotchFilter.new(:note, (20..50)).process(message)
|
58
|
+
assert_equal(message, output)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_multiband_note_reject
|
62
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
63
|
+
assert_equal(60, message.note)
|
64
|
+
output = MIDIFX::Filter.new(:note, [(20..30), (40..50)]).process(message)
|
65
|
+
assert_equal(nil, output)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_multiband_note_accept
|
69
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
70
|
+
assert_equal(60, message.note)
|
71
|
+
output = MIDIFX::Filter.new(:note, [(20..30), (50..70)]).process(message)
|
72
|
+
assert_equal(message, output)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_multinotch_note_reject
|
76
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
77
|
+
assert_equal(60, message.note)
|
78
|
+
output = MIDIFX::Filter.new(:note, [(20..30), (55..65)], :reject => true).process(message)
|
79
|
+
assert_equal(nil, output)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_multinotch_note_accept
|
83
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
84
|
+
assert_equal(60, message.note)
|
85
|
+
output = MIDIFX::Filter.new(:note, [(20..30), (40..50)], :reject => true).process(message)
|
86
|
+
assert_equal(message, output)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_numeric_note_accept
|
90
|
+
message1 = MIDIMessage::NoteOn["C4"].new(0, 100)
|
91
|
+
message2 = MIDIMessage::NoteOn["C5"].new(0, 100)
|
92
|
+
f = MIDIFX::Filter.new(:note, 60)
|
93
|
+
output = f.process(message1)
|
94
|
+
assert_equal(message1, output)
|
95
|
+
output = f.process(message2)
|
96
|
+
assert_equal(nil, output)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_numeric_note_reject
|
100
|
+
message1 = MIDIMessage::NoteOn["C4"].new(0, 100)
|
101
|
+
message2 = MIDIMessage::NoteOn["C5"].new(0, 100)
|
102
|
+
f = MIDIFX::Filter.new(:note, 60, :reject => true)
|
103
|
+
output = f.process(message1)
|
104
|
+
assert_equal(nil, output)
|
105
|
+
output = f.process(message2)
|
106
|
+
assert_equal(message2, output)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
data/test/helper.rb
ADDED
data/test/limit_test.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class MIDIFX::LimitTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_numeric_range
|
6
|
+
message = MIDIMessage::NoteOn["C0"].new(0, 100)
|
7
|
+
assert_equal(12, message.note)
|
8
|
+
MIDIFX::Limit.new(:note, 30).process(message)
|
9
|
+
assert_equal(30, message.note)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_low_note
|
13
|
+
message = MIDIMessage::NoteOn["C0"].new(0, 100)
|
14
|
+
assert_equal(12, message.note)
|
15
|
+
MIDIFX::Limit.new(:note, (20..50)).process(message)
|
16
|
+
assert_equal(20, message.note)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_high_note
|
20
|
+
message = MIDIMessage::NoteOn["C6"].new(0, 100)
|
21
|
+
assert_equal(84, message.note)
|
22
|
+
MIDIFX::Limit.new(:note, (20..50)).process(message)
|
23
|
+
assert_equal(50, message.note)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_low_velocity
|
27
|
+
message = MIDIMessage::NoteOn["C0"].new(0, 10)
|
28
|
+
assert_equal(10, message.velocity)
|
29
|
+
MIDIFX::Limit.new(:velocity, (30..110)).process(message)
|
30
|
+
assert_equal(30, message.velocity)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_high_velocity
|
34
|
+
message = MIDIMessage::NoteOn["C6"].new(0, 120)
|
35
|
+
assert_equal(120, message.velocity)
|
36
|
+
MIDIFX::Limit.new(:velocity, (25..75)).process(message)
|
37
|
+
assert_equal(75, message.velocity)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/test/module_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class MIDIFX::TransposeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_transpose_note_up
|
6
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
7
|
+
assert_equal(60, message.note)
|
8
|
+
MIDIFX::Transpose.new(:note, 5).process(message)
|
9
|
+
assert_equal(65, message.note)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_transpose_velocity_up
|
13
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 82)
|
14
|
+
assert_equal(82, message.velocity)
|
15
|
+
MIDIFX::Transpose.new(:velocity, 10).process(message)
|
16
|
+
assert_equal(92, message.velocity)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_transpose_note_down
|
20
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 100)
|
21
|
+
assert_equal(60, message.note)
|
22
|
+
MIDIFX::Transpose.new(:note, -5).process(message)
|
23
|
+
assert_equal(55, message.note)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_transpose_velocity_down
|
27
|
+
message = MIDIMessage::NoteOn["C4"].new(0, 82)
|
28
|
+
assert_equal(82, message.velocity)
|
29
|
+
MIDIFX::Transpose.new(:velocity, -10).process(message)
|
30
|
+
assert_equal(72, message.velocity)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midi-fx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ari Russo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: midi-message
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Process MIDI messages in Ruby
|
28
|
+
email:
|
29
|
+
- ari.russo@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE
|
35
|
+
- README.md
|
36
|
+
- lib/midi-fx.rb
|
37
|
+
- lib/midi-fx/filter.rb
|
38
|
+
- lib/midi-fx/limit.rb
|
39
|
+
- lib/midi-fx/transpose.rb
|
40
|
+
- test/filter_test.rb
|
41
|
+
- test/helper.rb
|
42
|
+
- test/limit_test.rb
|
43
|
+
- test/module_test.rb
|
44
|
+
- test/transpose_test.rb
|
45
|
+
homepage: http://github.com/arirusso/midi-fx
|
46
|
+
licenses:
|
47
|
+
- Apache 2.0
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.3.6
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project: midi-eye
|
65
|
+
rubygems_version: 2.2.2
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: MIDI effects in Ruby
|
69
|
+
test_files: []
|