mtk 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|