diff --git a/components/editor/AudioEditor.tsx b/components/editor/AudioEditor.tsx
index db63373..8bb5423 100644
--- a/components/editor/AudioEditor.tsx
+++ b/components/editor/AudioEditor.tsx
@@ -3,6 +3,7 @@
import * as React from 'react';
import { Music, Plus, Upload, Trash2, Settings, Download } from 'lucide-react';
import { PlaybackControls } from './PlaybackControls';
+import { MasterControls } from '@/components/controls/MasterControls';
import { ThemeToggle } from '@/components/layout/ThemeToggle';
import { CommandPalette } from '@/components/ui/CommandPalette';
import { GlobalSettingsDialog } from '@/components/settings/GlobalSettingsDialog';
@@ -1034,6 +1035,30 @@ export function AudioEditor() {
/>
+
+ {/* Right Sidebar - Master Controls */}
+
+ {
+ if (isMasterMuted) {
+ setMasterVolume(0.8);
+ setIsMasterMuted(false);
+ } else {
+ setMasterVolume(0);
+ setIsMasterMuted(true);
+ }
+ }}
+ onResetClip={resetClipIndicator}
+ />
+
{/* Transport Controls */}
@@ -1044,22 +1069,11 @@ export function AudioEditor() {
currentTime={currentTime}
duration={duration}
volume={masterVolume}
- pan={masterPan}
onPlay={play}
onPause={pause}
onStop={stop}
onSeek={seek}
onVolumeChange={setMasterVolume}
- onPanChange={setMasterPan}
- onMuteToggle={() => {
- if (isMasterMuted) {
- setMasterVolume(0.8);
- setIsMasterMuted(false);
- } else {
- setMasterVolume(0);
- setIsMasterMuted(true);
- }
- }}
currentTimeFormatted={formatDuration(currentTime)}
durationFormatted={formatDuration(duration)}
isRecording={recordingState.isRecording}
@@ -1073,10 +1087,6 @@ export function AudioEditor() {
onPunchOutTimeChange={setPunchOutTime}
overdubEnabled={overdubEnabled}
onOverdubEnabledChange={setOverdubEnabled}
- masterPeakLevel={masterPeakLevel}
- masterRmsLevel={masterRmsLevel}
- masterIsClipping={masterIsClipping}
- onResetClip={resetClipIndicator}
/>
diff --git a/components/editor/PlaybackControls.tsx b/components/editor/PlaybackControls.tsx
index 5fd2ca0..167f744 100644
--- a/components/editor/PlaybackControls.tsx
+++ b/components/editor/PlaybackControls.tsx
@@ -3,7 +3,6 @@
import * as React from 'react';
import { Play, Pause, Square, SkipBack, Circle, AlignVerticalJustifyStart, AlignVerticalJustifyEnd, Layers } from 'lucide-react';
import { Button } from '@/components/ui/Button';
-import { MasterControls } from '@/components/controls/MasterControls';
import { cn } from '@/lib/utils/cn';
export interface PlaybackControlsProps {
@@ -12,14 +11,11 @@ export interface PlaybackControlsProps {
currentTime: number;
duration: number;
volume: number;
- pan?: number;
onPlay: () => void;
onPause: () => void;
onStop: () => void;
onSeek: (time: number, autoPlay?: boolean) => void;
onVolumeChange: (volume: number) => void;
- onPanChange?: (pan: number) => void;
- onMuteToggle?: () => void;
disabled?: boolean;
className?: string;
currentTimeFormatted?: string;
@@ -35,10 +31,6 @@ export interface PlaybackControlsProps {
onPunchOutTimeChange?: (time: number) => void;
overdubEnabled?: boolean;
onOverdubEnabledChange?: (enabled: boolean) => void;
- masterPeakLevel?: number;
- masterRmsLevel?: number;
- masterIsClipping?: boolean;
- onResetClip?: () => void;
}
export function PlaybackControls({
@@ -47,14 +39,11 @@ export function PlaybackControls({
currentTime,
duration,
volume,
- pan = 0,
onPlay,
onPause,
onStop,
onSeek,
onVolumeChange,
- onPanChange,
- onMuteToggle,
disabled = false,
className,
currentTimeFormatted,
@@ -70,10 +59,6 @@ export function PlaybackControls({
onPunchOutTimeChange,
overdubEnabled = false,
onOverdubEnabledChange,
- masterPeakLevel = 0,
- masterRmsLevel = 0,
- masterIsClipping = false,
- onResetClip,
}: PlaybackControlsProps) {
const handlePlayPause = () => {
if (isPlaying) {
@@ -265,22 +250,6 @@ export function PlaybackControls({
>
)}
-
- {/* Master Controls */}
- {onPanChange && onMuteToggle && (
-
- )}
);
diff --git a/components/tracks/Track.tsx b/components/tracks/Track.tsx
index 0a3b107..5156aec 100644
--- a/components/tracks/Track.tsx
+++ b/components/tracks/Track.tsx
@@ -646,97 +646,40 @@ export function Track({
{/* Track Controls - Only show when not collapsed */}
{!track.collapsed && (
- {/* Integrated Track Controls (Pan + Fader + Mute) */}
+ {/* Integrated Track Controls (Pan + Fader + Buttons) */}
{
+ onUpdateTrack(track.id, {
+ automation: {
+ ...track.automation,
+ showAutomation: !track.automation?.showAutomation,
+ },
+ });
+ }}
+ onEffectsClick={() => {
+ onUpdateTrack(track.id, {
+ showEffects: !track.showEffects,
+ });
+ }}
onVolumeTouchStart={handleVolumeTouchStart}
onVolumeTouchEnd={handleVolumeTouchEnd}
onPanTouchStart={handlePanTouchStart}
onPanTouchEnd={handlePanTouchEnd}
/>
-
- {/* Inline Button Row - Below controls */}
-
- {/* R/S/A inline row with icons */}
-
- {/* Record Arm */}
- {onToggleRecordEnable && (
-
-
-
- )}
-
- {/* Solo Button */}
-
-
-
-
- {/* Automation Toggle */}
- {
- onUpdateTrack(track.id, {
- automation: {
- ...track.automation,
- showAutomation: !track.automation?.showAutomation,
- },
- });
- }}
- className={cn(
- 'h-6 w-6 rounded flex items-center justify-center transition-all text-[10px] font-bold',
- track.automation?.showAutomation
- ? 'bg-primary text-primary-foreground shadow-md shadow-primary/30'
- : 'bg-card hover:bg-accent text-muted-foreground border border-border/50'
- )}
- title={track.automation?.showAutomation ? 'Hide automation' : 'Show automation'}
- >
- A
-
-
- {/* Effects Toggle */}
- {
- onUpdateTrack(track.id, {
- showEffects: !track.showEffects,
- });
- }}
- className={cn(
- 'h-6 w-6 rounded flex items-center justify-center transition-all',
- track.showEffects
- ? 'bg-primary text-primary-foreground shadow-md shadow-primary/30'
- : 'bg-card hover:bg-accent text-muted-foreground border border-border/50'
- )}
- title={track.showEffects ? 'Hide effects' : 'Show effects'}
- >
-
-
-
-
)}
diff --git a/components/tracks/TrackControls.tsx b/components/tracks/TrackControls.tsx
index e9a88d8..45e5fd8 100644
--- a/components/tracks/TrackControls.tsx
+++ b/components/tracks/TrackControls.tsx
@@ -1,7 +1,7 @@
'use client';
import * as React from 'react';
-import { Volume2, VolumeX } from 'lucide-react';
+import { Circle, Headphones, Waveform, MoreHorizontal } from 'lucide-react';
import { CircularKnob } from '@/components/ui/CircularKnob';
import { TrackFader } from './TrackFader';
import { cn } from '@/lib/utils/cn';
@@ -12,9 +12,17 @@ export interface TrackControlsProps {
peakLevel: number;
rmsLevel: number;
isMuted?: boolean;
+ isSolo?: boolean;
+ isRecordEnabled?: boolean;
+ showAutomation?: boolean;
+ isRecording?: boolean;
onVolumeChange: (volume: number) => void;
onPanChange: (pan: number) => void;
onMuteToggle: () => void;
+ onSoloToggle?: () => void;
+ onRecordToggle?: () => void;
+ onAutomationToggle?: () => void;
+ onEffectsClick?: () => void;
onVolumeTouchStart?: () => void;
onVolumeTouchEnd?: () => void;
onPanTouchStart?: () => void;
@@ -28,9 +36,17 @@ export function TrackControls({
peakLevel,
rmsLevel,
isMuted = false,
+ isSolo = false,
+ isRecordEnabled = false,
+ showAutomation = false,
+ isRecording = false,
onVolumeChange,
onPanChange,
onMuteToggle,
+ onSoloToggle,
+ onRecordToggle,
+ onAutomationToggle,
+ onEffectsClick,
onVolumeTouchStart,
onVolumeTouchEnd,
onPanTouchStart,
@@ -38,7 +54,7 @@ export function TrackControls({
className,
}: TrackControlsProps) {
return (
-
+
{/* Pan Control */}
- {/* Mute Button */}
-
+ {/* Record Arm */}
+ {onRecordToggle && (
+
+
+
)}
- title={isMuted ? 'Unmute' : 'Mute'}
- >
- M
-
+
+ {/* Solo Button */}
+ {onSoloToggle && (
+
+
+
+ )}
+
+ {/* Mute Button */}
+
+ M
+
+
+
+ {/* Control Buttons Row 2: A/E */}
+
+ {/* Automation Toggle */}
+ {onAutomationToggle && (
+
+ A
+
+ )}
+
+ {/* Effects Button */}
+ {onEffectsClick && (
+
+ E
+
+ )}
+
);
}
diff --git a/components/ui/CircularKnob.tsx b/components/ui/CircularKnob.tsx
index d85800d..bfa4cbf 100644
--- a/components/ui/CircularKnob.tsx
+++ b/components/ui/CircularKnob.tsx
@@ -115,6 +115,28 @@ export function CircularKnob({
? `L${Math.abs(Math.round(value * 100))}`
: `R${Math.round(value * 100)}`;
+ // Calculate arc parameters for center-based rendering
+ const isNearCenter = Math.abs(value) < 0.01;
+ const centerPercentage = 0.5; // Center position (50%)
+
+ // Arc goes from center to current value
+ let arcStartPercentage: number;
+ let arcLength: number;
+
+ if (value < -0.01) {
+ // Left side: arc from value to center
+ arcStartPercentage = percentage;
+ arcLength = centerPercentage - percentage;
+ } else if (value > 0.01) {
+ // Right side: arc from center to value
+ arcStartPercentage = centerPercentage;
+ arcLength = percentage - centerPercentage;
+ } else {
+ // Center: no arc
+ arcStartPercentage = centerPercentage;
+ arcLength = 0;
+ }
+
return (
{label && (
@@ -147,19 +169,21 @@ export function CircularKnob({
className="text-muted/30"
/>
- {/* Value arc */}
-
+ {/* Value arc - only show when not centered */}
+ {!isNearCenter && (
+
+ )}
{/* Knob body */}