public AudioInfo ReadAudioInfo(Stream stream) { Contract.Ensures(Contract.Result <AudioInfo>() != null); var buffer = new byte[4096]; using (var decoder = new NativeVorbisDecoder()) { NativeOggStream oggStream = null; var vorbisComment = new VorbisComment(); try { SafeNativeMethods.VorbisCommentInitialize(out vorbisComment); using (var sync = new NativeOggSync()) { OggPage page; do { // Read from the buffer into a page: while (sync.PageOut(out page) != 1) { int bytesRead = stream.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { throw new IOException(Resources.ReadError); } IntPtr nativeBuffer = sync.Buffer(bytesRead); Marshal.Copy(buffer, 0, nativeBuffer, bytesRead); sync.Wrote(bytesRead); } if (oggStream == null) { oggStream = new NativeOggStream(SafeNativeMethods.OggPageGetSerialNumber(ref page)); } oggStream.PageIn(ref page); OggPacket packet; while (oggStream.PacketOut(out packet) == 1) { decoder.HeaderIn(ref vorbisComment, ref packet); VorbisInfo info = decoder.GetInfo(); return(new AudioInfo(string.Format(CultureInfo.CurrentCulture, "{0}kbps Ogg Vorbis", info.BitrateNominal / 1000), info.Channels, 0, info.Rate, 0)); } } while (SafeNativeMethods.OggPageEndOfStream(ref page) == 0); throw new IOException(Resources.EndOfStreamError); } } finally { oggStream?.Dispose(); SafeNativeMethods.VorbisCommentClear(ref vorbisComment); } } }
public void WriteMetadata(Stream stream, MetadataDictionary metadata, SettingsDictionary settings) { // This buffer is used for both reading and writing: var buffer = new byte[4096]; using (var tempStream = new MemoryStream()) { NativeOggStream inputOggStream = null; NativeOggStream outputOggStream = null; try { using (var sync = new NativeOggSync()) { OggPage inPage; do { // Read from the buffer into a page: while (sync.PageOut(out inPage) != 1) { int bytesRead = stream.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { throw new IOException(Resources.ReadError); } IntPtr nativeBuffer = sync.Buffer(bytesRead); Marshal.Copy(buffer, 0, nativeBuffer, bytesRead); sync.Wrote(bytesRead); } // Initialize the input and output streams, if necessary: if (inputOggStream == null) { inputOggStream = new NativeOggStream(SafeNativeMethods.OggPageGetSerialNumber(ref inPage)); } if (outputOggStream == null) { outputOggStream = new NativeOggStream(inputOggStream.SerialNumber); } inputOggStream.PageIn(ref inPage); OggPacket packet; while (inputOggStream.PacketOut(out packet) == 1) { // Substitute the new comment packet: if (packet.PacketNumber == 1) { OggPacket commentPacket = GetCommentPacket(metadata); outputOggStream.PacketIn(ref commentPacket); } else { outputOggStream.PacketIn(ref packet); } // Page out each packet, flushing at the end of the header: OggPage outPage; if (packet.PacketNumber == 2) { while (outputOggStream.Flush(out outPage)) { WritePage(outPage, tempStream, buffer); } } else { while (outputOggStream.PageOut(out outPage)) { WritePage(outPage, tempStream, buffer); } } } } while (SafeNativeMethods.OggPageEndOfStream(ref inPage) == 0); // If the end of the stream is reached, overwrite the original file and return: Overwrite(stream, tempStream); } } finally { inputOggStream?.Dispose(); outputOggStream?.Dispose(); } } }
public MetadataDictionary ReadMetadata(Stream stream) { Contract.Ensures(Contract.Result <MetadataDictionary>() != null); var buffer = new byte[4096]; using (var decoder = new NativeVorbisDecoder()) { NativeOggStream oggStream = null; var vorbisComment = new VorbisComment(); try { SafeNativeMethods.VorbisCommentInitialize(out vorbisComment); using (var sync = new NativeOggSync()) { OggPage page; do { // Read from the buffer into a page: while (sync.PageOut(out page) != 1) { int bytesRead = stream.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { throw new IOException(Resources.ReadError); } IntPtr nativeBuffer = sync.Buffer(bytesRead); Marshal.Copy(buffer, 0, nativeBuffer, bytesRead); sync.Wrote(bytesRead); } if (oggStream == null) { oggStream = new NativeOggStream(SafeNativeMethods.OggPageGetSerialNumber(ref page)); } oggStream.PageIn(ref page); OggPacket packet; while (oggStream.PacketOut(out packet) == 1) { decoder.HeaderIn(ref vorbisComment, ref packet); if (packet.PacketNumber == 1) { return(new VorbisCommentToMetadataAdapter(vorbisComment)); } } } while (SafeNativeMethods.OggPageEndOfStream(ref page) == 0); throw new IOException(Resources.EndOfStreamError); } } finally { oggStream?.Dispose(); SafeNativeMethods.VorbisCommentClear(ref vorbisComment); } } }