module MTK
The top level module for this library
And now that we’ve got some colors we can define colored constants
Constants
- PITCH_CLASSES
All 12 pitch classes in the chromatic scale. The index of each pitch class is the pitch class’s numeric {#value}.
Public Class Methods
Construct an ordered {MTK::Groups::Chord} with no duplicates. @see MTK::Groups::Chord @see MTK::Groups::Melody
# File lib/mtk/groups/chord.rb, line 51 def Chord(*anything) MTK::Groups::Chord.new MTK::Groups.to_pitches(*anything) end
Construct a {Duration} from any supported type
# File lib/mtk/core/duration.rb, line 217 def Duration(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Duration[anything] when String, Symbol then MTK::Core::Duration.from_s(anything) when Duration then anything else raise "Duration doesn't understand #{anything.class}" end end
Construct a {Duration} from any supported type
# File lib/mtk/core/intensity.rb, line 149 def Intensity(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Intensity[anything] when String, Symbol then MTK::Core::Intensity.from_s(anything) when Intensity then anything else raise "Intensity doesn't understand #{anything.class}" end end
Construct a {Duration} from any supported type
# File lib/mtk/core/interval.rb, line 153 def Interval(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Interval[anything] when String, Symbol then MTK::Core::Interval.from_s(anything) when Interval then anything else raise "Interval doesn't understand #{anything.class}" end end
Shortcut for MTK::IO::MIDIFile.new
@note Only available if you require ‘mtk/midi/file’
# File lib/mtk/io/midi_file.rb, line 213 def MIDIFile(f) ::MTK::IO::MIDIFile.new(f) end
Construct an ordered {MTK::Groups::Melody} that allows duplicates @see MTK::Groups::Melody @see MTK::Groups::Chord
# File lib/mtk/groups/melody.rb, line 91 def Melody(*anything) MTK::Groups::Melody.new MTK::Groups.to_pitches(*anything) end
Construct a {Events::Note} from a list of any supported type for the arguments: pitch, intensity, duration, channel
# File lib/mtk/events/note.rb, line 72 def Note(*anything) anything = anything.first if anything.size == 1 case anything when MTK::Events::Note then anything when MTK::Core::Pitch then MTK::Events::Note.new(anything) when Array pitch = nil duration = nil intensity = nil channel = nil unknowns = [] anything.each do |item| case item when MTK::Core::Pitch then pitch = item when MTK::Core::Duration then duration = item when MTK::Core::Intensity then intensity = item else unknowns << item end end pitch = MTK.Pitch(unknowns.shift) if pitch.nil? and not unknowns.empty? raise "MTK::Note() couldn't find a pitch in arguments: #{anything.inspect}" if pitch.nil? duration = MTK.Duration(unknowns.shift) if duration.nil? and not unknowns.empty? intensity = MTK.Intensity(unknowns.shift) if intensity.nil? and not unknowns.empty? channel = unknowns.shift.to_i if channel.nil? and not unknowns.empty? duration ||= MTK::Events::Note::DEFAULT_DURATION intensity ||= MTK::Events::Note::DEFAULT_INTENSITY MTK::Events::Note.new( pitch, duration, intensity, channel ) else raise "MTK::Note() doesn't understand #{anything.class}" end end
Construct a {Pitch} from any supported type
# File lib/mtk/core/pitch.rb, line 139 def Pitch(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Pitch.from_f(anything) when String, Symbol then MTK::Core::Pitch.from_s(anything) when MTK::Core::Pitch then anything when Array if anything.length == 2 MTK::Core::Pitch[*anything] else MTK::Core::Pitch.new(*anything) end else raise ArgumentError.new("Pitch doesn't understand #{anything.class}") end end
Construct a {Groups::PitchClassSet} @see Groups::PitchClassSet#initialize
# File lib/mtk/groups/pitch_class_set.rb, line 158 def PitchClassSet(*anything) MTK::Groups::PitchClassSet.new MTK::Groups.to_pitch_classes(*anything) end
Construct a {Events::Rest} from a list of any supported type for the arguments: pitch, intensity, duration, channel
# File lib/mtk/events/rest.rb, line 54 def Rest(*anything) anything = anything.first if anything.size == 1 case anything when MTK::Events::Rest then anything when MTK::Events::Event then MTK::Events::Rest.new(anything.duration, anything.channel) when Numeric then MTK::Events::Rest.new(anything) when Duration then MTK::Events::Rest.new(anything) when Array duration = nil channel = nil unknowns = [] anything.each do |item| case item when MTK::Core::Duration then duration = item else unknowns << item end end duration = MTK.Duration(unknowns.shift) if duration.nil? and not unknowns.empty? raise "MTK::Rest() couldn't find a duration in arguments: #{anything.inspect}" if duration.nil? channel = unknowns.shift.to_i if channel.nil? and not unknowns.empty? MTK::Events::Rest.new(duration, channel) else raise "MTK::Rest() doesn't understand #{anything.class}" end end
return the pitch class with the given float rounded to the nearest integer, mod 12 @param value [Float,#to_f]
# File lib/mtk/core/pitch_class.rb, line 112 def self.from_f(value) from_i value.to_f.round end
Lookup a PitchClass by name. @param name [String,#to_s] one of {VALID_NAMES} (case-insensitive)
# File lib/mtk/core/pitch_class.rb, line 84 def self.from_name(name) @flyweight[name] ||= ( valid_name = name.to_s.capitalize value = VALUES_BY_NAME[valid_name] or raise ArgumentError.new("Invalid PitchClass name: #{name}") new(valid_name,value) ) end
return the pitch class with the given integer value mod 12 @param value [Integer,#to_i]
# File lib/mtk/core/pitch_class.rb, line 102 def self.from_value(value) PITCH_CLASSES[value.to_i % 12] end
Public Instance Methods
Transpose this pitch class by adding it’s value to the value given (mod 12) @param interval [PitchClass,Float,#to_f]
# File lib/mtk/core/pitch_class.rb, line 149 def + interval new_value = (value + interval.to_f).round self.class.from_value new_value end
Transpose this pitch class by subtracing the given value from this value (mod 12) @param interval [PitchClass,Float,#to_f]
# File lib/mtk/core/pitch_class.rb, line 157 def - interval new_value = (value - interval.to_f).round self.class.from_value new_value end
Compare a pitch class with another pitch class or integer value @param other [PitchClass,#to_i] @return -1, 0, or +1 depending on whether this pitch class’s value is less than, equal to, or greater than the other object’s integer value @see ruby-doc.org/core-1.9.3/Comparable.html
# File lib/mtk/core/pitch_class.rb, line 127 def <=> other @value <=> other.to_i end
Compare 2 pitch classes for equal values. @param other [PitchClass] @return true if this pitch class’s value is equal to the other pitch class’s value
# File lib/mtk/core/pitch_class.rb, line 119 def == other other.is_a? PitchClass and other.value == @value end
the smallest interval in semitones that needs to be added to this PitchClass to reach the given PitchClass @param pitch_class [PitchClass,#value]
# File lib/mtk/core/pitch_class.rb, line 171 def distance_to(pitch_class) delta = (pitch_class.value - value) % 12 if delta > 6 delta -= 12 elsif delta == 6 and to_i >= 6 # this is a special edge case to prevent endlessly ascending pitch sequences when alternating between two pitch classes a tritone apart delta = -6 end delta end
Inverts (mirrors) the pitch class around the given center @param center [PitchClass,Pitch,Float,#to_f] the value to “mirror” this pitch class around
# File lib/mtk/core/pitch_class.rb, line 164 def invert(center) delta = (2*(center.to_f - value)).round self + delta end
This pitch class’s {#value} as a floating point number
# File lib/mtk/core/pitch_class.rb, line 143 def to_f @value.to_f end
This pitch class’s integer {#value}
# File lib/mtk/core/pitch_class.rb, line 138 def to_i @value.to_i end
This pitch class’s normalized {#name}. @see NAMES
# File lib/mtk/core/pitch_class.rb, line 133 def to_s @name.to_s end
Private Instance Methods
Construct an ordered {MTK::Groups::Chord} with no duplicates. @see MTK::Groups::Chord @see MTK::Groups::Melody
# File lib/mtk/groups/chord.rb, line 51 def Chord(*anything) MTK::Groups::Chord.new MTK::Groups.to_pitches(*anything) end
Construct a {Duration} from any supported type
# File lib/mtk/core/duration.rb, line 217 def Duration(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Duration[anything] when String, Symbol then MTK::Core::Duration.from_s(anything) when Duration then anything else raise "Duration doesn't understand #{anything.class}" end end
Construct a {Duration} from any supported type
# File lib/mtk/core/intensity.rb, line 149 def Intensity(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Intensity[anything] when String, Symbol then MTK::Core::Intensity.from_s(anything) when Intensity then anything else raise "Intensity doesn't understand #{anything.class}" end end
Construct a {Duration} from any supported type
# File lib/mtk/core/interval.rb, line 153 def Interval(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Interval[anything] when String, Symbol then MTK::Core::Interval.from_s(anything) when Interval then anything else raise "Interval doesn't understand #{anything.class}" end end
Shortcut for MTK::IO::MIDIFile.new
@note Only available if you require ‘mtk/midi/file’
# File lib/mtk/io/midi_file.rb, line 213 def MIDIFile(f) ::MTK::IO::MIDIFile.new(f) end
Construct an ordered {MTK::Groups::Melody} that allows duplicates @see MTK::Groups::Melody @see MTK::Groups::Chord
# File lib/mtk/groups/melody.rb, line 91 def Melody(*anything) MTK::Groups::Melody.new MTK::Groups.to_pitches(*anything) end
Construct a {Events::Note} from a list of any supported type for the arguments: pitch, intensity, duration, channel
# File lib/mtk/events/note.rb, line 72 def Note(*anything) anything = anything.first if anything.size == 1 case anything when MTK::Events::Note then anything when MTK::Core::Pitch then MTK::Events::Note.new(anything) when Array pitch = nil duration = nil intensity = nil channel = nil unknowns = [] anything.each do |item| case item when MTK::Core::Pitch then pitch = item when MTK::Core::Duration then duration = item when MTK::Core::Intensity then intensity = item else unknowns << item end end pitch = MTK.Pitch(unknowns.shift) if pitch.nil? and not unknowns.empty? raise "MTK::Note() couldn't find a pitch in arguments: #{anything.inspect}" if pitch.nil? duration = MTK.Duration(unknowns.shift) if duration.nil? and not unknowns.empty? intensity = MTK.Intensity(unknowns.shift) if intensity.nil? and not unknowns.empty? channel = unknowns.shift.to_i if channel.nil? and not unknowns.empty? duration ||= MTK::Events::Note::DEFAULT_DURATION intensity ||= MTK::Events::Note::DEFAULT_INTENSITY MTK::Events::Note.new( pitch, duration, intensity, channel ) else raise "MTK::Note() doesn't understand #{anything.class}" end end
Construct a {Pitch} from any supported type
# File lib/mtk/core/pitch.rb, line 139 def Pitch(*anything) anything = anything.first if anything.length == 1 case anything when Numeric then MTK::Core::Pitch.from_f(anything) when String, Symbol then MTK::Core::Pitch.from_s(anything) when MTK::Core::Pitch then anything when Array if anything.length == 2 MTK::Core::Pitch[*anything] else MTK::Core::Pitch.new(*anything) end else raise ArgumentError.new("Pitch doesn't understand #{anything.class}") end end
Construct a {Groups::PitchClassSet} @see Groups::PitchClassSet#initialize
# File lib/mtk/groups/pitch_class_set.rb, line 158 def PitchClassSet(*anything) MTK::Groups::PitchClassSet.new MTK::Groups.to_pitch_classes(*anything) end
Construct a {Events::Rest} from a list of any supported type for the arguments: pitch, intensity, duration, channel
# File lib/mtk/events/rest.rb, line 54 def Rest(*anything) anything = anything.first if anything.size == 1 case anything when MTK::Events::Rest then anything when MTK::Events::Event then MTK::Events::Rest.new(anything.duration, anything.channel) when Numeric then MTK::Events::Rest.new(anything) when Duration then MTK::Events::Rest.new(anything) when Array duration = nil channel = nil unknowns = [] anything.each do |item| case item when MTK::Core::Duration then duration = item else unknowns << item end end duration = MTK.Duration(unknowns.shift) if duration.nil? and not unknowns.empty? raise "MTK::Rest() couldn't find a duration in arguments: #{anything.inspect}" if duration.nil? channel = unknowns.shift.to_i if channel.nil? and not unknowns.empty? MTK::Events::Rest.new(duration, channel) else raise "MTK::Rest() doesn't understand #{anything.class}" end end