Class: Musa::MusicXML::Builder::Internal::Time Private

Inherits:
Object
  • Object
show all
Includes:
Extension::With, Helper::ToXML
Defined in:
lib/musa-dsl/musicxml/builder/attributes.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Time signature specification.

Time represents time signatures in MusicXML. It supports simple meters (4/4, 3/4), compound meters (6/8), complex meters (5/4), and compound time signatures with multiple beat groups. Also supports unmeasured time (senza misura) for cadenzas and free-form sections.

For multi-staff parts (like piano), the number attribute specifies which staff the time signature applies to.

Simple Time Signatures

Most common meters use a single beats/beat_type pair:

  • 4/4 (common time): beats=4, beat_type=4
  • 3/4 (waltz): beats=3, beat_type=4
  • 6/8 (compound): beats=6, beat_type=8
  • 2/2 (cut time): beats=2, beat_type=2

Reaching it

Time signatures are written through the attributes DSL rather than constructed directly. The examples below are against:

measure = Measure.new(1, divisions: 2)

The class itself is Musa::MusicXML::Builder::Internal::Time, which collides with Ruby's own Time anywhere outside this file.

Compound Time Signatures

Some meters combine multiple beat groups (e.g., 3+2+3/8). These are built by calling #add_beats once per group, either on the object or inside the configuration block, which is the only route the DSL has -- the adder builds the Time itself and hands back no reference.

Senza Misura (Unmeasured Time)

For cadenzas and free-form sections without strict meter, pass senza_misura: ''.

Examples:

Common time (4/4)

measure.attributes { time beats: 4, beat_type: 4 }

Waltz (3/4)

measure.attributes { time beats: 3, beat_type: 4 }

Compound meter (6/8)

measure.attributes { time beats: 6, beat_type: 8 }

Compound signature (3+2+3/8)

signature = Musa::MusicXML::Builder::Internal::Time.new
signature.add_beats(beats: 3, beat_type: 8)
signature.add_beats(beats: 2, beat_type: 8)
signature.add_beats(beats: 3, beat_type: 8)
signature.beats.size  # => 3

The same, through the DSL

compound = measure.attributes do
  time do
    add_beats beats: 3, beat_type: 8
    add_beats beats: 2, beat_type: 8
    add_beats beats: 3, beat_type: 8
  end
end
compound.times.first.beats.size  # => 3

Piano - different time per staff

measure.attributes do
  time 1, beats: 4, beat_type: 4  # Treble: 4/4
  time 2, beats: 3, beat_type: 4  # Bass: 3/4
end

Cadenza (unmeasured)

measure.attributes { time senza_misura: '' }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(number = nil, senza_misura: nil, beats: nil, beat_type: nil, &block) ⇒ Time

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a time signature.

Examples:

4/4 time

measure.attributes { time beats: 4, beat_type: 4 }

6/8 time

measure.attributes { time beats: 6, beat_type: 8 }

Unmeasured time

measure.attributes { time senza_misura: '' }

Compound meter (3+2+3/8), which needs the block

attributes = Musa::MusicXML::Builder::Internal::Attributes.new
attributes.time do
  add_beats beats: 3, beat_type: 8
  add_beats beats: 2, beat_type: 8
  add_beats beats: 3, beat_type: 8
end
attributes.times.first.beats.size  # => 3

Parameters:

  • number (Integer, nil) (defaults to: nil)

    staff number (for multi-staff parts)

  • senza_misura (String, nil) (defaults to: nil)

    unmeasured time indicator (typically empty string)

  • beats (Integer, nil) (defaults to: nil)

    time signature numerator (beats per measure)

  • beat_type (Integer, nil) (defaults to: nil)

    time signature denominator (note value per beat)



214
215
216
217
218
219
220
221
222
223
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 214

def initialize(number = nil, senza_misura: nil, beats: nil, beat_type: nil, &block)
  @number = number

  @senza_misura = senza_misura unless beats && beat_type
  @beats = []

  add_beats beats: beats, beat_type: beat_type if beats && beat_type

  with &block if block_given?
end

Instance Attribute Details

#beatsArray<Hash> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Array of beat groups for compound time signatures.

Returns:



235
236
237
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 235

def beats
  @beats
end

#numberInteger? (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Staff number (for multi-staff instruments).

Returns:

  • (Integer, nil)


227
228
229
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 227

def number
  @number
end

#senza_misuraString?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Senza misura indicator for unmeasured time.

Returns:



231
232
233
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 231

def senza_misura
  @senza_misura
end

Instance Method Details

#_to_xml(io, indent:, tabs:) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Generates the time signature XML element.

Parameters:

  • io (IO)

    output stream

  • indent (Integer)

    indentation level

  • tabs (String)

    tab string



264
265
266
267
268
269
270
271
272
273
274
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 264

def _to_xml(io, indent:, tabs:)
  io.puts "#{tabs}<time#{" number=\"#{@number.to_i}\"" if @number}>"

  io.puts "#{tabs}\t<senza-misura>#{@senza_misura}</senza-misura>" if @senza_misura
  @beats.each do |beats|
    io.puts "#{tabs}\t<beats>#{beats[:beats].to_i}</beats>"
    io.puts "#{tabs}\t<beat-type>#{beats[:beat_type].to_i}</beat-type>"
  end

  io.puts "#{tabs}</time>"
end

#add_beats(beats:, beat_type:) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Adds a beat group to the time signature.

Used for compound time signatures that combine multiple beat groups (e.g., 3+2+3/8 or 2+2+3/4).

Examples:

Complex meter (3+2+3/8)

signature = Musa::MusicXML::Builder::Internal::Time.new
signature.add_beats(beats: 3, beat_type: 8)
signature.add_beats(beats: 2, beat_type: 8)
signature.add_beats(beats: 3, beat_type: 8)
signature.beats.size  # => 3

Parameters:

  • beats (Integer)

    numerator for this beat group

  • beat_type (Integer)

    denominator for this beat group



252
253
254
# File 'lib/musa-dsl/musicxml/builder/attributes.rb', line 252

def add_beats(beats:, beat_type:)
  @beats << { beats: beats, beat_type: beat_type }
end

#to_xml(io = nil, indent: nil) ⇒ IO, StringIO Originally defined in module Helper::ToXML

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts the object to MusicXML format.

This method sets up the IO stream and indentation, then delegates to the private _to_xml method for actual XML generation.

Examples:

Writing to file

element = Measure.new(1, divisions: 2)
File.open('output.xml', 'w') do |f|
  element.to_xml(f)
end

Getting XML as string

xml_string = element.to_xml.string
xml_string.start_with?('<measure')  # => true

Parameters:

  • io (IO, StringIO, nil) (defaults to: nil)

    output stream (creates StringIO if nil)

  • indent (Integer, nil) (defaults to: nil)

    indentation level (default: 0)

Returns:

  • (IO, StringIO)

    the io parameter, containing the XML output

#with(*value_parameters, keep_block_context: nil, **key_parameters, &block) ⇒ Object Originally defined in module Extension::With

Note:

The _ parameter is special: when present, it signals "keep caller's context" and receives self (the object) as its value.

Note:

Uses SmartProcBinder internally to handle parameter matching.

Executes a block with flexible context and parameter handling.

Parameters:

  • value_parameters (Array)

    positional parameters to pass to block.

  • keep_block_context (Boolean, nil) (defaults to: nil)

    explicit control of context switching:

    • true: always keep caller's context
    • false: always use object's context
    • nil: auto-detect based on _ parameter
  • key_parameters (Hash)

    keyword parameters to pass to block.

  • block (Proc)

    block to execute.

Returns:

  • (Object)

    result of block execution.