Class: Musa::Neumas::Decoders::Decoder

Inherits:
DifferentialDecoder show all
Defined in:
lib/musa-dsl/neumas/neuma-decoder.rb

Overview

Stateful decoder with differential interpretation and transcription.

Maintains state (@base, @last) to interpret each neuma relative to the previous one. Supports optional transcriptor for post-processing (expanding ornaments, applying articulations, etc.).

Differential Interpretation

Each decoded event is interpreted relative to @last:

  • Grade changes: +2 = last_grade + 2
  • Duration changes: _2 = base_duration * 2

After decoding, @last is updated for next event.

Processing Pipeline

Input 

Examples:

Stateful decoding

decoder = Musa::Neumas::Decoders::NeumaDifferentialDecoder.new(
  base_duration: 1/4r
)

# Create mock GDVD object
gdvd1 = Object.new
def gdvd1.clone; self; end
def gdvd1.base_duration=(val); @bd = val; end

result = decoder.decode(gdvd1)
# Returns processed GDVD with base_duration set

Direct Known Subclasses

NeumaDecoder

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, transcriptor: nil) ⇒ Decoder

Creates stateful decoder.

Examples:

Create decoder with base state

base_state = { grade: 0, octave: 0, duration: 1/4r, velocity: 1 }
decoder = Musa::Neumas::Decoders::Decoder.new(base_state)

# Decoder maintains state
decoder.base[:grade]     # => 0
decoder.base[:duration]  # => 1/4r

Parameters:

  • base (Hash)

    base/initial state for differential decoding

  • transcriptor (Transcriptor, nil) (defaults to: nil)

    optional transcriptor for post-processing



214
215
216
217
218
219
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 214

def initialize(base, transcriptor: nil)
  @base = base
  @last = base.clone

  @transcriptor = transcriptor
end

Instance Attribute Details

#baseHash

Base state for decoder.

Returns:

  • (Hash)

    base state



233
234
235
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 233

def base
  @base
end

#transcriptorTranscriptor?

Transcriptor for post-processing decoded events.

Returns:

  • (Transcriptor, nil)

    transcriptor instance or nil



226
227
228
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 226

def transcriptor
  @transcriptor
end

Instance Method Details

#apply(_action, on:) ⇒ Hash

Applies processed attributes to previous state.

Abstract method - must be implemented by subclasses to define how differential attributes are applied to produce absolute values.

Parameters:

  • _action (Hash)

    processed attributes

  • on (Hash)

    previous state to apply attributes to

Returns:

  • (Hash)

    resulting absolute event

Raises:

  • (NotImplementedError)

    if not overridden



310
311
312
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 310

def apply(_action, on:)
  raise NotImplementedError
end

#decode(attributes) ⇒ Hash+

Decodes attributes with differential interpretation and transcription.

Pipeline:

  1. Process attributes
  2. Apply to last state
  3. Update last state
  4. Optional transcription

Examples:

Create decoder with transcriptor

base_state = { grade: 0, octave: 0, duration: 1/4r, velocity: 1 }

# Create mock transcriptor
transcriptor = Object.new
def transcriptor.transcript(gdv); [gdv, gdv.clone]; end

decoder = Musa::Neumas::Decoders::Decoder.new(
  base_state,
  transcriptor: transcriptor
)

# Transcriptor can expand events (e.g., ornaments)
decoder.transcriptor  # => transcriptor object

Parameters:

  • attributes (Hash)

    neuma attributes to decode

Returns:



285
286
287
288
289
290
291
292
293
294
295
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 285

def decode(attributes)
  result = apply process(attributes), on: @last

  @last = result.clone

  if @transcriptor
    @transcriptor.transcript(result)
  else
    result
  end
end

#subcontextDecoder

Creates independent subcontext decoder.

Returns new decoder with same base state but independent @last tracking. Used for nested structures like grace notes.

Returns:

  • (Decoder)

    independent decoder instance



253
254
255
# File 'lib/musa-dsl/neumas/neuma-decoder.rb', line 253

def subcontext
  Decoder.new @base
end