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; }
public AnalyticStreamWindower( IAnalyticStream stream, Windowing.Function function, double totalDuration = double.NaN, int smoothingSamples = 1000, int sampleOffset = 0, TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough) : base(stream) { if (sampleOffset > stream.Samples) { Debug.LogError("Requested a sampleOffset larger than clip length"); sampleOffset = 0; } this.sampleOffset = sampleOffset; if (!double.IsNaN(totalDuration)) { Samples = Math.Min( (int)(totalDuration * SamplingRate), stream.Samples - sampleOffset); } else { Samples = stream.Samples - sampleOffset; } this.rmsBehavior = rmsBehavior; smoothingSamples = Math.Min(smoothingSamples, Samples / 2); window = Windowing.GetHalfWindow64(function, smoothingSamples); endOpeningWindow = smoothingSamples; startClosingWindow = Samples - smoothingSamples; Reset(); }
public Vocoder( IBGCStream stream, IBGCStream carrierStream, double freqLowerBound = 50.0, double freqUpperBound = 16000.0, int bandCount = 22, int fftSize = 4096, int overlapRatio = 4, TransformRMSBehavior rmsBehavior = TransformRMSBehavior.Passthrough) : base(stream) { if (stream.Channels != 1) { throw new StreamCompositionException( $"Vocoder requires a mono input stream. Input stream has {stream.Channels} channels."); } if (carrierStream.Channels != 1) { throw new StreamCompositionException( $"Vocoder requires a mono carrier stream. Carrier stream has {carrierStream.Channels} channels."); } if (stream.SamplingRate != carrierStream.SamplingRate) { throw new StreamCompositionException( $"Vocoder requires the sampling rate of the stream and carrierStream to match. {stream.SamplingRate} vs {carrierStream.SamplingRate}."); } this.carrierStream = carrierStream; this.fftSize = fftSize; this.overlapRatio = overlapRatio; stepSize = fftSize / overlapRatio; overlapSize = fftSize - stepSize; inputBuffer = new float[fftSize]; carrierBuffer = new float[fftSize]; outputAccumulation = new double[fftSize]; cachedSampleBuffer = new float[stepSize]; carrierFFTBuffer = new Complex64[fftSize]; signalFFTBuffer = new Complex64[fftSize]; amplitudeBuffers = new Complex64[bandCount][]; carrierBandBuffers = new Complex64[bandCount][]; for (int i = 0; i < bandCount; i++) { amplitudeBuffers[i] = new Complex64[fftSize]; carrierBandBuffers[i] = new Complex64[fftSize]; } initialized = false; 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.rmsBehavior = rmsBehavior; bandFrequencies = GetExponentialDistribution(freqLowerBound, freqUpperBound, bandCount).ToArray(); outputFactor = 0.5 * Math.Sqrt(fftSize) / overlapRatio; }