Skip to content

Repository files navigation

PulseMap

PulseMap

An open-source protocol for mapping time-based media and layering synchronized experiences on top.

alpha · v0.1.0 · MIT

A map describes the inherent structure of a recording — chords, lyrics, words, beats, sections, tempo, key, fingerprint, MIDI references. It's source-agnostic: the same map works whether you're playing from YouTube, Spotify, a local audio file, or live audio.

A journey is a path through that map with synchronized events — lessons, audio overdubs, annotations, lighting cues, anything. Journeys reference maps but never modify them. One recording, one map, unlimited journeys. PulseMap defines maps and ships a suggested journey reference shape; everything layered on top is open territory.

The schema, the SDK, the bootstrap pipeline, the deployed Map Editor, and the 100+ map dataset are all in this repo. The companion player PulseGuide is a separate repo that uses PulseMap as a dependency and demonstrates the full protocol in action.

See it running

PulseGuide playing a song — chord chart over synced lyrics

PulseGuide (live demo player) https://hartphoenix.github.io/pulseguide/
Map Editor (correct any map) https://hartphoenix.github.io/pulsemap/editor/17416564-fb6e-471c-a4ad-0bfc45292cd9
Maps catalog (100+ maps, JSON) https://hartphoenix.github.io/pulsemap/maps/manifest.json

What a map looks like

{
  "version": "0.1.0",
  "id": "0cdc9b5b-b16b-4ff1-9f16-5b4ba76f1c17",   // MusicBrainz recording ID
  "duration_ms": 243030,
  "metadata": {
    "title": "Let It Be",
    "artist": "The Beatles",
    "key": "C major",
    "tempo": 69.8,
    "time_signature": "4/4"
  },
  "playback": [{
    "platform": "youtube",
    "uri": "https://www.youtube.com/watch?v=QDYfEBY9NM4",
    "id": "QDYfEBY9NM4",
    "capabilities": { "play": true, "pause": true, "seek": true, "volume": true, "mute": true }
  }],
  "lyrics":  [{ "t": 12670, "end": 17170, "text": "When I find myself in times of trouble" }],
  "words":   [{ "t": 12670, "end": 12880, "text": "When" }],
  "chords":  [{ "t":    20, "end":  1700, "chord": "C" }],
  "beats":   [{ "t":    40, "downbeat": true, "bpm": 72.3, "time_sig": "4/4" }],
  "sections": [],
  "midi": []
}

All timestamps are milliseconds. Musical data is transposable at render time. Per-field provenance lives in a top-level analysis field. Per-stem MIDI (drums, bass, vocals, other, backing) is referenced by SHA-256 content hash, not embedded. Full type definitions in schema/map.ts.

Use it from your code

Install via the GitHub URL — npm publish is on the roadmap:

// package.json
{
  "dependencies": {
    "pulsemap": "github:hartphoenix/pulsemap"
  }
}
import { YouTubeEmbedAdapter, createRegistry, youTubeEmbedMatcher } from "pulsemap/sdk";
import type { PulseMap } from "pulsemap/schema";

const registry = createRegistry([youTubeEmbedMatcher]);
const { sourceId } = registry.resolve(map.playback[0].uri)!;

const adapter = new YouTubeEmbedAdapter({ elementId: "player", videoId: sourceId });
await adapter.waitForReady();
adapter.play();

adapter.onStateChange(state => console.log(state));   // "playing" | "paused" | "ended" | ...
setInterval(() => render(map, adapter.getPosition()), 50);

Adapters declare what they can do via a PlaybackCapabilities object — feature-detect before calling optional methods like setPlaybackRate or setVolume.

See sdk/README.md for the full SDK reference and sdk/ADAPTERS.md for building your own adapter.

Adapter catalog

Adapter Platform Status
YouTubeEmbedAdapter YouTube shipped
HtmlAudioAdapter <audio> element (URL, Blob, File) next
WebAudioAdapter AudioContext graph good first issue
Spotify Spotify Web Playback open invitation
SoundCloud Widget API open invitation
Apple Music MusicKit JS open invitation
Bandcamp embed open invitation
HLS / DASH Shaka Player open invitation

The adapter contract is small, public, and unowned. Build whatever adapters your app needs in your own repo, on your own terms — contribution back upstream is optional and appreciated.

Repo structure

schema/              TypeScript types for the map format (and the suggested journey shape)
sdk/
  adapters/          PlaybackAdapter interface + reference adapters
  editor/            openEditor() / editorUrl() — link any player to the hosted editor
  playback.ts        parsePlaybackTarget(url) — URL → PlaybackTarget
  README.md          SDK reference
  ADAPTERS.md        How to build an adapter
src/
  bootstrap/         Map generation pipeline (audio → map JSON)
  db/                SQLite map database utilities
editor/              Standalone Map Editor (Vite + React) — deployed to GitHub Pages
maps/                Generated map JSON files (committed for distribution)
docs/proposals/      RFCs for protocol extensions
.github/             CI workflows + issue/PR templates

Contribute

Want to … Where to go
Fix a chord, lyric, or timing in a map Use the Map Editor — it generates a PR with the right provenance. Map corrections do not go through issues.
Build an adapter for a platform Read sdk/ADAPTERS.md, then file an Adapter proposal issue
Report a bug or propose a change Open an issue
Hack on the schema, SDK, pipeline, or editor Read CONTRIBUTING.md

Status

PulseMap is alpha. The map schema is stable in shape but not in semver — breaking changes are possible until v1.0. Versioning is unified: the package version is the schema version (see schema/VERSIONING.md). Journeys are an open layer on top — the schema/journey.ts reference shape is a suggestion, not a controlled spec.

The flagship open problem is windowed-fingerprint partial-audio recognition — see docs/proposals/0001-windowed-fingerprints.md. If you've worked on audio fingerprinting, ANN search, or indexing, that proposal is where to start the conversation.

Powered by PulseMap

Building on PulseMap? Drop a badge on your project's README, site, or pitch deck. Pick whichever fits the surrounding design — full kit (the four variants below plus a 2×2 contact sheet) lives in docs/badges/.

powered by PulseMap — dark glass powered by PulseMap — dark metal
powered by PulseMap — dark blue powered by PulseMap — white

License

MIT

About

An open-source protocol for mapping time-based media and layering synchronized experiences on top.

Topics

Resources

Contributing

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages