/// <summary> /// Reads the audio to the specified buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <returns> /// The length of the data written. /// </returns> public override int Read(Span <byte> buffer) { var cursor = MemoryMarshal.Cast <byte, Int24>(buffer); while (cursor.Length > 0) { var reader = cursor.Length >= readBuffer.Length ? readBuffer : readBuffer.Slice(0, cursor.Length); int u = Source.Read(reader.Span); var wrote = reader.Span.Slice(0, u); var dest = cursor.Slice(0, wrote.Length); if (wrote.Length != dest.Length) { new InvalidOperationException( $"The {nameof(wrote)}'s length and {nameof(dest)}'s length are not equal! This is a bug!").Throw(); } if (AccuracyMode) { var dsmAcc = dsmAccumulator.Span; var dsmLastOut = dsmLastOutput.Span; dsmChannelPointer %= dsmAcc.Length; for (int i = 0; i < dest.Length; i++) { var diff = wrote[i] - (dsmLastOut[dsmChannelPointer] / multiplier); dsmAcc[dsmChannelPointer] += diff; var v = dsmLastOut[dsmChannelPointer] = Convert(dsmAcc[dsmChannelPointer]); dest[i] = IsEndiannessConversionRequired ? Int24.ReverseEndianness(v) : v; dsmChannelPointer = ++dsmChannelPointer % dsmAcc.Length; } } else { for (int i = 0; i < dest.Length; i++) { var v = Convert(wrote[i]); dest[i] = IsEndiannessConversionRequired ? Int24.ReverseEndianness(v) : v; } } cursor = cursor.Slice(dest.Length); if (u != reader.Length) { return(buffer.Length - cursor.Length); //The Source doesn't fill whole reader so return here. } } return(buffer.Length); }
/// <summary> /// Reads the audio to the specified buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <returns> /// The length of the data written. /// </returns> public override int Read(Span <float> buffer) { Span <Int24> span = stackalloc Int24[buffer.Length > ActualBufferMax ? ActualBufferMax : buffer.Length]; var cursor = buffer; while (cursor.Length > 0) { var reader = cursor.Length >= span.Length ? span : span.Slice(0, cursor.Length); int u = Source.Read(MemoryMarshal.AsBytes(span)) / bytesPerSample; var wrote = reader.Slice(0, u); var dest = cursor.Slice(0, wrote.Length); if (wrote.Length != dest.Length) { new InvalidOperationException( $"The {nameof(wrote)}'s length and {nameof(dest)}'s length are not equal! This is a bug!").Throw(); } if (IsEndiannessConversionRequired) { for (int i = 0; i < wrote.Length && i < dest.Length; i++) { dest[i] = Int24.ReverseEndianness(wrote[i]) / divisor; } } else { for (int i = 0; i < wrote.Length && i < dest.Length; i++) { dest[i] = wrote[i] / divisor; } } cursor = cursor.Slice(u); if (u != reader.Length) { return(buffer.Length - cursor.Length); //The Source doesn't fill whole reader so return here. } } return(buffer.Length); }