Run in rhythm. Move with purpose.

Inspiration

I started running two years ago. Early on, I heard that a cadence of around 180 steps per minute improves running economy and lowers injury risk, so I went looking for music at 180 BPM. I quickly hit a problem: I didn't like every 180 BPM song I could find, and editing my own tracks was hard without any audio-production experience.

After several full marathons, my training changed. Easy runs gave way to tempo runs and intervals, and a constant 180 cadence was no longer enough—some segments called for 185, 190, or other targets, and music made for those was even harder to find. A single fixed tempo also couldn't follow the warm-up, acceleration, recovery, and finish of a structured workout.

What I really wanted was to keep listening to music I already loved while letting it adapt to my training—not the other way around. That became RunTempo.

What it does

RunTempo transforms local music into cadence-matched running mixes, with preview and rendering handled directly in the browser.

Starting with one favorite song

In single-track mode, you choose a song, set a target cadence, and let RunTempo analyze its tempo. The app weighs half-time, original, and double-time interpretations, then recommends the one that best fits your target. Beyond adjusting speed and aligning the beat, you can customize the click sound, accents, click volume, and output level, preview 30 seconds, then export a beat-aligned WAV.

Since I discover most of my music through video and streaming platforms, I added YouTube import alongside local file upload—a tool is far more useful when it fits how people already find and listen to music.

From a music folder to a complete workout

For longer or structured sessions, you can import an entire music folder instead of processing songs one by one. RunTempo analyzes each track's BPM, energy, key, mood, and intensity changes, and checks whether it can safely match the target cadence of each workout segment. I integrated TempoCNN and MusiCNN so the system understands more than a single BPM value.

You then choose a constant, progressive, interval, or custom structure. Using the extracted metadata and precomputed candidate scores, GPT assigns tracks to stages—warm-up, faster efforts, recovery, finish—and generates several alternative plans. You still make the final call: inspect the reasoning, compare plans, reorder tracks, and render locally.

Local audio files are never uploaded to GPT or our server. GPT receives only extracted metadata and precomputed candidate scores.

How we built it

RunTempo separates musical judgment from timing-critical audio processing.

The interface is built with React and TypeScript, while the Web Audio API and Web Workers handle decoding, preview, synchronization, mixing, and WAV rendering in the browser.

Each analysis tool has a distinct role:

  • Essentia.js — signal-based tempo and beat information
  • TempoCNN — a second, learned tempo estimate, so the system can detect agreement or disagreement between methods
  • MusiCNN — high-level mood information
  • Local signal processing — energy, key, beat phase, and possible embedded click patterns

Instead of trusting one BPM result, RunTempo builds a family of tempo interpretations, comparing detector confidence, tempo stability, half/double-time relationships, and the stretching required for the target cadence.

For multi-track planning, a deterministic TypeScript engine scores valid candidates for every segment. GPT receives this constrained set through the OpenAI Responses API and returns a ranking with structured reasoning. A Node.js/Express backend validates the response before the browser converts it into an executable plan with exact source ranges, timestamps, stretch ratios, beat offsets, crossfades, and click placement.

$$\text{GPT} \rightarrow \text{musical judgment, ranking, workout structure}$$

$$\text{Local engine} \rightarrow \text{timing, validation, rendering, export}$$

If GPT is unavailable, RunTempo falls back to a deterministic local planner.

Results and validation

We built an automated verification suite for the critical logic. At submission, all 51 tests pass:

  • 20 — BPM interpretation, detector agreement, cadence relationships, tempo stability
  • 22 — multi-track analysis, coverage, workout plans, click handling, transitions, deterministic selection
  • 3 — WAV export, metadata, embedded artwork
  • 6 — OpenAI response parsing, model connectivity, backend failure handling

Signal-level fixtures verify detection of a synthetic 120 BPM pulse train and a synthetic C-major triad, correct grouping of half/double-time estimates, crossfades that overlap without invalid blocks, and rejection of fixed-click tracks when a requested tempo change exceeds the safe 5% limit. This gave us a repeatable proof layer instead of relying on whether a single demo happened to sound right.

Challenges we ran into

Choosing and understanding the right CNN models. I had no background in music theory or CNNs, and at first I didn't understand what each model was for or how to read its output. With GPT's help I learned the distinct roles of TempoCNN, MusiCNN, and Essentia.js—tempo detection vs. mood classification vs. signal analysis—and how to combine them. GPT didn't make the final calls, but it got me past the initial knowledge barrier.

Preventing beat drift. A mix can sound aligned for 30 seconds but slowly drift over several minutes; even a tiny timing error becomes noticeable on a long run. To prevent this, tempo adjustment, beat phase, source offsets, click placement, and crossfades all follow one shared timing model—if each stage computed time independently, the errors would accumulate.

Improving local processing speed. To protect privacy, RunTempo does as much decoding, analysis, and rendering as possible in the browser, but a full folder can be heavy and freeze the UI. I moved expensive analysis off the main thread with Web Workers, capped per-step processing, cached results, and split the workflow into visible stages—keeping the privacy benefit while still showing clear progress.

Designing arrangement and mixing logic. Finding runnable songs isn't the same as producing a workout mix; the system must weigh cadence, energy, stages, intervals, duration, and transitions. GPT is good at deciding whether a song belongs in a warm-up or a finish, but not at sample-accurate timing. So the local engine filters and scores tracks against tempo and safety constraints first, GPT arranges from that validated set, and deterministic code handles the exact ranges, alignment, crossfades, and clicks.

Handling failure safely. Real files don't always analyze cleanly—detectors disagree, a song already has a fixed click, GPT returns an invalid selection, or the API is down. Manual confirmation states, backend validation, invalid-selection filtering, and a deterministic fallback planner keep the workflow intact even when GPT is unavailable.

Accomplishments we're proud of

RunTempo grew from a single-song BPM experiment into an end-to-end cadence workout studio that can:

  • Analyze and synchronize an individual song
  • Build constant, progressive, interval, and custom running plans
  • Use GPT for metadata-only musical arrangement
  • Explain candidate scores and track-selection decisions
  • Generate multiple mix variants from one workout
  • Render transitions, clicks, metadata, and artwork locally
  • Keep working with a deterministic planner when GPT is unavailable
  • Verify its critical logic through 51 passing automated tests

It's not just a playlist recommender—it produces an inspectable, executable audio plan for a real workout. But the most rewarding result isn't the feature list: I can now put on my headphones and actually run to music I remixed myself. The problem I hit two years ago finally has an answer I built.

What we learned

AI is most effective when it handles the part of a problem that benefits from judgment. GPT is good at reasoning about energy, variety, and sequencing; deterministic software is better at tempo conversion, beat alignment, validation, and rendering. Giving each layer a clear responsibility made RunTempo more reliable and explainable.

Codex helped us work across the interface, audio pipeline, planning engine, backend, and tests as one connected system. An AI coding agent is most useful when architectural constraints are explicit and every change is verified through builds, tests, and real behavior—not accepted as an isolated suggestion.

As a product manager, I treated RunTempo as a product, not a single dev task: I shipped a testable version, used it, found problems, gathered feedback, and iterated. And privacy turned out to be a capability, not a limitation—by sending GPT only metadata and keeping audio on the device, we added intelligent planning without asking users to give up control of their music. Finally, tempo matching isn't purely mathematical: confidence, rhythmic interpretation, accents, transitions, and perceived synchronization all shape whether a mix actually feels right.

What's next for RunTempo

  • Benchmark against a larger real-world music library
  • Improve beat and downbeat detection accuracy
  • Create smoother, more musically aware transitions
  • Personalize planning based on workout goals and past runs
  • Build a mobile app better suited to outdoor running
  • Connect with streaming services such as Apple Music where APIs and licensing allow

My long-term goal is for RunTempo to become more than a tool I built for myself—a product runners genuinely choose to use, and grow to love.

Built With

Share this project:

Updates