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,80 +0,0 @@
|
|
1
|
-
require 'rational'
|
2
|
-
|
3
|
-
module MTK
|
4
|
-
|
5
|
-
# Defines duration constants using abbreviations for standard rhythm values ('w' for whole note, 'h' for half note, etc).
|
6
|
-
#
|
7
|
-
# These can be thought of like constants, but in order to distinguish 'e' (eighth note) from the {PitchClass} 'E'
|
8
|
-
# it was necessary to use lower-case names and therefore define them as "pseudo constant" methods.
|
9
|
-
# The methods are available either through the module (MTK::Durations::e) or via mixin (include MTK::Durations; e)
|
10
|
-
#
|
11
|
-
# These values assume the quarter note is one beat (1.0), so they work best with 4/4 and other */4 time signatures.
|
12
|
-
#
|
13
|
-
# @note Including this module defines a bunch of single-character variables, which may shadow existing variable names.
|
14
|
-
# Just be mindful of what is defined in this module when including it.
|
15
|
-
#
|
16
|
-
# @see Note
|
17
|
-
module Durations
|
18
|
-
extend Helper::PseudoConstants
|
19
|
-
|
20
|
-
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
21
|
-
|
22
|
-
# whole note
|
23
|
-
# @macro [attach] durations.define_constant
|
24
|
-
# @attribute [r]
|
25
|
-
# @return [$2] number of beats for $1
|
26
|
-
define_constant 'w', 4
|
27
|
-
|
28
|
-
# half note
|
29
|
-
define_constant 'h', 2
|
30
|
-
|
31
|
-
# quarter note
|
32
|
-
define_constant 'q', 1
|
33
|
-
|
34
|
-
# eight note
|
35
|
-
define_constant 'e', Rational(1,2)
|
36
|
-
|
37
|
-
# sixteenth note
|
38
|
-
define_constant 's', Rational(1,4)
|
39
|
-
|
40
|
-
# thirty-second note
|
41
|
-
define_constant 'r', Rational(1,8)
|
42
|
-
|
43
|
-
# sixty-fourth note
|
44
|
-
define_constant 'x', Rational(1,16)
|
45
|
-
|
46
|
-
# The values of all "psuedo constants" defined in this module
|
47
|
-
DURATIONS = [w, h, q, e, s, r, x].freeze
|
48
|
-
|
49
|
-
# The names of all "psuedo constants" defined in this module
|
50
|
-
DURATION_NAMES = %w[w h q e s r x].freeze
|
51
|
-
|
52
|
-
# Lookup the value of an duration constant by name.
|
53
|
-
# This method supports appending any combination of '.' and 't' for more fine-grained values.
|
54
|
-
# each '.' multiplies by 3/2, and each 't' multiplies by 2/3.
|
55
|
-
# @example lookup value of 'e.' (eight note), which is 0.75 (0.5 * 1.5)
|
56
|
-
# MTK::Durations['e.']
|
57
|
-
def self.[](name)
|
58
|
-
begin
|
59
|
-
modifier = nil
|
60
|
-
if name =~ /(\w)((.|t)*)/
|
61
|
-
name = $1
|
62
|
-
modifier = $2
|
63
|
-
end
|
64
|
-
|
65
|
-
value = send name
|
66
|
-
modifier.each_char do |mod|
|
67
|
-
case mod
|
68
|
-
when '.' then value *= Rational(3,2)
|
69
|
-
when 't' then value *= Rational(2,3)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
value
|
73
|
-
|
74
|
-
rescue
|
75
|
-
nil
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
module MTK
|
2
|
-
|
3
|
-
# Defines intensity constants using standard dynamic symbols.
|
4
|
-
#
|
5
|
-
# These can be thought of like constants, but in order to distinguish 'f' (forte) from the {PitchClass} 'F'
|
6
|
-
# it was necessary to use lower-case names and therefore define them as "pseudo constant" methods.
|
7
|
-
# The methods are available either through the module (MTK::Intensities::f) or via mixin (include MTK::Intensities; f)
|
8
|
-
#
|
9
|
-
# These values are intensities in the range 0.125 - 1.0 (in increments of 1/8), so they can be easily scaled (unlike MIDI velocities).
|
10
|
-
#
|
11
|
-
# It is also possible to retrieve values in increments of 1/24 by using the '+' and '-' suffix when looking
|
12
|
-
# up values via the {.[]} method.
|
13
|
-
#
|
14
|
-
# @note Including this module shadows Ruby's built-in p() method.
|
15
|
-
# If you include this module, you can access the built-in p() method via Kernel.p()
|
16
|
-
#
|
17
|
-
# @see Note
|
18
|
-
module Intensities
|
19
|
-
extend Helper::PseudoConstants
|
20
|
-
|
21
|
-
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
22
|
-
|
23
|
-
# pianississimo
|
24
|
-
# @macro [attach] intensities.define_constant
|
25
|
-
# @attribute [r]
|
26
|
-
# @return [$2] intensity value for $1
|
27
|
-
define_constant 'ppp', 0.125
|
28
|
-
|
29
|
-
# pianissimo
|
30
|
-
define_constant 'pp', 0.25
|
31
|
-
|
32
|
-
# piano
|
33
|
-
# @note Including this module shadows Ruby's built-in p() method.
|
34
|
-
# If you include this module, you can access the built-in p() method via Kernel.p()
|
35
|
-
define_constant 'p', 0.375
|
36
|
-
|
37
|
-
# mezzo-piano
|
38
|
-
define_constant 'mp', 0.5
|
39
|
-
|
40
|
-
# mezzo-forte
|
41
|
-
define_constant 'mf', 0.625
|
42
|
-
|
43
|
-
# forte
|
44
|
-
define_constant 'f', 0.75
|
45
|
-
|
46
|
-
# fortissimo
|
47
|
-
define_constant 'ff', 0.875
|
48
|
-
|
49
|
-
# fortississimo
|
50
|
-
define_constant 'fff', 1.0
|
51
|
-
|
52
|
-
# The values of all "psuedo constants" defined in this module
|
53
|
-
INTENSITIES = [ppp, pp, p, mp, mf, f, ff, fff].freeze
|
54
|
-
|
55
|
-
# The names of all "psuedo constants" defined in this module
|
56
|
-
INTENSITY_NAMES = %w[ppp pp p mp mf f ff fff].freeze
|
57
|
-
|
58
|
-
# Lookup the value of an intensity constant by name.
|
59
|
-
# This method supports appending '+' or '-' for more fine-grained values.
|
60
|
-
# '+' and '-' add and subtract 1/24, respectively (enforcing the upper bound of 1.0 for 'fff+').
|
61
|
-
# @example lookup value of 'mp+', which is 0.5416666666666666 (0.5 + 1/24.0)
|
62
|
-
# MTK::Intensities['mp+']
|
63
|
-
def self.[](name)
|
64
|
-
return 1.0 if name == "fff+" # special case because "fff" is already the maximum
|
65
|
-
|
66
|
-
modifier = nil
|
67
|
-
if name =~ /(\w+)([+-])/
|
68
|
-
name = $1
|
69
|
-
modifier = $2
|
70
|
-
end
|
71
|
-
|
72
|
-
value = send name
|
73
|
-
value += 1.0/24 if modifier == '+'
|
74
|
-
value -= 1.0/24 if modifier == '-'
|
75
|
-
value
|
76
|
-
rescue
|
77
|
-
nil
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
module MTK
|
2
|
-
|
3
|
-
# Defines a constant for intervals up to an octave using diatonic naming conventions (see http://en.wikipedia.org/wiki/Interval_(music)#Main_intervals)
|
4
|
-
#
|
5
|
-
# Naming conventions
|
6
|
-
# P#: perfect interval
|
7
|
-
# M#: major interval
|
8
|
-
# m#: minor interval
|
9
|
-
# TT: tritone (AKA augmented 4th or diminshed 5th)
|
10
|
-
#
|
11
|
-
# These can be thought of like constants, but in order to succintly distinguish 'm2' (minor) from 'M2' (major),
|
12
|
-
# it was necessary to use lower-case names for some of the values and therefore define them as "pseudo constant" methods.
|
13
|
-
# The methods are available either through the module (MTK::Intervals::m2) or via mixin (include MTK::Intervals; m2)
|
14
|
-
module Intervals
|
15
|
-
extend Helper::PseudoConstants
|
16
|
-
|
17
|
-
# NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
|
18
|
-
|
19
|
-
# perfect unison
|
20
|
-
# @macro [attach] interval.define_constant
|
21
|
-
# @attribute [r]
|
22
|
-
# @return [$2] number of semitones in the interval $1
|
23
|
-
define_constant 'P1', 0
|
24
|
-
|
25
|
-
# minor second
|
26
|
-
# @macro [attach] interval.define_constant
|
27
|
-
# @attribute [r]
|
28
|
-
# @return [$2] number of semitones in the interval $1
|
29
|
-
define_constant 'm2', 1
|
30
|
-
|
31
|
-
# major second
|
32
|
-
define_constant 'M2', 2
|
33
|
-
|
34
|
-
# minor third
|
35
|
-
define_constant 'm3', 3
|
36
|
-
|
37
|
-
# major third
|
38
|
-
define_constant 'M3', 4
|
39
|
-
|
40
|
-
# pefect fourth
|
41
|
-
define_constant 'P4', 5
|
42
|
-
|
43
|
-
# tritone (AKA augmented fourth or diminished fifth)
|
44
|
-
define_constant 'TT', 6
|
45
|
-
|
46
|
-
# perfect fifth
|
47
|
-
define_constant 'P5', 7
|
48
|
-
|
49
|
-
# minor sixth
|
50
|
-
define_constant 'm6', 8
|
51
|
-
|
52
|
-
# major sixth
|
53
|
-
define_constant 'M6', 9
|
54
|
-
|
55
|
-
# minor seventh
|
56
|
-
define_constant 'm7', 10
|
57
|
-
|
58
|
-
# major seventh
|
59
|
-
define_constant 'M7', 11
|
60
|
-
|
61
|
-
# pefect octave
|
62
|
-
define_constant 'P8', 12
|
63
|
-
|
64
|
-
# The values of all "psuedo constants" defined in this module
|
65
|
-
INTERVALS = [P1, m2, M2, m3, M3, P4, TT, P5, m6, M6, m7, M7, P8].freeze
|
66
|
-
|
67
|
-
# The names of all "psuedo constants" defined in this module
|
68
|
-
INTERVAL_NAMES = %w[P1 m2 M2 m3 M3 P4 TT P5 m6 M6 m7 M7 P8].freeze
|
69
|
-
|
70
|
-
# Lookup the value of an interval constant by name.
|
71
|
-
# @example lookup value of 'M3', which is 4
|
72
|
-
# MTK::Intervals['M3']
|
73
|
-
def self.[](name)
|
74
|
-
send name
|
75
|
-
rescue
|
76
|
-
begin
|
77
|
-
const_get name
|
78
|
-
rescue
|
79
|
-
nil
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module MTK
|
2
|
-
|
3
|
-
# Defines a constant for each {PitchClass} in the Western chromatic scale.
|
4
|
-
|
5
|
-
module PitchClasses
|
6
|
-
|
7
|
-
# The values of all "psuedo constants" defined in this module
|
8
|
-
PITCH_CLASSES = []
|
9
|
-
|
10
|
-
# The names of all "psuedo constants" defined in this module
|
11
|
-
PITCH_CLASS_NAMES = PitchClass::NAMES
|
12
|
-
|
13
|
-
for name in PITCH_CLASS_NAMES
|
14
|
-
pc = PitchClass[name]
|
15
|
-
PITCH_CLASSES << pc
|
16
|
-
const_set name, pc
|
17
|
-
end
|
18
|
-
|
19
|
-
PITCH_CLASSES.freeze
|
20
|
-
|
21
|
-
# Lookup the value of an pitch class constant by name.
|
22
|
-
# @example lookup value of 'C'
|
23
|
-
# MTK::PitchClasses['C']
|
24
|
-
# @see PitchClass.[]
|
25
|
-
def self.[](name)
|
26
|
-
begin
|
27
|
-
const_get name
|
28
|
-
rescue
|
29
|
-
nil
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module MTK
|
2
|
-
|
3
|
-
# Defines a constants for each {Pitch} in the standard MIDI range using scientific pitch notation.
|
4
|
-
#
|
5
|
-
# See http://en.wikipedia.org/wiki/Scientific_pitch_notation
|
6
|
-
#
|
7
|
-
# @note Because the character '#' cannot be used in the name of a constant,
|
8
|
-
# the "black key" pitches are all named as flats with 'b' (for example, Gb3 or Cb4)
|
9
|
-
# @note Because the character '-' (minus) cannot be used in the name of a constant,
|
10
|
-
# the low pitches use '_' (underscore) in place of '-' (minus) (for example C_1).
|
11
|
-
module Pitches
|
12
|
-
|
13
|
-
# The values of all "psuedo constants" defined in this module
|
14
|
-
PITCHES = []
|
15
|
-
|
16
|
-
# The names of all "psuedo constants" defined in this module
|
17
|
-
PITCH_NAMES = []
|
18
|
-
|
19
|
-
128.times do |note_number|
|
20
|
-
pitch = Pitch.from_i( note_number )
|
21
|
-
PITCHES << pitch
|
22
|
-
|
23
|
-
octave_str = pitch.octave.to_s.sub(/-/,'_') # '_1' for -1
|
24
|
-
name = "#{pitch.pitch_class}#{octave_str}"
|
25
|
-
PITCH_NAMES << name
|
26
|
-
|
27
|
-
const_set name, pitch
|
28
|
-
end
|
29
|
-
|
30
|
-
PITCHES.freeze
|
31
|
-
PITCH_NAMES.freeze
|
32
|
-
|
33
|
-
# Lookup the value of an pitch constant by name.
|
34
|
-
# @example lookup value of 'C3'
|
35
|
-
# MTK::Pitches['C3']
|
36
|
-
# @see Pitch.from_s
|
37
|
-
# @note Unlike {Pitch.from_s} this method will accept either '_' (underscore) or '-' (minus) and treat it like '-' (minus)
|
38
|
-
# @note Unlike {Pitch.from_s} this method only accepts the accidental 'b'
|
39
|
-
def self.[](name)
|
40
|
-
begin
|
41
|
-
const_get name.sub('-','_')
|
42
|
-
rescue
|
43
|
-
nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
data/lib/mtk/event.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
module MTK
|
2
|
-
|
3
|
-
# An abstract musical event that has an intensity and a duration
|
4
|
-
# @abstract
|
5
|
-
class Event
|
6
|
-
|
7
|
-
# intensity of the note as a value in the range 0.0 - 1.0
|
8
|
-
attr_reader :intensity
|
9
|
-
|
10
|
-
def initialize(intensity, duration)
|
11
|
-
@intensity, @duration = intensity, duration
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.from_hash(hash)
|
15
|
-
new hash[:intensity], hash[:duration]
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_hash
|
19
|
-
{ :intensity => @intensity, :duration => @duration }
|
20
|
-
end
|
21
|
-
|
22
|
-
def clone_with(hash)
|
23
|
-
self.class.from_hash(to_hash.merge hash)
|
24
|
-
end
|
25
|
-
|
26
|
-
def scale_intensity(scaling_factor)
|
27
|
-
clone_with :intensity => @intensity * scaling_factor.to_f
|
28
|
-
end
|
29
|
-
|
30
|
-
def scale_duration(scaling_factor)
|
31
|
-
clone_with :duration => @duration * scaling_factor.to_f
|
32
|
-
end
|
33
|
-
|
34
|
-
# intensity scaled to the MIDI range 0-127
|
35
|
-
def velocity
|
36
|
-
@velocity ||= (127 * @intensity).round
|
37
|
-
end
|
38
|
-
|
39
|
-
# Duration of the Event in beats (e.g. 1.0 is a quarter note in 4/4 time signatures)
|
40
|
-
# This is the absolute value of the duration attribute used to construct the object.
|
41
|
-
# @see rest?
|
42
|
-
def duration
|
43
|
-
@abs_duration ||= @duration.abs
|
44
|
-
end
|
45
|
-
|
46
|
-
# By convention, any events with negative durations are considered a rest
|
47
|
-
def rest?
|
48
|
-
@duration < 0
|
49
|
-
end
|
50
|
-
|
51
|
-
def duration_in_pulses(pulses_per_beat)
|
52
|
-
@duration_in_pulses ||= (duration * pulses_per_beat).round
|
53
|
-
end
|
54
|
-
|
55
|
-
def == other
|
56
|
-
other.respond_to? :intensity and @intensity == other.intensity and
|
57
|
-
other.respond_to? :duration and @duration == other.duration
|
58
|
-
end
|
59
|
-
|
60
|
-
def to_s
|
61
|
-
"#{sprintf '%.2f',@intensity}, #{sprintf '%.2f',@duration}"
|
62
|
-
end
|
63
|
-
|
64
|
-
def inspect
|
65
|
-
"#@intensity, #@duration"
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module MTK::Helper
|
2
|
-
|
3
|
-
# Given a method #elements, which returns an Array of elements in the collection,
|
4
|
-
# including this module will make the class Enumerable and provide various methods you'd expect from an Array.
|
5
|
-
module Collection
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
# A mutable array of elements in this collection
|
9
|
-
def to_a
|
10
|
-
Array.new(elements) # we construct a new array since some including classes make elements be immutable
|
11
|
-
end
|
12
|
-
|
13
|
-
# The number of elements in this collection
|
14
|
-
def size
|
15
|
-
elements.size
|
16
|
-
end
|
17
|
-
alias length size
|
18
|
-
|
19
|
-
def empty?
|
20
|
-
elements.nil? or elements.size == 0
|
21
|
-
end
|
22
|
-
|
23
|
-
# The each iterator for providing Enumerable functionality
|
24
|
-
def each &block
|
25
|
-
elements.each &block
|
26
|
-
end
|
27
|
-
|
28
|
-
# The first element
|
29
|
-
def first(n=nil)
|
30
|
-
n ? elements.first(n) : elements.first
|
31
|
-
end
|
32
|
-
|
33
|
-
# The last element
|
34
|
-
def last(n=nil)
|
35
|
-
n ? elements.last(n) : elements.last
|
36
|
-
end
|
37
|
-
|
38
|
-
# The element with the given index
|
39
|
-
def [](index)
|
40
|
-
elements[index]
|
41
|
-
end
|
42
|
-
|
43
|
-
def repeat(times=2)
|
44
|
-
full_repetitions, fractional_repetitions = times.floor, times%1 # split into int and fractional part
|
45
|
-
repeated = elements * full_repetitions
|
46
|
-
repeated += elements[0...elements.size*fractional_repetitions]
|
47
|
-
clone_with repeated
|
48
|
-
end
|
49
|
-
|
50
|
-
def permute
|
51
|
-
clone_with elements.shuffle
|
52
|
-
end
|
53
|
-
alias shuffle permute
|
54
|
-
|
55
|
-
def rotate(offset=1)
|
56
|
-
clone_with elements.rotate(offset)
|
57
|
-
end
|
58
|
-
|
59
|
-
def concat(other)
|
60
|
-
other_elements = (other.respond_to? :elements) ? other.elements : other
|
61
|
-
clone_with(elements + other_elements)
|
62
|
-
end
|
63
|
-
|
64
|
-
def reverse
|
65
|
-
clone_with elements.reverse
|
66
|
-
end
|
67
|
-
alias retrograde reverse
|
68
|
-
|
69
|
-
def ==(other)
|
70
|
-
if other.respond_to? :elements
|
71
|
-
if other.respond_to? :options
|
72
|
-
elements == other.elements and @options == other.options
|
73
|
-
else
|
74
|
-
elements == other.elements
|
75
|
-
end
|
76
|
-
else
|
77
|
-
elements == other
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Create a copy of the collection.
|
82
|
-
# In order to use this method, the including class must implement .from_a()
|
83
|
-
def clone
|
84
|
-
clone_with to_a
|
85
|
-
end
|
86
|
-
|
87
|
-
#################################
|
88
|
-
private
|
89
|
-
|
90
|
-
# "clones" the object with the given elements, attempting to maintain any @options
|
91
|
-
# This is designed to work with 2 argument constructors: def initialize(elements, options={})
|
92
|
-
def clone_with elements
|
93
|
-
from_a = self.class.method(:from_a)
|
94
|
-
if from_a.arity == -2
|
95
|
-
from_a[elements, (@options || {})]
|
96
|
-
else
|
97
|
-
from_a[elements]
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
if not Array.instance_methods.include? :rotate
|
106
|
-
# Array#rotate is only available in Ruby 1.9, so we may have to implement it
|
107
|
-
class Array
|
108
|
-
def rotate(offset=1)
|
109
|
-
return self if empty?
|
110
|
-
offset %= length
|
111
|
-
self[offset..-1]+self[0...offset]
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|