コード例 #1
0
        public void ReadIntoSpread(CancellationToken ct)
        {
            var  channels    = FAudioFile.WaveFormat.Channels;
            long samples     = (long)Math.Round(FAudioFile.TotalTime.TotalSeconds * FAudioFile.WaveFormat.SampleRate);
            long startSample = 0;

            if (Loop)
            {
                startSample = (long)(StartTime * FAudioFile.WaveFormat.SampleRate);
                samples     = (long)((EndTime - StartTime) * FAudioFile.WaveFormat.SampleRate);
            }
            var localSpreadCount = (int)Math.Min(SpreadCount, samples);

            if (ToMono)
            {
                WaveFormSpread.SliceCount = 1;
                WaveFormSpread[0]         = new Spread <double>(localSpreadCount);
            }
            else
            {
                WaveFormSpread.SliceCount = channels;
                for (int i = 0; i < channels; i++)
                {
                    WaveFormSpread[i] = new Spread <double>(localSpreadCount);
                }
            }

            int blockSize = (int)(samples / localSpreadCount);

            FAudioFile.Position = startSample * channels * 4;
            var bufferSize    = blockSize * channels;
            var buffer        = new float[bufferSize];
            var maxValue      = 0.0f;
            var outputBuffers = WaveFormSpread.Select(s => s.Stream.Buffer).ToArray();

            for (int slice = 0; slice < localSpreadCount; slice++)
            {
                //read one interleaved block
                var samplesRead = FAudioFile.Read(buffer, 0, bufferSize);
                //split into channels and do the max
                for (int channel = 0; channel < channels; channel++)
                {
                    maxValue = MinValue;
                    for (int i = 0; i < samplesRead; i += channels)
                    {
                        maxValue = Math.Max(maxValue, Math.Abs(buffer[i + channel]));
                    }
                    if (ToMono)
                    {
                        outputBuffers[0][slice] = Math.Max(maxValue, outputBuffers[0][slice]);
                    }
                    else
                    {
                        outputBuffers[channel][slice] = maxValue;
                    }
                    ct.ThrowIfCancellationRequested();
                }
            }
        }
コード例 #2
0
        protected override void FillBuffers(float[][] buffer, int offset, int sampleCount)
        {
            if (FAudioFile == null)
            {
                return;
            }
            var channels   = FAudioFile.WaveFormat.Channels;
            var blockAlign = FAudioFile.OriginalFileFormat.BlockAlign;
            int samplesToRead;

            if (Speed == 1.0)
            {
                samplesToRead = sampleCount * channels;
            }
            else
            {
                var desiredSamples = sampleCount * channels * Speed;
                //ideal value
                samplesToRead = (int)Math.Truncate(desiredSamples);
                //can only read that much
                var rem = samplesToRead % blockAlign;
                samplesToRead    -= rem;
                FFractionalAccum += (desiredSamples - samplesToRead);
                //gather error
                //correct error
                if (FFractionalAccum >= blockAlign)
                {
                    samplesToRead    += blockAlign;
                    FFractionalAccum -= blockAlign;
                }
            }
            FFileBuffer = BufferHelpers.Ensure(FFileBuffer, samplesToRead);
            int samplesRead = 0;

            if (FPlay && samplesToRead > 0)
            {
                samplesRead = FAudioFile.Read(FFileBuffer, offset * channels, samplesToRead);
                if (samplesRead == 0)
                {
                    if (FLoop)
                    {
                        FAudioFile.CurrentTime = LoopStartTime;
                        FRunToEndBeforeLooping = false;
                        samplesRead            = FAudioFile.Read(FFileBuffer, offset * channels, samplesToRead);
                    }
                    else
                    {
                        samplesRead = FFileBuffer.ReadSilence(offset * channels, samplesToRead);
                    }

                    if (FLoop && FAudioFile.CurrentTime >= LoopEndTime)
                    {
                        FAudioFile.CurrentTime = LoopStartTime;
                        FRunToEndBeforeLooping = false;
                        //bytesread = FAudioFile.Read(FFileBuffer, offset*channels, samplesToRead);
                    }
                }
                if (Speed == 1.0)
                {
                    //copy to output buffers
                    for (int i = 0; i < channels; i++)
                    {
                        for (int j = 0; j < sampleCount; j++)
                        {
                            buffer[i][j] = FFileBuffer[i + j * channels];
                        }
                    }
                }
                else                //resample
                {
                    FResampler.ResampleDeinterleave(FFileBuffer, buffer, samplesToRead / channels, sampleCount, channels);
                }
            }
            else            //silence
            {
                for (int i = 0; i < channels; i++)
                {
                    buffer[i].ReadSilence(offset, sampleCount);
                }
            }
        }