import Foundation

// MARK: - Frequency Table

/// Utility for MIDI-to-frequency conversions and note name lookups.
/// Uses A4 = 440Hz equal temperament tuning.
struct FrequencyTable {

    /// Convert a MIDI note number to frequency in Hz
    /// MIDI 69 = A4 = 440 Hz
    static func frequency(forMIDI midi: Int) -> Double {
        return 440.0 * pow(2.0, Double(midi - 69) / 12.0)
    }

    /// Convert a frequency to the nearest MIDI note number
    static func nearestMIDI(forFrequency freq: Double) -> Int {
        guard freq > 0 else { return 0 }
        return Int(round(69.0 + 12.0 * log2(freq / 440.0)))
    }

    /// Standard note names for MIDI numbers (using sharps)
    static let noteNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]

    /// Get a display name for a MIDI note number (e.g., "A4", "C#5")
    static func noteName(forMIDI midi: Int) -> String {
        let octave = (midi / 12) - 1
        let noteIndex = midi % 12
        return "\(noteNames[noteIndex])\(octave)"
    }

    /// Common vocal ranges (approximate MIDI ranges)
    struct VocalRange {
        let name: String
        let lowMIDI: Int
        let highMIDI: Int

        static let soprano = VocalRange(name: "Soprano", lowMIDI: 60, highMIDI: 84)  // C4-C6
        static let alto    = VocalRange(name: "Alto",    lowMIDI: 53, highMIDI: 77)   // F3-F5
        static let tenor   = VocalRange(name: "Tenor",   lowMIDI: 48, highMIDI: 72)   // C3-C5
        static let bass    = VocalRange(name: "Bass",    lowMIDI: 40, highMIDI: 64)   // E2-E4
    }
}
