public static unsafe SoundEffect Decode(byte *start, byte *end) { FakeFile file = new FakeFile { start = start, position = start, end = end }; int sampleCount = *(int *)file.position; // <- We encoded this, before the packets start, because Vorbis doesn't know [not sure if this is still true for Ogg, haven't checked -AR] file.position += 4; int loopStart = *(int *)file.position; file.position += 4; int loopLength = *(int *)file.position; file.position += 4; // TODO: Consider modifying vorbisfile binding so we can stackalloc `vf` IntPtr vf; Vorbisfile.ov_open_callbacks((IntPtr)(&file), out vf, IntPtr.Zero, IntPtr.Zero, staticCallbacks); Vorbisfile.vorbis_info info = Vorbisfile.ov_info(vf, 0); byte[] audioData = new byte[sampleCount * info.channels * 2]; // *2 for 16-bit audio (as required by XNA) fixed(byte *writeStart = audioData) { byte *writePosition = writeStart; byte *writeEnd = writePosition + audioData.Length; while (true) { int currentSection; int result = (int)Vorbisfile.ov_read(vf, (IntPtr)writePosition, (int)(writeEnd - writePosition), 0, 2, 1, out currentSection); if (result == 0) // End of file { break; } else if (result > 0) { writePosition += result; } if (writePosition >= writeEnd) { break; } } Debug.Assert(writePosition == writeEnd); // <- If this fires, something went terribly wrong. (TODO: Throw exception?) } Vorbisfile.ov_clear(ref vf); return(new SoundEffect(audioData, 0, audioData.Length, (int)info.rate, (AudioChannels)info.channels, loopStart, loopLength)); }
void Dispose(bool disposing) { if (disposing) { Stop(); soundStream.Dispose(); soundStream = null; Vorbisfile.ov_clear(ref vorbisFile); } IsDisposed = true; }