Files
audio-ui/lib/hooks/useMultiTrack.ts

128 lines
3.9 KiB
TypeScript
Raw Normal View History

feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
import { useState, useCallback, useEffect } from 'react';
import type { Track } from '@/types/track';
import { createTrack, createTrackFromBuffer } from '@/lib/audio/track-utils';
import { createEffectChain } from '@/lib/audio/effects/chain';
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
const STORAGE_KEY = 'audio-ui-multi-track';
export function useMultiTrack() {
const [tracks, setTracks] = useState<Track[]>(() => {
if (typeof window === 'undefined') return [];
try {
const saved = localStorage.getItem(STORAGE_KEY);
if (saved) {
const parsed = JSON.parse(saved);
// Clear corrupted data immediately if we detect issues
const hasInvalidData = parsed.some((t: any) =>
typeof t.name !== 'string' || t.name === '[object Object]'
);
if (hasInvalidData) {
console.warn('Detected corrupted track data in localStorage, clearing...');
localStorage.removeItem(STORAGE_KEY);
return [];
}
feat: complete Phase 7.4 - real-time track effects system Implemented comprehensive real-time effect processing for multi-track audio: Core Features: - Per-track effect chains with drag-and-drop reordering - Effect bypass/enable toggle per effect - Real-time parameter updates (filters, dynamics, time-based, distortion, bitcrusher, pitch, timestretch) - Add/remove effects during playback without interruption - Effect chain persistence via localStorage - Automatic playback stop when tracks are deleted Technical Implementation: - Effect processor with dry/wet routing for bypass functionality - Real-time effect parameter updates using AudioParam setValueAtTime - Structure change detection for add/remove/reorder operations - Stale closure fix using refs for latest track state - ScriptProcessorNode for bitcrusher, pitch shifter, and time stretch - Dual-tap delay line for pitch shifting - Overlap-add synthesis for time stretching UI Components: - EffectBrowser dialog with categorized effects - EffectDevice component with parameter controls - EffectParameters for all 19 real-time effect types - Device rack with horizontal scrolling (Ableton-style) Removed offline-only effects (normalize, fadeIn, fadeOut, reverse) as they don't fit the real-time processing model. Completed all items in Phase 7.4: - [x] Per-track effect chain - [x] Effect rack UI - [x] Effect bypass per track - [x] Real-time effect processing during playback - [x] Add/remove effects during playback - [x] Real-time parameter updates - [x] Effect chain persistence 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 12:08:33 +01:00
// Note: AudioBuffers can't be serialized, but EffectChains can
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
return parsed.map((t: any) => ({
...t,
name: String(t.name || 'Untitled Track'), // Ensure name is always a string
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
audioBuffer: null, // Will need to be reloaded
feat: complete Phase 7.4 - real-time track effects system Implemented comprehensive real-time effect processing for multi-track audio: Core Features: - Per-track effect chains with drag-and-drop reordering - Effect bypass/enable toggle per effect - Real-time parameter updates (filters, dynamics, time-based, distortion, bitcrusher, pitch, timestretch) - Add/remove effects during playback without interruption - Effect chain persistence via localStorage - Automatic playback stop when tracks are deleted Technical Implementation: - Effect processor with dry/wet routing for bypass functionality - Real-time effect parameter updates using AudioParam setValueAtTime - Structure change detection for add/remove/reorder operations - Stale closure fix using refs for latest track state - ScriptProcessorNode for bitcrusher, pitch shifter, and time stretch - Dual-tap delay line for pitch shifting - Overlap-add synthesis for time stretching UI Components: - EffectBrowser dialog with categorized effects - EffectDevice component with parameter controls - EffectParameters for all 19 real-time effect types - Device rack with horizontal scrolling (Ableton-style) Removed offline-only effects (normalize, fadeIn, fadeOut, reverse) as they don't fit the real-time processing model. Completed all items in Phase 7.4: - [x] Per-track effect chain - [x] Effect rack UI - [x] Effect bypass per track - [x] Real-time effect processing during playback - [x] Add/remove effects during playback - [x] Real-time parameter updates - [x] Effect chain persistence 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 12:08:33 +01:00
effectChain: t.effectChain || createEffectChain(`${t.name} Effects`), // Restore effect chain or create new
selection: t.selection || null, // Initialize selection
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
}));
}
} catch (error) {
console.error('Failed to load tracks from localStorage:', error);
// Clear corrupted data
localStorage.removeItem(STORAGE_KEY);
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
}
return [];
});
// Save tracks to localStorage (without audio buffers)
useEffect(() => {
if (typeof window === 'undefined') return;
try {
feat: complete Phase 7.4 - real-time track effects system Implemented comprehensive real-time effect processing for multi-track audio: Core Features: - Per-track effect chains with drag-and-drop reordering - Effect bypass/enable toggle per effect - Real-time parameter updates (filters, dynamics, time-based, distortion, bitcrusher, pitch, timestretch) - Add/remove effects during playback without interruption - Effect chain persistence via localStorage - Automatic playback stop when tracks are deleted Technical Implementation: - Effect processor with dry/wet routing for bypass functionality - Real-time effect parameter updates using AudioParam setValueAtTime - Structure change detection for add/remove/reorder operations - Stale closure fix using refs for latest track state - ScriptProcessorNode for bitcrusher, pitch shifter, and time stretch - Dual-tap delay line for pitch shifting - Overlap-add synthesis for time stretching UI Components: - EffectBrowser dialog with categorized effects - EffectDevice component with parameter controls - EffectParameters for all 19 real-time effect types - Device rack with horizontal scrolling (Ableton-style) Removed offline-only effects (normalize, fadeIn, fadeOut, reverse) as they don't fit the real-time processing model. Completed all items in Phase 7.4: - [x] Per-track effect chain - [x] Effect rack UI - [x] Effect bypass per track - [x] Real-time effect processing during playback - [x] Add/remove effects during playback - [x] Real-time parameter updates - [x] Effect chain persistence 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 12:08:33 +01:00
// Only save serializable fields, excluding audioBuffer and any DOM references
const trackData = tracks.map((track) => ({
id: track.id,
name: String(track.name || 'Untitled Track'),
color: track.color,
height: track.height,
volume: track.volume,
pan: track.pan,
mute: track.mute,
solo: track.solo,
recordEnabled: track.recordEnabled,
collapsed: track.collapsed,
selected: track.selected,
feat: complete Phase 7.4 - real-time track effects system Implemented comprehensive real-time effect processing for multi-track audio: Core Features: - Per-track effect chains with drag-and-drop reordering - Effect bypass/enable toggle per effect - Real-time parameter updates (filters, dynamics, time-based, distortion, bitcrusher, pitch, timestretch) - Add/remove effects during playback without interruption - Effect chain persistence via localStorage - Automatic playback stop when tracks are deleted Technical Implementation: - Effect processor with dry/wet routing for bypass functionality - Real-time effect parameter updates using AudioParam setValueAtTime - Structure change detection for add/remove/reorder operations - Stale closure fix using refs for latest track state - ScriptProcessorNode for bitcrusher, pitch shifter, and time stretch - Dual-tap delay line for pitch shifting - Overlap-add synthesis for time stretching UI Components: - EffectBrowser dialog with categorized effects - EffectDevice component with parameter controls - EffectParameters for all 19 real-time effect types - Device rack with horizontal scrolling (Ableton-style) Removed offline-only effects (normalize, fadeIn, fadeOut, reverse) as they don't fit the real-time processing model. Completed all items in Phase 7.4: - [x] Per-track effect chain - [x] Effect rack UI - [x] Effect bypass per track - [x] Real-time effect processing during playback - [x] Add/remove effects during playback - [x] Real-time parameter updates - [x] Effect chain persistence 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 12:08:33 +01:00
effectChain: track.effectChain, // Save effect chain
}));
feat: implement Phase 7.1-7.2 multi-track infrastructure Added core multi-track support with track management and controls: **Track Types & Utilities:** - Track interface with audio buffer, controls (volume/pan/solo/mute) - Track utility functions for creation, mixing, and gain calculation - Track color system with 9 preset colors - Configurable track heights (60-300px) **Components:** - TrackHeader: Collapsible track controls with inline name editing - Solo/Mute buttons with visual feedback - Volume slider (0-100%) and Pan control (L-C-R) - Track color indicator and remove button - Track: Waveform display component with canvas rendering - Click-to-seek on waveform - Playhead visualization - Support for collapsed state - TrackList: Container managing multiple tracks - Scrollable track list with custom scrollbar - Add track button - Empty state UI **State Management:** - useMultiTrack hook with localStorage persistence - Add/remove/update/reorder track operations - Track buffer management Features implemented: - ✅ Track creation and removal - ✅ Track naming (editable) - ✅ Track colors - ✅ Solo/Mute per track - ✅ Volume fader per track (0-100%) - ✅ Pan control per track (L-C-R) - ✅ Track collapse/expand - ✅ Track height configuration - ✅ Waveform visualization per track - ✅ Multi-track audio mixing utilities Next: Integrate into AudioEditor and implement multi-track playback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:59:36 +01:00
localStorage.setItem(STORAGE_KEY, JSON.stringify(trackData));
} catch (error) {
console.error('Failed to save tracks to localStorage:', error);
}
}, [tracks]);
const addTrack = useCallback((name?: string) => {
const track = createTrack(name);
setTracks((prev) => [...prev, track]);
return track;
}, []);
const addTrackFromBuffer = useCallback((buffer: AudioBuffer, name?: string) => {
const track = createTrackFromBuffer(buffer, name);
setTracks((prev) => [...prev, track]);
return track;
}, []);
const removeTrack = useCallback((trackId: string) => {
setTracks((prev) => prev.filter((t) => t.id !== trackId));
}, []);
const updateTrack = useCallback((trackId: string, updates: Partial<Track>) => {
setTracks((prev) =>
prev.map((track) =>
track.id === trackId ? { ...track, ...updates } : track
)
);
}, []);
const clearTracks = useCallback(() => {
setTracks([]);
}, []);
const reorderTracks = useCallback((fromIndex: number, toIndex: number) => {
setTracks((prev) => {
const newTracks = [...prev];
const [movedTrack] = newTracks.splice(fromIndex, 1);
newTracks.splice(toIndex, 0, movedTrack);
return newTracks;
});
}, []);
const setTrackBuffer = useCallback((trackId: string, buffer: AudioBuffer) => {
setTracks((prev) =>
prev.map((track) =>
track.id === trackId ? { ...track, audioBuffer: buffer } : track
)
);
}, []);
return {
tracks,
addTrack,
addTrackFromBuffer,
removeTrack,
updateTrack,
clearTracks,
reorderTracks,
setTrackBuffer,
};
}