-
Notifications
You must be signed in to change notification settings - Fork 0
Description
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
- Load transcription:
689cae91742e91fab7502a0f - Access phrase 13, trajectory with ID 6 (the third trajectory in the phrase)
- Sample the trajectory at multiple x values using
compute(x, True) - 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.090Jump 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
findLastIndexto 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.6Suggested 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:
- Correct segment boundary calculation
- Proper segment index finding logic
- Smooth interpolation within segments
Related Files
- TypeScript reference:
/src/ts/model/trajectory.tslines 518-551 (id6method) - Python implementation: Location of the corresponding
id6method 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.