예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }