internal bool TryInit() { // try to process the stream header... if (!ProcessStreamHeader(_packetProvider.PeekNextPacket())) { return(false); } // seek past the stream header packet _packetProvider.GetNextPacket().Done(); // load the comments header... var packet = _packetProvider.GetNextPacket(); if (!LoadComments(packet)) { throw new InvalidDataException("Comment header was not readable!"); } packet.Done(); // load the book header... packet = _packetProvider.GetNextPacket(); if (!LoadBooks(packet)) { throw new InvalidDataException("Book header was not readable!"); } packet.Done(); // get the decoding logic bootstrapped InitDecoder(); return(true); }
/// <summary> /// Seeks the stream for a valid packet at the specified granule position. /// </summary> /// <param name="granulePosition">The granule position.</param> private void SeekToGranulePosition(long granulePosition) { if (!CanSeek) { throw new InvalidOperationException("Stream is not seekable."); } if (granulePosition < 0 || granulePosition > GranuleCount) { throw new ArgumentOutOfRangeException(nameof(granulePosition)); } // Find a packet based on offset and return 1 in the callback if the packet is valid var foundPacket = _packetProvider.FindPacket(granulePosition, GetPacketLength); // Check of the found packet is valid if (foundPacket == null || foundPacket.IsEndOfStream) { _endOfStream = true; _nextDataPacket = null; return; } // Just seek to this found packet and get the previous packet (preRoll = 1) _packetProvider.SeekToPacket(foundPacket, 1); // Update the PageGranulePosition to the position from this next packet which will be retrieved by the next QueueNextPacket call PageGranulePosition = _packetProvider.PeekNextPacket().PageGranulePosition; // Reset the state from the decoder to start processing a fresh stream _decoder.ResetState(); }
private void SkipOpusTags(IPacketProvider packetProvider) { DataPacket packet = packetProvider.PeekNextPacket(); byte[] buffer = GetPacketData(packet); if (Encoding.UTF8.GetString(buffer, 0, 8) == "OpusTags") { packetProvider.GetNextPacket(); } }
internal void SeekTo(long granulePos) { if (!_packetProvider.CanSeek) { throw new NotSupportedException(); } if (granulePos < 0) { throw new ArgumentOutOfRangeException("granulePos"); } var targetPacketIndex = 3; if (granulePos > 0) { var idx = _packetProvider.FindPacket(granulePos, GetPacketLength); if (idx == -1) { throw new ArgumentOutOfRangeException("granulePos"); } targetPacketIndex = idx - 1; // move to the previous packet to prime the decoder } // seek the stream _packetProvider.SeekToPacket(targetPacketIndex); // now figure out where we are and how many samples we need to discard... // note that we use the granule position of the "current" packet, since it will be discarded no matter what // get the packet that we'll decode next var dataPacket = _packetProvider.PeekNextPacket(); // now read samples until we are exactly at the granule position requested CurrentPosition = dataPacket.GranulePosition; var cnt = (int)((granulePos - CurrentPosition) * _channels); if (cnt > 0) { var seekBuffer = new float[cnt]; while (cnt > 0) { var temp = ReadSamples(seekBuffer, 0, cnt); if (temp == 0) { break; // we're at the end... } cnt -= temp; } } }
internal bool TryInit() { if (!ProcessStreamHeader(_packetProvider.PeekNextPacket())) { return(false); } _packetProvider.GetNextPacket().Done(); DataPacket nextPacket = _packetProvider.GetNextPacket(); if (!LoadComments(nextPacket)) { throw new InvalidDataException("Comment header was not readable!"); } nextPacket.Done(); nextPacket = _packetProvider.GetNextPacket(); if (!LoadBooks(nextPacket)) { throw new InvalidDataException("Book header was not readable!"); } nextPacket.Done(); InitDecoder(); return(true); }
internal StreamDecoder(IPacketProvider packetProvider, IFactory factory) { _packetProvider = packetProvider ?? throw new ArgumentNullException(nameof(packetProvider)); _factory = factory ?? throw new ArgumentNullException(nameof(factory)); _stats = new StreamStats(); _currentPosition = 0L; ClipSamples = true; var packet = _packetProvider.PeekNextPacket(); if (!ProcessHeaderPackets(packet)) { _packetProvider = null !; packet?.Reset(); throw GetInvalidStreamException(packet); } }