Files
audio-ui/lib/audio/track-utils.ts

163 lines
4.6 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
/**
* Track utility functions
*/
import type { Track, TrackColor } from '@/types/track';
import { DEFAULT_TRACK_HEIGHT, TRACK_COLORS } from '@/types/track';
import { createEffectChain } from '@/lib/audio/effects/chain';
import { createAutomationLane } from '@/lib/audio/automation-utils';
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
/**
* Generate a unique track ID
*/
export function generateTrackId(): string {
return `track-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
/**
* Create a new empty track
*/
export function createTrack(name?: string, color?: TrackColor): Track {
const colors: TrackColor[] = ['blue', 'green', 'purple', 'orange', 'pink', 'indigo', 'yellow', 'red'];
const randomColor = colors[Math.floor(Math.random() * colors.length)];
// Ensure name is always a string, handle cases where event objects might be passed
const trackName = typeof name === 'string' && name.trim() ? name.trim() : 'New Track';
const trackId = generateTrackId();
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 {
id: trackId,
name: trackName,
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
color: TRACK_COLORS[color || randomColor],
height: DEFAULT_TRACK_HEIGHT,
audioBuffer: null,
volume: 0.8,
pan: 0,
mute: false,
solo: false,
recordEnabled: false,
effectChain: createEffectChain(`${trackName} Effects`),
feat: Ableton Live-style effects and complete automation system Enhanced visual design: - Improved device rack container with darker background and inner shadow - Device cards now have rounded corners, shadows, and colored indicators - Better visual separation between enabled/disabled effects - Active devices highlighted with accent border Complete automation infrastructure (Phase 9): - Created comprehensive type system for automation lanes and points - Implemented AutomationPoint component with drag-and-drop editing - Implemented AutomationHeader with mode controls (Read/Write/Touch/Latch) - Implemented AutomationLane with canvas-based curve rendering - Integrated automation lanes into Track component below effects - Created automation playback engine with real-time interpolation - Added automation data persistence to localStorage Automation features: - Add/remove automation points by clicking/double-clicking - Drag points to change time and value - Multiple automation modes (Read, Write, Touch, Latch) - Linear and step curve types (bezier planned) - Adjustable lane height (60-180px) - Show/hide automation per lane - Real-time value display at playhead - Color-coded lanes by parameter type - Keyboard delete support (Delete/Backspace) Track type updates: - Added automation field to Track interface - Updated track creation to initialize empty automation - Updated localStorage save/load to include automation data Files created: - components/automation/AutomationPoint.tsx - components/automation/AutomationHeader.tsx - components/automation/AutomationLane.tsx - lib/audio/automation/utils.ts (helper functions) - lib/audio/automation/playback.ts (playback engine) - types/automation.ts (complete type system) Files modified: - components/effects/EffectDevice.tsx (Ableton-style visual improvements) - components/tracks/Track.tsx (automation lanes integration) - types/track.ts (automation field added) - lib/audio/track-utils.ts (automation initialization) - lib/hooks/useMultiTrack.ts (automation persistence) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:30:01 +01:00
automation: {
lanes: [
createAutomationLane(trackId, 'volume', 'Volume', {
min: 0,
max: 1,
unit: 'dB',
}),
createAutomationLane(trackId, 'pan', 'Pan', {
min: -1,
max: 1,
formatter: (value: number) => {
if (value === 0) return 'C';
if (value < 0) return `${Math.abs(value * 100).toFixed(0)}L`;
return `${(value * 100).toFixed(0)}R`;
},
}),
],
feat: Ableton Live-style effects and complete automation system Enhanced visual design: - Improved device rack container with darker background and inner shadow - Device cards now have rounded corners, shadows, and colored indicators - Better visual separation between enabled/disabled effects - Active devices highlighted with accent border Complete automation infrastructure (Phase 9): - Created comprehensive type system for automation lanes and points - Implemented AutomationPoint component with drag-and-drop editing - Implemented AutomationHeader with mode controls (Read/Write/Touch/Latch) - Implemented AutomationLane with canvas-based curve rendering - Integrated automation lanes into Track component below effects - Created automation playback engine with real-time interpolation - Added automation data persistence to localStorage Automation features: - Add/remove automation points by clicking/double-clicking - Drag points to change time and value - Multiple automation modes (Read, Write, Touch, Latch) - Linear and step curve types (bezier planned) - Adjustable lane height (60-180px) - Show/hide automation per lane - Real-time value display at playhead - Color-coded lanes by parameter type - Keyboard delete support (Delete/Backspace) Track type updates: - Added automation field to Track interface - Updated track creation to initialize empty automation - Updated localStorage save/load to include automation data Files created: - components/automation/AutomationPoint.tsx - components/automation/AutomationHeader.tsx - components/automation/AutomationLane.tsx - lib/audio/automation/utils.ts (helper functions) - lib/audio/automation/playback.ts (playback engine) - types/automation.ts (complete type system) Files modified: - components/effects/EffectDevice.tsx (Ableton-style visual improvements) - components/tracks/Track.tsx (automation lanes integration) - types/track.ts (automation field added) - lib/audio/track-utils.ts (automation initialization) - lib/hooks/useMultiTrack.ts (automation persistence) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:30:01 +01:00
showAutomation: false,
},
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
collapsed: false,
selected: false,
selection: null,
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
};
}
/**
* Create a track from an audio buffer
*/
export function createTrackFromBuffer(
buffer: AudioBuffer,
name?: string,
color?: TrackColor
): Track {
// Ensure name is a string before passing to createTrack
const trackName = typeof name === 'string' && name.trim() ? name.trim() : undefined;
const track = createTrack(trackName, color);
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
track.audioBuffer = buffer;
return track;
}
/**
* Mix multiple tracks into a single stereo buffer
*/
export function mixTracks(
tracks: Track[],
sampleRate: number,
duration: number
): AudioBuffer {
// Determine the length needed
const length = Math.ceil(duration * sampleRate);
// Create output buffer (stereo)
const offlineContext = new OfflineAudioContext(2, length, sampleRate);
const outputBuffer = offlineContext.createBuffer(2, length, sampleRate);
const leftChannel = outputBuffer.getChannelData(0);
const rightChannel = outputBuffer.getChannelData(1);
// Check if any tracks are soloed
const soloedTracks = tracks.filter((t) => t.solo && !t.mute);
const audibleTracks = soloedTracks.length > 0 ? soloedTracks : tracks.filter((t) => !t.mute);
// Mix each audible track
for (const track of audibleTracks) {
if (!track.audioBuffer) continue;
const buffer = track.audioBuffer;
const trackLength = Math.min(buffer.length, length);
// Get source channels (handle mono/stereo)
const sourceLeft = buffer.getChannelData(0);
const sourceRight = buffer.numberOfChannels > 1 ? buffer.getChannelData(1) : sourceLeft;
// Calculate pan gains (constant power panning)
const panAngle = (track.pan * Math.PI) / 4; // -π/4 to π/4
const leftGain = Math.cos(panAngle + Math.PI / 4) * track.volume;
const rightGain = Math.sin(panAngle + Math.PI / 4) * track.volume;
// Mix into output buffer
for (let i = 0; i < trackLength; i++) {
leftChannel[i] += sourceLeft[i] * leftGain;
rightChannel[i] += sourceRight[i] * rightGain;
}
}
return outputBuffer;
}
/**
* Get the maximum duration across all tracks
*/
export function getMaxTrackDuration(tracks: Track[]): number {
let maxDuration = 0;
for (const track of tracks) {
if (track.audioBuffer) {
const duration = track.audioBuffer.duration;
if (duration > maxDuration) {
maxDuration = duration;
}
}
}
return maxDuration;
}
/**
* Calculate track mix gain (considering solo/mute)
*/
export function getTrackGain(track: Track, allTracks: Track[]): number {
// If track is muted, gain is 0
if (track.mute) return 0;
// Check if any tracks are soloed
const hasSoloedTracks = allTracks.some((t) => t.solo);
// If there are soloed tracks and this track is not soloed, gain is 0
if (hasSoloedTracks && !track.solo) return 0;
// Otherwise, return the track's volume
return track.volume;
}