/// <summary> /// Reads bytes from this stream /// </summary> /// <param name="array">Buffer to read into</param> /// <param name="offset">Offset in array to read into</param> /// <param name="count">Number of bytes to read</param> /// <returns>Number of bytes read</returns> public override int Read(byte[] array, int offset, int count) { lock (lockObject) { if (Enabled) { if (sourceBuffer == null || sourceBuffer.Length < count) { sourceBuffer = new byte[count]; } int sourceBytesRead = sourceStream.Read(sourceBuffer, 0, count); int sampleCount = sourceBytesRead / (bytesPerSample * channels); for (int sample = 0; sample < sampleCount; sample++) { int start = sample * bytesPerSample * channels; double in1; double in2; ReadSamples(sourceBuffer, start, out in1, out in2); simpleCompressor.Process(ref in1, ref in2); WriteSamples(array, offset + start, in1, in2); } return(count); } else { return(sourceStream.Read(array, offset, count)); } } }
/// <summary> /// Reads bytes from this wave stream /// </summary> /// <param name="destBuffer">The destination buffer</param> /// <param name="offset">Offset into the destination buffer</param> /// <param name="numBytes">Number of bytes read</param> /// <returns>Number of bytes read.</returns> public override int Read(byte[] destBuffer, int offset, int numBytes) { lock (lockObject) { int bytesWritten = 0; // 1. fill with silence if (position < audioStartPosition) { bytesWritten = (int)Math.Min(numBytes, audioStartPosition - position); for (int n = 0; n < bytesWritten; n++) { destBuffer[n + offset] = 0; } } if (bytesWritten < numBytes) { // don't read too far into source stream int sourceBytesRequired = (int)Math.Min( numBytes - bytesWritten, sourceLengthBytes + sourceOffsetBytes - sourceStream.Position); int read = sourceStream.Read(destBuffer, bytesWritten + offset, sourceBytesRequired); bytesWritten += read; } // 3. Fill out with zeroes for (int n = bytesWritten; n < numBytes; n++) { destBuffer[offset + n] = 0; } position += numBytes; return(numBytes); } }
/// <summary> /// Reads bytes from this wave stream /// </summary> /// <param name="destBuffer">Destination buffer</param> /// <param name="offset">Offset into destination buffer</param> /// <param name="numBytes"></param> /// <returns>Number of bytes read.</returns> public override int Read(byte[] destBuffer, int offset, int numBytes) { lock (lockObject) { byte[] sourceBuffer = new byte[numBytes * 2]; int bytesRead = sourceStream.Read(sourceBuffer, 0, numBytes * 2); Convert32To16(destBuffer, offset, sourceBuffer, bytesRead); position += (bytesRead / 2); return(bytesRead / 2); } }
/// <summary> /// Reads data from this stream /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public override int Read(byte[] buffer, int offset, int count) { lock (lockObject) { // 1. attempt to fill the circular buffer with enough data to meet our request while (BufferEndPosition < position + count) { int sourceReadCount = count; if (sourceReadCount % sourceStream.BlockAlign != 0) { sourceReadCount = (count + sourceStream.BlockAlign) - (count % sourceStream.BlockAlign); } int sourceRead = sourceStream.Read(GetSourceBuffer(sourceReadCount), 0, sourceReadCount); circularBuffer.Write(GetSourceBuffer(sourceReadCount), 0, sourceRead); if (sourceRead == 0) { // assume we have run out of data break; } } // 2. discard any unnecessary stuff from the start if (bufferStartPosition < position) { circularBuffer.Advance((int)(position - bufferStartPosition)); bufferStartPosition = position; } // 3. now whatever is in the buffer we can return int bytesRead = circularBuffer.Read(buffer, offset, count); position += bytesRead; // anything left in buffer is at start position bufferStartPosition = position; return(bytesRead); } }
//private int leftoverSourceOffset = 0; /// <summary> /// Reads bytes from this stream /// </summary> /// <param name="buffer">Buffer to read into</param> /// <param name="offset">Offset in buffer to read into</param> /// <param name="count">Number of bytes to read</param> /// <returns>Number of bytes read</returns> public override int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; if (count % BlockAlign != 0) { //throw new ArgumentException("Must read complete blocks"); count -= (count % BlockAlign); } while (bytesRead < count) { // first copy in any leftover destination bytes int readFromLeftoverDest = Math.Min(count - bytesRead, leftoverDestBytes); if (readFromLeftoverDest > 0) { Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + bytesRead, readFromLeftoverDest); leftoverDestOffset += readFromLeftoverDest; leftoverDestBytes -= readFromLeftoverDest; bytesRead += readFromLeftoverDest; } if (bytesRead >= count) { // we've fulfilled the request from the leftovers alone break; } // now we'll convert one full source buffer if (leftoverSourceBytes > 0) { // TODO: still to be implemented: see moving the source position back below: } // always read our preferred size, we can always keep leftovers for the next call to Read if we get // too much int sourceBytesRead = sourceStream.Read(conversionStream.SourceBuffer, 0, preferredSourceReadSize); if (sourceBytesRead == 0) { // we've reached the end of the input break; } int sourceBytesConverted; int destBytesConverted = conversionStream.Convert(sourceBytesRead, out sourceBytesConverted); if (sourceBytesConverted == 0) { Debug.WriteLine(String.Format("Warning: couldn't convert anything from {0}", sourceBytesRead)); // no point backing up in this case as we're not going to manage to finish playing this break; } else if (sourceBytesConverted < sourceBytesRead) { // cheat by backing up in the source stream (better to save the lefto sourceStream.Position -= (sourceBytesRead - sourceBytesConverted); } if (destBytesConverted > 0) { int bytesRequired = count - bytesRead; int toCopy = Math.Min(destBytesConverted, bytesRequired); // save leftovers if (toCopy < destBytesConverted) { leftoverDestBytes = destBytesConverted - toCopy; leftoverDestOffset = toCopy; } Array.Copy(conversionStream.DestBuffer, 0, buffer, bytesRead + offset, toCopy); bytesRead += toCopy; } else { // possible error here Debug.WriteLine(string.Format("sourceBytesRead: {0}, sourceBytesConverted {1}, destBytesConverted {2}", sourceBytesRead, sourceBytesConverted, destBytesConverted)); //Debug.Assert(false, "conversion stream returned nothing at all"); break; } } position += bytesRead; return(bytesRead); }