コード例 #1
0
        public NoiseGateFilter(
            IBGCStream stream,
            double openThreshold             = -26.0,
            double closeThreshold            = -32.0,
            double attackDuration            = 0.025,
            double holdDuration              = 0.200,
            double releaseDuration           = 0.150,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            this.openThreshold  = Math.Pow(10.0, openThreshold / 20.0);
            this.closeThreshold = Math.Pow(10.0, closeThreshold / 20.0);

            attackRate  = (float)(1.0 / (attackDuration * SamplingRate));
            releaseRate = (float)(1.0 / (releaseDuration * SamplingRate));

            double thresholdDiff  = this.openThreshold - this.closeThreshold;
            double minDecayPeriod = (1.0 / 75.0) * SamplingRate;

            decayRate         = thresholdDiff / minDecayPeriod;
            this.holdDuration = holdDuration;

            isOpen      = false;
            attenuation = 0;
            level       = 0;
            heldTime    = 0;

            inverseSampleRate = 1.0 / SamplingRate;

            this.rmsBehavior = rmsBehavior;
        }
コード例 #2
0
        public static BiQuadFilter HighShelfFilter(
            IBGCStream stream,
            double criticalFrequency,
            double dbGain,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Recalculate)
        {
            double k          = Math.Tan(Math.PI * criticalFrequency / stream.SamplingRate);
            double gainFactor = Math.Pow(10.0, Math.Abs(dbGain) / 20.0);

            double norm, a0, a1, a2, b1, b2;

            if (dbGain >= 0.0)
            {
                //Boost
                norm = 1.0 / (1.0 + Math.Sqrt(2.0) * k + k * k);
                a0   = (gainFactor + Math.Sqrt(2.0 * gainFactor) * k + k * k) * norm;
                a1   = 2.0 * (k * k - gainFactor) * norm;
                a2   = (gainFactor - Math.Sqrt(2.0 * gainFactor) * k + k * k) * norm;
                b1   = 2.0 * (k * k - 1.0) * norm;
                b2   = (1.0 - Math.Sqrt(2.0) * k + k * k) * norm;
            }
            else
            {
                //Cut
                norm = 1.0 / (gainFactor + Math.Sqrt(2.0 * gainFactor) * k + k * k);
                a0   = (1.0 + Math.Sqrt(2.0) * k + k * k) * norm;
                a1   = 2.0 * (k * k - 1.0) * norm;
                a2   = (1.0 - Math.Sqrt(2.0) * k + k * k) * norm;
                b1   = 2.0 * (k * k - gainFactor) * norm;
                b2   = (gainFactor - Math.Sqrt(2.0 * gainFactor) * k + k * k) * norm;
            }

            return(new BiQuadFilter(stream, a0, a1, a2, b1, b2, rmsBehavior));
        }
コード例 #3
0
 public static IBGCStream Convolve(
     this IBGCStream stream,
     double[] filter,
     TransformRMSBehavior transformRMSBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new ConvolutionFilter(stream, filter, transformRMSBehavior));
 }
コード例 #4
0
 public static IBGCStream PhaseVocode(
     this IBGCStream stream,
     double speed,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new PhaseVocoder(stream, speed, rmsBehavior));
 }
コード例 #5
0
        public NoiseVocoder(
            IBGCStream stream,
            double freqLowerBound            = 20.0,
            double freqUpperBound            = 16000.0,
            int bandCount                    = 22,
            int fftSize                      = 4096,
            int overlapRatio                 = 4,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough,
            Random randomizer                = null)
            : base(stream)
        {
            if (stream.Channels != 1)
            {
                throw new StreamCompositionException(
                          $"Noise Vocoder requires a mono input stream. Input stream has {stream.Channels} channels.");
            }

            this.fftSize      = fftSize;
            this.overlapRatio = overlapRatio;
            stepSize          = fftSize / overlapRatio;
            overlapSize       = fftSize - stepSize;

            inputBuffer        = new float[fftSize];
            noiseBuffer        = new double[fftSize];
            outputAccumulation = new double[fftSize];
            cachedSampleBuffer = new float[stepSize];

            noiseFFTBuffer  = new Complex64[fftSize];
            signalFFTBuffer = new Complex64[fftSize];

            amplitudeBuffers = new Complex64[bandCount][];
            noiseBandBuffers = new Complex64[bandCount][];

            for (int i = 0; i < bandCount; i++)
            {
                amplitudeBuffers[i] = new Complex64[fftSize];
                noiseBandBuffers[i] = new Complex64[fftSize];
            }

            initialized = false;

            noiseScalarA = Math.Sqrt(1.0 / 3.0);
            noiseScalarB = 2.0 * noiseScalarA;

            double[] windowTemplate = Windowing.GetHalfWindow64(Windowing.Function.BlackmanHarris, fftSize / 2);

            window = new double[fftSize];
            for (int i = 0; i < fftSize / 2; i++)
            {
                window[i] = windowTemplate[i];
                window[fftSize - i - 1] = windowTemplate[i];
            }

            this.randomizer  = randomizer ?? new Random(CustomRandom.Next());
            this.rmsBehavior = rmsBehavior;

            bandFrequencies = GetExponentialDistribution(freqLowerBound, freqUpperBound, bandCount).ToArray();

            outputFactor = 0.5 * Math.Sqrt(fftSize) / overlapRatio;
        }
コード例 #6
0
        public CarlileShuffler(
            IBGCStream stream,
            double freqLowerBound            = 20.0,
            double freqUpperBound            = 16000.0,
            int bandCount                    = 22,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough,
            Random randomizer                = null)
            : base(stream)
        {
            if (stream.Channels != 1)
            {
                throw new StreamCompositionException(
                          $"Carlile Shuffler requires a mono input stream. Input stream has {stream.Channels} channels.");
            }

            if (stream.ChannelSamples == int.MaxValue)
            {
                throw new StreamCompositionException(
                          $"Carlile Shuffler cannot be performed on a stream of infinite duration. Try truncating first.");
            }

            this.randomizer  = randomizer ?? new Random(CustomRandom.Next());
            this.rmsBehavior = rmsBehavior;

            frequencyDistribution = GetExponentialDistribution(freqLowerBound, freqUpperBound, bandCount);
        }
コード例 #7
0
        public ExpanderFilter(
            IBGCStream stream,
            double ratio                     = 2.0,
            double threshold                 = -40.0,
            double attackDuration            = 0.010,
            double releaseDuration           = 0.050,
            double outputGain                = 0.0,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            this.threshold = threshold;

            attackGain  = (float)Math.Exp(-1.0 / (SamplingRate * attackDuration));
            releaseGain = (float)Math.Exp(-1.0 / (SamplingRate * releaseDuration));

            this.outputGain = (float)Math.Pow(10.0, outputGain / 20.0);

            slope = 1.0 - ratio;

            lastGain       = 0f;
            runningAverage = 0f;

            rmscoef = (float)Math.Pow(2, -100.0 / SamplingRate);

            this.rmsBehavior = rmsBehavior;
        }
コード例 #8
0
 public static IBGCStream Truncate(
     this IBGCStream stream,
     int totalChannelSamples,
     int offset = 0,
     TransformRMSBehavior transformRMSBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new StreamTruncator(stream, totalChannelSamples, offset, transformRMSBehavior));
 }
コード例 #9
0
 /// <summary>
 /// Returns of stream padded by <paramref name="prependSamples"/> and <paramref name="appendSamples"/>
 /// </summary>
 public static IBGCStream PadBy(
     this IBGCStream stream,
     int prependSamples,
     int appendSamples,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new StreamPadder(stream, prependSamples, appendSamples, rmsBehavior));
 }
コード例 #10
0
 public static IBGCStream Truncate(
     this IBGCStream stream,
     double totalDuration,
     int offset = 0,
     TransformRMSBehavior transformRMSBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new StreamTruncator(stream, totalDuration, offset, transformRMSBehavior));
 }
コード例 #11
0
 /// <summary>
 /// Returns of stream padded by <paramref name="prependDuration"/> and <paramref name="appendDuration"/>
 /// </summary>
 public static IBGCStream PadBy(
     this IBGCStream stream,
     double prependDuration,
     double appendDuration,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new StreamPadder(stream, prependDuration, appendDuration, rmsBehavior));
 }
コード例 #12
0
 /// <summary>
 /// Returns of stream <paramref name="duration"/> in duration, with the stream placed accordingly
 /// </summary>
 public static IBGCStream PadTo(
     this IBGCStream stream,
     double duration,
     StreamPadder.StimulusPlacement placement,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new StreamPadder(stream, duration, placement, rmsBehavior));
 }
コード例 #13
0
 public static IBGCStream MultiConvolve(
     this IBGCStream stream,
     float[] filter1,
     float[] filter2,
     TransformRMSBehavior transformRMSBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new MultiConvolutionFilter(stream, filter1, filter2, transformRMSBehavior));
 }
コード例 #14
0
        public MultiConvolutionFilter(
            IBGCStream stream,
            float[] filterL,
            float[] filterR,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            if (stream.Channels != 1)
            {
                throw new StreamCompositionException(
                          $"MultiConvolutionFilter expects a mono input stream. Input stream had {stream.Channels} channels.");
            }

            if (filterL.Length != filterR.Length)
            {
                throw new StreamCompositionException(
                          $"MultiConvolutionFilter expects filterL and filterR lengths match. Filter lengths: {filterL.Length} {filterR.Length}.");
            }

            filterLength = filterL.Length;
            Channels     = 2;

            int fftSize = Math.Max(FFT_EXP_MIN, filterLength.ToNextExponentOf2() + FFT_SIZE_BUMP);

            fftLength         = 1 << fftSize;
            samplesPerOverlap = fftLength - filterLength;

            //Protect against infinite streams
            if (stream.ChannelSamples == int.MaxValue)
            {
                ChannelSamples = int.MaxValue;
                TotalSamples   = int.MaxValue;
            }
            else
            {
                ChannelSamples = filterLength + stream.ChannelSamples - 1;
                TotalSamples   = Channels * ChannelSamples;
            }

            inputBuffer        = new float[samplesPerOverlap];
            outputAccumulation = new float[Channels * fftLength];

            fftBuffer   = new Complex64[fftLength];
            ifftBuffer  = new Complex64[fftLength];
            filterFD    = new Complex64[Channels][];
            filterFD[0] = new Complex64[fftLength];
            filterFD[1] = new Complex64[fftLength];

            for (int i = 0; i < filterLength; i++)
            {
                filterFD[0][i] = filterL[i];
                filterFD[1][i] = filterR[i];
            }

            initialized = false;

            this.rmsBehavior = rmsBehavior;
        }
コード例 #15
0
        public SingleFrequencyDomainToneComposer(
            IEnumerable <ComplexCarrierTone> carrierTones,
            int sampleCount,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
        {
            this.carrierTones = carrierTones.ToArray();
            Samples           = new float[sampleCount];

            this.rmsBehavior = rmsBehavior;
        }
コード例 #16
0
 public static IBGCStream CarlileShuffle(
     this IBGCStream stream,
     IEnumerable <double> frequencyDistribution,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough,
     Random randomizer = null)
 {
     return(new CarlileShuffler(
                stream: stream,
                frequencyDistribution: frequencyDistribution,
                rmsBehavior: rmsBehavior,
                randomizer: randomizer));
 }
コード例 #17
0
        public SingleFrequencyDomainToneComposer(
            IEnumerable <ComplexCarrierTone> carrierTones,
            double duration,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
        {
            this.carrierTones = carrierTones.ToArray();
            int sampleCount = (int)Math.Ceiling(duration * SamplingRate);

            Samples = new float[sampleCount];

            this.rmsBehavior = rmsBehavior;
        }
コード例 #18
0
 public static IBGCStream EchoEffector(
     this IBGCStream stream,
     double delay = 0.100,
     double decay = 0.200,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     throw new NotImplementedException();
     //return new EchoEffector(
     //    stream: stream,
     //    delay: delay,
     //    decay: decay,
     //    rmsBehavior: rmsBehavior);
 }
コード例 #19
0
        public StreamPadder(
            IBGCStream stream,
            double totalDuration,
            StimulusPlacement stimPlacement,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            if (stream.ChannelSamples == int.MaxValue)
            {
                throw new StreamCompositionException("Cannot pad infinite stream using stimPlacement");
            }

            int requestedSamples = (int)Math.Round(totalDuration * SamplingRate);
            int paddingSamples   = requestedSamples - stream.ChannelSamples;

            this.rmsBehavior = rmsBehavior;

            if (paddingSamples < 0)
            {
                throw new StreamCompositionException("Stimulus exceeds targeted padding length");
            }

            switch (stimPlacement)
            {
            case StimulusPlacement.Front:
                appendedSamples  = 0;
                prependedSamples = paddingSamples;
                break;

            case StimulusPlacement.Center:
                //Putting our extra sample in front
                appendedSamples  = paddingSamples / 2;
                prependedSamples = paddingSamples - appendedSamples;
                break;

            case StimulusPlacement.Back:
                appendedSamples  = paddingSamples;
                prependedSamples = 0;
                break;

            default:
                throw new NotSupportedException($"Stimulus Placement not supported: {stimPlacement}");
            }

            appendStartSample = stream.ChannelSamples + prependedSamples;
            ChannelSamples    = requestedSamples;
            TotalSamples      = Channels * ChannelSamples;

            Reset();
        }
コード例 #20
0
        public StreamWindower(
            IBGCStream stream,
            Windowing.Function function      = Windowing.Function.Hamming,
            double totalDuration             = double.NaN,
            int smoothingSamples             = 1000,
            int sampleShift                  = 0,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            if (sampleShift > stream.ChannelSamples)
            {
                Debug.LogError("Requested a sampleOffset larger than clip length");
                sampleShift = 0;
            }

            this.sampleShift = sampleShift;

            if (!double.IsNaN(totalDuration))
            {
                ChannelSamples = Math.Min(
                    (int)Math.Round(totalDuration * SamplingRate),
                    stream.ChannelSamples - sampleShift);
                TotalSamples = Channels * ChannelSamples;
            }
            else
            {
                if (stream.ChannelSamples == int.MaxValue)
                {
                    ChannelSamples = int.MaxValue;
                    TotalSamples   = int.MaxValue;
                }
                else
                {
                    ChannelSamples = stream.ChannelSamples - sampleShift;
                    TotalSamples   = Channels * ChannelSamples;
                }
            }

            this.rmsBehavior = rmsBehavior;

            smoothingSamples = Math.Min(smoothingSamples, ChannelSamples / 2);

            openingWindow = Windowing.GetHalfWindow(function, smoothingSamples);
            closingWindow = openingWindow;

            endOpeningWindow   = smoothingSamples;
            startClosingWindow = ChannelSamples - smoothingSamples;

            Reset();
        }
コード例 #21
0
 public static IBGCStream ChorusEffector(
     this IBGCStream stream,
     double minDelay = 0.040,
     double maxDelay = 0.060,
     double rate     = 0.25,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
 {
     return(new ChorusEffector(
                stream: stream,
                minDelay: minDelay,
                maxDelay: maxDelay,
                rate: rate,
                rmsBehavior: rmsBehavior));
 }
コード例 #22
0
 public static IBGCStream CarlileShuffle(
     this IBGCStream stream,
     double freqLowerBound            = 20.0,
     double freqUpperBound            = 16000.0,
     int bandCount                    = 22,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough,
     Random randomizer                = null)
 {
     return(new CarlileShuffler(
                stream: stream,
                freqLowerBound: freqLowerBound,
                freqUpperBound: freqUpperBound,
                bandCount: bandCount,
                rmsBehavior: rmsBehavior,
                randomizer: randomizer));
 }
コード例 #23
0
        public MultiChannelNoiseGateFilter(
            IBGCStream stream,
            double threshold                 = -50.0,
            double windowDuration            = 0.1,
            double minNonSilentDuration      = 0.07,
            double attackDuration            = 0.05,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            this.minNonSilentDuration = minNonSilentDuration;

            threshold = Math.Pow(10.0, threshold / 20.0);
            int halfWindowSamples   = (int)Math.Floor(windowDuration * SamplingRate * 0.5f);
            int windowSamples       = 2 * halfWindowSamples + 1;
            int smoothingWindowSize = (int)Math.Floor(attackDuration * SamplingRate);

            latencySamples = halfWindowSamples + smoothingWindowSize;

            nonSilenceWindow = new NonSilenceWindow(
                nonSilentSize: windowSamples,
                maxWindowSize: (int)Math.Round(SamplingRate * 0.005),
                samplingRate: SamplingRate,
                channels: Channels,
                levelThreshold: (float)threshold);

            smoothingWindow = new SmoothingWindow(
                windowSize: smoothingWindowSize,
                channels: Channels);

            sampleRingBuffer = new RingBuffer <float>(Channels * latencySamples);

            bufferSize   = BUFFER_SIZE_PER_CHANNEL * Channels;
            sampleBuffer = new float[bufferSize];

            this.rmsBehavior = rmsBehavior;

            if (stream.ChannelSamples == int.MaxValue)
            {
                ChannelSamples = int.MaxValue;
                TotalSamples   = int.MaxValue;
            }
            else
            {
                ChannelSamples = stream.ChannelSamples + latencySamples;
                TotalSamples   = Channels * ChannelSamples;
            }
        }
コード例 #24
0
        public static IBGCStream NoiseVocode(
            this IBGCStream stream,
            double freqLowerBound = 50.0,
            double freqUpperBound = 16000.0,
            int bandCount         = 22,
            int fftSize           = 1 << 13,
                int overlapRatio  = 4,
                TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough,
                Random randomizer = null)
        {
            if (stream.Channels == 1)
            {
                return(new NoiseVocoder(
                           stream: stream,
                           freqLowerBound: freqLowerBound,
                           freqUpperBound: freqUpperBound,
                           bandCount: bandCount,
                           fftSize: fftSize,
                           overlapRatio: overlapRatio,
                           rmsBehavior: rmsBehavior,
                           randomizer: randomizer));
            }

            IBGCStream leftStream = stream.Split(out IBGCStream rightStream);

            leftStream = leftStream.NoiseVocode(
                freqLowerBound: freqLowerBound,
                freqUpperBound: freqUpperBound,
                bandCount: bandCount,
                fftSize: fftSize,
                overlapRatio: overlapRatio,
                rmsBehavior: rmsBehavior,
                randomizer: randomizer);

            rightStream = rightStream.NoiseVocode(
                freqLowerBound: freqLowerBound,
                freqUpperBound: freqUpperBound,
                bandCount: bandCount,
                fftSize: fftSize,
                overlapRatio: overlapRatio,
                rmsBehavior: rmsBehavior,
                randomizer: randomizer);

            return(new StreamMergeFilter(leftStream, rightStream));
        }
コード例 #25
0
 public static IBGCStream ContinuousFilter(
     this IBGCStream stream,
     IBGCEnvelopeStream envelopeStream,
     ContinuousFilter.FilterType filterType,
     double freqLB,
     double freqUB,
     double qFactor = double.NaN,
     TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Recalculate)
 {
     return(new ContinuousFilter(
                stream: stream,
                filterEnvelope: envelopeStream,
                filterType: filterType,
                freqLB: freqLB,
                freqUB: freqUB,
                qFactor: qFactor,
                rmsBehavior: rmsBehavior));
 }
コード例 #26
0
        public StreamPadder(
            IBGCStream stream,
            double prependDuration,
            double appendDuration,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            if (prependDuration < 0.0)
            {
                throw new StreamCompositionException("Cannot prepend negative durations");
            }

            if (appendDuration < 0.0)
            {
                throw new StreamCompositionException("Cannot append negative durations");
            }

            prependedSamples = (int)Math.Round(prependDuration * stream.SamplingRate);
            appendedSamples  = (int)Math.Round(appendDuration * stream.SamplingRate);

            this.rmsBehavior = rmsBehavior;

            if (stream.ChannelSamples == int.MaxValue)
            {
                if (appendedSamples != 0)
                {
                    throw new StreamCompositionException("Cannot append padding to an infinite stream");
                }

                appendStartSample = int.MaxValue;
                ChannelSamples    = int.MaxValue;
                TotalSamples      = int.MaxValue;
            }
            else
            {
                appendStartSample = stream.ChannelSamples + prependedSamples;
                ChannelSamples    = stream.ChannelSamples + prependedSamples + appendedSamples;
                TotalSamples      = stream.Channels * ChannelSamples;
            }

            Reset();
        }
コード例 #27
0
        public StreamEnveloper(
            IBGCStream stream,
            IBGCEnvelopeStream envelopeStream,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            this.rmsBehavior    = rmsBehavior;
            this.envelopeStream = envelopeStream;

            ChannelSamples = Math.Min(envelopeStream.Samples, stream.ChannelSamples);

            if (ChannelSamples == int.MaxValue)
            {
                TotalSamples = int.MaxValue;
            }
            else
            {
                TotalSamples = Channels * ChannelSamples;
            }
        }
コード例 #28
0
        public static BiQuadFilter HighpassFilter(
            IBGCStream stream,
            double criticalFrequency,
            double qFactor = double.NaN,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Recalculate)
        {
            if (double.IsNaN(qFactor))
            {
                qFactor = 1.0 / Math.Sqrt(2.0);
            }

            double k    = Math.Tan(Math.PI * criticalFrequency / stream.SamplingRate);
            double norm = 1.0 / (1.0 + k / qFactor + k * k);
            double a0   = 1.0 * norm;
            double a1   = -2.0 * a0;
            double a2   = a0;
            double b1   = 2.0 * (k * k - 1.0) * norm;
            double b2   = (1.0 - k / qFactor + k * k) * norm;

            return(new BiQuadFilter(stream, a0, a1, a2, b1, b2, rmsBehavior));
        }
コード例 #29
0
        public ConvolutionFilter(
            IBGCStream stream,
            IBGCStream filter,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            if (filter.Channels != 1)
            {
                throw new StreamCompositionException($"ConvolutionFilter expects a single-channel filter.");
            }

            filterLength = filter.ChannelSamples;

            int fftSize = Math.Max(FFT_EXP_MIN, filterLength.ToNextExponentOf2() + FFT_SIZE_BUMP);

            fftLength         = 1 << fftSize;
            samplesPerOverlap = fftLength - filterLength;

            //Protect against infinite streams
            if (stream.ChannelSamples == int.MaxValue)
            {
                ChannelSamples = int.MaxValue;
                TotalSamples   = int.MaxValue;
            }
            else
            {
                ChannelSamples = filterLength + stream.ChannelSamples - 1;
                TotalSamples   = Channels * ChannelSamples;
            }

            inputBuffer        = new float[Channels * samplesPerOverlap];
            outputAccumulation = new float[Channels * fftLength];

            fftBuffer = new Complex64[fftLength];
            filterFD  = filter.ComplexSamples(fftLength);

            initialized = false;

            this.rmsBehavior = rmsBehavior;
        }
コード例 #30
0
        public ConvolutionFilter(
            IBGCStream stream,
            double[] filter,
            TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough)
            : base(stream)
        {
            filterLength = filter.Length;

            int fftSize = Math.Max(FFT_EXP_MIN, filterLength.ToNextExponentOf2() + FFT_SIZE_BUMP);

            fftLength         = 1 << fftSize;
            samplesPerOverlap = fftLength - filterLength;

            //Protect against infinite streams
            if (stream.ChannelSamples == int.MaxValue)
            {
                ChannelSamples = int.MaxValue;
                TotalSamples   = int.MaxValue;
            }
            else
            {
                ChannelSamples = filterLength + stream.ChannelSamples - 1;
                TotalSamples   = Channels * ChannelSamples;
            }

            inputBuffer        = new float[Channels * samplesPerOverlap];
            outputAccumulation = new float[Channels * fftLength];

            fftBuffer = new Complex64[fftLength];
            filterFD  = new Complex64[fftLength];

            for (int i = 0; i < filterLength; i++)
            {
                filterFD[i] = filter[i];
            }

            initialized = false;

            this.rmsBehavior = rmsBehavior;
        }