private IWaveSource GetSoundSource(Stream stream) { var magic = new byte[8]; stream.Read(magic, 0, 8); stream.Position = 0; if (VisualC.CompareMemory(magic, _mp3Magic, 3) == 0 || VisualC.CompareMemory(magic, _mp3Magic2, 2) == 0) { return(new DmoMp3Decoder(stream)); } if (VisualC.CompareMemory(magic, _oggMagic, 4) == 0) { stream.Position = 0x1C; stream.Read(magic, 0, 8); stream.Position = 0; if (VisualC.CompareMemory(magic, _opusMagic, 8) == 0) { throw new NotSupportedException("Ogg Opus is not currently supported."); } var decoder = new VorbisDecoder(stream); var converter = new SampleToPcm16(decoder); return(converter); } if (VisualC.CompareMemory(magic, _flacMagic, 4) == 0) { return(new FlacFile(stream, FlacPreScanMode.Sync)); } if (VisualC.CompareMemory(magic, _riffMagic, 4) == 0) { stream.Position = 8; stream.Read(magic, 0, 7); if (VisualC.CompareMemory(magic, _waveMagic, 7) == 0) { return(new MediaFoundationDecoder(stream)); } stream.Position = 0; } if (VisualC.CompareMemory(magic, _m4aMagic, 7) == 0) { return(new MediaFoundationDecoder(stream)); } throw new FormatException("The stream is an unsupported format."); }
// This is split out so that it can run late in the loading process (because it saturates the CPU) public void FillSoundEffectArray(SafeSoundEffect[] sounds) { if (!AudioDevice.Available) { return; } if (vorbisPointer == null) { throw new ObjectDisposedException(typeof(AudioPackage).Name); } // IMPORTANT: This is lock-free, because each entry only writes to its own slot (everything else is read-only) int count = sounds.Length; //for (int i = 0; i < count; i++) Parallel.ForEach(Enumerable.Range(0, count), i => { var entry = GetEntryByIndex(i); sounds[i].inner = VorbisDecoder.DecodeVorbis(entry.VorbisStart, entry.VorbisEnd, entry.ExpectedSamples, entry.LoopStart, entry.LoopLength); }); }