feat: complete Phase 10.3 - master metering with peak/RMS display
Added comprehensive master output level monitoring: - Created MasterMeter component with dual vertical bars (peak + RMS) - Implemented real-time level monitoring in useMultiTrackPlayer hook - Added master analyser node connected to audio output - Displays color-coded levels (green/yellow/red) based on dB thresholds - Shows numerical dB readouts for both peak and RMS - Includes clickable clip indicator with reset functionality - Integrated into PlaybackControls next to master volume 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -219,6 +219,10 @@ export function AudioEditor() {
|
||||
currentTime,
|
||||
duration,
|
||||
trackLevels,
|
||||
masterPeakLevel,
|
||||
masterRmsLevel,
|
||||
masterIsClipping,
|
||||
resetClipIndicator,
|
||||
play,
|
||||
pause,
|
||||
stop,
|
||||
@@ -1056,6 +1060,10 @@ export function AudioEditor() {
|
||||
onPunchOutTimeChange={setPunchOutTime}
|
||||
overdubEnabled={overdubEnabled}
|
||||
onOverdubEnabledChange={setOverdubEnabled}
|
||||
masterPeakLevel={masterPeakLevel}
|
||||
masterRmsLevel={masterRmsLevel}
|
||||
masterIsClipping={masterIsClipping}
|
||||
onResetClip={resetClipIndicator}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as React from 'react';
|
||||
import { Play, Pause, Square, SkipBack, Volume2, VolumeX, Circle, AlignVerticalJustifyStart, AlignVerticalJustifyEnd, Layers } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Slider } from '@/components/ui/Slider';
|
||||
import { MasterMeter } from '@/components/controls/MasterMeter';
|
||||
import { cn } from '@/lib/utils/cn';
|
||||
|
||||
export interface PlaybackControlsProps {
|
||||
@@ -32,6 +33,10 @@ export interface PlaybackControlsProps {
|
||||
onPunchOutTimeChange?: (time: number) => void;
|
||||
overdubEnabled?: boolean;
|
||||
onOverdubEnabledChange?: (enabled: boolean) => void;
|
||||
masterPeakLevel?: number;
|
||||
masterRmsLevel?: number;
|
||||
masterIsClipping?: boolean;
|
||||
onResetClip?: () => void;
|
||||
}
|
||||
|
||||
export function PlaybackControls({
|
||||
@@ -60,6 +65,10 @@ export function PlaybackControls({
|
||||
onPunchOutTimeChange,
|
||||
overdubEnabled = false,
|
||||
onOverdubEnabledChange,
|
||||
masterPeakLevel = 0,
|
||||
masterRmsLevel = 0,
|
||||
masterIsClipping = false,
|
||||
onResetClip,
|
||||
}: PlaybackControlsProps) {
|
||||
const [isMuted, setIsMuted] = React.useState(false);
|
||||
const [previousVolume, setPreviousVolume] = React.useState(volume);
|
||||
@@ -275,29 +284,40 @@ export function PlaybackControls({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Volume Control */}
|
||||
<div className="flex items-center gap-3 min-w-[200px]">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleMuteToggle}
|
||||
title={isMuted ? 'Unmute' : 'Mute'}
|
||||
>
|
||||
{isMuted || volume === 0 ? (
|
||||
<VolumeX className="h-5 w-5" />
|
||||
) : (
|
||||
<Volume2 className="h-5 w-5" />
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<Slider
|
||||
value={volume}
|
||||
onChange={handleVolumeChange}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
className="flex-1"
|
||||
{/* Volume Control & Master Meter */}
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Master Meter */}
|
||||
<MasterMeter
|
||||
peakLevel={masterPeakLevel}
|
||||
rmsLevel={masterRmsLevel}
|
||||
isClipping={masterIsClipping}
|
||||
onResetClip={onResetClip}
|
||||
/>
|
||||
|
||||
{/* Volume Control */}
|
||||
<div className="flex items-center gap-3 min-w-[200px]">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleMuteToggle}
|
||||
title={isMuted ? 'Unmute' : 'Mute'}
|
||||
>
|
||||
{isMuted || volume === 0 ? (
|
||||
<VolumeX className="h-5 w-5" />
|
||||
) : (
|
||||
<Volume2 className="h-5 w-5" />
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<Slider
|
||||
value={volume}
|
||||
onChange={handleVolumeChange}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
className="flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user