music-performance 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/.document +3 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.rdoc +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +28 -0
- data/Rakefile +54 -0
- data/bin/midify +61 -0
- data/lib/music-performance.rb +25 -0
- data/lib/music-performance/arrangement/midi/midi_events.rb +9 -0
- data/lib/music-performance/arrangement/midi/midi_util.rb +38 -0
- data/lib/music-performance/arrangement/midi/part_sequencer.rb +121 -0
- data/lib/music-performance/arrangement/midi/score_sequencer.rb +33 -0
- data/lib/music-performance/conversion/glissando_converter.rb +36 -0
- data/lib/music-performance/conversion/note_sequence_extractor.rb +100 -0
- data/lib/music-performance/conversion/note_time_converter.rb +76 -0
- data/lib/music-performance/conversion/portamento_converter.rb +26 -0
- data/lib/music-performance/conversion/score_collator.rb +121 -0
- data/lib/music-performance/conversion/score_time_converter.rb +112 -0
- data/lib/music-performance/model/note_attacks.rb +21 -0
- data/lib/music-performance/model/note_sequence.rb +113 -0
- data/lib/music-performance/util/interpolation.rb +18 -0
- data/lib/music-performance/util/note_linker.rb +30 -0
- data/lib/music-performance/util/optimization.rb +33 -0
- data/lib/music-performance/util/piecewise_function.rb +124 -0
- data/lib/music-performance/util/value_computer.rb +172 -0
- data/lib/music-performance/version.rb +7 -0
- data/music-performance.gemspec +33 -0
- data/spec/conversion/glissando_converter_spec.rb +93 -0
- data/spec/conversion/note_sequence_extractor_spec.rb +230 -0
- data/spec/conversion/note_time_converter_spec.rb +96 -0
- data/spec/conversion/portamento_converter_spec.rb +91 -0
- data/spec/conversion/score_collator_spec.rb +136 -0
- data/spec/conversion/score_time_converter_spec.rb +73 -0
- data/spec/model/note_sequence_spec.rb +147 -0
- data/spec/music-performance_spec.rb +7 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/util/note_linker_spec.rb +68 -0
- data/spec/util/optimization_spec.rb +73 -0
- data/spec/util/value_computer_spec.rb +146 -0
- metadata +242 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe NoteLinker do
|
4
|
+
describe '.find_unlinked_pitches' do
|
5
|
+
{
|
6
|
+
'note has no pitches' => [Note.quarter,[]],
|
7
|
+
'note has 1 pitch, no links' => [Note.quarter([C4]),[C4]],
|
8
|
+
'note has 2 pitches, no links' => [Note.quarter([C4,E4]),[C4,E4]],
|
9
|
+
'note has 1 pitch, which is linked' => [Note.quarter([C4], links: {C4 => Link::Tie.new} ),[]],
|
10
|
+
'note has 2 pitch, 1 of which is linked' => [Note.quarter([C4,E4], links: {C4 => Link::Tie.new} ),[E4]],
|
11
|
+
'note has 2 pitches, both of which are linked' => [Note.quarter([C4,E4], links: {C4 => Link::Tie.new, E4 => Link::Tie.new} ),[]],
|
12
|
+
'note has 1 pitch, and 1 unrelated link' => [Note.quarter([C4], links: {D4 => Link::Tie.new}),[C4]],
|
13
|
+
'note has 2 pitch, and 2 unrelated links' => [Note.quarter([C4,E4], links: {D4 => Link::Tie.new, F4 => Link::Tie.new}),[C4,E4]],
|
14
|
+
}.each do |descr,given_expected|
|
15
|
+
context descr do
|
16
|
+
given, expected = given_expected
|
17
|
+
it "should return #{expected}" do
|
18
|
+
actual = NoteLinker.find_unlinked_pitches(given)
|
19
|
+
actual.should eq(expected)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '.find_untargeted_pitches' do
|
26
|
+
{
|
27
|
+
'note has no pitches, next note has no pitches' => [Note.quarter,Note.quarter,[]],
|
28
|
+
'note has no pitches, next note has 3 pitch' => [Note.quarter,Note.quarter([C3,E3,F3]),[C3,E3,F3]],
|
29
|
+
'note has 3 pitches + no links, next note has 2 pitches' => [Note.quarter([C3,E3,F3]),Note.quarter([D2,F2]),[D2,F2]],
|
30
|
+
'note has 1 pitch + 1 unrelated link, next note has 1 pitch' => [Note.quarter([C3], links: {C3 => Link::Slur.new(C2)}),Note.quarter([D2]),[D2]],
|
31
|
+
'note has 1 pitch + 1 related link, next note has 1 pitch' => [Note.quarter([C3], links: {C3 => Link::Slur.new(D2)}),Note.quarter([D2]),[]],
|
32
|
+
'note has 2 pitches + 2 related link, next note has 2 pitches' => [Note.quarter([C3,E3], links: {C3 => Link::Slur.new(D2), E3 => Link::Slur.new(E2) }),Note.quarter([D2,E2]),[]],
|
33
|
+
'note has 2 pitches + 1 unrelated link, next note has 2 pitches' => [Note.quarter([C3,E3], links: {C3 => Link::Slur.new(D2), E3 => Link::Slur.new(F2) }),Note.quarter([D2,E2]),[E2]],
|
34
|
+
}.each do |descr,given_expected|
|
35
|
+
context descr do
|
36
|
+
given_note, given_next_note, expected = given_expected
|
37
|
+
it "should return #{expected}" do
|
38
|
+
actual = NoteLinker.find_untargeted_pitches(given_note, given_next_note)
|
39
|
+
actual.should eq(expected)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '.fully_link' do
|
46
|
+
[
|
47
|
+
[ Note.quarter([C4,E4,G4]), Note.quarter, Note.quarter([C4,E4,G4]) ],
|
48
|
+
[ Note.quarter([G4]), Note.quarter([A4]), Note.quarter([G4], links: {G4 => Link::Slur.new(A4)}) ],
|
49
|
+
[
|
50
|
+
Note.quarter([G4,A4]),
|
51
|
+
Note.quarter([A4]),
|
52
|
+
Note.quarter([G4,A4], links: {A4 => Link::Slur.new(A4)})
|
53
|
+
],
|
54
|
+
[
|
55
|
+
Note.quarter([G4,A4], links: {A4 => Link::Slur.new(B4)}),
|
56
|
+
Note.quarter([A4,B4]),
|
57
|
+
Note.quarter([G4,A4], links: {G4 => Link::Slur.new(A4), A4 => Link::Slur.new(B4)})
|
58
|
+
],
|
59
|
+
].each do |note,next_note,modified|
|
60
|
+
context "given note: #{note.to_s}, next_note: #{next_note.to_s}" do
|
61
|
+
it "should modifiy note to equal #{modified.to_s}" do
|
62
|
+
NoteLinker.fully_link(note, next_note, Link::Slur)
|
63
|
+
note.should eq(modified)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Optimization do
|
4
|
+
describe '.linking' do
|
5
|
+
context 'one unlinked, one untargeted' do
|
6
|
+
it 'should map the one unlinked to the one untargeted' do
|
7
|
+
[ C4, Bb4, G2, A3 ].each do |p1|
|
8
|
+
[ C4, Bb4, G2, A3 ].each do |p2|
|
9
|
+
sol = Optimization.linking([p1], [p2])
|
10
|
+
sol.size.should eq 1
|
11
|
+
sol.should have_key p1
|
12
|
+
sol[p1].should eq p2
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'two unlinked, one untargeted' do
|
19
|
+
it 'should map the closest unlinked to the one untargeted' do
|
20
|
+
unlinked = [C4,G4]
|
21
|
+
{ [Bb4] => {G4 => Bb4},
|
22
|
+
[F4] => {G4 => F4},
|
23
|
+
[E4] => {G4 => E4},
|
24
|
+
[Eb4] => {C4 => Eb4},
|
25
|
+
[D4] => {C4 => D4},
|
26
|
+
[Bb3] => {C4 => Bb3}
|
27
|
+
}.each do |untargeted, expected_map|
|
28
|
+
sol = Optimization.linking(unlinked, untargeted)
|
29
|
+
sol.should eq expected_map
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'one unlinked, two untargeted' do
|
35
|
+
it 'should map the one unlinked to the closest untargeted' do
|
36
|
+
unlinked = [C4]
|
37
|
+
{ [G4,Bb4] => {C4 => G4},
|
38
|
+
[G4,F4] => {C4 => F4},
|
39
|
+
[Eb4,D4] => {C4 => D4},
|
40
|
+
[G4,Bb3] => {C4 => Bb3},
|
41
|
+
[G3,G4] => {C4 => G3}
|
42
|
+
}.each do |untargeted, expected_map|
|
43
|
+
sol = Optimization.linking(unlinked, untargeted)
|
44
|
+
sol.should eq expected_map
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'many unlinked, many untargeted' do
|
50
|
+
it 'should map [unlinked.size, untargeted.size].min unlinked to untargeted, such that total pitch diffs is minimized' do
|
51
|
+
{
|
52
|
+
[[A3,B3,C3],[B3,Db3]] => { B3 => B3, C3 => Db3 },
|
53
|
+
[[A3,B3,C3],[Bb3,C3]] => { A3 => Bb3, C3 => C3 },
|
54
|
+
[[A3,B3,C3],[Gb3,Bb3]] => { A3 => Gb3, B3 => Bb3 },
|
55
|
+
[[D5,Gb5],[B5,E5,G5]] => { D5 => E5, Gb5 => G5 },
|
56
|
+
[[D5,Gb5],[Db5,E5,G5]] => { D5 => Db5, Gb5 => G5 },
|
57
|
+
[[D5,Gb5],[C5,E5,G5]] => { D5 => C5, Gb5 => G5 },
|
58
|
+
[[D5,Gb5],[B5,E5,G5]] => { D5 => E5, Gb5 => G5 },
|
59
|
+
[[D5,Gb5],[B5,E5,F5,G5]] => { D5 => E5, Gb5 => F5 },
|
60
|
+
[[D5,Gb5],[B5,F5,G5]] => { D5 => F5, Gb5 => G5 },
|
61
|
+
[[G5],[B5,F5,G5]] => { G5 => G5 },
|
62
|
+
[[B5,F5,G5],[G5]] => { G5 => G5 },
|
63
|
+
[[G5],[C5,A5,B5]] => { G5 => A5 },
|
64
|
+
[[C4,E4,G4,Bb4],[D4,Gb4,A4,C5]] => { C4 => D4, E4 => Gb4, G4 => A4, Bb4 => C5 }
|
65
|
+
}.each do |unlinked_untargeted, expected_map|
|
66
|
+
unlinked,untargeted = unlinked_untargeted
|
67
|
+
sol = Optimization.linking(unlinked, untargeted)
|
68
|
+
sol.should eq expected_map
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ValueComputer do
|
4
|
+
describe '#value_at' do
|
5
|
+
before :all do
|
6
|
+
@value_change1 = Change::Immediate.new(0.6)
|
7
|
+
@value_change2 = Change::Gradual.new(0.6, 1.0)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "constant value" do
|
11
|
+
before :each do
|
12
|
+
@comp = ValueComputer.new 0.5
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should always return default value if no changes are given" do
|
16
|
+
[ValueComputer.domain_min, -1000, 0, 1, 5, 100, 10000, ValueComputer.domain_max].each do |offset|
|
17
|
+
@comp.value_at(offset).should eq(0.5)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "one change, no transition" do
|
23
|
+
before :each do
|
24
|
+
@comp = ValueComputer.new 0.5, 1.0 => @value_change1
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be the default value just before the first change" do
|
28
|
+
@comp.value_at(0.999).should eq(0.5)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should transition to the second value immediately" do
|
32
|
+
@comp.value_at(1.0).should eq(0.6)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be the first value for all time before" do
|
36
|
+
@comp.value_at(ValueComputer.domain_min).should eq(0.5)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be at the second value for all time after" do
|
40
|
+
@comp.value_at(ValueComputer.domain_max).should eq(0.6)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "one change, linear transition" do
|
45
|
+
before :each do
|
46
|
+
@comp = ValueComputer.new 0.2, 1.0 => @value_change2
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be the first (starting) value just before the second value" do
|
50
|
+
@comp.value_at(0.999).should eq(0.2)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be the first (starting) value exactly at the second value" do
|
54
|
+
@comp.value_at(1.0).should eq(0.2)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be 1/4 to the second value after 1/4 transition duration has elapsed" do
|
58
|
+
@comp.value_at(Rational(5,4).to_f).should eq(0.3)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be 1/2 to the second value after 1/2 transition duration has elapsed" do
|
62
|
+
@comp.value_at(Rational(6,4).to_f).should eq(0.4)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be 3/4 to the second value after 3/4 transition duration has elapsed" do
|
66
|
+
@comp.value_at(Rational(7,4).to_f).should eq(0.5)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be at the second value after transition duration has elapsed" do
|
70
|
+
@comp.value_at(Rational(8,4).to_f).should eq(0.6)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# context "one change, sigmoid transition" do
|
75
|
+
# before :all do
|
76
|
+
# @cases = [
|
77
|
+
# { :start_value => 0, :end_value => 1, :offset => 0, :duration => 1.0, :abruptness => 0.75 },
|
78
|
+
# { :start_value => 0.25, :end_value => 0.75, :offset => 1.0, :duration => 2.0, :abruptness => 0.75 },
|
79
|
+
# { :start_value => -1.0, :end_value => 5.5, :offset => 2.4, :duration => 20, :abruptness => 0.75 },
|
80
|
+
# { :start_value => 10, :end_value => 100, :offset => 20, :duration => 4, :abruptness => 0.75 },
|
81
|
+
# ]
|
82
|
+
#
|
83
|
+
# @computers = {}
|
84
|
+
# @cases.each do |case_hash|
|
85
|
+
# start_value = case_hash[:start_value]
|
86
|
+
# offset = case_hash[:offset]
|
87
|
+
# end_value = case_hash[:end_value]
|
88
|
+
# duration = case_hash[:duration]
|
89
|
+
# #abruptness = case_hash[:abruptness]
|
90
|
+
#
|
91
|
+
# change = Change::Gradual.new(end_value, duration)
|
92
|
+
# @computers[case_hash] = ValueComputer.new start_value, offset => change
|
93
|
+
# # @computers[case_hash].plot_range(offset..(offset + duration), 0.01)
|
94
|
+
# end
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# it "should be the first (starting) value just before the value change offset" do
|
98
|
+
# @computers.each do |case_hash, comp|
|
99
|
+
# comp.value_at(case_hash[:offset] - 0.0001).should eq(case_hash[:start_value])
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# it "should be very nearly the first (starting) value exactly at the value change offset" do
|
104
|
+
# @computers.each do |case_hash, comp|
|
105
|
+
# comp.value_at(case_hash[:offset]).should be_within(0.0001).of(case_hash[:start_value])
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# it "should be within 1% of start/end difference away from the start value after 1/4 transition duration has elapsed" do
|
110
|
+
# @computers.each do |case_hash, comp|
|
111
|
+
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.25)
|
112
|
+
# start_value = case_hash[:start_value]
|
113
|
+
# end_value = case_hash[:end_value]
|
114
|
+
# tolerance = 0.01 * (end_value - start_value)
|
115
|
+
# comp.value_at(test_offset).should be_within(tolerance).of(start_value)
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# it "should be half way to the end value after half way through transition" do
|
120
|
+
# @computers.each do |case_hash, comp|
|
121
|
+
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.5)
|
122
|
+
# start_value = case_hash[:start_value]
|
123
|
+
# expected_value = start_value + (case_hash[:end_value] - start_value) * 0.5
|
124
|
+
# comp.value_at(test_offset).should be_within(0.0001).of(expected_value)
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# it "should be within 1% of start/end difference away from the end value after 3/4 transition duration has elapsed" do
|
129
|
+
# @computers.each do |case_hash, comp|
|
130
|
+
# test_offset = case_hash[:offset] + (case_hash[:duration] * 0.75)
|
131
|
+
# start_value = case_hash[:start_value]
|
132
|
+
# end_value = case_hash[:end_value]
|
133
|
+
# tolerance = 0.01 * (end_value - start_value)
|
134
|
+
# comp.value_at(test_offset).should be_within(tolerance).of(end_value)
|
135
|
+
# end
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# it "should be at the second value after transition duration has elapsed" do
|
139
|
+
# @computers.each do |case_hash, comp|
|
140
|
+
# comp.value_at(case_hash[:offset] + case_hash[:duration]).should eq(case_hash[:end_value])
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
metadata
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: music-performance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Tunnell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubygems-bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.14'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: yard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-nav
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: music-transcription
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.17.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.17.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: midilib
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: docopt
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: |
|
154
|
+
Prepare a transcribed musical score for performance by a computer.
|
155
|
+
email: jamestunnell@gmail.com
|
156
|
+
executables:
|
157
|
+
- midify
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- .document
|
162
|
+
- .gitignore
|
163
|
+
- .rspec
|
164
|
+
- .ruby-version
|
165
|
+
- .yardopts
|
166
|
+
- ChangeLog.rdoc
|
167
|
+
- Gemfile
|
168
|
+
- LICENSE.txt
|
169
|
+
- README.rdoc
|
170
|
+
- Rakefile
|
171
|
+
- bin/midify
|
172
|
+
- lib/music-performance.rb
|
173
|
+
- lib/music-performance/arrangement/midi/midi_events.rb
|
174
|
+
- lib/music-performance/arrangement/midi/midi_util.rb
|
175
|
+
- lib/music-performance/arrangement/midi/part_sequencer.rb
|
176
|
+
- lib/music-performance/arrangement/midi/score_sequencer.rb
|
177
|
+
- lib/music-performance/conversion/glissando_converter.rb
|
178
|
+
- lib/music-performance/conversion/note_sequence_extractor.rb
|
179
|
+
- lib/music-performance/conversion/note_time_converter.rb
|
180
|
+
- lib/music-performance/conversion/portamento_converter.rb
|
181
|
+
- lib/music-performance/conversion/score_collator.rb
|
182
|
+
- lib/music-performance/conversion/score_time_converter.rb
|
183
|
+
- lib/music-performance/model/note_attacks.rb
|
184
|
+
- lib/music-performance/model/note_sequence.rb
|
185
|
+
- lib/music-performance/util/interpolation.rb
|
186
|
+
- lib/music-performance/util/note_linker.rb
|
187
|
+
- lib/music-performance/util/optimization.rb
|
188
|
+
- lib/music-performance/util/piecewise_function.rb
|
189
|
+
- lib/music-performance/util/value_computer.rb
|
190
|
+
- lib/music-performance/version.rb
|
191
|
+
- music-performance.gemspec
|
192
|
+
- spec/conversion/glissando_converter_spec.rb
|
193
|
+
- spec/conversion/note_sequence_extractor_spec.rb
|
194
|
+
- spec/conversion/note_time_converter_spec.rb
|
195
|
+
- spec/conversion/portamento_converter_spec.rb
|
196
|
+
- spec/conversion/score_collator_spec.rb
|
197
|
+
- spec/conversion/score_time_converter_spec.rb
|
198
|
+
- spec/model/note_sequence_spec.rb
|
199
|
+
- spec/music-performance_spec.rb
|
200
|
+
- spec/spec_helper.rb
|
201
|
+
- spec/util/note_linker_spec.rb
|
202
|
+
- spec/util/optimization_spec.rb
|
203
|
+
- spec/util/value_computer_spec.rb
|
204
|
+
homepage: https://github.com/jamestunnell/music-performance
|
205
|
+
licenses:
|
206
|
+
- MIT
|
207
|
+
metadata: {}
|
208
|
+
post_install_message:
|
209
|
+
rdoc_options: []
|
210
|
+
require_paths:
|
211
|
+
- lib
|
212
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
213
|
+
requirements:
|
214
|
+
- - '>='
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0'
|
217
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
requirements: []
|
223
|
+
rubyforge_project:
|
224
|
+
rubygems_version: 2.4.2
|
225
|
+
signing_key:
|
226
|
+
specification_version: 4
|
227
|
+
summary: Classes for representing music notational features like pitch, note, loudness,
|
228
|
+
tempo, etc.
|
229
|
+
test_files:
|
230
|
+
- spec/conversion/glissando_converter_spec.rb
|
231
|
+
- spec/conversion/note_sequence_extractor_spec.rb
|
232
|
+
- spec/conversion/note_time_converter_spec.rb
|
233
|
+
- spec/conversion/portamento_converter_spec.rb
|
234
|
+
- spec/conversion/score_collator_spec.rb
|
235
|
+
- spec/conversion/score_time_converter_spec.rb
|
236
|
+
- spec/model/note_sequence_spec.rb
|
237
|
+
- spec/music-performance_spec.rb
|
238
|
+
- spec/spec_helper.rb
|
239
|
+
- spec/util/note_linker_spec.rb
|
240
|
+
- spec/util/optimization_spec.rb
|
241
|
+
- spec/util/value_computer_spec.rb
|
242
|
+
has_rdoc:
|