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. Four quarter notes span a whole note, so the value’s fraction of its own unit is scaled by four.
35 36 37 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 35 def self.single_quarter_fraction(rhythmic_value) HeadMusic::Notation::DottedDuration.dotted_unit_fraction(rhythmic_value) * 4 end |
Instance Method Details
#build_component(link, index, length) ⇒ Object (private)
52 53 54 55 56 57 58 59 60 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 52 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)
46 47 48 49 50 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 46 def chain(rhythmic_value) links = [rhythmic_value] links << links.last.tied_value while links.last.tied_value links end |
#components(rhythmic_value) ⇒ Object
39 40 41 42 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 39 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)
62 63 64 65 66 67 68 69 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 62 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)
71 72 73 74 75 |
# File 'lib/head_music/notation/music_xml/duration_writer.rb', line 71 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 |