mtk 0.0.3.2 → 0.0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +2 -2
- data/DEVELOPMENT_NOTES.md +20 -0
- data/README.md +9 -3
- data/Rakefile +47 -13
- data/bin/mtk +55 -20
- data/examples/crescendo.rb +4 -4
- data/examples/{drum_pattern1.rb → drum_pattern.rb} +8 -8
- data/examples/dynamic_pattern.rb +5 -5
- data/examples/gets_and_play.rb +3 -2
- data/examples/notation.rb +3 -3
- data/examples/play_midi.rb +4 -4
- data/examples/print_midi.rb +2 -2
- data/examples/random_tone_row.rb +3 -3
- data/examples/syntax_to_midi.rb +2 -2
- data/examples/test_output.rb +4 -5
- data/examples/tone_row_melody.rb +7 -5
- data/lib/mtk/core/duration.rb +213 -0
- data/lib/mtk/core/intensity.rb +158 -0
- data/lib/mtk/core/interval.rb +157 -0
- data/lib/mtk/core/pitch.rb +154 -0
- data/lib/mtk/core/pitch_class.rb +194 -0
- data/lib/mtk/events/event.rb +4 -4
- data/lib/mtk/events/note.rb +12 -12
- data/lib/mtk/events/timeline.rb +232 -0
- data/lib/mtk/groups/chord.rb +56 -0
- data/lib/mtk/{helpers → groups}/collection.rb +33 -1
- data/lib/mtk/groups/melody.rb +96 -0
- data/lib/mtk/groups/pitch_class_set.rb +163 -0
- data/lib/mtk/{helpers → groups}/pitch_collection.rb +1 -1
- data/lib/mtk/{midi → io}/dls_synth_device.rb +3 -1
- data/lib/mtk/{midi → io}/dls_synth_output.rb +10 -10
- data/lib/mtk/{midi → io}/jsound_input.rb +2 -2
- data/lib/mtk/{midi → io}/jsound_output.rb +9 -9
- data/lib/mtk/{midi/file.rb → io/midi_file.rb} +13 -13
- data/lib/mtk/{midi/input.rb → io/midi_input.rb} +4 -4
- data/lib/mtk/{midi/output.rb → io/midi_output.rb} +8 -8
- data/lib/mtk/{helpers/lilypond.rb → io/notation.rb} +5 -5
- data/lib/mtk/{midi → io}/unimidi_input.rb +2 -2
- data/lib/mtk/{midi → io}/unimidi_output.rb +14 -9
- data/lib/mtk/{constants → lang}/durations.rb +11 -11
- data/lib/mtk/{constants → lang}/intensities.rb +11 -11
- data/lib/mtk/{constants → lang}/intervals.rb +17 -17
- data/lib/mtk/lang/mtk_grammar.citrus +9 -9
- data/lib/mtk/{constants → lang}/pitch_classes.rb +5 -5
- data/lib/mtk/{constants → lang}/pitches.rb +7 -7
- data/lib/mtk/{helpers → lang}/pseudo_constants.rb +1 -1
- data/lib/mtk/{variable.rb → lang/variable.rb} +1 -1
- data/lib/mtk/numeric_extensions.rb +40 -47
- data/lib/mtk/patterns/for_each.rb +1 -1
- data/lib/mtk/patterns/pattern.rb +3 -3
- data/lib/mtk/sequencers/event_builder.rb +16 -15
- data/lib/mtk/sequencers/legato_sequencer.rb +1 -1
- data/lib/mtk/sequencers/rhythmic_sequencer.rb +1 -1
- data/lib/mtk/sequencers/sequencer.rb +8 -8
- data/lib/mtk/sequencers/step_sequencer.rb +2 -2
- data/lib/mtk.rb +33 -39
- data/spec/mtk/{duration_spec.rb → core/duration_spec.rb} +3 -3
- data/spec/mtk/{intensity_spec.rb → core/intensity_spec.rb} +3 -3
- data/spec/mtk/{interval_spec.rb → core/interval_spec.rb} +1 -1
- data/spec/mtk/{pitch_class_spec.rb → core/pitch_class_spec.rb} +1 -1
- data/spec/mtk/{pitch_spec.rb → core/pitch_spec.rb} +8 -8
- data/spec/mtk/events/event_spec.rb +4 -4
- data/spec/mtk/events/note_spec.rb +8 -8
- data/spec/mtk/{timeline_spec.rb → events/timeline_spec.rb} +47 -47
- data/spec/mtk/{chord_spec.rb → groups/chord_spec.rb} +18 -16
- data/spec/mtk/{helpers → groups}/collection_spec.rb +3 -3
- data/spec/mtk/{melody_spec.rb → groups/melody_spec.rb} +36 -34
- data/spec/mtk/{pitch_class_set_spec.rb → groups/pitch_class_set_spec.rb} +57 -55
- data/spec/mtk/{midi/file_spec.rb → io/midi_file_spec.rb} +17 -17
- data/spec/mtk/{midi/output_spec.rb → io/midi_output_spec.rb} +6 -6
- data/spec/mtk/{constants → lang}/durations_spec.rb +1 -1
- data/spec/mtk/{constants → lang}/intensities_spec.rb +1 -1
- data/spec/mtk/{constants → lang}/intervals_spec.rb +1 -1
- data/spec/mtk/lang/parser_spec.rb +12 -6
- data/spec/mtk/{constants → lang}/pitch_classes_spec.rb +1 -1
- data/spec/mtk/{constants → lang}/pitches_spec.rb +1 -1
- data/spec/mtk/{helpers → lang}/pseudo_constants_spec.rb +2 -2
- data/spec/mtk/{variable_spec.rb → lang/variable_spec.rb} +4 -4
- data/spec/mtk/numeric_extensions_spec.rb +35 -55
- data/spec/mtk/patterns/for_each_spec.rb +1 -1
- data/spec/mtk/patterns/sequence_spec.rb +1 -1
- data/spec/mtk/sequencers/legato_sequencer_spec.rb +2 -2
- data/spec/mtk/sequencers/rhythmic_sequencer_spec.rb +4 -4
- data/spec/mtk/sequencers/step_sequencer_spec.rb +5 -5
- data/spec/spec_helper.rb +7 -6
- metadata +75 -61
- data/ext/mkrf_conf.rb +0 -25
- data/lib/mtk/chord.rb +0 -55
- data/lib/mtk/duration.rb +0 -211
- data/lib/mtk/helpers/convert.rb +0 -36
- data/lib/mtk/helpers/output_selector.rb +0 -67
- data/lib/mtk/intensity.rb +0 -156
- data/lib/mtk/interval.rb +0 -155
- data/lib/mtk/melody.rb +0 -94
- data/lib/mtk/pitch.rb +0 -152
- data/lib/mtk/pitch_class.rb +0 -192
- data/lib/mtk/pitch_class_set.rb +0 -161
- data/lib/mtk/timeline.rb +0 -230
- data/spec/mtk/midi/jsound_input_spec.rb +0 -11
- data/spec/mtk/midi/jsound_output_spec.rb +0 -11
- data/spec/mtk/midi/unimidi_input_spec.rb +0 -11
- data/spec/mtk/midi/unimidi_output_spec.rb +0 -11
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'unimidi'
|
2
2
|
|
3
3
|
module MTK
|
4
|
-
module
|
4
|
+
module IO
|
5
5
|
|
6
6
|
# Provides realtime MIDI output for "standard" Ruby (MRI) via the unimidi and gamelan gems.
|
7
7
|
# @note This class is optional and only available if you require 'mtk/midi/unimidi_output'.
|
8
8
|
# It depends on the 'unimidi' and 'gamelan' gems.
|
9
|
-
class UniMIDIOutput <
|
9
|
+
class UniMIDIOutput < MIDIOutput
|
10
10
|
|
11
11
|
public_class_method :new
|
12
12
|
|
@@ -22,37 +22,37 @@ module MTK
|
|
22
22
|
######################
|
23
23
|
protected
|
24
24
|
|
25
|
-
# (see
|
25
|
+
# (see MIDIOutput#note_on)
|
26
26
|
def note_on(pitch, velocity, channel)
|
27
27
|
@device.puts(0x90|channel, pitch, velocity)
|
28
28
|
end
|
29
29
|
|
30
|
-
# (see
|
30
|
+
# (see MIDIOutput#note_off)
|
31
31
|
def note_off(pitch, velocity, channel)
|
32
32
|
@device.puts(0x80|channel, pitch, velocity)
|
33
33
|
end
|
34
34
|
|
35
|
-
# (see
|
35
|
+
# (see MIDIOutput#control)
|
36
36
|
def control(number, midi_value, channel)
|
37
37
|
@device.puts(0xB0|channel, number, midi_value)
|
38
38
|
end
|
39
39
|
|
40
|
-
# (see
|
40
|
+
# (see MIDIOutput#channel_pressure)
|
41
41
|
def channel_pressure(midi_value, channel)
|
42
42
|
@device.puts(0xD0|channel, midi_value, 0)
|
43
43
|
end
|
44
44
|
|
45
|
-
# (see
|
45
|
+
# (see MIDIOutput#poly_pressure)
|
46
46
|
def poly_pressure(pitch, midi_value, channel)
|
47
47
|
@device.puts(0xA0|channel, pitch, midi_value)
|
48
48
|
end
|
49
49
|
|
50
|
-
# (see
|
50
|
+
# (see MIDIOutput#bend)
|
51
51
|
def bend(midi_value, channel)
|
52
52
|
@device.puts(0xE0|channel, midi_value & 127, (midi_value >> 7) & 127)
|
53
53
|
end
|
54
54
|
|
55
|
-
# (see
|
55
|
+
# (see MIDIOutput#program)
|
56
56
|
def program(number, channel)
|
57
57
|
@device.puts(0xC0|channel, number, 0)
|
58
58
|
end
|
@@ -79,6 +79,8 @@ if RbConfig::CONFIG['host_os'] =~ /darwin/
|
|
79
79
|
|
80
80
|
# @private
|
81
81
|
module CoreMIDI
|
82
|
+
|
83
|
+
# @private
|
82
84
|
class Device
|
83
85
|
def initialize(id, device_pointer, options = {})
|
84
86
|
include_if_offline = options[:include_offline] || false
|
@@ -104,7 +106,10 @@ if RbConfig::CONFIG['host_os'] =~ /darwin/
|
|
104
106
|
|
105
107
|
end
|
106
108
|
|
109
|
+
# @private
|
107
110
|
module Map
|
111
|
+
|
112
|
+
# @private
|
108
113
|
module CF
|
109
114
|
|
110
115
|
extend FFI::Library
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rational'
|
2
2
|
|
3
3
|
module MTK
|
4
|
-
module
|
4
|
+
module Lang
|
5
5
|
|
6
6
|
# Defines duration constants using abbreviations for standard rhythm values ('w' for whole note, 'h' for half note, etc).
|
7
7
|
#
|
@@ -9,7 +9,7 @@ module MTK
|
|
9
9
|
#
|
10
10
|
# These can be thought of like constants, but they
|
11
11
|
# use lower-case names and therefore define them as "pseudo constant" methods.
|
12
|
-
# The methods are available either through the module (MTK::Durations::e) or via mixin (include MTK::Durations; q)
|
12
|
+
# The methods are available either through the module (MTK::Core::Durations::e) or via mixin (include MTK::Core::Durations; q)
|
13
13
|
#
|
14
14
|
# These values assume the quarter note is one beat (1.0), so they work best with 4/4 and other */4 time signatures.
|
15
15
|
#
|
@@ -18,7 +18,7 @@ module MTK
|
|
18
18
|
#
|
19
19
|
# @see Note
|
20
20
|
module Durations
|
21
|
-
extend
|
21
|
+
extend MTK::Lang::PseudoConstants
|
22
22
|
|
23
23
|
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
24
24
|
|
@@ -26,31 +26,31 @@ module MTK
|
|
26
26
|
# @macro [attach] durations.define_constant
|
27
27
|
# @attribute [r]
|
28
28
|
# @return [$2] number of beats for $1
|
29
|
-
define_constant 'w', MTK::Duration[4]
|
29
|
+
define_constant 'w', MTK::Core::Duration[4]
|
30
30
|
|
31
31
|
# half note
|
32
|
-
define_constant 'h', MTK::Duration[2]
|
32
|
+
define_constant 'h', MTK::Core::Duration[2]
|
33
33
|
|
34
34
|
# quarter note
|
35
|
-
define_constant 'q', MTK::Duration[1]
|
35
|
+
define_constant 'q', MTK::Core::Duration[1]
|
36
36
|
|
37
37
|
# eight note
|
38
|
-
define_constant 'i', MTK::Duration[Rational(1,2)]
|
38
|
+
define_constant 'i', MTK::Core::Duration[Rational(1,2)]
|
39
39
|
|
40
40
|
# sixteenth note
|
41
|
-
define_constant 's', MTK::Duration[Rational(1,4)]
|
41
|
+
define_constant 's', MTK::Core::Duration[Rational(1,4)]
|
42
42
|
|
43
43
|
# thirty-second note
|
44
|
-
define_constant 'r', MTK::Duration[Rational(1,8)]
|
44
|
+
define_constant 'r', MTK::Core::Duration[Rational(1,8)]
|
45
45
|
|
46
46
|
# sixty-fourth note
|
47
|
-
define_constant 'x', MTK::Duration[Rational(1,16)]
|
47
|
+
define_constant 'x', MTK::Core::Duration[Rational(1,16)]
|
48
48
|
|
49
49
|
# The values of all "psuedo constants" defined in this module
|
50
50
|
DURATIONS = [w, h, q, i, s, r, x].freeze
|
51
51
|
|
52
52
|
# The names of all "psuedo constants" defined in this module
|
53
|
-
DURATION_NAMES = MTK::Duration::NAMES
|
53
|
+
DURATION_NAMES = MTK::Core::Duration::NAMES
|
54
54
|
|
55
55
|
end
|
56
56
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module MTK
|
2
|
-
module
|
2
|
+
module Lang
|
3
3
|
|
4
4
|
# Defines intensity constants using standard dynamic symbols.
|
5
5
|
#
|
@@ -17,7 +17,7 @@ module MTK
|
|
17
17
|
#
|
18
18
|
# @see Note
|
19
19
|
module Intensities
|
20
|
-
extend
|
20
|
+
extend MTK::Lang::PseudoConstants
|
21
21
|
|
22
22
|
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
23
23
|
|
@@ -25,36 +25,36 @@ module MTK
|
|
25
25
|
# @macro [attach] intensities.define_constant
|
26
26
|
# @attribute [r]
|
27
27
|
# @return [$2] intensity value for $1
|
28
|
-
define_constant 'ppp', MTK::Intensity[0.125]
|
28
|
+
define_constant 'ppp', MTK::Core::Intensity[0.125]
|
29
29
|
|
30
30
|
# pianissimo
|
31
|
-
define_constant 'pp', MTK::Intensity[0.25]
|
31
|
+
define_constant 'pp', MTK::Core::Intensity[0.25]
|
32
32
|
|
33
33
|
# piano
|
34
34
|
# @note Including this module shadows Ruby's built-in p() method.
|
35
35
|
# If you include this module, you can access the built-in p() method via Kernel.p()
|
36
|
-
define_constant 'p', MTK::Intensity[0.375]
|
36
|
+
define_constant 'p', MTK::Core::Intensity[0.375]
|
37
37
|
|
38
38
|
# mezzo-piano
|
39
|
-
define_constant 'mp', MTK::Intensity[0.5]
|
39
|
+
define_constant 'mp', MTK::Core::Intensity[0.5]
|
40
40
|
|
41
41
|
# mezzo-forte
|
42
|
-
define_constant 'mf', MTK::Intensity[0.625]
|
42
|
+
define_constant 'mf', MTK::Core::Intensity[0.625]
|
43
43
|
|
44
44
|
# forte
|
45
|
-
define_constant 'o', MTK::Intensity[0.75]
|
45
|
+
define_constant 'o', MTK::Core::Intensity[0.75]
|
46
46
|
|
47
47
|
# fortissimo
|
48
|
-
define_constant 'ff', MTK::Intensity[0.875]
|
48
|
+
define_constant 'ff', MTK::Core::Intensity[0.875]
|
49
49
|
|
50
50
|
# fortississimo
|
51
|
-
define_constant 'fff', MTK::Intensity[1.0]
|
51
|
+
define_constant 'fff', MTK::Core::Intensity[1.0]
|
52
52
|
|
53
53
|
# The values of all "psuedo constants" defined in this module
|
54
54
|
INTENSITIES = [ppp, pp, p, mp, mf, o, ff, fff].freeze
|
55
55
|
|
56
56
|
# The names of all "psuedo constants" defined in this module
|
57
|
-
INTENSITY_NAMES = MTK::Intensity::NAMES
|
57
|
+
INTENSITY_NAMES = MTK::Core::Intensity::NAMES
|
58
58
|
|
59
59
|
end
|
60
60
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module MTK
|
2
|
-
module
|
2
|
+
module Lang
|
3
3
|
|
4
4
|
# Defines a constant for intervals up to an octave using diatonic naming conventions (see http://en.wikipedia.org/wiki/Interval_(music)#Main_intervals)
|
5
5
|
#
|
@@ -11,9 +11,9 @@ module MTK
|
|
11
11
|
#
|
12
12
|
# These can be thought of like constants, but in order to succinctly distinguish 'm2' (minor) from 'M2' (major),
|
13
13
|
# it was necessary to use lower-case names for some of the values and therefore define them as "pseudo constant" methods.
|
14
|
-
# The methods are available either through the module (MTK::Intervals::m2) or via mixin (include MTK::Intervals; m2)
|
14
|
+
# The methods are available either through the module (MTK::Core::Intervals::m2) or via mixin (include MTK::Core::Intervals; m2)
|
15
15
|
module Intervals
|
16
|
-
extend
|
16
|
+
extend MTK::Lang::PseudoConstants
|
17
17
|
|
18
18
|
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
19
19
|
|
@@ -21,52 +21,52 @@ module MTK
|
|
21
21
|
# @macro [attach] interval.define_constant
|
22
22
|
# @attribute [r]
|
23
23
|
# @return [$2] number of semitones in the interval $1
|
24
|
-
define_constant 'P1', MTK::Interval[0]
|
24
|
+
define_constant 'P1', MTK::Core::Interval[0]
|
25
25
|
|
26
26
|
# minor second
|
27
27
|
# @macro [attach] interval.define_constant
|
28
28
|
# @attribute [r]
|
29
29
|
# @return [$2] number of semitones in the interval $1
|
30
|
-
define_constant 'm2', MTK::Interval[1]
|
30
|
+
define_constant 'm2', MTK::Core::Interval[1]
|
31
31
|
|
32
32
|
# major second
|
33
|
-
define_constant 'M2', MTK::Interval[2]
|
33
|
+
define_constant 'M2', MTK::Core::Interval[2]
|
34
34
|
|
35
35
|
# minor third
|
36
|
-
define_constant 'm3', MTK::Interval[3]
|
36
|
+
define_constant 'm3', MTK::Core::Interval[3]
|
37
37
|
|
38
38
|
# major third
|
39
|
-
define_constant 'M3', MTK::Interval[4]
|
39
|
+
define_constant 'M3', MTK::Core::Interval[4]
|
40
40
|
|
41
41
|
# pefect fourth
|
42
|
-
define_constant 'P4', MTK::Interval[5]
|
42
|
+
define_constant 'P4', MTK::Core::Interval[5]
|
43
43
|
|
44
44
|
# tritone (AKA augmented fourth or diminished fifth)
|
45
|
-
define_constant 'TT', MTK::Interval[6]
|
45
|
+
define_constant 'TT', MTK::Core::Interval[6]
|
46
46
|
|
47
47
|
# perfect fifth
|
48
|
-
define_constant 'P5', MTK::Interval[7]
|
48
|
+
define_constant 'P5', MTK::Core::Interval[7]
|
49
49
|
|
50
50
|
# minor sixth
|
51
|
-
define_constant 'm6', MTK::Interval[8]
|
51
|
+
define_constant 'm6', MTK::Core::Interval[8]
|
52
52
|
|
53
53
|
# major sixth
|
54
|
-
define_constant 'M6', MTK::Interval[9]
|
54
|
+
define_constant 'M6', MTK::Core::Interval[9]
|
55
55
|
|
56
56
|
# minor seventh
|
57
|
-
define_constant 'm7', MTK::Interval[10]
|
57
|
+
define_constant 'm7', MTK::Core::Interval[10]
|
58
58
|
|
59
59
|
# major seventh
|
60
|
-
define_constant 'M7', MTK::Interval[11]
|
60
|
+
define_constant 'M7', MTK::Core::Interval[11]
|
61
61
|
|
62
62
|
# pefect octave
|
63
|
-
define_constant 'P8', MTK::Interval[12]
|
63
|
+
define_constant 'P8', MTK::Core::Interval[12]
|
64
64
|
|
65
65
|
# The values of all "psuedo constants" defined in this module
|
66
66
|
INTERVALS = [P1, m2, M2, m3, M3, P4, TT, P5, m6, M6, m7, M7, P8].freeze
|
67
67
|
|
68
68
|
# The names of all "psuedo constants" defined in this module
|
69
|
-
INTERVAL_NAMES = MTK::Interval::NAMES
|
69
|
+
INTERVAL_NAMES = MTK::Core::Interval::NAMES
|
70
70
|
|
71
71
|
end
|
72
72
|
end
|
@@ -22,14 +22,14 @@ grammar MTK_Grammar
|
|
22
22
|
|
23
23
|
rule timeline
|
24
24
|
( left_curly timepoint pattern (space timepoint pattern)* right_curly ) {
|
25
|
-
|
25
|
+
MTK::Events::Timeline.from_a values_of(:timepoint).zip(values_of :pattern)
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
29
29
|
rule pattern
|
30
30
|
( pattern:(bare_choice | choice) '' ) {
|
31
31
|
val = first.value
|
32
|
-
if val.is_a? MTK::Patterns::Pattern then val else MTK::Patterns::
|
32
|
+
if val.is_a? MTK::Patterns::Pattern then val else MTK::Patterns::Sequence.new [val] end
|
33
33
|
}
|
34
34
|
end
|
35
35
|
|
@@ -122,43 +122,43 @@ grammar MTK_Grammar
|
|
122
122
|
|
123
123
|
# rule chord
|
124
124
|
# ( left_bracket pitch (space pitch)* right_bracket ) {
|
125
|
-
# MTK::Chord *values_of(:pitch)
|
125
|
+
# MTK::Groups::Chord *values_of(:pitch)
|
126
126
|
# }
|
127
127
|
# end
|
128
128
|
|
129
129
|
rule pitch
|
130
130
|
( pitch_class int ) {
|
131
|
-
MTK::Pitch[pitch_class.value, int.value]
|
131
|
+
MTK::Core::Pitch[pitch_class.value, int.value]
|
132
132
|
}
|
133
133
|
end
|
134
134
|
|
135
135
|
rule pitch_class
|
136
136
|
( [A-Ga-g] [#b]*2 ) {
|
137
|
-
MTK::PitchClass[to_s]
|
137
|
+
MTK::Core::PitchClass[to_s]
|
138
138
|
}
|
139
139
|
end
|
140
140
|
|
141
141
|
rule interval
|
142
142
|
( [Pp] [1458] | ('maj'|'min'|[Mm]) [2367] | 'TT' | 'tt' ) {
|
143
|
-
MTK::Interval.from_s(to_s)
|
143
|
+
MTK::Core::Interval.from_s(to_s)
|
144
144
|
}
|
145
145
|
end
|
146
146
|
|
147
147
|
rule intensity
|
148
148
|
( ('p'1*3 | 'mp' | 'mf' | 'o' | 'f'2*3) ('+'|'-')? ) {
|
149
|
-
MTK::Intensity.from_s(to_s)
|
149
|
+
MTK::Core::Intensity.from_s(to_s)
|
150
150
|
}
|
151
151
|
end
|
152
152
|
|
153
153
|
rule duration
|
154
154
|
( rest:'-'? multiplier:number? [whqisrx] ('.'|'t')* ) {
|
155
|
-
MTK::Duration.from_s(to_s)
|
155
|
+
MTK::Core::Duration.from_s(to_s)
|
156
156
|
}
|
157
157
|
end
|
158
158
|
|
159
159
|
rule variable
|
160
160
|
( '$'+ ) {
|
161
|
-
MTK::Variable.new(to_s)
|
161
|
+
MTK::Lang::Variable.new(to_s)
|
162
162
|
}
|
163
163
|
end
|
164
164
|
|
@@ -1,21 +1,21 @@
|
|
1
1
|
module MTK
|
2
|
-
module
|
2
|
+
module Lang
|
3
3
|
|
4
4
|
# Defines a constant for each {PitchClass} in the Western chromatic scale.
|
5
5
|
module PitchClasses
|
6
6
|
|
7
7
|
# The values of all constants defined in this module
|
8
|
-
PITCH_CLASSES = MTK::PitchClass::PITCH_CLASSES
|
8
|
+
PITCH_CLASSES = MTK::Core::PitchClass::PITCH_CLASSES
|
9
9
|
|
10
10
|
# The names of all constants defined in this module
|
11
|
-
PITCH_CLASS_NAMES = MTK::PitchClass::NAMES
|
11
|
+
PITCH_CLASS_NAMES = MTK::Core::PitchClass::NAMES
|
12
12
|
|
13
13
|
PITCH_CLASSES.each { |pc| const_set pc.name, pc }
|
14
14
|
|
15
15
|
# Lookup the value of an pitch class constant by name.
|
16
16
|
# @example lookup value of 'C'
|
17
|
-
# MTK::PitchClasses['C']
|
18
|
-
# @see PitchClass.[]
|
17
|
+
# MTK::Core::PitchClasses['C']
|
18
|
+
# @see Groups::PitchClass.[]
|
19
19
|
def self.[](name)
|
20
20
|
begin
|
21
21
|
const_get name
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module MTK
|
2
|
-
module
|
2
|
+
module Lang
|
3
3
|
|
4
|
-
# Defines a constants for each {Pitch} in the standard MIDI range using scientific pitch notation.
|
4
|
+
# Defines a constants for each {Core::Pitch} in the standard MIDI range using scientific pitch notation.
|
5
5
|
#
|
6
6
|
# See http://en.wikipedia.org/wiki/Scientific_pitch_notation
|
7
7
|
#
|
@@ -18,7 +18,7 @@ module MTK
|
|
18
18
|
PITCH_NAMES = []
|
19
19
|
|
20
20
|
128.times do |note_number|
|
21
|
-
pitch = Pitch.from_i( note_number )
|
21
|
+
pitch = MTK::Core::Pitch.from_i( note_number )
|
22
22
|
PITCHES << pitch
|
23
23
|
|
24
24
|
octave_str = pitch.octave.to_s.sub(/-/,'_') # '_1' for -1
|
@@ -35,10 +35,10 @@ module MTK
|
|
35
35
|
|
36
36
|
# Lookup the value of an pitch constant by name.
|
37
37
|
# @example lookup value of 'C3'
|
38
|
-
# MTK::Pitches['C3']
|
39
|
-
# @see Pitch.from_s
|
40
|
-
# @note Unlike {Pitch.from_s} this method will accept either '_' (underscore) or '-' (minus) and treat it like '-' (minus)
|
41
|
-
# @note Unlike {Pitch.from_s} this method only accepts the accidental 'b'
|
38
|
+
# MTK::Core::Pitches['C3']
|
39
|
+
# @see Core::Pitch.from_s
|
40
|
+
# @note Unlike {Core::Pitch.from_s} this method will accept either '_' (underscore) or '-' (minus) and treat it like '-' (minus)
|
41
|
+
# @note Unlike {Core::Pitch.from_s} this method only accepts the accidental 'b'
|
42
42
|
def self.[](name)
|
43
43
|
begin
|
44
44
|
const_get name.sub('-','_')
|
@@ -1,73 +1,66 @@
|
|
1
|
-
# Optional Numeric methods for converting
|
1
|
+
# Optional Numeric methods for converting to {MTK::Core} objects.
|
2
2
|
#
|
3
3
|
# @note you must require 'mtk/numeric_extensions' to use these methods.
|
4
4
|
#
|
5
5
|
class Numeric
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
# Convert a Numeric to a {MTK::Core::Pitch}
|
8
|
+
# @example 60.to_pitch => C4
|
9
|
+
def to_pitch
|
10
|
+
MTK::Core::Pitch.from_f(self)
|
9
11
|
end
|
10
|
-
alias beat beats
|
11
12
|
|
12
13
|
|
13
|
-
#
|
14
|
-
|
15
|
-
def
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def cents
|
20
|
-
self/100.0
|
14
|
+
# Convert a Numeric to a {MTK::Core::PitchClass}
|
15
|
+
# @example 2.to_pitch_class => D
|
16
|
+
def to_pitch_class
|
17
|
+
MTK::Core::PitchClass.from_f(self)
|
21
18
|
end
|
22
19
|
|
23
|
-
def minor_seconds
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
def major_seconds
|
28
|
-
self * 2
|
29
|
-
end
|
30
20
|
|
31
|
-
|
32
|
-
|
21
|
+
# Convert a Numeric to a {MTK::Core::Duration}
|
22
|
+
# @example 3.5.to_duration + 1.beat + 2.beats
|
23
|
+
def to_duration
|
24
|
+
MTK::Core::Duration.from_f(self)
|
33
25
|
end
|
26
|
+
alias beats to_duration
|
27
|
+
alias beat to_duration
|
34
28
|
|
35
|
-
def major_thirds
|
36
|
-
self * 4
|
37
|
-
end
|
38
29
|
|
39
|
-
|
40
|
-
|
30
|
+
# Convert a Numeric to a {MTK::Core::Intensity}
|
31
|
+
# @note The standard range of intensity values is from 0.0 - 1.0
|
32
|
+
# @example 1.to_pitch => fff
|
33
|
+
def to_intensity
|
34
|
+
MTK::Core::Intensity.from_f(self)
|
41
35
|
end
|
42
36
|
|
43
|
-
|
44
|
-
|
37
|
+
# Convert a Numeric percentage to a {MTK::Core::Intensity}
|
38
|
+
# @note The standard range of intensity percentages is from 0 - 100
|
39
|
+
# @example 100.percent_intensity => fff
|
40
|
+
def percent_intensity
|
41
|
+
MTK::Core::Intensity.from_f(self/100.0)
|
45
42
|
end
|
46
|
-
alias augmented_fourths tritones
|
47
|
-
alias diminshed_fifths tritones
|
48
43
|
|
49
|
-
|
50
|
-
|
44
|
+
# Convert a Numeric to a {MTK::Core::Interval}
|
45
|
+
# @example 3.5.to_interval + 1.semitone + 2.semitones
|
46
|
+
def to_interval
|
47
|
+
MTK::Core::Interval.from_f(self)
|
51
48
|
end
|
49
|
+
alias semitones to_interval
|
50
|
+
alias semitone to_interval
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def major_sixths
|
58
|
-
self * 9
|
59
|
-
end
|
60
|
-
|
61
|
-
def minor_sevenths
|
62
|
-
self * 10
|
63
|
-
end
|
64
|
-
|
65
|
-
def major_sevenths
|
66
|
-
self * 11
|
52
|
+
# Convert a Numeric cents value to a {MTK::Core::Interval}
|
53
|
+
# @example 100.cents => 1.semitone
|
54
|
+
def cents
|
55
|
+
MTK::Core::Interval.from_f(self/100.0)
|
67
56
|
end
|
57
|
+
alias cent cents
|
68
58
|
|
59
|
+
# Convert a Numeric octaves value to a {MTK::Core::Interval}
|
60
|
+
# @example 1.octave => 12.semitones
|
69
61
|
def octaves
|
70
|
-
self * 12
|
62
|
+
MTK::Core::Interval.from_f(self * 12)
|
71
63
|
end
|
64
|
+
alias octave octaves
|
72
65
|
|
73
66
|
end
|
@@ -55,7 +55,7 @@ module MTK
|
|
55
55
|
|
56
56
|
def evaluate_variables(element)
|
57
57
|
case element
|
58
|
-
when ::MTK::Variable
|
58
|
+
when ::MTK::Lang::Variable
|
59
59
|
if element.implicit?
|
60
60
|
return @vars[-element.name.length] # '$' is most recently pushed value, $$' goes back 2 levels, '$$$' goes back 3, etc
|
61
61
|
end
|
data/lib/mtk/patterns/pattern.rb
CHANGED
@@ -5,10 +5,10 @@ module MTK
|
|
5
5
|
#
|
6
6
|
# Patterns can be reset to the beginning via {#rewind}.
|
7
7
|
#
|
8
|
-
# @abstract Subclass and override {#advance}
|
8
|
+
# @abstract Subclass and override {#advance} to implement a Pattern.
|
9
9
|
#
|
10
10
|
class Pattern
|
11
|
-
include MTK::
|
11
|
+
include MTK::Groups::Collection
|
12
12
|
|
13
13
|
# The elements in the pattern
|
14
14
|
attr_reader :elements
|
@@ -24,7 +24,7 @@ module MTK
|
|
24
24
|
|
25
25
|
# The maximum number of elements this Pattern will emit before a StopIteration exception
|
26
26
|
# A nil value means infinite elements.
|
27
|
-
# @note {max_cycles} may cause this Pattern to end before max_elements are emitted.
|
27
|
+
# @note {#max_cycles} may cause this Pattern to end before max_elements are emitted.
|
28
28
|
# If this is undesirable then use min_elements to override max_cycles.
|
29
29
|
attr_reader :max_elements
|
30
30
|
|
@@ -4,16 +4,17 @@ module MTK
|
|
4
4
|
# A special pattern that takes a list of event properties and/or patterns and emits lists of {Events::Event}s
|
5
5
|
class EventBuilder
|
6
6
|
|
7
|
-
DEFAULT_PITCH
|
8
|
-
DEFAULT_DURATION
|
9
|
-
DEFAULT_INTENSITY =
|
7
|
+
DEFAULT_PITCH = MTK.Pitch(60)
|
8
|
+
DEFAULT_DURATION = MTK.Duration(1)
|
9
|
+
DEFAULT_INTENSITY = MTK.Intensity(0.75)
|
10
10
|
|
11
11
|
def initialize(patterns, options={})
|
12
12
|
@patterns = patterns
|
13
13
|
@options = options
|
14
|
-
@default_pitch = if options.has_key? :default_pitch then MTK
|
15
|
-
@default_duration = if options.has_key? :default_duration then MTK
|
16
|
-
@default_intensity = if options.has_key? :default_intensity then MTK
|
14
|
+
@default_pitch = if options.has_key? :default_pitch then MTK.Pitch( options[:default_pitch]) else DEFAULT_PITCH end
|
15
|
+
@default_duration = if options.has_key? :default_duration then MTK.Duration( options[:default_duration]) else DEFAULT_DURATION end
|
16
|
+
@default_intensity = if options.has_key? :default_intensity then MTK.Intensity(options[:default_intensity]) else DEFAULT_INTENSITY end
|
17
|
+
@channel = options[:channel]
|
17
18
|
@max_interval = options.fetch(:max_interval, 127)
|
18
19
|
rewind
|
19
20
|
end
|
@@ -33,19 +34,19 @@ module MTK
|
|
33
34
|
return nil if element.nil? or element == :skip
|
34
35
|
|
35
36
|
case element
|
36
|
-
when ::MTK::Pitch then pitches << element
|
37
|
-
when ::MTK::PitchClass then pitches += pitches_for_pitch_classes([element], @previous_pitch)
|
38
|
-
when ::MTK::PitchClassSet then pitches += pitches_for_pitch_classes(element, @previous_pitch)
|
39
|
-
when ::MTK::
|
37
|
+
when ::MTK::Core::Pitch then pitches << element
|
38
|
+
when ::MTK::Core::PitchClass then pitches += pitches_for_pitch_classes([element], @previous_pitch)
|
39
|
+
when ::MTK::Groups::PitchClassSet then pitches += pitches_for_pitch_classes(element, @previous_pitch)
|
40
|
+
when ::MTK::Groups::PitchCollection then pitches += element.pitches # this must be after the PitchClassSet case, because that is also a PitchCollection
|
40
41
|
|
41
|
-
when ::MTK::Duration
|
42
|
+
when ::MTK::Core::Duration
|
42
43
|
duration ||= 0
|
43
44
|
duration += element
|
44
45
|
|
45
|
-
when ::MTK::Intensity
|
46
|
+
when ::MTK::Core::Intensity
|
46
47
|
intensities << element
|
47
48
|
|
48
|
-
when ::MTK::Interval
|
49
|
+
when ::MTK::Core::Interval
|
49
50
|
if @previous_pitches
|
50
51
|
pitches += @previous_pitches.map{|pitch| pitch + element }
|
51
52
|
else
|
@@ -66,7 +67,7 @@ module MTK
|
|
66
67
|
if intensities.empty?
|
67
68
|
intensity = @previous_intensity
|
68
69
|
else
|
69
|
-
intensity = MTK::Intensity[intensities.map{|i| i.to_f }.inject(:+)/intensities.length] # average the intensities
|
70
|
+
intensity = MTK::Core::Intensity[intensities.map{|i| i.to_f }.inject(:+)/intensities.length] # average the intensities
|
70
71
|
end
|
71
72
|
|
72
73
|
# Not using this yet, maybe later...
|
@@ -79,7 +80,7 @@ module MTK
|
|
79
80
|
@previous_intensity = intensity
|
80
81
|
@previous_duration = duration
|
81
82
|
|
82
|
-
pitches.map{|pitch| MTK::Events::Note.new(pitch,duration,intensity) }
|
83
|
+
pitches.map{|pitch| MTK::Events::Note.new(pitch,duration,intensity,@channel) }
|
83
84
|
end
|
84
85
|
|
85
86
|
# Reset the EventBuilder to its initial state
|
@@ -2,7 +2,7 @@ module MTK
|
|
2
2
|
module Sequencers
|
3
3
|
|
4
4
|
# A Sequencer which uses the longest duration of the events at each step to determine
|
5
|
-
# the delta times between entries in the {Timeline}.
|
5
|
+
# the delta times between entries in the {Events::Timeline}.
|
6
6
|
class LegatoSequencer < Sequencer
|
7
7
|
|
8
8
|
# (see Sequencer#next)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module MTK
|
2
2
|
module Sequencers
|
3
3
|
|
4
|
-
# A Sequencer which uses a :rhythm type {Patterns::Pattern} to determine the delta times between entries in the {Timeline}.
|
4
|
+
# A Sequencer which uses a :rhythm type {Patterns::Pattern} to determine the delta times between entries in the {Events::Timeline}.
|
5
5
|
class RhythmicSequencer < Sequencer
|
6
6
|
|
7
7
|
def initialize(patterns, options={})
|