mtk 0.0.2 → 0.0.3
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/.yardopts +3 -2
- data/DEVELOPMENT_NOTES.md +114 -0
- data/INTRO.md +64 -8
- data/LICENSE.txt +1 -1
- data/README.md +31 -102
- data/Rakefile +56 -18
- data/bin/mtk +215 -0
- data/examples/crescendo.rb +5 -5
- data/examples/drum_pattern1.rb +23 -0
- data/examples/dynamic_pattern.rb +8 -11
- data/examples/gets_and_play.rb +26 -0
- data/examples/notation.rb +22 -0
- data/examples/play_midi.rb +8 -10
- data/examples/random_tone_row.rb +2 -2
- data/examples/syntax_to_midi.rb +28 -0
- data/examples/test_output.rb +8 -0
- data/examples/tone_row_melody.rb +6 -6
- data/lib/mtk.rb +52 -40
- data/lib/mtk/chord.rb +55 -0
- data/lib/mtk/constants/durations.rb +57 -0
- data/lib/mtk/constants/intensities.rb +61 -0
- data/lib/mtk/constants/intervals.rb +73 -0
- data/lib/mtk/constants/pitch_classes.rb +29 -0
- data/lib/mtk/constants/pitches.rb +52 -0
- data/lib/mtk/duration.rb +211 -0
- data/lib/mtk/events/event.rb +119 -0
- data/lib/mtk/events/note.rb +112 -0
- data/lib/mtk/events/parameter.rb +54 -0
- data/lib/mtk/helpers/collection.rb +164 -0
- data/lib/mtk/helpers/convert.rb +36 -0
- data/lib/mtk/helpers/lilypond.rb +162 -0
- data/lib/mtk/helpers/output_selector.rb +67 -0
- data/lib/mtk/helpers/pitch_collection.rb +23 -0
- data/lib/mtk/helpers/pseudo_constants.rb +26 -0
- data/lib/mtk/intensity.rb +156 -0
- data/lib/mtk/interval.rb +155 -0
- data/lib/mtk/lang/mtk_grammar.citrus +190 -13
- data/lib/mtk/lang/parser.rb +29 -0
- data/lib/mtk/melody.rb +94 -0
- data/lib/mtk/midi/dls_synth_device.rb +144 -0
- data/lib/mtk/midi/dls_synth_output.rb +62 -0
- data/lib/mtk/midi/file.rb +67 -32
- data/lib/mtk/midi/input.rb +97 -0
- data/lib/mtk/midi/jsound_input.rb +36 -17
- data/lib/mtk/midi/jsound_output.rb +48 -46
- data/lib/mtk/midi/output.rb +195 -0
- data/lib/mtk/midi/unimidi_input.rb +117 -0
- data/lib/mtk/midi/unimidi_output.rb +121 -0
- data/lib/mtk/{_numeric_extensions.rb → numeric_extensions.rb} +12 -0
- data/lib/mtk/patterns/chain.rb +49 -0
- data/lib/mtk/{pattern → patterns}/choice.rb +14 -8
- data/lib/mtk/patterns/cycle.rb +18 -0
- data/lib/mtk/patterns/for_each.rb +71 -0
- data/lib/mtk/patterns/function.rb +39 -0
- data/lib/mtk/{pattern → patterns}/lines.rb +11 -17
- data/lib/mtk/{pattern → patterns}/palindrome.rb +11 -8
- data/lib/mtk/patterns/pattern.rb +171 -0
- data/lib/mtk/patterns/sequence.rb +20 -0
- data/lib/mtk/pitch.rb +7 -6
- data/lib/mtk/pitch_class.rb +124 -46
- data/lib/mtk/pitch_class_set.rb +58 -35
- data/lib/mtk/sequencers/event_builder.rb +131 -0
- data/lib/mtk/sequencers/legato_sequencer.rb +24 -0
- data/lib/mtk/sequencers/rhythmic_sequencer.rb +28 -0
- data/lib/mtk/{sequencer/abstract_sequencer.rb → sequencers/sequencer.rb} +37 -11
- data/lib/mtk/{sequencer → sequencers}/step_sequencer.rb +4 -4
- data/lib/mtk/timeline.rb +39 -22
- data/lib/mtk/variable.rb +32 -0
- data/spec/mtk/chord_spec.rb +83 -0
- data/spec/mtk/{_constants → constants}/durations_spec.rb +12 -41
- data/spec/mtk/{_constants → constants}/intensities_spec.rb +13 -37
- data/spec/mtk/{_constants → constants}/intervals_spec.rb +14 -32
- data/spec/mtk/{_constants → constants}/pitch_classes_spec.rb +8 -4
- data/spec/mtk/{_constants → constants}/pitches_spec.rb +5 -1
- data/spec/mtk/duration_spec.rb +372 -0
- data/spec/mtk/events/event_spec.rb +234 -0
- data/spec/mtk/events/note_spec.rb +174 -0
- data/spec/mtk/events/parameter_spec.rb +220 -0
- data/spec/mtk/{helper → helpers}/collection_spec.rb +86 -3
- data/spec/mtk/{helper → helpers}/pseudo_constants_spec.rb +2 -2
- data/spec/mtk/intensity_spec.rb +289 -0
- data/spec/mtk/interval_spec.rb +265 -0
- data/spec/mtk/lang/parser_spec.rb +597 -0
- data/spec/mtk/melody_spec.rb +223 -0
- data/spec/mtk/midi/file_spec.rb +16 -16
- data/spec/mtk/midi/jsound_input_spec.rb +11 -0
- data/spec/mtk/midi/jsound_output_spec.rb +11 -0
- data/spec/mtk/midi/output_spec.rb +102 -0
- data/spec/mtk/midi/unimidi_input_spec.rb +11 -0
- data/spec/mtk/midi/unimidi_output_spec.rb +11 -0
- data/spec/mtk/{_numeric_extensions_spec.rb → numeric_extensions_spec.rb} +1 -0
- data/spec/mtk/patterns/chain_spec.rb +110 -0
- data/spec/mtk/{pattern → patterns}/choice_spec.rb +20 -30
- data/spec/mtk/{pattern → patterns}/cycle_spec.rb +25 -35
- data/spec/mtk/patterns/for_each_spec.rb +136 -0
- data/spec/mtk/{pattern → patterns}/function_spec.rb +17 -30
- data/spec/mtk/{pattern → patterns}/lines_spec.rb +11 -27
- data/spec/mtk/{pattern → patterns}/palindrome_spec.rb +13 -29
- data/spec/mtk/patterns/pattern_spec.rb +132 -0
- data/spec/mtk/patterns/sequence_spec.rb +203 -0
- data/spec/mtk/pitch_class_set_spec.rb +23 -21
- data/spec/mtk/pitch_class_spec.rb +151 -39
- data/spec/mtk/pitch_spec.rb +22 -1
- data/spec/mtk/sequencers/event_builder_spec.rb +245 -0
- data/spec/mtk/sequencers/legato_sequencer_spec.rb +45 -0
- data/spec/mtk/sequencers/rhythmic_sequencer_spec.rb +84 -0
- data/spec/mtk/sequencers/sequencer_spec.rb +215 -0
- data/spec/mtk/{sequencer → sequencers}/step_sequencer_spec.rb +35 -13
- data/spec/mtk/timeline_spec.rb +109 -16
- data/spec/mtk/variable_spec.rb +52 -0
- data/spec/spec_coverage.rb +2 -0
- data/spec/spec_helper.rb +3 -0
- metadata +188 -91
- data/lib/mtk/_constants/durations.rb +0 -80
- data/lib/mtk/_constants/intensities.rb +0 -81
- data/lib/mtk/_constants/intervals.rb +0 -85
- data/lib/mtk/_constants/pitch_classes.rb +0 -35
- data/lib/mtk/_constants/pitches.rb +0 -49
- data/lib/mtk/event.rb +0 -70
- data/lib/mtk/helper/collection.rb +0 -114
- data/lib/mtk/helper/event_builder.rb +0 -85
- data/lib/mtk/helper/pseudo_constants.rb +0 -26
- data/lib/mtk/lang/grammar.rb +0 -17
- data/lib/mtk/note.rb +0 -63
- data/lib/mtk/pattern/abstract_pattern.rb +0 -132
- data/lib/mtk/pattern/cycle.rb +0 -51
- data/lib/mtk/pattern/enumerator.rb +0 -26
- data/lib/mtk/pattern/function.rb +0 -46
- data/lib/mtk/pattern/sequence.rb +0 -30
- data/lib/mtk/pitch_set.rb +0 -84
- data/lib/mtk/sequencer/rhythmic_sequencer.rb +0 -29
- data/lib/mtk/transform/invertible.rb +0 -15
- data/lib/mtk/transform/mappable.rb +0 -18
- data/lib/mtk/transform/set_theory_operations.rb +0 -34
- data/lib/mtk/transform/transposable.rb +0 -14
- data/spec/mtk/event_spec.rb +0 -139
- data/spec/mtk/helper/event_builder_spec.rb +0 -92
- data/spec/mtk/lang/grammar_spec.rb +0 -100
- data/spec/mtk/note_spec.rb +0 -115
- data/spec/mtk/pattern/abstract_pattern_spec.rb +0 -45
- data/spec/mtk/pattern/note_cycle_spec.rb.bak +0 -116
- data/spec/mtk/pattern/pitch_cycle_spec.rb.bak +0 -47
- data/spec/mtk/pattern/pitch_sequence_spec.rb.bak +0 -37
- data/spec/mtk/pattern/sequence_spec.rb +0 -151
- data/spec/mtk/pitch_set_spec.rb +0 -198
- data/spec/mtk/sequencer/abstract_sequencer_spec.rb +0 -159
- data/spec/mtk/sequencer/rhythmic_sequencer_spec.rb +0 -49
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'mtk/lang/grammar'
|
3
|
-
|
4
|
-
describe MTK::Lang::Grammar do
|
5
|
-
|
6
|
-
def parse syntax, root
|
7
|
-
MTK::Lang::Grammar.parse(syntax, root)
|
8
|
-
end
|
9
|
-
|
10
|
-
describe ".parse" do
|
11
|
-
|
12
|
-
it "should parse pitch sequences" do
|
13
|
-
parse("C4 D4 E4", :pitch_sequence).should == Pattern.PitchSequence(C4, D4, E4)
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should parse pitches" do
|
17
|
-
for pitch_class_name in PitchClass::VALID_NAMES
|
18
|
-
for octave in -1..9
|
19
|
-
parse("#{pitch_class_name}#{octave}", :pitch).should == Pitch[PitchClass[pitch_class_name],octave]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should parse pitch classes" do
|
25
|
-
for pitch_class_name in PitchClass::VALID_NAMES
|
26
|
-
parse(pitch_class_name, :pitch_class).should == PitchClass[pitch_class_name]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should parse intervals" do
|
31
|
-
for interval_name in Intervals::INTERVAL_NAMES
|
32
|
-
parse(interval_name, :interval).should == Intervals[interval_name]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should parse intensities" do
|
37
|
-
for intensity_name in Intensities::INTENSITY_NAMES
|
38
|
-
parse(intensity_name, :intensity).should == Intensities[intensity_name]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should parse intensities with + and - modifiers" do
|
43
|
-
for intensity_name in Intensities::INTENSITY_NAMES
|
44
|
-
name = "#{intensity_name}+"
|
45
|
-
parse(name, :intensity).should == Intensities[name]
|
46
|
-
name = "#{intensity_name}-"
|
47
|
-
parse(name, :intensity).should == Intensities[name]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should parse durations" do
|
52
|
-
for duration in Durations::DURATION_NAMES
|
53
|
-
parse(duration, :duration).should == Durations[duration]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should parse durations with . and t modifiers" do
|
58
|
-
for duration in Durations::DURATION_NAMES
|
59
|
-
name = "#{duration}."
|
60
|
-
parse(name, :duration).should == Durations[name]
|
61
|
-
name = "#{duration}t"
|
62
|
-
parse(name, :duration).should == Durations[name]
|
63
|
-
name = "#{duration}..t.t"
|
64
|
-
parse(name, :duration).should == Durations[name]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should parse ints as numbers" do
|
69
|
-
parse("123", :number).should == 123
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should parse floats as numbers" do
|
73
|
-
parse("1.23", :number).should == 1.23
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should parse floats" do
|
77
|
-
parse("1.23", :float).should == 1.23
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should parse negative floats" do
|
81
|
-
parse("-1.23", :float).should == -1.23
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should parse ints" do
|
85
|
-
parse("123", :int).should == 123
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should parse negative ints" do
|
89
|
-
parse("-123", :int).should == -123
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should parse negative ints" do
|
93
|
-
parse("-123", :int).should == -123
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should give nil as the value for whitespace" do
|
97
|
-
parse(" \t\n", :space).should == nil
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/spec/mtk/note_spec.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MTK::Note do
|
4
|
-
|
5
|
-
let(:pitch) { C4 }
|
6
|
-
let(:intensity) { mf }
|
7
|
-
let(:duration) { 2.5 }
|
8
|
-
let(:note) { Note.new(pitch, intensity, duration) }
|
9
|
-
|
10
|
-
describe "#pitch" do
|
11
|
-
it "is the pitch used to create the Note" do
|
12
|
-
note.pitch.should == pitch
|
13
|
-
end
|
14
|
-
|
15
|
-
it "is a read-only attribute" do
|
16
|
-
lambda{ note.pitch = D4 }.should raise_error
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe ".from_hash" do
|
21
|
-
it "constructs a Note using a hash" do
|
22
|
-
Note.from_hash({ :pitch => C4, :intensity => intensity, :duration => duration }).should == note
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '.from_midi' do
|
27
|
-
it "constructs a Note using a MIDI pitch and velocity" do
|
28
|
-
Note.from_midi(C4.to_i, mf*127, 2.5).should == note
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "#to_midi" do
|
33
|
-
it "converts the Note to an Array of MIDI values: [pitch, velocity, duration]" do
|
34
|
-
note.to_midi.should == [60, (mf*127).round, duration]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "#to_hash" do
|
39
|
-
it "is a hash containing all the attributes of the Note" do
|
40
|
-
note.to_hash.should == { :pitch => pitch, :intensity => intensity, :duration => duration }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe '#transpose' do
|
45
|
-
it 'adds the given interval to the @pitch' do
|
46
|
-
(note.transpose 2.semitones).should == Note.new(D4, intensity, duration)
|
47
|
-
end
|
48
|
-
it 'does not affect the immutability of the Note' do
|
49
|
-
(note.transpose 2.semitones).should_not == note
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#invert" do
|
54
|
-
context 'higher center pitch' do
|
55
|
-
it 'inverts the pitch around the given center pitch' do
|
56
|
-
note.invert(Pitch 66).should == Note.new(Pitch(72), intensity, duration)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'lower center pitch' do
|
61
|
-
it 'inverts the pitch around the given center pitch' do
|
62
|
-
note.invert(Pitch 54).should == Note.new(Pitch(48), intensity, duration)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "returns the an equal note when given it's pitch as an argument" do
|
67
|
-
note.invert(note.pitch).should == note
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "#==" do
|
72
|
-
it "is true when the pitches, intensities, and durations are equal" do
|
73
|
-
note.should == Note.new(pitch, intensity, duration)
|
74
|
-
end
|
75
|
-
|
76
|
-
it "is false when the pitches are not equal" do
|
77
|
-
note.should_not == Note.new(pitch + 1, intensity, duration)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "is false when the intensities are not equal" do
|
81
|
-
note.should_not == Note.new(pitch, intensity * 0.5, duration)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "is false when the durations are not equal" do
|
85
|
-
note.should_not == Note.new(pitch, intensity, duration * 2)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
describe MTK do
|
92
|
-
|
93
|
-
describe '#Note' do
|
94
|
-
|
95
|
-
it "acts like new for multiple arguments" do
|
96
|
-
Note(C4,mf,1).should == Note.new(C4,mf,1)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "acts like new for an Array of arguments by unpacking (splatting) them" do
|
100
|
-
Note([C4,mf,1]).should == Note.new(C4,mf,1)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "returns the argument if it's already a Note" do
|
104
|
-
note = Note.new(C4,mf,1)
|
105
|
-
Note(note).should be_equal note
|
106
|
-
end
|
107
|
-
|
108
|
-
it "raises an error for types it doesn't understand" do
|
109
|
-
lambda{ Note({:not => :compatible}) }.should raise_error
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MTK::Pattern::AbstractPattern do
|
4
|
-
|
5
|
-
PATTERN = MTK::Pattern::AbstractPattern
|
6
|
-
|
7
|
-
let(:elements) { [1,2,3] }
|
8
|
-
|
9
|
-
describe "#type" do
|
10
|
-
it "is the :type value from the constuctor's options hash" do
|
11
|
-
PATTERN.new([], :type => :my_type).type.should == :my_type
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#max_elements" do
|
16
|
-
it "is the :max_elements option the pattern was constructed with" do
|
17
|
-
PATTERN.new([], :max_elements => 1).max_elements.should == 1
|
18
|
-
end
|
19
|
-
|
20
|
-
it "is nil by default" do
|
21
|
-
PATTERN.new([]).max_elements.should be_nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it "causes a StopIteration exception after the number of elements have been emitted" do
|
25
|
-
cycle = PATTERN.new([:anything], :max_elements => 5)
|
26
|
-
5.times { cycle.next }
|
27
|
-
lambda { cycle.next }.should raise_error
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "#==" do
|
32
|
-
it "is true if the elements and types are equal" do
|
33
|
-
PATTERN.new(elements, :type => :some_type).should == PATTERN.new(elements, :type => :some_type)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "is false if the elements are not equal" do
|
37
|
-
PATTERN.new(elements, :type => :some_type).should_not == PATTERN.new(elements + [4], :type => :some_type)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "is false if the types are not equal" do
|
41
|
-
PATTERN.new(elements, :type => :some_type).should_not == PATTERN.new(elements, :type => :another_type)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MTK::Pattern::NoteCycle do
|
4
|
-
|
5
|
-
def note(pitch, intensity=mf, duration=1)
|
6
|
-
Note(pitch, intensity, duration)
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "#new" do
|
10
|
-
it "allows default pitch to be specified" do
|
11
|
-
cycle = Pattern::NoteCycle.new [], [p], [1], :pitch => Gb4
|
12
|
-
cycle.next.should == Note(Gb4, p, 1)
|
13
|
-
end
|
14
|
-
it "allows default intensity to be specified" do
|
15
|
-
cycle = Pattern::NoteCycle.new [C4], [], [1], :intensity => ppp
|
16
|
-
cycle.next.should == Note(C4, ppp, 1)
|
17
|
-
end
|
18
|
-
it "allows default duration to be specified" do
|
19
|
-
cycle = Pattern::NoteCycle.new [C4], [mf], [], :duration => 12
|
20
|
-
cycle.next.should == Note(C4, mf, 12)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "#next" do
|
25
|
-
it "iterates through the pitch, intensity, and duration list in parallel to emit Notes" do
|
26
|
-
cycle = Pattern::NoteCycle.new [C4, D4, E4], [p, f], [1,2,3,4]
|
27
|
-
cycle.next.should == Note(C4, p, 1)
|
28
|
-
cycle.next.should == Note(D4, f, 2)
|
29
|
-
cycle.next.should == Note(E4, p, 3)
|
30
|
-
cycle.next.should == Note(C4, f, 4)
|
31
|
-
cycle.next.should == Note(D4, p, 1)
|
32
|
-
cycle.next.should == Note(E4, f, 2)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "defaults to Pitch 'C4' when no pitches are given" do
|
36
|
-
cycle = Pattern::NoteCycle.new [], [p,f], [1,2,3]
|
37
|
-
cycle.next.should == Note(C4, p, 1)
|
38
|
-
cycle.next.should == Note(C4, f, 2)
|
39
|
-
cycle.next.should == Note(C4, p, 3)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "defaults to intensity 'mf' when no intensities are given" do
|
43
|
-
cycle = Pattern::NoteCycle.new [C4, D4, E4], nil, [2]
|
44
|
-
cycle.next.should == Note(C4, mf, 2)
|
45
|
-
cycle.next.should == Note(D4, mf, 2)
|
46
|
-
cycle.next.should == Note(E4, mf, 2)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "defaults to duration 1 when no durations are given" do
|
50
|
-
cycle = Pattern::NoteCycle.new [C4, D4, E4], [p, f]
|
51
|
-
cycle.next.should == Note(C4, p, 1)
|
52
|
-
cycle.next.should == Note(D4, f, 1)
|
53
|
-
cycle.next.should == Note(E4, p, 1)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "uses the previous pitch/intensity/duration when it encounters a nil value" do
|
57
|
-
cycle = Pattern::NoteCycle.new [C4, D4, E4, F4, nil], [mp, mf, f, nil], [1, 2, nil]
|
58
|
-
cycle.next.should == Note(C4, mp, 1)
|
59
|
-
cycle.next.should == Note(D4, mf, 2)
|
60
|
-
cycle.next.should == Note(E4, f, 2)
|
61
|
-
cycle.next.should == Note(F4, f, 1)
|
62
|
-
cycle.next.should == Note(F4, mp, 2)
|
63
|
-
cycle.next.should == Note(C4, mf, 2)
|
64
|
-
end
|
65
|
-
|
66
|
-
it "adds Numeric intervals in the pitch list to the previous pitch" do
|
67
|
-
cycle = Pattern::NoteCycle.new [C4, 1, 2, 3]
|
68
|
-
cycle.next.should == note(C4)
|
69
|
-
cycle.next.should == note(C4+1)
|
70
|
-
cycle.next.should == note(C4+1+2)
|
71
|
-
cycle.next.should == note(C4+1+2+3)
|
72
|
-
cycle.next.should == note(C4)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "goes to the nearest Pitch for any PitchClasses in the pitch list" do
|
76
|
-
cycle = Pattern::NoteCycle.new [C4, F, C, G, C]
|
77
|
-
cycle.next.should == note(C4)
|
78
|
-
cycle.next.should == note(F4)
|
79
|
-
cycle.next.should == note(C4)
|
80
|
-
cycle.next.should == note(G3)
|
81
|
-
cycle.next.should == note(C4)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "does not endlessly ascend or descend when alternating between two pitch classes a tritone apart" do
|
85
|
-
cycle = Pattern::NoteCycle.new [C4, Gb, C, Gb, C]
|
86
|
-
cycle.next.should == note(C4)
|
87
|
-
cycle.next.should == note(Gb4)
|
88
|
-
cycle.next.should == note(C4)
|
89
|
-
cycle.next.should == note(Gb4)
|
90
|
-
cycle.next.should == note(C4)
|
91
|
-
end
|
92
|
-
|
93
|
-
it "cycles Note Arrays for pitch list items that are PitchSets" do
|
94
|
-
cycle = Pattern::NoteCycle.new [PitchSet.new([C4, E4, G4]), C4, PitchSet.new([D4, F4, A4])]
|
95
|
-
cycle.next.should == [note(C4), note(E4), note(G4)]
|
96
|
-
cycle.next.should == note(C4)
|
97
|
-
cycle.next.should == [note(D4), note(F4), note(A4)]
|
98
|
-
end
|
99
|
-
|
100
|
-
it "adds numeric intervals to PitchSets" do
|
101
|
-
cycle = Pattern::NoteCycle.new [PitchSet.new([C4, E4, G4]), 2]
|
102
|
-
cycle.next.should == [note(C4), note(E4), note(G4)]
|
103
|
-
cycle.next.should == [note(D4), note(Gb4), note(A4)]
|
104
|
-
end
|
105
|
-
|
106
|
-
it "goes to the nearest Pitch relative to the lowest note in the PitchSet for any PitchClasses in the pitch list" do
|
107
|
-
cycle = Pattern::NoteCycle.new [PitchSet.new([C4, E4, G4]), F, D, Bb]
|
108
|
-
cycle.next.should == [note(C4), note(E4), note(G4)]
|
109
|
-
cycle.next.should == [note(F4), note(A4), note(C5)]
|
110
|
-
cycle.next.should == [note(D4), note(Gb4), note(A4)]
|
111
|
-
cycle.next.should == [note(Bb3), note(D4), note(F4)]
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MTK::Pattern::PitchCycle do
|
4
|
-
|
5
|
-
describe "#next" do
|
6
|
-
it "enumerates Pitches" do
|
7
|
-
cycle = Pattern::PitchCycle.new [C4, D4, E4]
|
8
|
-
cycle.next.should == C4
|
9
|
-
cycle.next.should == D4
|
10
|
-
cycle.next.should == E4
|
11
|
-
end
|
12
|
-
|
13
|
-
it "adds Numeric elements (intervals) to the previous pitch" do
|
14
|
-
cycle = Pattern::PitchCycle.new [C4, 1, 2, 3]
|
15
|
-
cycle.next.should == C4
|
16
|
-
cycle.next.should == C4+1
|
17
|
-
cycle.next.should == C4+1+2
|
18
|
-
cycle.next.should == C4+1+2+3
|
19
|
-
end
|
20
|
-
|
21
|
-
it "returns a Pitch when encountering a Pitch after another type" do
|
22
|
-
cycle = Pattern::PitchCycle.new [C4, 1, C4]
|
23
|
-
cycle.next
|
24
|
-
cycle.next
|
25
|
-
cycle.next.should == C4
|
26
|
-
end
|
27
|
-
|
28
|
-
it "goes to the nearest Pitch for any PitchClasses in the pitch list" do
|
29
|
-
cycle = Pattern::PitchCycle.new [C4, F, C, G, C]
|
30
|
-
cycle.next.should == C4
|
31
|
-
cycle.next.should == F4
|
32
|
-
cycle.next.should == C4
|
33
|
-
cycle.next.should == G3
|
34
|
-
cycle.next.should == C4
|
35
|
-
end
|
36
|
-
|
37
|
-
it "does not endlessly ascend or descend when alternating between two pitch classes a tritone apart" do
|
38
|
-
cycler = Pattern::PitchCycle.new [C4, Gb, C, Gb, C]
|
39
|
-
cycler.next.should == C4
|
40
|
-
cycler.next.should == Gb4
|
41
|
-
cycler.next.should == C4
|
42
|
-
cycler.next.should == Gb4
|
43
|
-
cycler.next.should == C4
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MTK::Pattern::PitchSequence do
|
4
|
-
|
5
|
-
let(:pitches) { [C4,D4,E4] }
|
6
|
-
let(:pitch_sequence) { Pattern::PitchSequence.new(pitches) }
|
7
|
-
|
8
|
-
|
9
|
-
describe ".from_pitch_classes" do
|
10
|
-
it "creates a pitch sequence from a list of pitch classes and starting point, selecting the nearest pitch to each pitch class" do
|
11
|
-
Pattern::PitchSequence.from_pitch_classes([C,G,B,Eb,D,C], D3).should == [C3,G2,B2,Eb3,D3,C3]
|
12
|
-
end
|
13
|
-
|
14
|
-
it "defaults to a starting point of C4 (middle C)" do
|
15
|
-
Pattern::PitchSequence.from_pitch_classes([C]).should == [C4]
|
16
|
-
end
|
17
|
-
|
18
|
-
it "doesn't travel within an octave above or below the starting point by default" do
|
19
|
-
Pattern::PitchSequence.from_pitch_classes([C,F,Bb,D,A,E,B]).should == [C4,F4,Bb4,D4,A3,E3,B3]
|
20
|
-
end
|
21
|
-
|
22
|
-
it "allows max distance above or below the starting point to be set via the third argument" do
|
23
|
-
Pattern::PitchSequence.from_pitch_classes([C,F,Bb,D,A,E,B], C4, 6).should == [C4,F4,Bb3,D4,A3,E4,B3]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
describe MTK::Pattern do
|
31
|
-
|
32
|
-
it "converts the arguments to Pitches when possible" do
|
33
|
-
Pattern.PitchSequence(:C4,:D4,:E4).elements.should == [C4,D4,E4]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|