Class: HeadMusic::Notation::MusicXML::DurationWriter
- Inherits:
-
Object
- Object
- HeadMusic::Notation::MusicXML::DurationWriter
- Defined in:
- lib/head_music/notation/music_xml/duration_writer.rb
Overview
Converts a HeadMusic::Rudiment::RhythmicValue into the
Defined Under Namespace
Classes: Component
Constant Summary collapse
- TYPES_BY_UNIT_NAME =
MusicXML’s
element uses these fixed names rather than the gem's American duration names. { "maxima" => "maxima", "longa" => "long", "double whole" => "breve", "whole" => "whole", "half" => "half", "quarter" => "quarter", "eighth" => "eighth", "sixteenth" => "16th", "thirty-second" => "32nd", "sixty-fourth" => "64th", "hundred twenty-eighth" => "128th", "two hundred fifty-sixth" => "256th" }.freeze
Instance Attribute Summary collapse
-
#divisions ⇒ Object
readonly
Returns the value of attribute divisions.
Class Method Summary collapse
-
.single_quarter_fraction(rhythmic_value) ⇒ Object
A rhythmic value’s own duration in quarter notes, ignoring any tied chain.
Instance Method Summary collapse
-
#build_component(link, index, length) ⇒ Object
private
-
#chain(rhythmic_value) ⇒ Object
private
-
#components(rhythmic_value) ⇒ Object
-
#initialize(divisions) ⇒ DurationWriter
constructor
A new instance of DurationWriter.
-
#integer_duration(link) ⇒ Object
private
-
#type_for(link) ⇒ Object
private
Constructor Details
#initialize(divisions) ⇒ DurationWriter
Returns a new instance of DurationWriter.
28 29 30 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 28 def initialize(divisions) @divisions = divisions end |
Instance Attribute Details
#divisions ⇒ Object (readonly)
Returns the value of attribute divisions.
26 27 28 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 26 def divisions @divisions end |
Class Method Details
.single_quarter_fraction(rhythmic_value) ⇒ Object
A rhythmic value’s own duration in quarter notes, ignoring any tied chain. RhythmicValue’s own methods (relative_value, total_value, ticks) return Floats, so the fraction is rebuilt here from the unit’s integer numerator and denominator to keep the divisions arithmetic exact.
37 38 39 40 41 42 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 37 def self.single_quarter_fraction(rhythmic_value) unit = rhythmic_value.unit dots = rhythmic_value.dots # A value with d dots spans (2^(d+1) - 1) / 2^d of its own unit. Rational(unit.numerator, unit.denominator) * Rational((2**(dots + 1)) - 1, 2**dots) * 4 end |
Instance Method Details
#build_component(link, index, length) ⇒ Object (private)
57 58 59 60 61 62 63 64 65 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 57 def build_component(link, index, length) Component.new( duration: integer_duration(link), type: type_for(link), dots: link.dots, tie_start: index != length - 1, tie_stop: index != 0 ) end |
#chain(rhythmic_value) ⇒ Object (private)
51 52 53 54 55 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 51 def chain(rhythmic_value) links = [rhythmic_value] links << links.last.tied_value while links.last.tied_value links end |
#components(rhythmic_value) ⇒ Object
44 45 46 47 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 44 def components(rhythmic_value) links = chain(rhythmic_value) links.each_with_index.map { |link, index| build_component(link, index, links.length) } end |
#integer_duration(link) ⇒ Object (private)
67 68 69 70 71 72 73 74 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 67 def integer_duration(link) fraction = self.class.single_quarter_fraction(link) * divisions unless fraction.denominator == 1 raise HeadMusic::Notation::MusicXML::RenderError, "cannot express #{link} as an integer duration at #{divisions} divisions per quarter note" end fraction.numerator end |
#type_for(link) ⇒ Object (private)
76 77 78 79 80 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 76 def type_for(link) TYPES_BY_UNIT_NAME.fetch(link.unit_name) do raise HeadMusic::Notation::MusicXML::RenderError, "no MusicXML note type is known for #{link.unit_name}" end end |