An agentic approach to figure skating music & art
Nov. 6, 2026I’m working on putting together a figure skating program for the winter of 2026–27. Last season, I performed my first lyrical program, Chasing Cars, which left me with lots of memories. I’ve enjoyed skating to dramatic and lyrical pieces (my first attempt was Merry Christmas Mr. Lawrence by Ryuichi Sakamoto), as they speak to me the most. But this year, I wanted to try tango, a genre typically considered both playful and mature, fast-paced and technically challenging in skating. I started trying out tango through social dancing in early 2025. Going to milongas in the East Village was a great experience for learning the basic steps and poses.
Putting together a skating program is a very creative experience. One starts with choosing the music, defining the significance behind the program and any character to portray (I always tend to skate to my own experience), editing the music piece(s), working with my coach on choreography and skating elements, doing tons of run-throughs, refining the details (gestures, eye contact, facial expressions, etc.), and voilà!
Last year, I edited Chasing Cars by hand. That mostly involved inspecting the audio waveform, putting together lyrics that made sense (the program was 1m40s long), and adding transitions. Pop songs felt easier to edit because of their repetition and rather formulaic structure. With tango, I wanted to put two pieces together for the different energies they bring out. The challenge comes from putting two pieces with different tempos and themes together seamlessly.
For the music, I picked Por Una Cabeza and Libertango — both very well-known tango pieces that work well for skating. One playful, wistful, and classical, the other passionate, hypnotic, and modern.
One of the early challenges was finding versions of both pieces that would work well together and wouldn’t feel too stylistically removed from each other. I was considering a few versions of Cabeza on Spotify, together with Yo-Yo Ma’s Libertango. The issue with this version of Libertango (as much as Yo-Yo Ma is amazing!) is that the ending gradually fades out, which wouldn’t work with my vision for a dramatic ending. I had to look elsewhere.
One night, I came across the Korean band Layers Classic on YouTube, specifically their interpretations of Por Una Cabeza and Libertango. Their Libertango is naughty, sexy, free, hypnotic, and seductive all at once, and it has a dramatic ending! The remaining challenge was to edit the 3:49 Cabeza and 4:34 Libertango down to 1:50 (the standard length of an Adult Bronze free skate program). Their band is amazing, so please check out their work!
Here’s the final 1:50 edit of Por Una Cabeza and Libertango, put together for my skating program!
Press play, or click anywhere on the map. The ribbons show which stretch of each original recording every second of the program came from.
I’ve been wanting to try using AI in my audio/video editing workflow for a while now, given that AI agents have evolved to a good level of maturity for creative work (a bit ironically). Audio recognition, understanding, and editing, specifically when it comes to complex orchestral pieces (especially sections where multiple instruments are playing at once in harmony), are a lot more challenging than their video counterparts, in my impression, since an agent can’t sample frames like in video recognition to understand the context.
Audio editing also has a lower tolerance for imperfections or mistakes, as even a single wrong note can be very noticeable to our ears. Understanding and interpreting the music becomes a very scientific operation. With human-AI collaboration, I’m the ear that feels and senses “what’s right” and provides creative direction, while the agent figures out the right places to make the edits. It’s a perfect game of Wavelength between human intuition and machine precision.
For context, I’m using Claude Opus 5.5 with High/Medium effort for this project.
Below is more technical stuff for a nerdy audience, narrated from Claude’s perspective.
follow Claude
In Claude’s words
Tools
Everything ran in a Linux workspace with free, open-source tools. No DAW or AI audio service was used.
| Tool | What it did |
|---|---|
| ffmpeg / ffprobe | Decoded the MP3s, measured loudness (EBU R128 ebur128), limited peaks (alimiter), time-stretched the held chord (rubberband), encoded the WAV and 320 kbps MP3 |
| Python + NumPy | Sample-accurate cutting, crossfades, gain changes, and assembly |
| SciPy | Short-time Fourier transforms, onset detection, filtering, cross-correlation |
| matplotlib | Spectrograms, loudness curves, and self-similarity maps, inspected as images to read each recording’s structure |
| Rubber Band (via ffmpeg) | High-quality time-stretch that lengthened Por Una Cabeza’s final chord without pitch change |
Methodology
Every edit followed the same five-step loop: map the structure, find matching cut points, splice, level, then verify.
- Map each recording’s structure.
- Loudness curves and spectrograms showed where sections start and stop, such as the free-time intro, a breath of silence, or the full-band entrance.
- Self-similarity maps compared every moment against every other by harmony (chroma). Repeated material shows up as diagonal lines, which revealed that Por Una Cabeza’s theme returns 65.4 s later and that Libertango’s post-break passage returns 154.5 s later, just before the ending.
- Onset detection (spectral flux) located every note attack and accent.
- Find cut points where the music matches. For each candidate jump, the onset patterns and harmony of a few seconds on either side were cross-correlated. The best offset gave a splice where what follows the cut sounds like what would naturally follow. Most final splices jump between two statements of the same music, so they’re close to invisible.
- Splice precisely. Cuts land 40 ms before a note attack or inside a breath, joined with a 25 ms equal-power crossfade so there’s no click.
- Level the loudness. The two recordings were mastered at different levels, so each was gain-matched to about −14 LUFS on its full-band sections. A limiter keeps peaks at −1 dBFS or below.
- Verify before delivering.
- Every splice was checked for clicks with a high-pass spike detector.
- The waveform and loudness of each draft were plotted and inspected.
- The total length was confirmed with ffprobe.
What the analysis looked like
These are the working pictures the edit was made from, rebuilt here from the same recordings so you can play with them. Each one keeps the original working figure underneath.
Figure 1 — Structure map (step 1). Por Una Cabeza as a spectrogram, one row per minute, with loudness underneath. The free-time violin and cello intro (0:00–0:42) shows as long horizontal bands that fade to silence. The rhythmic tango starts at 0:45.5 as regular vertical strikes. The flourish at 1:18 and the final chord at 3:27 stand out as bright vertical hits.
The original working figure

Figure 2 — Self-similarity map (step 1). Each point compares one moment’s harmony with another’s, so diagonal stripes mean repeated music. The stripes linking 1:20–1:50 with 2:25–2:55 showed that the main theme returns 65.4 s later. That’s what made the splice into the theme’s return possible.
The original working figure

Figure 3 — Close-ups for placing cuts (steps 2–3). Spectrogram strips with the loudness curve, used to place cuts within about 10 ms:
- Top: The theme’s held note decays until 1:50.4, and the next section starts at 1:50.62, so the cut goes between them.
- Middle: The violin’s phrase starts with a slide at 0:30.4.
- Bottom: Libertango’s bandoneon chord hits at 0:39.41.
The original working figure

Try a splice. Here are the program’s two jumps between statements of the same music, with the knobs from steps 2 and 3 exposed. The outgoing and incoming recordings are loaded side by side. Move the cut, knock the incoming music out of alignment, or take the crossfade away, then listen and watch the click detector from step 5.
Figure 4 — Final check (step 5). The finished program’s loudness over time with every edit point marked (that’s the map at the top of the page), plus waveform close-ups through the three splices. The waveforms run smoothly through each red line, with no gaps, jumps, or spikes, and the high-pass click detector agreed.
The original working figure

Two special techniques shaped the final cut:
- Fade-in bridge: The slow intro naturally fades to silence, so the exposition fades in from that silence with no hard edit.
- Real held chord: In the theme’s climactic restatement, the final chord is cut short. The edit switches mid-chord to the same chord in the theme’s first statement, where it is actually held, matches its level, and gently time-stretches it to about 1.9× its original length. A synthesized hold was tried first but sounded grainy.
Figure 5 — The held-chord ending. Program time 0:51.5–0:59: spectrogram on top, level below. The chord’s harmonics carry on unbroken from 0:52.6, where the switch happens, then fade evenly to silence by 0:55.2. After the 1.2 s breather, Libertango enters at 0:56.4. Switch to As recorded to hear how the climactic restatement actually goes on.
The original working figure

How the music was understood without hearing it
The editor never heard the audio. It worked from measurements plus learned musical knowledge, and the skater’s ear made the final call on every version.
- Measurement (the math half): Spectrograms show which pitches sound when, loudness curves show swells, breaths, and stops, and self-similarity maps reveal repeats. That’s how the theme’s return 65.4 s later was found, which made the clean splices possible (Figures 1 and 2).
- Interpretation (the knowledge half): Conventions learned from text, such as 4- and 8-bar phrases, held chords as resolutions, and tango accents as places for a gesture. The numbers say where things happen; this knowledge says what they likely mean.
- The gap: Neither shows how music feels. By the numbers, the finale was the best choice, but it sounded “heated too fast”. The first synthesized held chord looked smooth on every plot but sounded grainy. Splices could be verified as click-free (Figure 4), but whether they felt natural was the skater’s judgment.
lead Aubrey
Overall, the agent acted as a precise score-reader, fast at finding structures, alignments, and timings. I played the role of reviewer and judge of how the music felt. I’m sure that using an agent as a DAW plugin would enable me to edit or create more complex pieces of music.
It took 17 (and counting!) delivered versions across two sets of recordings: 9 with the first recordings using Yo-Yo Ma’s Libertango, and 8 with the Layers Classic recordings used in the final version.
For funsies, I continued with the agentic collaboration and made a skating animation with the edited music. The animation is inspired by Line Rider and the traces skaters leave behind on the ice. This side quest went through a similar iterative creation process, except this time Claude could see video frames! I thought about using the Line Rider source code and modifying it for figure skating, but then I realized that a real physics engine with a curvy surface and a stick figure on skates would be a recipe for spectacularly ungraceful landings. This one only took 7 rounds of back-and-forth!
Now I’m super excited about my actual skating program. It won’t have a 2A or 3Lz, of course, but I’m looking forward to what’s to come!
What I enjoyed most about this experiment was how much room it left for creative exploration. The agent took care of the technical precision while I got to focus on what I wanted the music to feel like, and how I might eventually express it through movement on ice. It’s fascinating how a piece of music can go through so much technical manipulation, yet the final judgment still comes down to something super intuition-based.
For now, the music is ready, and I can’t wait to see how this creative experiment takes shape on ice!