using System.Text.Json.Serialization; namespace Robovoice.Core.Voices; public sealed class VoiceInfo { public string Key { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public VoiceLanguage Language { get; set; } = new(); public string Quality { get; set; } = string.Empty; public int NumSpeakers { get; set; } public VoiceFiles Files { get; set; } = new(); public List Aliases { get; set; } = new(); [JsonIgnore] public string DisplayName => $"{Language.NameEnglish} ({Language.Code}) — {Name} [{Quality}]"; [JsonIgnore] public long SizeBytes => Files.FirstOrDefault(f => f.Key.EndsWith(".onnx")).Value?.SizeBytes ?? 0; [JsonIgnore] public string SizeDisplay { get { double mb = SizeBytes / (1024.0 * 1024.0); return mb >= 1024 ? $"{mb / 1024:F1} GB" : $"{mb:F0} MB"; } } [JsonIgnore] public string OnnxFileKey => Files.Keys.FirstOrDefault(k => k.EndsWith(".onnx")) ?? ""; [JsonIgnore] public string JsonFileKey => Files.Keys.FirstOrDefault(k => k.EndsWith(".onnx.json")) ?? ""; } public sealed class VoiceLanguage { public string Code { get; set; } = string.Empty; public string Family { get; set; } = string.Empty; public string Region { get; set; } = string.Empty; [JsonPropertyName("name_native")] public string NameNative { get; set; } = string.Empty; [JsonPropertyName("name_english")] public string NameEnglish { get; set; } = string.Empty; [JsonPropertyName("country_english")] public string CountryEnglish { get; set; } = string.Empty; } public sealed class VoiceFiles : Dictionary { } public sealed class VoiceFile { [JsonPropertyName("size_bytes")] public long SizeBytes { get; set; } [JsonPropertyName("md5_digest")] public string Md5Digest { get; set; } = string.Empty; }