public override int ReadSample(byte[] buffer, int start, int count) { MultiplexedFrame fr = new MultiplexedFrame(); fr.BitsInSample = streamInfo.BitsPerSample; fr.NumChannels = streamInfo.NumberOfChannels; fr.SampleCount = 0; fr.BitOffset = 0; fr.BufferUsed = 0; fr.Buffer = new byte[fr.NumChannels,count * (fr.BitsInSample / 8 + 1)]; int sampleCount = 0; int samplesLeft = count; try { for (; ; ) { if(!frameDecoded) { currentFrame.Decode(physicalStream,flacStreamInfo); frameDecoded = true; } int samplesToRead = 0; if((ulong)samplesLeft > currentFrame.LastSampleNumber - currentSample + 1) { samplesToRead = (int) (currentFrame.LastSampleNumber - currentSample + 1); } else { samplesToRead = samplesLeft; } MultiplexFrame(currentFrame,fr,samplesToRead,currentSample); samplesLeft -= samplesToRead; currentSample += (ulong)samplesToRead; sampleCount += samplesToRead; if (samplesLeft > 0) { currentFrame.Decode(physicalStream, flacStreamInfo); frameDecoded = true; } if (sampleCount == count) { break; } } } catch (LostSynchronizationException) { if (AutoSyncronize) { SynchronizeRight(); } } catch (MalformedFileException) { if (AutoSyncronize) { SynchronizeRight(); } } catch (UnexpectedEndOfStreamException) { if (sampleCount == 0) { sampleCount = -1; } } if (sampleCount != -1) { fr.ToByteArray(buffer, start); } return sampleCount; }
private void MultiplexFrame(Frame fr, MultiplexedFrame mfr, int numSamples, ulong fromSample) { long startBuffer = mfr.BufferUsed; for (int chan = 0; chan < mfr.NumChannels; chan++) { mfr.BufferUsed = startBuffer; for (int sampleNum = 0; sampleNum < numSamples; sampleNum++) { int sampleToMultiplex = fr.output[chan, sampleNum+(int)(fromSample-fr.FirstSampleNumber)]; int bitsLeft = streamInfo.BitsPerSample; int bitsRead = 0; while (bitsLeft > 0) { int bitsToAdd = 0; if (bitsLeft > 8 - mfr.BitOffset) { bitsToAdd = 8 - mfr.BitOffset; } else { bitsToAdd = bitsLeft; } mfr.Buffer[chan, mfr.BufferUsed] |= //(byte)(((byte)(sampleToMultiplex << bitsRead)) >> (8 - bitsToAdd)); (byte)(sampleToMultiplex >> streamInfo.BitsPerSample - bitsRead - bitsToAdd); bitsRead += bitsToAdd; mfr.BitOffset += bitsToAdd; bitsLeft -= bitsToAdd; if (mfr.BitOffset == 8) { mfr.BufferUsed++; mfr.BitOffset = 0; } } } } mfr.SampleCount += (ulong)numSamples; }