Skip to content

Bug: Trajectory ID 6 (Yoyo) compute() method produces discontinuous jumps #6

@jon-myers

Description

@jon-myers

Bug Report: Trajectory ID 6 (Yoyo) compute() method produces discontinuous jumps

Summary

The Python Trajectory.compute() method for trajectory ID 6 ("yoyo" - multiple pitch trajectory) produces sharp discontinuous frequency jumps that do not exist in the TypeScript implementation. This creates visually jarring spikes in melodic contour visualizations.

Environment

  • idtap Python version: [Current version from pip]
  • Python version: 3.13
  • Platform: macOS Darwin 24.6.0

Bug Description

When calling traj.compute(x, True) on a Trajectory object with id=6, the method returns discontinuous frequency values that create sharp vertical spikes instead of smooth interpolation between multiple pitches.

Reproduction Steps

  1. Load transcription: 689cae91742e91fab7502a0f
  2. Access phrase 13, trajectory with ID 6 (the third trajectory in the phrase)
  3. Sample the trajectory at multiple x values using compute(x, True)
  4. Observe discontinuous jumps in the returned log frequencies

Expected Behavior

Based on the TypeScript implementation (trajectory.ts lines 518-551), trajectory ID 6 should smoothly interpolate between multiple pitches using segmented interpolation without discontinuous jumps.

Actual Behavior

The Python compute() method produces sharp discontinuous jumps, as evidenced by this data:

Trajectory Data:

  • ID: 6 (yoyo/multiple pitch)
  • Pitches: 3 pitches with frequencies [234.76, 274.41, 248.72]
  • Raw log frequencies: [7.875, 8.100, 7.958]

Problematic computed values:

# Sample x values: [0.0, 0.111, 0.222, 0.333, 0.444, 0.556, 0.667, 0.778, 0.889, 1.0]
# Computed log freqs: [8.100, 8.069, 7.994, 7.915, 7.876, 8.090, 8.055, 8.010, 7.973, 7.958]
#                                                      ^^^^^ SHARP JUMP FROM 7.876 to 8.090

Jump magnitude: 0.214 octaves in a single sample step, creating a visible spike.

Root Cause Analysis

Comparing with the TypeScript implementation:

TypeScript id6 method (lines 518-551):

  • Uses getStarts(durArray) to calculate segment boundaries
  • Uses findLastIndex to find the correct segment for a given x
  • Smoothly interpolates within each segment using id1 (half-cosine interpolation)

Python implementation: Appears to have a bug in the segment boundary calculation or interpolation logic for trajectory ID 6.

Impact

  • Melodic contour visualizations show unrealistic sharp spikes
  • Affects analysis accuracy for complex trajectory types
  • Creates confusing visual artifacts in musical transcription analysis

Minimal Reproduction Code

from idtap import SwaraClient, Piece

client = SwaraClient()
piece_data = client.get_piece('689cae91742e91fab7502a0f')
piece = Piece(piece_data)

# Get the problematic trajectory (phrase 13, trajectory 3)
phrase_obj = piece.phrases[12]  # 0-indexed, so phrase 13 is index 12
problematic_traj = None

for traj in phrase_obj.trajectories:
    if traj.id == 6 and len(traj.pitches) == 3:
        problematic_traj = traj
        break

if problematic_traj:
    # Sample at multiple points to see the discontinuity
    sample_xs = [0.4, 0.5, 0.6]  # Around where the jump occurs
    for x in sample_xs:
        log_freq = problematic_traj.compute(x, True)
        print(f"x={x:.1f}: log_freq={log_freq:.3f}")
    
    # Expected: smooth transition
    # Actual: sharp jump between x=0.5 and x=0.6

Suggested Fix

Review the Python implementation of the id6 method in the Trajectory class and ensure it matches the segmentation and interpolation logic from the TypeScript version, particularly:

  1. Correct segment boundary calculation
  2. Proper segment index finding logic
  3. Smooth interpolation within segments

Related Files

  • TypeScript reference: /src/ts/model/trajectory.ts lines 518-551 (id6 method)
  • Python implementation: Location of the corresponding id6 method in Python idtap module

Additional Context

This bug was discovered while creating melodic contour visualizations using the Python idtap library. The same trajectory data produces smooth contours in the web application (which uses TypeScript) but creates sharp spikes in Python-generated visualizations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions