9public static class NAudioReaderRegistry
11 private sealed record Registration(Func<Stream, WaveStream>? StreamFactory, Func<string, WaveStream>? FileFactory);
13 private static readonly System.Collections.Concurrent.ConcurrentDictionary<string, Registration> Readers =
new(StringComparer.OrdinalIgnoreCase);
15 static NAudioReaderRegistry()
17 Register(
".wav", stream =>
new WaveFileReader(stream));
18 Register(
".mp3", stream =>
new Mp3FileReader(stream));
19 Register(
".ogg", stream =>
new VorbisWaveReader(stream));
20 Register(
".oga", stream =>
new VorbisWaveReader(stream));
21 Register(
".mogg", stream =>
new VorbisWaveReader(stream));
22 RegisterFile(
".wma", path =>
new MediaFoundationReader(path));
23 RegisterFile(
".m4a", path =>
new MediaFoundationReader(path));
33 public static void Register(
string extension, Func<Stream, WaveStream> readerFactory)
35 ArgumentNullException.ThrowIfNull(readerFactory);
36 Readers[NormalizeExtension(extension)] =
new Registration(readerFactory,
null);
46 public static void RegisterFile(
string extension, Func<string, WaveStream> readerFactory)
48 ArgumentNullException.ThrowIfNull(readerFactory);
49 Readers[NormalizeExtension(extension)] =
new Registration(
null, readerFactory);
57 public static bool Supports(
string fileNameOrExtension) => Readers.ContainsKey(GetExtension(fileNameOrExtension));
63 public static IEnumerable<string> SupportedExtensions() => Readers.Keys.OrderBy(ext => ext);
65 internal static (WaveStream Reader,
string? TemporaryFilePath) Open(
byte[] data,
string fileNameOrExtension)
67 var extension = GetExtension(fileNameOrExtension);
68 if (!Readers.TryGetValue(extension, out var registration))
69 throw new NotSupportedException($
"Format '{extension}' is not supported by Gondwana.Audio.NAudio.");
71 if (registration.StreamFactory is not
null)
73 var stream =
new MemoryStream(data, writable:
false);
76 return (registration.StreamFactory(stream),
null);
85 var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + extension);
88 File.WriteAllBytes(tempPath, data);
89 return (registration.FileFactory!(tempPath), tempPath);
98 private static string GetExtension(
string fileNameOrExtension)
100 var extension = Path.GetExtension(fileNameOrExtension);
101 if (
string.IsNullOrWhiteSpace(extension) &&
102 !fileNameOrExtension.Contains(
'/') && !fileNameOrExtension.Contains(
'\\'))
103 extension = fileNameOrExtension;
105 return NormalizeExtension(extension);
108 private static string NormalizeExtension(
string? extension)
110 if (
string.IsNullOrWhiteSpace(extension))
111 throw new InvalidOperationException(
"Audio source has no file extension.");
113 return extension.StartsWith(
'.') ? extension.ToLowerInvariant() :
"." + extension.ToLowerInvariant();
116 internal static void TryDelete(
string? path)
118 if (
string.IsNullOrWhiteSpace(path))
123 if (File.Exists(path))