{"id":13408982,"url":"https://github.com/naomiaro/waveform-playlist","last_synced_at":"2026-06-28T03:01:32.029Z","repository":{"id":6900310,"uuid":"8150190","full_name":"naomiaro/waveform-playlist","owner":"naomiaro","description":"Multitrack Web Audio editor and player with canvas waveform preview. Set cues, fades and shift multiple tracks in time. Record audio tracks or provide audio annotations. Export your mix to AudioBuffer or WAV! Add effects from Tone.js. Project inspired by Audacity.","archived":false,"fork":false,"pushed_at":"2026-06-27T23:14:40.000Z","size":78895,"stargazers_count":1654,"open_issues_count":54,"forks_count":309,"subscribers_count":57,"default_branch":"main","last_synced_at":"2026-06-27T23:20:16.902Z","etag":null,"topics":["annotations","audio","audio-player","audio-visualizer","audiorecorder","audioworklet","daw","harmony","music","playback","playlist","tonejs","waveform","webaudio"],"latest_commit_sha":null,"homepage":"https://naomiaro.github.io/waveform-playlist/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/naomiaro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["naomiaro"],"patreon":"naomiaro","buy_me_a_coffee":"naomiaro","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2013-02-12T00:37:03.000Z","updated_at":"2026-06-27T22:22:36.000Z","dependencies_parsed_at":"2023-02-16T07:30:21.487Z","dependency_job_id":"0e26542d-6e66-4a58-8e8b-2bdaabaa682b","html_url":"https://github.com/naomiaro/waveform-playlist","commit_stats":{"total_commits":725,"total_committers":23,"mean_commits":31.52173913043478,"dds":0.09379310344827585,"last_synced_commit":"5d912cf3e1b7ed8bcc190902e1c1bd329083e9f9"},"previous_names":[],"tags_count":124,"template":false,"template_full_name":null,"purl":"pkg:github/naomiaro/waveform-playlist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naomiaro%2Fwaveform-playlist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naomiaro%2Fwaveform-playlist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naomiaro%2Fwaveform-playlist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naomiaro%2Fwaveform-playlist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/naomiaro","download_url":"https://codeload.github.com/naomiaro/waveform-playlist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/naomiaro%2Fwaveform-playlist/sbom","scorecard":{"id":674287,"data":{"date":"2025-08-11","repo":{"name":"github.com/naomiaro/waveform-playlist","commit":"5d912cf3e1b7ed8bcc190902e1c1bd329083e9f9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":5,"reason":"Found 3/6 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/naomiaro/waveform-playlist/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/naomiaro/waveform-playlist/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/naomiaro/waveform-playlist/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/naomiaro/waveform-playlist/codeql-analysis.yml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"45 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-7f5c-rpf4-86p8","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-hc6q-2mpp-qw7j","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-f82v-jwr5-mffw","Warn: Project is vulnerable to: GHSA-c59h-r6p8-q9wc","Warn: Project is vulnerable to: GHSA-g77x-44xx-532m","Warn: Project is vulnerable to: GHSA-7gfc-8cq8-jh5f","Warn: Project is vulnerable to: GHSA-qpjv-v59x-3qc4","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-8mmm-9v2q-x3f9","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-4www-5p9h-95mh","Warn: Project is vulnerable to: GHSA-9gqv-wp59-fq42","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T21:03:06.093Z","repository_id":6900310,"created_at":"2025-08-21T21:03:06.094Z","updated_at":"2025-08-21T21:03:06.094Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34875362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotations","audio","audio-player","audio-visualizer","audiorecorder","audioworklet","daw","harmony","music","playback","playlist","tonejs","waveform","webaudio"],"created_at":"2024-07-30T20:00:57.078Z","updated_at":"2026-06-28T03:01:32.009Z","avatar_url":"https://github.com/naomiaro.png","language":"TypeScript","funding_links":["https://github.com/sponsors/naomiaro","https://patreon.com/naomiaro","https://buymeacoffee.com/naomiaro"],"categories":["Libraries","JavaScript","Sound editing","Packages","HarmonyOS","Repository","TypeScript"],"sub_categories":["Waveforms animation","Sound samplers:","Apps","Windows Manager","Animation","JavaScript"],"readme":"# Waveform Playlist\n\nA multi-track audio editor and player built with React, Tone.js, and the Web Audio API. Features canvas-based waveform visualization, drag-and-drop clip editing, and professional audio effects.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/naomiaro/waveform-playlist/main/website/static/img/waveform-playlist.png\" alt=\"Waveform Playlist Screenshot\" width=\"800\"\u003e\n\u003c/p\u003e\n\n## Features\n\n- **Multi-track editing** - Multiple clips per track with drag-to-move and trim\n- **Waveform visualization** - Canvas-based rendering with zoom controls\n- **20+ audio effects** - Reverb, delay, filters, distortion, and more via Tone.js\n- **Recording** - AudioWorklet-based recording with live waveform preview\n- **Export** - WAV export with effects, individual tracks or full mix\n- **Annotations** - Time-synced text annotations with keyboard navigation\n- **Theming** - Full theme customization with dark/light mode support\n- **MIDI playback** - MIDI file parsing with piano roll visualization and SoundFont sample playback\n- **TypeScript** - Full type definitions included\n\n## Quick Start\n\n```bash\nnpm install @waveform-playlist/browser tone @dnd-kit/react\n```\n\n\u003e **Note**: `tone` and `@dnd-kit/react` are peer dependencies and must be installed separately. `@dnd-kit/dom` and `@dnd-kit/abstract` are transitive dependencies of `@dnd-kit/react`.\n\n\u003e **v14:** the playout engines are optional peers. Install the one(s) you use:\n\u003e - WebAudio/Tone path: `npm install @waveform-playlist/browser @waveform-playlist/playout tone`\n\u003e - MediaElement path: `npm install @waveform-playlist/browser @waveform-playlist/media-element-playout`\n\u003e - Custom adapter: `npm install @waveform-playlist/browser` and pass `createAdapter` (no `tone`).\n\u003e\n\u003e The `Tone` convenience re-export was removed in v14 — `import * as Tone from 'tone'` directly.\n\u003e\n\u003e **v14:** effects, WAV export, output metering, and the `useAudioTracks`/`useDynamicTracks` loaders import from `@waveform-playlist/browser/tone`.\n\n```tsx\nimport { WaveformPlaylistProvider, Waveform, PlayButton, PauseButton, StopButton } from '@waveform-playlist/browser';\nimport { createTrack, createClipFromSeconds } from '@waveform-playlist/core';\n\nfunction App() {\n  const [tracks, setTracks] = useState([]);\n\n  // Load audio and create tracks\n  useEffect(() =\u003e {\n    async function loadAudio() {\n      const response = await fetch('/audio/song.mp3');\n      const arrayBuffer = await response.arrayBuffer();\n      const audioContext = new AudioContext();\n      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n      const track = createTrack({\n        name: 'My Track',\n        clips: [createClipFromSeconds({ audioBuffer, startTime: 0 })],\n      });\n\n      setTracks([track]);\n    }\n    loadAudio();\n  }, []);\n\n  return (\n    \u003cWaveformPlaylistProvider tracks={tracks}\u003e\n      \u003cdiv\u003e\n        \u003cPlayButton /\u003e\n        \u003cPauseButton /\u003e\n        \u003cStopButton /\u003e\n      \u003c/div\u003e\n      \u003cWaveform /\u003e\n    \u003c/WaveformPlaylistProvider\u003e\n  );\n}\n```\n\n## Documentation\n\n- [**Live Examples**](https://naomiaro.github.io/waveform-playlist/examples/stem-tracks) - Interactive demos\n- [**Getting Started**](https://naomiaro.github.io/waveform-playlist/docs/getting-started/installation) - Installation and basic usage\n- [**Guides**](https://naomiaro.github.io/waveform-playlist/docs/guides/loading-audio) - In-depth tutorials\n- [**API Reference**](https://naomiaro.github.io/waveform-playlist/docs/api/provider) - Component and hook documentation\n\n## Examples\n\n| Example | Description |\n|---------|-------------|\n| [Stem Tracks](https://naomiaro.github.io/waveform-playlist/examples/stem-tracks) | Multi-track playback with mute/solo/volume controls |\n| [Effects](https://naomiaro.github.io/waveform-playlist/examples/effects) | 20 Tone.js effects with real-time parameter control |\n| [Recording](https://naomiaro.github.io/waveform-playlist/examples/recording) | Live recording with VU meter and waveform preview |\n| [Multi-Clip](https://naomiaro.github.io/waveform-playlist/examples/multi-clip) | Drag-and-drop clip editing with trim handles |\n| [Annotations](https://naomiaro.github.io/waveform-playlist/examples/annotations) | Time-synced text with keyboard navigation |\n| [Waveform Data](https://naomiaro.github.io/waveform-playlist/examples/waveform-data) | Pre-computed peaks for fast loading |\n| [MIDI](https://naomiaro.github.io/waveform-playlist/examples/midi) | MIDI file playback with piano roll and SoundFont samples |\n| [Beats \u0026 Bars](https://naomiaro.github.io/waveform-playlist/examples/beats-and-bars) | Tempo-synced timescale with beats and bars ruler |\n| [Fades](https://naomiaro.github.io/waveform-playlist/examples/fades) | Fade in/out with configurable curves |\n| [Stereo](https://naomiaro.github.io/waveform-playlist/examples/stereo) | Stereo waveform rendering and pan controls |\n| [Spectrogram](https://naomiaro.github.io/waveform-playlist/examples/mir-spectrogram) | FFT-based spectrogram visualization |\n| [Media Element](https://naomiaro.github.io/waveform-playlist/examples/media-element) | HTMLMediaElement playout with playback rate |\n| [Styling](https://naomiaro.github.io/waveform-playlist/examples/styling) | Bar width, gaps, gradients, and theme colors |\n| [Flexible API](https://naomiaro.github.io/waveform-playlist/examples/flexible-api) | Custom playheads, timestamps, and full UI customization |\n\n## Packages\n\n| Package | Description |\n|---------|-------------|\n| `@waveform-playlist/browser` | Main React components, hooks, and context |\n| `@waveform-playlist/core` | Types, utilities, and clip/track creation |\n| `@waveform-playlist/engine` | Framework-agnostic timeline engine with pure operations |\n| `@waveform-playlist/ui-components` | Styled UI components (buttons, sliders, etc.) |\n| `@waveform-playlist/playout` | Tone.js audio engine |\n| `@waveform-playlist/webaudio-peaks` | Peak extraction from AudioBuffer or sample arrays |\n| `@waveform-playlist/loaders` | Audio loaders |\n\n**Optional packages:**\n\n| Package | Description |\n|---------|-------------|\n| `@waveform-playlist/midi` | React `useMidiTracks` hook + piano roll visualization with SoundFont/PolySynth playback. Re-exports the parser from `@dawcore/midi`. |\n| `@waveform-playlist/annotations` | Time-synced text annotations with drag editing |\n| `@waveform-playlist/recording` | AudioWorklet recording with live waveform preview (requires [setup](https://naomiaro.github.io/waveform-playlist/docs/guides/recording#audioworklet-setup)) |\n| `@waveform-playlist/worklets` | Shared AudioWorklet processors for metering and recording (auto-installed with recording) |\n| `@waveform-playlist/spectrogram` | React `SpectrogramProvider` + UI (menu items, settings modal). Computation/worker/orchestrator are imported from `@dawcore/spectrogram`. |\n| `@waveform-playlist/media-element-playout` | HTMLMediaElement-based playout with pitch-preserving playback rate |\n\n## Key Hooks\n\n```tsx\n// Load audio files into tracks\nconst { tracks, loading, error } = useAudioTracks([\n  { src: '/audio/vocals.mp3', name: 'Vocals' },\n  { src: '/audio/drums.mp3', name: 'Drums' },\n]);\n\n// Playback controls\nconst { play, pause, stop, seekTo } = usePlaylistControls();\n\n// Playback animation (60fps updates)\nconst { currentTime, isPlaying } = usePlaybackAnimation();\n\n// Zoom controls\nconst { zoomIn, zoomOut, samplesPerPixel } = useZoomControls();\n\n// Master effects chain\nconst { masterEffects, toggleBypass, updateParameter } = useDynamicEffects();\n\n// WAV export\nconst { exportWav, isExporting, progress } = useExportWav();\n\n// Recording\nconst { startRecording, stopRecording, isRecording } = useIntegratedRecording();\n```\n\n## Web Components (Experimental)\n\n`@dawcore/components` provides framework-agnostic Web Components for multi-track audio editing — no React required. Built with Lit, adapter-pluggable: choose between `@dawcore/transport` (native Web Audio) or `@waveform-playlist/playout` (Tone.js).\n\n```bash\nnpm install @dawcore/components @waveform-playlist/core @waveform-playlist/engine\n```\n\nAudio backend (choose one):\n```bash\nnpm install @dawcore/transport          # Native Web Audio (multi-tempo, multi-meter, metronome)\n# or\nnpm install @waveform-playlist/playout tone  # Tone.js (effects, MIDI synths)\n```\n\n```html\n\u003cscript type=\"module\"\u003e\n  import '@dawcore/components';\n  import { NativePlayoutAdapter } from '@dawcore/transport';\n\n  const editor = document.querySelector('daw-editor');\n  const adapter = new NativePlayoutAdapter(new AudioContext());\n  editor.adapter = adapter;\n\u003c/script\u003e\n\n\u003cdaw-editor id=\"editor\" clip-headers interactive-clips timescale\u003e\n  \u003cdaw-track name=\"Vocals\"\u003e\n    \u003cdaw-clip src=\"/audio/vocals.mp3\" start=\"0\" duration=\"10\"\u003e\u003c/daw-clip\u003e\n  \u003c/daw-track\u003e\n  \u003cdaw-keyboard-shortcuts playback splitting undo\u003e\u003c/daw-keyboard-shortcuts\u003e\n\u003c/daw-editor\u003e\n\n\u003cdaw-transport for=\"editor\"\u003e\n  \u003cdaw-play-button\u003e\u003c/daw-play-button\u003e\n  \u003cdaw-pause-button\u003e\u003c/daw-pause-button\u003e\n  \u003cdaw-stop-button\u003e\u003c/daw-stop-button\u003e\n  \u003cdaw-record-button\u003e\u003c/daw-record-button\u003e\n\u003c/daw-transport\u003e\n```\n\n**Features:**\n- Declarative `\u003cdaw-track\u003e` and `\u003cdaw-clip\u003e` elements with auto-loading\n- Imperative API for programmatic mutation — `editor.addTrack/removeTrack/updateTrack/addClip/removeClip/updateClip` and `editor.ready()` for engine bootstrap before any track loads\n- Adapter-pluggable — choose Native Web Audio or Tone.js backend\n- Clip move, trim, and split with collision detection\n- Undo/redo with transaction-based grouping\n- Keyboard shortcuts (Space=play/pause, S=split, Cmd/Ctrl+Z=undo)\n- File drop for adding tracks\n- Frozen-panes layout — height-constrained editors scroll vertically with a pinned ruler and row-locked track controls; controls adapt to short rows\n- Recording with overdub and latency compensation\n- Metronome with mixed meters and tempo changes\n- Tempo automation — linear ramps and Möbius-Ease curves with exact integration\n- Pre-computed peaks for fast initial render\n- `indefinite-playback` attribute fills the viewport when no audio is loaded — ruler renders before any track\n\n**Packages:**\n\n| Package | Description |\n|---------|-------------|\n| `@dawcore/components` | Lit Web Components for multi-track editing |\n| `@dawcore/transport` | Native Web Audio transport — scheduling, looping, tempo automation, time signatures, metronome |\n| `@dawcore/spectrogram` | Framework-agnostic spectrogram orchestrator, FFT worker pool, and color maps — used by `render-mode=\"spectrogram\"` |\n| `@dawcore/midi` | Framework-agnostic MIDI parser (`parseMidiFile`, `parseMidiUrl`) — used by `editor.loadMidi()` and re-exported by `@waveform-playlist/midi` |\n\nRun the examples locally:\n\n```bash\npnpm example:dawcore-native  # Native Web Audio — localhost:5173\npnpm example:dawcore-tone    # Tone.js backend — localhost:5174\npnpm example:dawcore-wam     # WAM 2.0 plugins + Faust — localhost:5175\npnpm example:media-element   # MediaElement-only React starter (no Tone) — localhost:5176\n```\n\nThe **[media-element-player](examples/media-element-player/)** starter is a minimal React\nsingle-track player using only `@waveform-playlist/browser` + `@waveform-playlist/media-element-playout`\n(no `@waveform-playlist/playout`, no `tone`) — see its [README](examples/media-element-player/README.md).\n\n**dawcore-native** example pages:\n\n- [`basic.html`](examples/dawcore-native/basic.html) — Basic playback with timescale and file drop\n- [`multiclip.html`](examples/dawcore-native/multiclip.html) — Multi-clip editing with move, trim, and split\n- [`programmatic.html`](examples/dawcore-native/programmatic.html) — Imperative `editor.addTrack` / `addClip` / `updateClip` / `removeClip` plus declarative DOM mutation, side-by-side\n- [`beats-grid.html`](examples/dawcore-native/beats-grid.html) — Beats \u0026 bars grid mode with snap-to-grid\n- [`beat-map-grid.html`](examples/dawcore-native/beat-map-grid.html) — Variable tempo from beat maps with metronome\n- [`record.html`](examples/dawcore-native/record.html) — Recording with overdub\n- [`metronome.html`](examples/dawcore-native/metronome.html) — Metronome with mixed meters, tempo presets, and looping sequences\n- [`automation.html`](examples/dawcore-native/automation.html) — Tempo automation with step, linear, and curve presets\n- [`analyser.html`](examples/dawcore-native/analyser.html) — Spectrum analyser connected to master output\n- [`spectrogram.html`](examples/dawcore-native/spectrogram.html) — Per-track FFT spectrograms via `render-mode=\"spectrogram\"` with color-map and frequency-scale controls\n- [`effects.html`](examples/dawcore-native/effects.html) — Per-track and master insert effects (`native-*` registry) with live parameter sliders, bypass, and `daw-effect-*` event log\n\n**dawcore-tone** example pages:\n\n- [`basic.html`](examples/dawcore-tone/basic.html) — Basic playback with Tone.js adapter\n- [`multiclip.html`](examples/dawcore-tone/multiclip.html) — Multi-clip editing with Tone.js\n- [`programmatic.html`](examples/dawcore-tone/programmatic.html) — Imperative `editor.addTrack` / `addClip` / `updateClip` / `removeClip` plus declarative DOM mutation, with the Tone.js adapter\n- [`beats-grid.html`](examples/dawcore-tone/beats-grid.html) — Beats \u0026 bars grid with Tone.js\n- [`record.html`](examples/dawcore-tone/record.html) — Mic recording with overdub\n- [`analyser.html`](examples/dawcore-tone/analyser.html) — Spectrum analyser connected to master output\n- [`spectrogram.html`](examples/dawcore-tone/spectrogram.html) — Per-track FFT spectrograms with the Tone.js adapter\n- [`midi.html`](examples/dawcore-tone/midi.html) — Programmatic MIDI clips with piano-roll render mode and Tone.js PolySynth\n- [`midi-load.html`](examples/dawcore-tone/midi-load.html) — Load `.mid` files (URL or file picker) via `editor.loadMidi()` and play them through Tone.js PolySynth\n- [`soundfont.html`](examples/dawcore-tone/soundfont.html) — MIDI through SoundFont samples: `SoundFontCache.fromUrl()` + `createToneAdapter({ soundFontCache })`, with PolySynth fallback when the `.sf2` fails to load\n\n**dawcore-wam** example pages:\n\n- [`index.html`](examples/dawcore-wam/index.html) — WAM 2.0 plugin hosting end to end: load community plugins by URL or from the [webaudiomodules.com](https://www.webaudiomodules.com/) library, open plugin GUIs, reorder/bypass chains, save and restore chains (including state) via localStorage, export the mix to WAV through `exportAudio()`, and compile Faust DSP to a live effect in the browser (`@dawcore/faust`) — plus pre-compiled Faust effects served from this repo\n\n**Spec \u0026 roadmap:** [`docs/specs/web-components-migration.md`](docs/specs/web-components-migration.md) — full element catalogue, attribute/property/event tables, programmatic API contracts, theming tokens, and migration phases.\n\n## Browser Support\n\nRequires Web Audio API support: Chrome, Firefox, Safari, Edge (modern versions).\n\nSee [Can I Use: Web Audio API](https://caniuse.com/audio-api)\n\n## Development\n\n```bash\n# Install dependencies\npnpm install\n\n# Start dev server\npnpm website\n\n# Run tests\npnpm test\n\n# Build all packages\npnpm build\n```\n\nVisit http://localhost:3000/waveform-playlist to see the examples.\n\n## Books\n\nCurrently writing: [Mastering Tone.js](https://leanpub.com/masteringtonejs)\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://leanpub.com/masteringtonejs\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://masteringtonejs.com/title_page.png\" title=\"Mastering Tone.js Cover\" width=\"360\" alt=\"Mastering Tone.js\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Credits\n\nOriginally created for the [Airtime](https://www.sourcefabric.org/software/airtime/) project at [Sourcefabric](https://www.sourcefabric.org/).\n\n## License\n\n[MIT License](http://doge.mit-license.org)\n\n## Sponsors\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://moises.ai/\" target=\"_blank\"\u003e\n    \u003cimg width=\"222px\" src=\"https://raw.githubusercontent.com/naomiaro/waveform-playlist/main/website/static/img/logos/moises-ai.svg\" alt=\"Moises.ai\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/sponsors/naomiaro\"\u003eBecome a sponsor\u003c/a\u003e\n\u003c/p\u003e\n\n## Partners\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.telecom-paris.fr/\" target=\"_blank\"\u003e\n    \u003cimg width=\"120px\" src=\"https://raw.githubusercontent.com/naomiaro/waveform-playlist/main/website/static/img/logos/telecom-paris.svg\" alt=\"Télécom Paris\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaomiaro%2Fwaveform-playlist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnaomiaro%2Fwaveform-playlist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnaomiaro%2Fwaveform-playlist/lists"}