public void PacketIn(OggPacket packet) { if (packet == null) { return; } ClearReturnedBody(); var bytes = packet.PacketData.Length; var lacingValueCount = (int)(bytes / 255f + 1); // make sure we have the buffer storage ExpandBody(bytes); ExpandLacing(lacingValueCount); // Copy in the submitted packet. Array.Copy(packet.PacketData, 0, _bodyData, _bodyFill, bytes); _bodyFill += bytes; // Store lacing vals for this packet int i; for (i = 0; i < lacingValueCount - 1; i++) { _lacingValues[_lacingFill + i] = 255; _granuleValues[_lacingFill + i] = _granulePosition; } _lacingValues[_lacingFill + i] = (int)(bytes % 255f); _granulePosition = _granuleValues[_lacingFill + i] = packet.GranulePosition; // flag the first segment as the beginning of the packet _lacingValues[_lacingFill] |= 0x100; _lacingFill += lacingValueCount; if (packet.EndOfStream) { Finished = true; } }
public bool PacketOut(out OggPacket packet) { packet = null; // Have we started? if (!_preExtrapolated) { return(false); } // Are we done? if (_eofFlag == -1) { return(false); } var codecSetup = _vorbisInfo.CodecSetup; // By our invariant, we have lW, W and centerW set. Search for // the next boundary so we can determine nW (the next window size) // which lets us compute the shape of the current block's window // we do an envelope search even on a single blocksize; we may still // be throwing more bits at impulses, and envelope search handles // marking impulses too. var testWindow = _centerWindow + codecSetup.BlockSizes[_currentWindow] / 4 + codecSetup.BlockSizes[1] / 2 + codecSetup.BlockSizes[0] / 4; var bp = _lookups.EnvelopeLookup.Search(_pcm, _pcmCurrent, _centerWindow, testWindow); if (bp == -1) { if (_eofFlag == 0) { return(false); // not enough data currently to search for a full int block } _nextWindow = 0; } else { _nextWindow = codecSetup.BlockSizes[0] == codecSetup.BlockSizes[1] ? 0 : bp; } var centerNext = _centerWindow + codecSetup.BlockSizes[_currentWindow] / 4 + codecSetup.BlockSizes[_nextWindow] / 4; // center of next block + next block maximum right side. var blockbound = centerNext + codecSetup.BlockSizes[_nextWindow] / 2; // Not enough data yet if (_pcmCurrent < blockbound) { return(false); } // copy the vectors; ampPtr uses the local storage in vb // ampPtr tracks 'strongest peak' for later psychoacoustics var n = codecSetup.BlockSizes[_currentWindow] / 2; _lookups.PsyGlobalLookup.DecayAmpMax(n, _vorbisInfo.SampleRate); var pcmEnd = codecSetup.BlockSizes[_currentWindow]; var pcm = new float[_pcm.Length][]; var beginWindow = _centerWindow - codecSetup.BlockSizes[_currentWindow] / 2; for (var channel = 0; channel < _pcm.Length; channel++) { pcm[channel] = new float[pcmEnd]; Array.Copy(_pcm[channel], beginWindow, pcm[channel], 0, pcm[channel].Length); } // handle eof detection: eof==0 means that we've not yet received EOF eof>0 // marks the last 'real' sample in pcm[] eof<0 'no more to do'; doesn't get here var eofFlag = false; if (_eofFlag != 0) { if (_centerWindow >= _eofFlag) { _eofFlag = -1; eofFlag = true; } } var data = PerformAnalysis(pcm, pcmEnd); packet = new OggPacket(data, eofFlag, _granulePosition, _sequence++); if (!eofFlag) { AdvanceStorageVectors(centerNext); } return(true); }