export type OutputFormat = "wav" | "flac" | "mp3" | "aac"; export type PresetName = "gentle" | "balanced" | "strong" | "heritage" | "denoise" | "scrub"; export type ChannelLayoutKind = "mono" | "stereo" | "multichannel"; /** Clipping assessment. Peak alone must never be reported as confirmed clipping. */ export type ClippingStatus = "none" | "high_peak" | "possible" | "confirmed"; export type DemucsDevice = "auto" | "cpu" | "cuda" | "mps"; export type VocalClarity = "light" | "balanced" | "strong"; export type SeparationQuality = "fast" | "best"; export type VocalDucking = "off" | "light" | "balanced" | "strong"; export interface LoudnessStats { integratedLufs: number | null; loudnessRange: number | null; truePeak: number | null; threshold: number | null; } export interface SilenceInfo { leadingSeconds: number; trailingSeconds: number; } /** * Highest frequency still carrying performance, from measured per-band level * and movement over time. It must not alone decide poor quality or trigger HF * enhancement — missing highs are never synthesised. */ export interface BandwidthEstimate { approximateHighFrequencyHz: number | null; /** False when the measurement could not be taken. */ measured: boolean; note: string; } export interface AudioProbe { path: string; format: string; codec: string; durationSeconds: number | null; sampleRate: number | null; channels: number | null; channelLayout: string | null; channelLayoutKind: ChannelLayoutKind; bitrate: number | null; tags: Record; hasEmbeddedArtwork: boolean; /** True when the file carries a real picture track, not just cover artwork. */ hasVideoStream: boolean; videoCodec: string | null; /** Stream index of the picture track, for mapping it through untouched. */ videoStreamIndex: number | null; } export interface AudioAnalysis extends AudioProbe { loudness: LoudnessStats; peakLevelDb: number | null; clippingStatus: ClippingStatus; clippingNote: string; silence: SilenceInfo; bandwidth: BandwidthEstimate; appearsLowBitrate: boolean; lowBitrateNote: string | null; } export interface CompareResult { original: AudioAnalysis; processed: AudioAnalysis; durationDifferenceSeconds: number | null; loudnessDifferenceLufs: number | null; truePeakDifferenceDb: number | null; sampleRateDifference: number | null; channelLayoutChanged: boolean; spectralDifferenceNote: string; processedLikelyClipped: boolean; durationChangedUnexpectedly: boolean; disclaimer: string; } export interface FilterDecision { name: string; filter: string; reason: string; } export interface BuiltFilterChain { filters: FilterDecision[]; chain: string | null; warnings: string[]; } export type NoiseProfileMode = { kind: "auto"; } | { kind: "adaptive"; } | { kind: "none"; } | { kind: "segment"; startSeconds: number; endSeconds: number; }; export type NoiseTypeMode = "auto" | "hiss" | "broadband" | "vinyl" | "shellac"; export type ArtifactProtection = "high" | "balanced" | "off"; export type NoiseClass = "stationary-broadband" | "changing-broadband" | "repetitive-broadband" | "impulsive" | "clipping" | "rumble" | "tonal-hum" | "codec-damage"; export interface QuietSegment { startSeconds: number; endSeconds: number; confidence: number; } export interface HumCandidate { frequencyHz: number; confidence: number; harmonics: number[]; /** How far the measured narrow band sits above its own neighbourhood, dB. */ excessDb: number | null; } /** What a measured frequency band actually contains. */ export type BandContentKind = "signal" | "noise" | "empty"; export interface NoiseBandReport { lowHz: number; /** null on the top band (open-ended). */ highHz: number | null; /** Typical level of the band, dBFS. */ levelDb: number | null; /** Level the band falls back to, dBFS. */ floorDb: number | null; /** p90 - p10 of window level. Music moves; a noise floor sits still. */ spreadDb: number | null; content: BandContentKind; } /** * Where the noise floor estimate came from, best first: * `gap` — observed directly where the performance stops; * `hiss-band` — extrapolated from the region above the content, which holds * nothing but noise; * `quietest-window` — the quietest full-mix window, an upper bound only. */ export type NoiseFloorSourceKind = "gap" | "hiss-band" | "quietest-window" | "none"; export interface NoiseAnalysis { noiseFloorDb: number | null; /** * 0–1 confidence in `noiseFloorDb`. High only when the floor was observed in a * genuine gap in the performance. Denoise thresholds must stay below the floor * when this is low: an over-estimated floor subtracts music, not noise. */ noiseFloorConfidence: number; noiseFloorSource: NoiseFloorSourceKind; estimatedSnrDb: number | null; /** Level the music core sits at, dBFS. */ musicReferenceDb: number | null; stationaryNoiseScore: number | null; changingNoiseScore: number | null; spectralFlatness: number | null; spectralFlux: number | null; hissScore: number | null; rumbleScore: number | null; /** Highest frequency of measured stationary low-frequency noise, Hz. */ rumbleEdgeHz: number | null; humCandidates: HumCandidate[]; impulsiveNoiseScore: number | null; clippingStatus: ClippingStatus; /** Highest frequency still carrying performance, measured. */ usefulBandwidthHz: number | null; codecArtifactScore: number | null; quietSegments: QuietSegment[]; profileConfidence: number | null; dcOffset: number | null; crestFactor: number | null; /** Side-to-mid level, dB. Below about -20 the source is effectively mono. */ sideToMidDb: number | null; /** Per-band measurement map, low to high. */ bands: NoiseBandReport[]; } export type NoiseProfileSource = "sampled-segment" | "adaptive-tracking" | "preset-white" | "preset-vinyl" | "preset-shellac" | "none"; export interface NoiseProfileResolution { source: NoiseProfileSource; segment?: { startSeconds: number; endSeconds: number; }; confidence: number | null; /** afftdn nt= w|v|s|c */ afftdnNoiseType: "w" | "v" | "s" | "c"; useTracking: boolean; } export type RestorationTradeoff = "fidelity-first" | "balanced" | "removal-first"; export type RestorationMode = "clean" | "heritage" | "denoise" | "scrub"; export type RestorationStageKind = "dc" | "adeclip" | "adeclick" | "highpass" | "hum" | "afftdn" | "lowpass" | "hiss" | "mudcut" | "bass" | "presence" | "air" | "acompressor"; export interface RestorationStage { kind: RestorationStageKind; name: string; filter: string; reason: string; } export interface RestorationPlan { mode: RestorationMode; strength: number; noiseClassifications: NoiseClass[]; noiseProfile: NoiseProfileResolution; stages: RestorationStage[]; candidateSelectionRequired: boolean; preserveLoudness: boolean; expectedTradeoff: RestorationTradeoff; warnings: string[]; selectedCandidate?: "conservative" | "target" | "maximum"; } export interface CandidateScore { id: "conservative" | "target" | "maximum"; estimatedNoiseReduction: number; residualNoiseScore: number; transientLossPenalty: number; bandwidthLossPenalty: number; tonalRemovalPenalty: number; musicalNoisePenalty: number; finalScore: number; meetsRemovalTarget: boolean; } export interface RestorationValidation { clippingIntroduced: boolean; bandwidthBeforeHz: number | null; bandwidthAfterHz: number | null; peakBeforeDb: number | null; peakAfterDb: number | null; excessiveBandwidthLoss: boolean; likelyTransientLoss: boolean; likelyMusicalNoise: boolean; /** * Worst drop in a content band's own floor, dB. A large drop means the * denoiser reached past the noise and subtracted quiet musical detail. */ contentFloorDropDb: number | null; /** * Worst rise in a content band's level spread, dB. Denoising that flutters * gain frame to frame — musical noise — shows up here. */ contentSpreadRiseDb: number | null; /** Change in crest factor. A large fall indicates flattened transients. */ crestDeltaDb: number | null; accepted: boolean; reasons: string[]; } export interface ProcessingOptions { preset: PresetName; strength: number; normalize: boolean; targetLufs: number | null; truePeak: number; sampleRate: number | null; format: OutputFormat; bitrate: string | null; overwrite: boolean; dryRun: boolean; keepTemp: boolean; keepDownload: boolean; stripMetadata: boolean; quiet: boolean; verbose: boolean; json: boolean; noiseProfile: NoiseProfileMode; noiseType: NoiseTypeMode; artifactProtection: ArtifactProtection; keepDiagnostics: boolean; /** Infer preset + strength from noise analysis. */ smart: boolean; /** True when user passed --artifact-protection explicitly. */ artifactProtectionExplicit: boolean; /** True when user passed --preserve-loudness (or forced normalize off). */ preserveLoudnessExplicit: boolean; /** * Copy a picture track through to the output when the input has one. * On by default: dropping it turns a music video into an audio-only file. */ keepVideo: boolean; } export interface VocalAnalysis { path: string; /** Measured in the gaps between phrases; null when it could not be observed. */ noiseFloorDb: number | null; noiseFloorConfidence: number; clippingStatus: ClippingStatus; peakLevelDb: number | null; /** Relative 200–450 Hz energy vs broader vocal band; null if unmeasured. */ mudScore: number | null; /** Relative 5–8 kHz energy; null if unmeasured. */ harshnessScore: number | null; /** Relative 6–10 kHz energy; null if unmeasured. */ sibilanceScore: number | null; bandwidthHz: number | null; durationSeconds: number | null; } export interface VocalClarityOptions { clarity: VocalClarity; separationQuality: SeparationQuality; /** Set only when the user passed `--demucs-model`. */ demucsModel?: string; device: DemucsDevice; keepStems: boolean; vocalGainDb: number; musicGainDb: number; vocalDucking: VocalDucking; } export interface VocalOptions extends ProcessingOptions, VocalClarityOptions { } export interface RestoreOptions extends VocalOptions { vocalAware: boolean; }