import React from "react"; import { Download, FileDown, Activity, Info, TrendingUp, Key } from "lucide-react"; import { NoteEvent } from "../utils/midiWriter"; interface StatsPanelProps { notes: NoteEvent[]; bpm: number; duration: number; selectedPreset: string; onDownloadMidi: () => void; isDownloading: boolean; } export default function StatsPanel({ notes, bpm, duration, selectedPreset, onDownloadMidi, isDownloading }: StatsPanelProps) { if (notes.length === 0) return null; // Calculate stats const noteCount = notes.length; const density = duration > 0 ? (noteCount / duration).toFixed(1) : "0.0"; const pitches = notes.map(n => n.midi_note); const minPitch = Math.min(...pitches); const maxPitch = Math.max(...pitches); const getNoteName = (midiNum: number) => { const names = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]; const octave = Math.floor(midiNum / 12) - 1; const noteName = names[midiNum % 12]; return `${noteName}${octave}`; }; // Estimate a simple musical Key based on Pitch frequency tally const estimateKey = () => { const pitchCounts = new Array(12).fill(0); pitches.forEach(p => { pitchCounts[p % 12]++; }); const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]; let maxIdx = 0; let maxCount = 0; for (let i = 0; i < 12; i++) { if (pitchCounts[i] > maxCount) { maxCount = pitchCounts[i]; maxIdx = i; } } // Return estimated tonic + dynamic modality heuristic // If notes contain G and E relative to C, say Major, otherwise Minor const tonic = keyNames[maxIdx]; const isMajor = pitchCounts[(maxIdx + 4) % 12] >= pitchCounts[(maxIdx + 3) % 12]; return `${tonic} ${isMajor ? "Major" : "Minor"}`; }; return (
{/* Title */}

TRANSCRIPTION METRICS

{/* Grid of stats */}
{/* Total notes */}
Total Notes {noteCount}
{/* Note Density */}
Density {density} n/s
{/* Est. Key Signature */}
Est. Key TONALITY {estimateKey()}
{/* Pitch Range */}
Pitch Range {getNoteName(minPitch)} ~ {getNoteName(maxPitch)}
{/* Helper notice */}
DAW Ready MIDI Format

Our exported file includes absolute note events, velocity mappings, and sustain meta events. It is saved in Format 0 standard MIDI structure compatibility, immediately readable in Ableton Live, Logic Pro, GarageBand, Pro Tools, or FL Studio templates.

{/* Downloads Action Panel */}
); }