musicality 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +45 -2
- data/bin/lilify +83 -0
- data/bin/midify +7 -1
- data/lib/musicality.rb +5 -4
- data/lib/musicality/composition/convenience_methods.rb +53 -0
- data/lib/musicality/composition/dsl/score_dsl.rb +3 -6
- data/lib/musicality/composition/{note_generation.rb → util/note_generation.rb} +0 -15
- data/lib/musicality/notation/model/note.rb +1 -1
- data/lib/musicality/notation/model/score.rb +2 -1
- data/lib/musicality/printing/lilypond/score_engraver.rb +4 -4
- data/lib/musicality/printing/lilypond/score_engraving.rb +12 -0
- data/lib/musicality/version.rb +1 -1
- data/spec/composition/convenience_methods_spec.rb +60 -0
- data/spec/composition/{note_generation_spec.rb → util/note_generation_spec.rb} +1 -1
- data/spec/notation/model/note_spec.rb +1 -1
- data/spec/notation/model/score_spec.rb +32 -0
- metadata +10 -7
- data/lib/musicality/composition/transposition.rb +0 -8
- data/spec/composition/transposition_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b76956290ba2ff351587624b43db12c84fc99a5
|
4
|
+
data.tar.gz: 02460a5a7b390c335ffac5c8050b76bb280fd149
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed2d94a4bd155e24a072481ed45027b362475c68628d41be6cf1e565e08636564fd71375f01936fbb74a7fe13dfcd5bcd22649117b76e5d179ffa83d19031d53
|
7
|
+
data.tar.gz: 05d65518d4f9d8abb5bda61490cdfa18d4458148648b46f6edc4ba518d10caaf6f12c9dea74522cc4615fd650441a0892e43057928d97b358dcdc2eacc6d540a
|
data/README.md
CHANGED
@@ -58,13 +58,56 @@ twinkle = Score::Measured.new(TWO_FOUR, 120) do |s|
|
|
58
58
|
end
|
59
59
|
```
|
60
60
|
|
61
|
-
|
61
|
+
## MIDI Sequencing
|
62
|
+
|
63
|
+
A score can be prepared for MIDI playback using the `ScoreSequencer` class or `#to_midi_seq` method. To continue the previous example,
|
62
64
|
```ruby
|
63
65
|
TEMPO_SAMPLE_RATE = 500
|
64
66
|
seq = twinkle.to_midi_seq TEMPO_SAMPLE_RATE
|
65
67
|
File.open('twinkle.mid', 'wb'){ |fout| seq.write(fout) }
|
66
68
|
```
|
67
|
-
##
|
69
|
+
## Score DSL
|
70
|
+
|
71
|
+
The score DSL is an internal DSL (built on Ruby) that consists of a *score* block with additional blocks inside this to add sections, notes, and tempo/meter/dynamic changes.
|
72
|
+
|
73
|
+
Here is an example of a score file.
|
74
|
+
```ruby
|
75
|
+
measured_score FOUR_FOUR, 120 do
|
76
|
+
title "Twinkle, Twinkle, Little Star"
|
77
|
+
|
78
|
+
Cmaj = [C3,E3,G3]
|
79
|
+
Fmaj = [F2,A2,C3]
|
80
|
+
Gmaj = [G2,B2,D3]
|
81
|
+
section "A" do
|
82
|
+
notes(
|
83
|
+
"rhand" => q(C4,C4,G4,G4,A4,A4) + h(G4) +
|
84
|
+
q(F4,F4,E4,E4,D4,D4) + h(C4),
|
85
|
+
"lhand" => h(Cmaj,Cmaj,Fmaj,Cmaj) +
|
86
|
+
h(Fmaj,Cmaj,Gmaj,Cmaj)
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
section "B" do
|
91
|
+
notes(
|
92
|
+
"rhand" => q(G4,G4,F4,F4,E4,E4) + h(D4),
|
93
|
+
"lhand" => h(Cmaj,Fmaj,Cmaj,Gmaj)
|
94
|
+
)
|
95
|
+
end
|
96
|
+
repeat "B"
|
97
|
+
repeat "A"
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
The above score file is processed by the `ScoreDSL.load` method, as in:
|
102
|
+
```ruby
|
103
|
+
require 'musicality'
|
104
|
+
include Musicality
|
105
|
+
include Meters
|
106
|
+
include Pitches
|
107
|
+
|
108
|
+
dsl = ScoreDSL.load 'twinkle.score'
|
109
|
+
score = dsl.score
|
110
|
+
```
|
68
111
|
|
69
112
|
## Contributing
|
70
113
|
|
data/bin/lilify
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
exe_name = File.basename(__FILE__)
|
4
|
+
|
5
|
+
doc = <<DOCOPT
|
6
|
+
Loads a musicality score from YAML file, and converts it to a Lilypond file for engraving.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
#{exe_name} <input> [PART TITLE] ... [options]
|
10
|
+
#{exe_name} -h | --help
|
11
|
+
#{exe_name} --version
|
12
|
+
|
13
|
+
Arguments:
|
14
|
+
input A musicality score file (may be packed as a hash) in YAML format
|
15
|
+
PART name of a part in the score (e.g. "lhand")
|
16
|
+
TITLE The title to give the part (e.g. "Left Hand")
|
17
|
+
|
18
|
+
Options:
|
19
|
+
--all Select all parts for engraving, and use part name as the title if not given
|
20
|
+
-h --help Show this screen.
|
21
|
+
--version Show version.
|
22
|
+
--outfile=OUTF Name of output Lilypond file
|
23
|
+
|
24
|
+
DOCOPT
|
25
|
+
|
26
|
+
require 'docopt'
|
27
|
+
begin
|
28
|
+
args = Docopt::docopt(doc)
|
29
|
+
puts args
|
30
|
+
rescue Docopt::Exit => e
|
31
|
+
puts e.message
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'musicality'
|
36
|
+
|
37
|
+
if args["--version"]
|
38
|
+
puts "#{exe_name} from musicality v#{Musicality::VERSION}"
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
require 'yaml'
|
43
|
+
include Musicality
|
44
|
+
|
45
|
+
fin_name = args["<input>"]
|
46
|
+
File.open(fin_name) do |fin|
|
47
|
+
print "Reading file '#{fin_name}'..."
|
48
|
+
score = YAML.load(fin.read)
|
49
|
+
|
50
|
+
if score.is_a? Hash
|
51
|
+
score = Score.unpack(score)
|
52
|
+
end
|
53
|
+
puts "done"
|
54
|
+
|
55
|
+
if score.valid?
|
56
|
+
part_names = args["PART"]
|
57
|
+
part_titles = args["TITLE"]
|
58
|
+
name_title_map =
|
59
|
+
|
60
|
+
make_lilypond_args = {
|
61
|
+
:part_titles => Hash[[part_names,part_titles].transpose]
|
62
|
+
}
|
63
|
+
unless args["--all"]
|
64
|
+
make_lilypond_args[:selected_parts] = part_names
|
65
|
+
end
|
66
|
+
|
67
|
+
print "Making Lilypond instructions..."
|
68
|
+
engraver = ScoreEngraver.new(score)
|
69
|
+
lilypond_text = engraver.make_lilypond(make_lilypond_args)
|
70
|
+
puts "done"
|
71
|
+
|
72
|
+
fout_name = args["--outfile"]
|
73
|
+
if fout_name.nil?
|
74
|
+
fout_name = "#{File.dirname(fin_name)}/#{File.basename(fin_name,File.extname(fin_name))}.ly"
|
75
|
+
end
|
76
|
+
print "Writing Lilypond file '#{fout_name}'..."
|
77
|
+
File.write(fout_name, lilypond_text)
|
78
|
+
puts "done"
|
79
|
+
else
|
80
|
+
puts "Score is not valid. See errors:"
|
81
|
+
puts score.errors.join("\n")
|
82
|
+
end
|
83
|
+
end
|
data/bin/midify
CHANGED
@@ -33,8 +33,14 @@ rescue Docopt::Exit => e
|
|
33
33
|
exit
|
34
34
|
end
|
35
35
|
|
36
|
-
require 'yaml'
|
37
36
|
require 'musicality'
|
37
|
+
|
38
|
+
if args["--version"]
|
39
|
+
puts "#{exe_name} in musicality v#{Musicality::VERSION}"
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
require 'yaml'
|
38
44
|
include Musicality
|
39
45
|
|
40
46
|
fin_name = args["<input>"]
|
data/lib/musicality.rb
CHANGED
@@ -69,6 +69,7 @@ require 'musicality/composition/util/adding_sequence'
|
|
69
69
|
require 'musicality/composition/util/compound_sequence'
|
70
70
|
require 'musicality/composition/util/random_sampler'
|
71
71
|
require 'musicality/composition/util/probabilities'
|
72
|
+
require 'musicality/composition/util/note_generation'
|
72
73
|
|
73
74
|
require 'musicality/composition/model/pitch_class'
|
74
75
|
require 'musicality/composition/model/pitch_classes'
|
@@ -76,15 +77,14 @@ require 'musicality/composition/model/scale'
|
|
76
77
|
require 'musicality/composition/model/scale_class'
|
77
78
|
require 'musicality/composition/model/scale_classes'
|
78
79
|
|
79
|
-
require 'musicality/composition/note_generation'
|
80
|
-
require 'musicality/composition/transposition'
|
81
|
-
|
82
80
|
require 'musicality/composition/generation/counterpoint_generator'
|
83
81
|
require 'musicality/composition/generation/random_rhythm_generator'
|
84
82
|
|
85
83
|
require 'musicality/composition/dsl/score_methods'
|
86
84
|
require 'musicality/composition/dsl/score_dsl'
|
87
85
|
|
86
|
+
require 'musicality/composition/convenience_methods'
|
87
|
+
|
88
88
|
#
|
89
89
|
# Performance
|
90
90
|
#
|
@@ -115,4 +115,5 @@ require 'musicality/printing/lilypond/errors'
|
|
115
115
|
require 'musicality/printing/lilypond/pitch_engraving'
|
116
116
|
require 'musicality/printing/lilypond/note_engraving'
|
117
117
|
require 'musicality/printing/lilypond/meter_engraving'
|
118
|
-
require 'musicality/printing/lilypond/score_engraver'
|
118
|
+
require 'musicality/printing/lilypond/score_engraver'
|
119
|
+
require 'musicality/printing/lilypond/score_engraving'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Musicality
|
2
|
+
|
3
|
+
def transpose notes, diff
|
4
|
+
notes.map {|n| n.transpose(diff) }
|
5
|
+
end
|
6
|
+
module_function :transpose
|
7
|
+
|
8
|
+
def s(*pitch_groups)
|
9
|
+
pitch_groups.map {|pg| Note.sixteenth(pg) }
|
10
|
+
end
|
11
|
+
module_function :s
|
12
|
+
|
13
|
+
def ds(*pitch_groups)
|
14
|
+
pitch_groups.map {|pg| Note.dotted_sixteenth(pg) }
|
15
|
+
end
|
16
|
+
module_function :ds
|
17
|
+
|
18
|
+
def e(*pitch_groups)
|
19
|
+
pitch_groups.map {|pg| Note.eighth(pg) }
|
20
|
+
end
|
21
|
+
module_function :e
|
22
|
+
|
23
|
+
def de(*pitch_groups)
|
24
|
+
pitch_groups.map {|pg| Note.dotted_eighth(pg) }
|
25
|
+
end
|
26
|
+
module_function :e
|
27
|
+
|
28
|
+
def q(*pitch_groups)
|
29
|
+
pitch_groups.map {|pg| Note.quarter(pg) }
|
30
|
+
end
|
31
|
+
module_function :q
|
32
|
+
|
33
|
+
def dq(*pitch_groups)
|
34
|
+
pitch_groups.map {|pg| Note.dotted_quarter(pg) }
|
35
|
+
end
|
36
|
+
module_function :dq
|
37
|
+
|
38
|
+
def h(*pitch_groups)
|
39
|
+
pitch_groups.map {|pg| Note.half(pg) }
|
40
|
+
end
|
41
|
+
module_function :h
|
42
|
+
|
43
|
+
def dh(*pitch_groups)
|
44
|
+
pitch_groups.map {|pg| Note.dotted_half(pg) }
|
45
|
+
end
|
46
|
+
module_function :dh
|
47
|
+
|
48
|
+
def w(*pitch_groups)
|
49
|
+
pitch_groups.map {|pg| Note.whole(pg) }
|
50
|
+
end
|
51
|
+
module_function :w
|
52
|
+
|
53
|
+
end
|
@@ -1,24 +1,21 @@
|
|
1
1
|
module Musicality
|
2
2
|
|
3
|
-
class ScoreDSL
|
3
|
+
class ScoreDSL
|
4
4
|
def self.load fname
|
5
5
|
dsl = ScoreDSL.new
|
6
6
|
dsl.instance_eval(File.read(fname), fname)
|
7
7
|
dsl
|
8
8
|
end
|
9
9
|
|
10
|
+
attr_reader :score
|
10
11
|
def initialize
|
11
12
|
@score = nil
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
+
def measured_score start_meter, start_tempo, &block
|
15
16
|
@score = Score::Measured.new(start_meter,start_tempo)
|
16
17
|
@score.instance_eval(&block)
|
17
18
|
end
|
18
|
-
|
19
|
-
def score_yaml
|
20
|
-
@score.pack.to_yaml
|
21
|
-
end
|
22
19
|
end
|
23
20
|
|
24
21
|
end
|
@@ -28,19 +28,4 @@ def make_notes rhythm, pitch_groups
|
|
28
28
|
end
|
29
29
|
module_function :make_notes
|
30
30
|
|
31
|
-
def e(pitch_groups)
|
32
|
-
pitch_groups.map {|pg| Note.eighth(pg) }
|
33
|
-
end
|
34
|
-
module_function :e
|
35
|
-
|
36
|
-
def q(pitch_groups)
|
37
|
-
pitch_groups.map {|pg| Note.quarter(pg) }
|
38
|
-
end
|
39
|
-
module_function :q
|
40
|
-
|
41
|
-
def dq(pitch_groups)
|
42
|
-
pitch_groups.map {|pg| Note.dotted_quarter(pg) }
|
43
|
-
end
|
44
|
-
module_function :dq
|
45
|
-
|
46
31
|
end
|
@@ -44,7 +44,7 @@ class ScoreEngraver
|
|
44
44
|
output += " \\time #{@start_meter.to_lilypond}\n"
|
45
45
|
end
|
46
46
|
|
47
|
-
line = ""
|
47
|
+
line = " "
|
48
48
|
part.notes.each_index do |i|
|
49
49
|
note = part.notes[i]
|
50
50
|
begin
|
@@ -54,12 +54,12 @@ class ScoreEngraver
|
|
54
54
|
end
|
55
55
|
|
56
56
|
if (line.size + str.size) > MAX_LINE_LEN
|
57
|
-
output +=
|
58
|
-
line = ""
|
57
|
+
output += line + "\n"
|
58
|
+
line = " "
|
59
59
|
end
|
60
60
|
line += str
|
61
61
|
end
|
62
|
-
output +=
|
62
|
+
output += line + "\n"
|
63
63
|
|
64
64
|
output += " }\n"
|
65
65
|
end
|
data/lib/musicality/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe 'transpose' do
|
4
|
+
it 'should map given notes to new notes, transposing by given diff' do
|
5
|
+
notes = "/4A2,C2 /4D2,F2,Gb2 /8 /8E4".to_notes
|
6
|
+
semitones = 3
|
7
|
+
notes2 = transpose(notes,semitones)
|
8
|
+
|
9
|
+
notes2.size.should eq(notes.size)
|
10
|
+
notes2.each_index do |i|
|
11
|
+
notes2[i].pitches.each_with_index do |pitch2,j|
|
12
|
+
pitch = notes[i].pitches[j]
|
13
|
+
pitch2.diff(pitch).should eq(semitones)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
{
|
20
|
+
:s => "1/16".to_r,
|
21
|
+
:ds => "3/32".to_r,
|
22
|
+
:e => "1/8".to_r,
|
23
|
+
:de => "3/16".to_r,
|
24
|
+
:q => "1/4".to_r,
|
25
|
+
:dq => "3/8".to_r,
|
26
|
+
:h => "1/2".to_r,
|
27
|
+
:dh => "3/4".to_r,
|
28
|
+
:w => '1'.to_r
|
29
|
+
}.each do |method,dur|
|
30
|
+
describe method do
|
31
|
+
context 'given no args' do
|
32
|
+
it 'should produce an empty array' do
|
33
|
+
send(method).should eq([])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'given one pitch' do
|
38
|
+
it 'should produce an array with one note, with proper duration' do
|
39
|
+
send(method,*[C2]).should eq([Note.new(dur,C2)])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'given one pitch group' do
|
44
|
+
it 'should produce an array with one note, given pitch group, and with proper duration' do
|
45
|
+
send(method,*[[C2,E2,G2]]).should eq([Note.new(dur,[C2,E2,G2])])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'given many pitch groups' do
|
50
|
+
it 'should produce an array of notes with same pitch groups, and with proper duration' do
|
51
|
+
pg1 = A3
|
52
|
+
pg2 = [B3,G3]
|
53
|
+
pg3 = F4
|
54
|
+
send(method,*[pg1,pg2,pg3]).should eq([
|
55
|
+
Note.new(dur,pg1), Note.new(dur,pg2), Note.new(dur,pg3)
|
56
|
+
])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,6 +1,38 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
3
|
describe Score do
|
4
|
+
describe '#title' do
|
5
|
+
context 'given no arg' do
|
6
|
+
it 'should return the title' do
|
7
|
+
Score.new(:title => "MyTitle").title.should eq("MyTitle")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'given an arg' do
|
12
|
+
it 'should assign the given value to title' do
|
13
|
+
score = Score.new(:title => "MyTitle")
|
14
|
+
score.title("A Better Title")
|
15
|
+
score.title.should eq("A Better Title")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#composer' do
|
21
|
+
context 'given no arg' do
|
22
|
+
it 'should return the composer' do
|
23
|
+
Score.new(:composer => "Beethoven").composer.should eq("Beethoven")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'given an arg' do
|
28
|
+
it 'should assign the given value to composer' do
|
29
|
+
score = Score.new(:composer => "Beethoven")
|
30
|
+
score.composer("Mozart")
|
31
|
+
score.composer.should eq("Mozart")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
4
36
|
describe '#collated?' do
|
5
37
|
context 'has program with more than one segment' do
|
6
38
|
it 'should return false' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musicality
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Tunnell
|
@@ -116,6 +116,7 @@ description: "The library is based around an abstract representation for music n
|
|
116
116
|
email:
|
117
117
|
- jamestunnell@gmail.com
|
118
118
|
executables:
|
119
|
+
- lilify
|
119
120
|
- midify
|
120
121
|
extensions: []
|
121
122
|
extra_rdoc_files: []
|
@@ -128,6 +129,7 @@ files:
|
|
128
129
|
- LICENSE.txt
|
129
130
|
- README.md
|
130
131
|
- Rakefile
|
132
|
+
- bin/lilify
|
131
133
|
- bin/midify
|
132
134
|
- examples/composition/auto_counterpoint.rb
|
133
135
|
- examples/composition/part_generator.rb
|
@@ -137,6 +139,7 @@ files:
|
|
137
139
|
- examples/notation/song1.rb
|
138
140
|
- examples/notation/song2.rb
|
139
141
|
- lib/musicality.rb
|
142
|
+
- lib/musicality/composition/convenience_methods.rb
|
140
143
|
- lib/musicality/composition/dsl/score_dsl.rb
|
141
144
|
- lib/musicality/composition/dsl/score_methods.rb
|
142
145
|
- lib/musicality/composition/generation/counterpoint_generator.rb
|
@@ -146,11 +149,10 @@ files:
|
|
146
149
|
- lib/musicality/composition/model/scale.rb
|
147
150
|
- lib/musicality/composition/model/scale_class.rb
|
148
151
|
- lib/musicality/composition/model/scale_classes.rb
|
149
|
-
- lib/musicality/composition/note_generation.rb
|
150
|
-
- lib/musicality/composition/transposition.rb
|
151
152
|
- lib/musicality/composition/util/adding_sequence.rb
|
152
153
|
- lib/musicality/composition/util/biinfinite_sequence.rb
|
153
154
|
- lib/musicality/composition/util/compound_sequence.rb
|
155
|
+
- lib/musicality/composition/util/note_generation.rb
|
154
156
|
- lib/musicality/composition/util/probabilities.rb
|
155
157
|
- lib/musicality/composition/util/random_sampler.rb
|
156
158
|
- lib/musicality/composition/util/repeating_sequence.rb
|
@@ -233,18 +235,19 @@ files:
|
|
233
235
|
- lib/musicality/printing/lilypond/part_engraver.rb
|
234
236
|
- lib/musicality/printing/lilypond/pitch_engraving.rb
|
235
237
|
- lib/musicality/printing/lilypond/score_engraver.rb
|
238
|
+
- lib/musicality/printing/lilypond/score_engraving.rb
|
236
239
|
- lib/musicality/validatable.rb
|
237
240
|
- lib/musicality/version.rb
|
238
241
|
- musicality.gemspec
|
242
|
+
- spec/composition/convenience_methods_spec.rb
|
239
243
|
- spec/composition/generation/random_rhythm_generator_spec.rb
|
240
244
|
- spec/composition/model/pitch_class_spec.rb
|
241
245
|
- spec/composition/model/pitch_classes_spec.rb
|
242
246
|
- spec/composition/model/scale_class_spec.rb
|
243
247
|
- spec/composition/model/scale_spec.rb
|
244
|
-
- spec/composition/note_generation_spec.rb
|
245
|
-
- spec/composition/transposition_spec.rb
|
246
248
|
- spec/composition/util/adding_sequence_spec.rb
|
247
249
|
- spec/composition/util/compound_sequence_spec.rb
|
250
|
+
- spec/composition/util/note_generation_spec.rb
|
248
251
|
- spec/composition/util/probabilities_spec.rb
|
249
252
|
- spec/composition/util/random_sampler_spec.rb
|
250
253
|
- spec/composition/util/repeating_sequence_spec.rb
|
@@ -323,15 +326,15 @@ signing_key:
|
|
323
326
|
specification_version: 4
|
324
327
|
summary: Music notation, composition, and performance
|
325
328
|
test_files:
|
329
|
+
- spec/composition/convenience_methods_spec.rb
|
326
330
|
- spec/composition/generation/random_rhythm_generator_spec.rb
|
327
331
|
- spec/composition/model/pitch_class_spec.rb
|
328
332
|
- spec/composition/model/pitch_classes_spec.rb
|
329
333
|
- spec/composition/model/scale_class_spec.rb
|
330
334
|
- spec/composition/model/scale_spec.rb
|
331
|
-
- spec/composition/note_generation_spec.rb
|
332
|
-
- spec/composition/transposition_spec.rb
|
333
335
|
- spec/composition/util/adding_sequence_spec.rb
|
334
336
|
- spec/composition/util/compound_sequence_spec.rb
|
337
|
+
- spec/composition/util/note_generation_spec.rb
|
335
338
|
- spec/composition/util/probabilities_spec.rb
|
336
339
|
- spec/composition/util/random_sampler_spec.rb
|
337
340
|
- spec/composition/util/repeating_sequence_spec.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe 'transpose' do
|
4
|
-
it 'should map given notes to new notes, transposing by given diff' do
|
5
|
-
notes = "/4A2,C2 /4D2,F2,Gb2 /8 /8E4".to_notes
|
6
|
-
semitones = 3
|
7
|
-
notes2 = transpose(notes,semitones)
|
8
|
-
|
9
|
-
notes2.size.should eq(notes.size)
|
10
|
-
notes2.each_index do |i|
|
11
|
-
notes2[i].pitches.each_with_index do |pitch2,j|
|
12
|
-
pitch = notes[i].pitches[j]
|
13
|
-
pitch2.diff(pitch).should eq(semitones)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|