Recording Settings (Phase 8.3): - Added input gain control (0.0-2.0 with dB display) - Real-time gain adjustment via GainNode during recording - Mono/Stereo recording mode selection - Sample rate matching (44.1kHz, 48kHz, 96kHz) - Mono conversion averages all channels when enabled - Recording settings panel shown when track is armed Components Created: - RecordingSettings.tsx: Settings panel with gain slider, mono/stereo toggle, sample rate buttons Components Modified: - useRecording hook: Added settings state and GainNode integration - AudioEditor: Pass recording settings to TrackList - TrackList: Forward settings to Track components - Track: Show RecordingSettings when armed for recording Technical Details: - GainNode inserted between source and analyser in recording chain - Real-time gain updates via gainNode.gain.value - AudioContext created with target sample rate - Mono conversion done post-recording by averaging channels - Settings persist during recording session Phase 8 Complete: - ✅ Phase 8.1: Audio Input - ✅ Phase 8.2: Recording Controls (punch/overdub) - ✅ Phase 8.3: Recording Settings - 📋 Phase 9: Automation (NEXT) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
107 lines
3.5 KiB
TypeScript
107 lines
3.5 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { Volume2, Radio } from 'lucide-react';
|
|
import { Slider } from '@/components/ui/Slider';
|
|
import { cn } from '@/lib/utils/cn';
|
|
import type { RecordingSettings as RecordingSettingsType } from '@/lib/hooks/useRecording';
|
|
|
|
export interface RecordingSettingsProps {
|
|
settings: RecordingSettingsType;
|
|
onInputGainChange: (gain: number) => void;
|
|
onRecordMonoChange: (mono: boolean) => void;
|
|
onSampleRateChange: (sampleRate: number) => void;
|
|
className?: string;
|
|
}
|
|
|
|
const SAMPLE_RATES = [44100, 48000, 96000];
|
|
|
|
export function RecordingSettings({
|
|
settings,
|
|
onInputGainChange,
|
|
onRecordMonoChange,
|
|
onSampleRateChange,
|
|
className,
|
|
}: RecordingSettingsProps) {
|
|
return (
|
|
<div className={cn('space-y-2 p-3 bg-muted/50 rounded border border-border', className)}>
|
|
<div className="text-xs font-medium text-muted-foreground mb-2">Recording Settings</div>
|
|
|
|
{/* Input Gain */}
|
|
<div className="flex items-center gap-2">
|
|
<label className="text-xs text-muted-foreground flex items-center gap-1 w-24 flex-shrink-0">
|
|
<Volume2 className="h-3.5 w-3.5" />
|
|
Input Gain
|
|
</label>
|
|
<div className="flex-1">
|
|
<Slider
|
|
value={settings.inputGain}
|
|
onChange={onInputGainChange}
|
|
min={0}
|
|
max={2}
|
|
step={0.1}
|
|
/>
|
|
</div>
|
|
<span className="text-xs text-muted-foreground w-12 text-right flex-shrink-0">
|
|
{settings.inputGain === 1 ? '0 dB' : `${(20 * Math.log10(settings.inputGain)).toFixed(1)} dB`}
|
|
</span>
|
|
</div>
|
|
|
|
{/* Mono/Stereo Toggle */}
|
|
<div className="flex items-center gap-2">
|
|
<label className="text-xs text-muted-foreground flex items-center gap-1 w-24 flex-shrink-0">
|
|
<Radio className="h-3.5 w-3.5" />
|
|
Channels
|
|
</label>
|
|
<div className="flex gap-1 flex-1">
|
|
<button
|
|
onClick={() => onRecordMonoChange(true)}
|
|
className={cn(
|
|
'flex-1 px-2 py-1 text-xs rounded transition-colors',
|
|
settings.recordMono
|
|
? 'bg-primary text-primary-foreground'
|
|
: 'bg-muted hover:bg-muted/80 text-muted-foreground'
|
|
)}
|
|
>
|
|
Mono
|
|
</button>
|
|
<button
|
|
onClick={() => onRecordMonoChange(false)}
|
|
className={cn(
|
|
'flex-1 px-2 py-1 text-xs rounded transition-colors',
|
|
!settings.recordMono
|
|
? 'bg-primary text-primary-foreground'
|
|
: 'bg-muted hover:bg-muted/80 text-muted-foreground'
|
|
)}
|
|
>
|
|
Stereo
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Sample Rate Selection */}
|
|
<div className="flex items-center gap-2">
|
|
<label className="text-xs text-muted-foreground w-24 flex-shrink-0">
|
|
Sample Rate
|
|
</label>
|
|
<div className="flex gap-1 flex-1">
|
|
{SAMPLE_RATES.map((rate) => (
|
|
<button
|
|
key={rate}
|
|
onClick={() => onSampleRateChange(rate)}
|
|
className={cn(
|
|
'flex-1 px-2 py-1 text-xs rounded transition-colors font-mono',
|
|
settings.sampleRate === rate
|
|
? 'bg-primary text-primary-foreground'
|
|
: 'bg-muted hover:bg-muted/80 text-muted-foreground'
|
|
)}
|
|
>
|
|
{rate / 1000}k
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|