naomiaro/waveform-playlist

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.

TypeScript

1,686

1,587 commits

updated Oct 6, 2026

See the code

README

Waveform Playlist

A 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.

Waveform Playlist Screenshot

Join the dawcore Discord

Features

  • Multi-track editing - Multiple clips per track with drag-to-move and trim
  • Waveform visualization - Canvas-based rendering with zoom controls
  • 20+ audio effects - Reverb, delay, filters, distortion, and more via Tone.js
  • Recording - AudioWorklet-based recording with live waveform preview
  • Export - WAV export with effects, individual tracks or full mix
  • Annotations - Time-synced text annotations with keyboard navigation
  • Theming - Full theme customization with dark/light mode support
  • MIDI playback - MIDI file parsing with piano roll visualization and SoundFont sample playback
  • TypeScript - Full type definitions included

Quick Start

npm install @waveform-playlist/browser tone @dnd-kit/react

Note: tone and @dnd-kit/react are peer dependencies and must be installed separately. @dnd-kit/dom and @dnd-kit/abstract are also declared peers (they install automatically as dependencies of @dnd-kit/react).

v14: the playout engines are optional peers. Install the one(s) you use:

  • WebAudio/Tone path: npm install @waveform-playlist/browser @waveform-playlist/playout tone
  • MediaElement path: npm install @waveform-playlist/browser @waveform-playlist/media-element-playout
  • Custom adapter: npm install @waveform-playlist/browser and pass createAdapter (no tone).

The Tone convenience re-export was removed in v14 — import * as Tone from 'tone' directly.

v14: effects, WAV export, output metering, and the useAudioTracks/useDynamicTracks loaders import from @waveform-playlist/browser/tone.

v16: @dnd-kit/* ^0.5.0 is required (^0.3 is no longer supported). noDropAnimationPlugins was removed — Clip, AnnotationBox, and SortableTrackControls configure their own @dnd-kit Feedback behavior, so a custom DragDropProvider needs no plugins prop. @dnd-kit/dom is now a declared peer of ui-components and annotations.

import { WaveformPlaylistProvider, Waveform, PlayButton, PauseButton, StopButton } from '@waveform-playlist/browser';
import { createTrack, createClipFromSeconds } from '@waveform-playlist/core';

function App() {
  const [tracks, setTracks] = useState([]);

  // Load audio and create tracks
  useEffect(() => {
    async function loadAudio() {
      const response = await fetch('/audio/song.mp3');
      const arrayBuffer = await response.arrayBuffer();
      const audioContext = new AudioContext();
      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);

      const track = createTrack({
        name: 'My Track',
        clips: [createClipFromSeconds({ audioBuffer, startTime: 0 })],
      });

      setTracks([track]);
    }
    loadAudio();
  }, []);

  return (
    <WaveformPlaylistProvider tracks={tracks}>
      <div>
        <PlayButton />
        <PauseButton />
        <StopButton />
      </div>
      <Waveform />
    </WaveformPlaylistProvider>
  );
}

Documentation

Community

  • Discord - Chat, get help, and share what you're building on the dawcore server
  • Issues - Bug reports and feature requests
  • Code of Conduct - The standards we hold this community to, on GitHub and Discord

Examples

ExampleDescription
Stem TracksMulti-track playback with mute/solo/volume controls
Effects20 Tone.js effects with real-time parameter control
WAM! Kick It Up a NotchHost WAM 2.0 plugins with community library, native GUIs, and mixed Tone+WAM chains
RecordingLive recording with VU meter and waveform preview
Multi-ClipDrag-and-drop clip editing with trim handles
AnnotationsTime-synced text with keyboard navigation
Waveform DataPre-computed peaks for fast loading
MIDIMIDI file playback with piano roll and SoundFont samples
Beats & BarsTempo-synced timescale with beats and bars ruler
FadesFade in/out with configurable curves
StereoStereo waveform rendering and pan controls
SpectrogramFFT-based spectrogram visualization
Media ElementHTMLMediaElement playout with playback rate
StylingBar width, gaps, rounded bars, gradients, and theme colors
Flexible APICustom playheads, timestamps, and full UI customization

Packages

PackageDescription
@waveform-playlist/browserMain React components, hooks, and context
@waveform-playlist/coreTypes, utilities, and clip/track creation
@waveform-playlist/engineFramework-agnostic timeline engine with pure operations
@waveform-playlist/ui-componentsStyled UI components (buttons, sliders, etc.)
@waveform-playlist/playoutTone.js audio engine
@waveform-playlist/webaudio-peaksPeak extraction from AudioBuffer or sample arrays

Optional packages:

PackageDescription
@waveform-playlist/midiReact useMidiTracks hook + piano roll visualization with SoundFont/PolySynth playback. Re-exports the parser from @dawcore/midi.
@waveform-playlist/annotationsTime-synced text annotations with drag editing
@waveform-playlist/recordingAudioWorklet recording with live waveform preview (requires setup)
@waveform-playlist/workletsShared AudioWorklet processors for metering and recording (auto-installed with recording)
@waveform-playlist/spectrogramReact SpectrogramProvider + UI (menu items, settings modal). Computation/worker/orchestrator are imported from @dawcore/spectrogram.
@waveform-playlist/media-element-playoutHTMLMediaElement-based playout with pitch-preserving playback rate

Key Hooks

// Load audio files into tracks
const { tracks, loading, error } = useAudioTracks([
  { src: '/audio/vocals.mp3', name: 'Vocals' },
  { src: '/audio/drums.mp3', name: 'Drums' },
]);

// Playback controls
const { play, pause, stop, seekTo } = usePlaylistControls();

// Playback animation (60fps updates)
const { currentTime, isPlaying } = usePlaybackAnimation();

// Zoom controls
const { zoomIn, zoomOut, samplesPerPixel } = useZoomControls();

// Master effects chain
const { masterEffects, toggleBypass, updateParameter } = useDynamicEffects();

// WAV export
const { exportWav, isExporting, progress } = useExportWav();

// Recording
const { startRecording, stopRecording, isRecording } = useIntegratedRecording(
  tracks, setTracks, selectedTrackId
);

Web Components (Experimental)

@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).

npm install @dawcore/components @waveform-playlist/core @waveform-playlist/engine

Audio backend (choose one):

npm install @dawcore/transport          # Native Web Audio (multi-tempo, multi-meter, metronome)
# or
npm install @waveform-playlist/playout tone  # Tone.js (effects, MIDI synths)
<script type="module">
  import '@dawcore/components';
  import { NativePlayoutAdapter } from '@dawcore/transport';

  const editor = document.querySelector('daw-editor');
  const adapter = new NativePlayoutAdapter(new AudioContext());
  editor.adapter = adapter;
</script>

<daw-editor id="editor" clip-headers interactive-clips timescale>
  <daw-track name="Vocals">
    <daw-clip src="/audio/vocals.mp3" start="0" duration="10"></daw-clip>
  </daw-track>
  <daw-keyboard-shortcuts playback splitting undo></daw-keyboard-shortcuts>
</daw-editor>

<daw-transport for="editor">
  <daw-play-button></daw-play-button>
  <daw-pause-button></daw-pause-button>
  <daw-stop-button></daw-stop-button>
  <daw-record-button></daw-record-button>
</daw-transport>

Features:

  • Declarative <daw-track> and <daw-clip> elements with auto-loading
  • Imperative API for programmatic mutation — editor.addTrack/removeTrack/updateTrack/addClip/removeClip/updateClip and editor.ready() for engine bootstrap before any track loads
  • Adapter-pluggable — choose Native Web Audio or Tone.js backend
  • Clip move, trim, and split with collision detection
  • Undo/redo with transaction-based grouping
  • Keyboard shortcuts (Space=play/pause, S=split, Cmd/Ctrl+Z=undo)
  • File drop for adding tracks
  • Frozen-panes layout — height-constrained editors scroll vertically with a pinned ruler and row-locked track controls; controls adapt to short rows
  • Recording with overdub, punch-in replace (takes land at the playhead and replace overlapped content), automatic armed-track mute (the recorded-over material is silenced during the take), named takes with live clip headers, and latency compensation
  • Metronome with mixed meters and tempo changes
  • Tempo automation — linear ramps and Möbius-Ease curves with exact integration
  • Pre-computed peaks for fast initial render
  • Player-style end-of-timeline auto-stop by default; indefinite-playback rolls DAW-style until an explicit stop, fill-viewport fills the empty viewport so the ruler renders before any track (recording sessions suppress the auto-stop automatically)

Packages:

PackageDescription
@dawcore/componentsLit Web Components for multi-track editing
@dawcore/transportNative Web Audio transport — scheduling, looping, tempo automation, time signatures, metronome
@dawcore/spectrogramFramework-agnostic spectrogram orchestrator, FFT worker pool, and color maps — used by render-mode="spectrogram"
@dawcore/midiFramework-agnostic MIDI parser (parseMidiFile, parseMidiUrl) — used by editor.loadMidi() and re-exported by @waveform-playlist/midi
@dawcore/wamWeb Audio Modules (WAM 2.0) plugin hosting and generic parameter GUIs — used by editor.addWamPlugin() and the effects chain (optional peer, loaded on demand)
@dawcore/faustIn-browser Faust DSP → WAM 2.0 compilation — used by editor.addFaustEffect() (optional peer, loaded on demand)

Run the examples locally:

pnpm example:dawcore-native  # Native Web Audio — localhost:5173
pnpm example:dawcore-tone    # Tone.js backend — localhost:5174
pnpm example:dawcore-wam     # WAM 2.0 plugins + Faust — localhost:5175
pnpm example:media-element   # MediaElement-only React starter (no Tone) — localhost:5176
pnpm example:react-starter   # Full multitrack React starter (Tone engine) — localhost:5177

The react-starter is the smallest correct setup for the full multitrack editor — WaveformPlaylistProvider on the default Tone.js engine with mixer controls, plus a README section explaining the "AudioContext was prevented from starting" browser warning and how the provider's gesture-safe startup avoids it (see its README).

The media-element-player starter is a minimal React single-track player using only @waveform-playlist/browser + @waveform-playlist/media-element-playout (no @waveform-playlist/playout, no tone) — see its README.

dawcore-native example pages:

  • basic.html — Basic playback with timescale and file drop
  • multiclip.html — Multi-clip editing with move, trim, and split, plus drag-to-reorder tracks with a live slot-snap drop preview
  • programmatic.html — Imperative editor.addTrack / addClip / updateClip / removeClip plus declarative DOM mutation, side-by-side
  • beats-grid.html — Beats & bars grid mode with snap-to-grid, plus bar-aligned tick-based annotation regions (start-tick/end-tick)
  • beat-map-grid.html — Variable tempo from beat maps with metronome
  • record.html — Recording with overdub
  • metronome.html — Metronome with mixed meters, tempo presets, and looping sequences
  • automation.html — Tempo automation with step, linear, and curve presets
  • analyser.html — Spectrum analyser connected to master output
  • spectrogram.html — Per-track FFT spectrograms via render-mode="spectrogram" with color-map and frequency-scale controls
  • effects.html — Per-track and master insert effects (native-* registry) with live parameter sliders, bypass, and daw-effect-* event log
  • player.html — Lightweight <daw-player> single-track HTMLMediaElement player: waveform with peaks-src + timescale ruler, and a scrubber-only fallback (no peaks-src), with daw-ready/daw-timeupdate/daw-play/daw-stop event log
  • annotations.html — <daw-annotation-track> lyric/section markers with dual-view sync between the timeline lane and <daw-annotation-list>, drag-to-resize boundaries, and keyboard navigation/playback
  • sonnet.html — Sonnet 1 parity demo: box-label="id" bars with the full text in <daw-annotation-list>

dawcore-tone example pages:

  • basic.html — Basic playback with Tone.js adapter
  • multiclip.html — Multi-clip editing with Tone.js, plus drag-to-reorder tracks with a live slot-snap drop preview
  • programmatic.html — Imperative editor.addTrack / addClip / updateClip / removeClip plus declarative DOM mutation, with the Tone.js adapter
  • beats-grid.html — Beats & bars grid with Tone.js
  • record.html — Mic recording with overdub
  • analyser.html — Spectrum analyser connected to master output
  • spectrogram.html — Per-track FFT spectrograms with the Tone.js adapter
  • midi.html — Programmatic MIDI clips with piano-roll render mode and Tone.js PolySynth
  • midi-load.html — Load .mid files (URL or file picker) via editor.loadMidi() and play them through Tone.js PolySynth
  • soundfont.html — MIDI through SoundFont samples: SoundFontCache.fromUrl() + createToneAdapter({ soundFontCache }), with PolySynth fallback when the .sf2 fails to load
  • annotations.html — <daw-annotation-track> lyric/section markers with dual-view sync between the timeline lane and <daw-annotation-list>, drag-to-resize boundaries, and keyboard navigation/playback with the Tone.js adapter

dawcore-wam example pages:

  • index.html — WAM 2.0 plugin hosting end to end: insert plugins on any track or the master bus (one rack per track + master), with the target chosen from a dropdown that tracks every track — including stems dragged-and-dropped onto the editor (file-drop). Load community plugins by URL or from the 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

Spec & roadmap: docs/specs/web-components-migration.md — full element catalogue, attribute/property/event tables, programmatic API contracts, theming tokens, and migration phases.

Browser Support

Requires Web Audio API support: Chrome, Firefox, Safari, Edge (modern versions).

See Can I Use: Web Audio API

Development

# Install dependencies
pnpm install

# Start dev server
pnpm website

# Run tests
pnpm test

# Build all packages
pnpm build

Visit http://localhost:3000/waveform-playlist to see the examples.

Books

Currently writing: Mastering Tone.js

Mastering Tone.js

Credits

Originally created for the Airtime project at Sourcefabric.

License

MIT License

annotations
audio
audio-player
audiorecorder
audio-visualizer
audioworklet
daw
hacktoberfest
harmony
music
playback
playlist
tonejs
waveform
webaudio

naomiaro/waveform-playlist

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.

TypeScript

1,686

1,587 commits

updated Oct 6, 2026

See the code

README

Waveform Playlist

A 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.

Waveform Playlist Screenshot

Join the dawcore Discord

Features

  • Multi-track editing - Multiple clips per track with drag-to-move and trim
  • Waveform visualization - Canvas-based rendering with zoom controls
  • 20+ audio effects - Reverb, delay, filters, distortion, and more via Tone.js
  • Recording - AudioWorklet-based recording with live waveform preview
  • Export - WAV export with effects, individual tracks or full mix
  • Annotations - Time-synced text annotations with keyboard navigation
  • Theming - Full theme customization with dark/light mode support
  • MIDI playback - MIDI file parsing with piano roll visualization and SoundFont sample playback
  • TypeScript - Full type definitions included

Quick Start

npm install @waveform-playlist/browser tone @dnd-kit/react

Note: tone and @dnd-kit/react are peer dependencies and must be installed separately. @dnd-kit/dom and @dnd-kit/abstract are also declared peers (they install automatically as dependencies of @dnd-kit/react).

v14: the playout engines are optional peers. Install the one(s) you use:

  • WebAudio/Tone path: npm install @waveform-playlist/browser @waveform-playlist/playout tone
  • MediaElement path: npm install @waveform-playlist/browser @waveform-playlist/media-element-playout
  • Custom adapter: npm install @waveform-playlist/browser and pass createAdapter (no tone).

The Tone convenience re-export was removed in v14 — import * as Tone from 'tone' directly.

v14: effects, WAV export, output metering, and the useAudioTracks/useDynamicTracks loaders import from @waveform-playlist/browser/tone.

v16: @dnd-kit/* ^0.5.0 is required (^0.3 is no longer supported). noDropAnimationPlugins was removed — Clip, AnnotationBox, and SortableTrackControls configure their own @dnd-kit Feedback behavior, so a custom DragDropProvider needs no plugins prop. @dnd-kit/dom is now a declared peer of ui-components and annotations.

import { WaveformPlaylistProvider, Waveform, PlayButton, PauseButton, StopButton } from '@waveform-playlist/browser';
import { createTrack, createClipFromSeconds } from '@waveform-playlist/core';

function App() {
  const [tracks, setTracks] = useState([]);

  // Load audio and create tracks
  useEffect(() => {
    async function loadAudio() {
      const response = await fetch('/audio/song.mp3');
      const arrayBuffer = await response.arrayBuffer();
      const audioContext = new AudioContext();
      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);

      const track = createTrack({
        name: 'My Track',
        clips: [createClipFromSeconds({ audioBuffer, startTime: 0 })],
      });

      setTracks([track]);
    }
    loadAudio();
  }, []);

  return (
    <WaveformPlaylistProvider tracks={tracks}>
      <div>
        <PlayButton />
        <PauseButton />
        <StopButton />
      </div>
      <Waveform />
    </WaveformPlaylistProvider>
  );
}

Documentation

Community

  • Discord - Chat, get help, and share what you're building on the dawcore server
  • Issues - Bug reports and feature requests
  • Code of Conduct - The standards we hold this community to, on GitHub and Discord

Examples

ExampleDescription
Stem TracksMulti-track playback with mute/solo/volume controls
Effects20 Tone.js effects with real-time parameter control
WAM! Kick It Up a NotchHost WAM 2.0 plugins with community library, native GUIs, and mixed Tone+WAM chains
RecordingLive recording with VU meter and waveform preview
Multi-ClipDrag-and-drop clip editing with trim handles
AnnotationsTime-synced text with keyboard navigation
Waveform DataPre-computed peaks for fast loading
MIDIMIDI file playback with piano roll and SoundFont samples
Beats & BarsTempo-synced timescale with beats and bars ruler
FadesFade in/out with configurable curves
StereoStereo waveform rendering and pan controls
SpectrogramFFT-based spectrogram visualization
Media ElementHTMLMediaElement playout with playback rate
StylingBar width, gaps, rounded bars, gradients, and theme colors
Flexible APICustom playheads, timestamps, and full UI customization

Packages

PackageDescription
@waveform-playlist/browserMain React components, hooks, and context
@waveform-playlist/coreTypes, utilities, and clip/track creation
@waveform-playlist/engineFramework-agnostic timeline engine with pure operations
@waveform-playlist/ui-componentsStyled UI components (buttons, sliders, etc.)
@waveform-playlist/playoutTone.js audio engine
@waveform-playlist/webaudio-peaksPeak extraction from AudioBuffer or sample arrays

Optional packages:

PackageDescription
@waveform-playlist/midiReact useMidiTracks hook + piano roll visualization with SoundFont/PolySynth playback. Re-exports the parser from @dawcore/midi.
@waveform-playlist/annotationsTime-synced text annotations with drag editing
@waveform-playlist/recordingAudioWorklet recording with live waveform preview (requires setup)
@waveform-playlist/workletsShared AudioWorklet processors for metering and recording (auto-installed with recording)
@waveform-playlist/spectrogramReact SpectrogramProvider + UI (menu items, settings modal). Computation/worker/orchestrator are imported from @dawcore/spectrogram.
@waveform-playlist/media-element-playoutHTMLMediaElement-based playout with pitch-preserving playback rate

Key Hooks

// Load audio files into tracks
const { tracks, loading, error } = useAudioTracks([
  { src: '/audio/vocals.mp3', name: 'Vocals' },
  { src: '/audio/drums.mp3', name: 'Drums' },
]);

// Playback controls
const { play, pause, stop, seekTo } = usePlaylistControls();

// Playback animation (60fps updates)
const { currentTime, isPlaying } = usePlaybackAnimation();

// Zoom controls
const { zoomIn, zoomOut, samplesPerPixel } = useZoomControls();

// Master effects chain
const { masterEffects, toggleBypass, updateParameter } = useDynamicEffects();

// WAV export
const { exportWav, isExporting, progress } = useExportWav();

// Recording
const { startRecording, stopRecording, isRecording } = useIntegratedRecording(
  tracks, setTracks, selectedTrackId
);

Web Components (Experimental)

@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).

npm install @dawcore/components @waveform-playlist/core @waveform-playlist/engine

Audio backend (choose one):

npm install @dawcore/transport          # Native Web Audio (multi-tempo, multi-meter, metronome)
# or
npm install @waveform-playlist/playout tone  # Tone.js (effects, MIDI synths)
<script type="module">
  import '@dawcore/components';
  import { NativePlayoutAdapter } from '@dawcore/transport';

  const editor = document.querySelector('daw-editor');
  const adapter = new NativePlayoutAdapter(new AudioContext());
  editor.adapter = adapter;
</script>

<daw-editor id="editor" clip-headers interactive-clips timescale>
  <daw-track name="Vocals">
    <daw-clip src="/audio/vocals.mp3" start="0" duration="10"></daw-clip>
  </daw-track>
  <daw-keyboard-shortcuts playback splitting undo></daw-keyboard-shortcuts>
</daw-editor>

<daw-transport for="editor">
  <daw-play-button></daw-play-button>
  <daw-pause-button></daw-pause-button>
  <daw-stop-button></daw-stop-button>
  <daw-record-button></daw-record-button>
</daw-transport>

Features:

  • Declarative <daw-track> and <daw-clip> elements with auto-loading
  • Imperative API for programmatic mutation — editor.addTrack/removeTrack/updateTrack/addClip/removeClip/updateClip and editor.ready() for engine bootstrap before any track loads
  • Adapter-pluggable — choose Native Web Audio or Tone.js backend
  • Clip move, trim, and split with collision detection
  • Undo/redo with transaction-based grouping
  • Keyboard shortcuts (Space=play/pause, S=split, Cmd/Ctrl+Z=undo)
  • File drop for adding tracks
  • Frozen-panes layout — height-constrained editors scroll vertically with a pinned ruler and row-locked track controls; controls adapt to short rows
  • Recording with overdub, punch-in replace (takes land at the playhead and replace overlapped content), automatic armed-track mute (the recorded-over material is silenced during the take), named takes with live clip headers, and latency compensation
  • Metronome with mixed meters and tempo changes
  • Tempo automation — linear ramps and Möbius-Ease curves with exact integration
  • Pre-computed peaks for fast initial render
  • Player-style end-of-timeline auto-stop by default; indefinite-playback rolls DAW-style until an explicit stop, fill-viewport fills the empty viewport so the ruler renders before any track (recording sessions suppress the auto-stop automatically)

Packages:

PackageDescription
@dawcore/componentsLit Web Components for multi-track editing
@dawcore/transportNative Web Audio transport — scheduling, looping, tempo automation, time signatures, metronome
@dawcore/spectrogramFramework-agnostic spectrogram orchestrator, FFT worker pool, and color maps — used by render-mode="spectrogram"
@dawcore/midiFramework-agnostic MIDI parser (parseMidiFile, parseMidiUrl) — used by editor.loadMidi() and re-exported by @waveform-playlist/midi
@dawcore/wamWeb Audio Modules (WAM 2.0) plugin hosting and generic parameter GUIs — used by editor.addWamPlugin() and the effects chain (optional peer, loaded on demand)
@dawcore/faustIn-browser Faust DSP → WAM 2.0 compilation — used by editor.addFaustEffect() (optional peer, loaded on demand)

Run the examples locally:

pnpm example:dawcore-native  # Native Web Audio — localhost:5173
pnpm example:dawcore-tone    # Tone.js backend — localhost:5174
pnpm example:dawcore-wam     # WAM 2.0 plugins + Faust — localhost:5175
pnpm example:media-element   # MediaElement-only React starter (no Tone) — localhost:5176
pnpm example:react-starter   # Full multitrack React starter (Tone engine) — localhost:5177

The react-starter is the smallest correct setup for the full multitrack editor — WaveformPlaylistProvider on the default Tone.js engine with mixer controls, plus a README section explaining the "AudioContext was prevented from starting" browser warning and how the provider's gesture-safe startup avoids it (see its README).

The media-element-player starter is a minimal React single-track player using only @waveform-playlist/browser + @waveform-playlist/media-element-playout (no @waveform-playlist/playout, no tone) — see its README.

dawcore-native example pages:

  • basic.html — Basic playback with timescale and file drop
  • multiclip.html — Multi-clip editing with move, trim, and split, plus drag-to-reorder tracks with a live slot-snap drop preview
  • programmatic.html — Imperative editor.addTrack / addClip / updateClip / removeClip plus declarative DOM mutation, side-by-side
  • beats-grid.html — Beats & bars grid mode with snap-to-grid, plus bar-aligned tick-based annotation regions (start-tick/end-tick)
  • beat-map-grid.html — Variable tempo from beat maps with metronome
  • record.html — Recording with overdub
  • metronome.html — Metronome with mixed meters, tempo presets, and looping sequences
  • automation.html — Tempo automation with step, linear, and curve presets
  • analyser.html — Spectrum analyser connected to master output
  • spectrogram.html — Per-track FFT spectrograms via render-mode="spectrogram" with color-map and frequency-scale controls
  • effects.html — Per-track and master insert effects (native-* registry) with live parameter sliders, bypass, and daw-effect-* event log
  • player.html — Lightweight <daw-player> single-track HTMLMediaElement player: waveform with peaks-src + timescale ruler, and a scrubber-only fallback (no peaks-src), with daw-ready/daw-timeupdate/daw-play/daw-stop event log
  • annotations.html — <daw-annotation-track> lyric/section markers with dual-view sync between the timeline lane and <daw-annotation-list>, drag-to-resize boundaries, and keyboard navigation/playback
  • sonnet.html — Sonnet 1 parity demo: box-label="id" bars with the full text in <daw-annotation-list>

dawcore-tone example pages:

  • basic.html — Basic playback with Tone.js adapter
  • multiclip.html — Multi-clip editing with Tone.js, plus drag-to-reorder tracks with a live slot-snap drop preview
  • programmatic.html — Imperative editor.addTrack / addClip / updateClip / removeClip plus declarative DOM mutation, with the Tone.js adapter
  • beats-grid.html — Beats & bars grid with Tone.js
  • record.html — Mic recording with overdub
  • analyser.html — Spectrum analyser connected to master output
  • spectrogram.html — Per-track FFT spectrograms with the Tone.js adapter
  • midi.html — Programmatic MIDI clips with piano-roll render mode and Tone.js PolySynth
  • midi-load.html — Load .mid files (URL or file picker) via editor.loadMidi() and play them through Tone.js PolySynth
  • soundfont.html — MIDI through SoundFont samples: SoundFontCache.fromUrl() + createToneAdapter({ soundFontCache }), with PolySynth fallback when the .sf2 fails to load
  • annotations.html — <daw-annotation-track> lyric/section markers with dual-view sync between the timeline lane and <daw-annotation-list>, drag-to-resize boundaries, and keyboard navigation/playback with the Tone.js adapter

dawcore-wam example pages:

  • index.html — WAM 2.0 plugin hosting end to end: insert plugins on any track or the master bus (one rack per track + master), with the target chosen from a dropdown that tracks every track — including stems dragged-and-dropped onto the editor (file-drop). Load community plugins by URL or from the 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

Spec & roadmap: docs/specs/web-components-migration.md — full element catalogue, attribute/property/event tables, programmatic API contracts, theming tokens, and migration phases.

Browser Support

Requires Web Audio API support: Chrome, Firefox, Safari, Edge (modern versions).

See Can I Use: Web Audio API

Development

# Install dependencies
pnpm install

# Start dev server
pnpm website

# Run tests
pnpm test

# Build all packages
pnpm build

Visit http://localhost:3000/waveform-playlist to see the examples.

Books

Currently writing: Mastering Tone.js

Mastering Tone.js

Credits

Originally created for the Airtime project at Sourcefabric.

License

MIT License

annotations
audio
audio-player
audiorecorder
audio-visualizer
audioworklet
daw
hacktoberfest
harmony
music
playback
playlist
tonejs
waveform
webaudio

Project health

Overall

3.5/10

Maintained

10/10

Code review

0/10
OpenSSF Scorecard

Latest release

4.3.3 · Feb 26, 2022

Releases this year

0

Significant stargazers

Egon Elbre

606 followers · starred Apr 2022

Orivej Desh

69 followers · starred Oct 2023

mrdoob

25,619 followers · starred Jul 2021

Wesley Wigham

476 followers · starred Jul 2015