FIR フィルタ。
Inheritance: IFilter
Esempio n. 1
0
	public object Clone()
	{
		FirFilter f = new FirFilter(this.a);
		for (int i = 0; i < this.buf.Count; ++i)
		{
			f.GetValue(this.buf[i]);
		}
		return f;
	}
Esempio n. 2
0
 /// <summary>
 /// Construct BlockConvolver from a specific FIR filter
 /// </summary>
 /// <param name="filter"></param>
 /// <param name="fftSize"></param>
 /// <returns></returns>
 public static OlsBlockConvolver FromFilter(FirFilter filter, int fftSize)
 {
     fftSize = MathUtils.NextPowerOfTwo(fftSize);
     return(new OlsBlockConvolver(filter.Kernel, fftSize));
 }
Esempio n. 3
0
        /// <summary>
        /// Simple resampling as the combination of interpolation and decimation.
        /// </summary>
        /// <param name="signal"></param>
        /// <param name="up"></param>
        /// <param name="down"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public DiscreteSignal ResampleUpDown(DiscreteSignal signal, int up, int down, FirFilter filter = null)
        {
            if (up == down)
            {
                return(signal.Copy());
            }

            var newSamplingRate = signal.SamplingRate * up / down;

            if (up > 20 && down > 20)
            {
                return(Resample(signal, newSamplingRate, filter));
            }

            var output = new float[signal.Length * up];

            var pos = 0;

            for (var i = 0; i < signal.Length; i++)
            {
                output[pos] = up * signal[i];
                pos        += up;
            }

            var lpFilter = filter;

            if (filter == null)
            {
                var factor     = Math.Max(up, down);
                var filterSize = factor > MinResamplingFilterOrder / 2 ?
                                 8 * factor + 1 :
                                 MinResamplingFilterOrder;

                lpFilter = DesignFilter.FirLp(filterSize, 0.5f / factor);
            }

            var upsampled = lpFilter.ApplyTo(new DiscreteSignal(signal.SamplingRate * up, output));

            output = new float[upsampled.Length / down];

            pos = 0;
            for (var i = 0; i < output.Length; i++)
            {
                output[i] = upsampled[pos];
                pos      += down;
            }

            return(new DiscreteSignal(newSamplingRate, output));
        }
Esempio n. 4
0
        public unsafe void ProcessBuffer(
            Burst burst,
            Complex *iqBuffer,
            double iqSamplerate,
            int iqBufferLength,
            float *digitalBuffer)
        {
            burst.Type   = BurstType.WaitBurst;
            burst.Length = 0;
            if (this._buffer == null || iqSamplerate != this._samplerateIn)
            {
                this._samplerateIn  = iqSamplerate;
                this._samplerate    = this._samplerateIn;
                this._interpolation = 1;
                while (this._samplerateIn * (double)this._interpolation < 90000.0)
                {
                    ++this._interpolation;
                }
                this._samplerate       = this._samplerateIn * (double)this._interpolation;
                this._length           = iqBufferLength * this._interpolation;
                this._symbolLength     = this._samplerate / 18000.0;
                this._windowLength     = (int)Math.Round(this._symbolLength * (double)byte.MaxValue);
                this._writeAddress     = 0;
                this._tailBufferLength = (int)Math.Round(this._symbolLength);
                this._syncCounter      = 0;
                this._buffer           = UnsafeBuffer.Create(this._length + this._tailBufferLength, sizeof(Complex));
                this._bufferPtr        = (Complex *)(void *)this._buffer;
                this._tempBuffer       = UnsafeBuffer.Create((int)this._samplerate, 4);
                this._tempBufferPtr    = (float *)(void *)this._tempBuffer;
                this._filterLength     = Math.Max((int)(this._samplerate / 18000.0) | 1, 5);
                float[] coefficients = FilterBuilder.MakeSinc(this._samplerate, 13500.0, this._filterLength);
                this._matchedFilter = new IQFirFilter(coefficients);
                this._fsFilter      = new FirFilter(coefficients);
                this.CreateFrameSynchronization();
            }
            if (this._interpolation > 1)
            {
                int     num     = 0;
                Complex complex = new Complex(0.0f, 0.0f);
                for (int index = 0; index < this._length; ++index)
                {
                    this._bufferPtr[index + this._tailBufferLength] = index % this._interpolation == 0 ? iqBuffer[num++] : complex;
                }
            }
            else
            {
                Radio.Utils.Memcpy((void *)(this._bufferPtr + this._tailBufferLength), (void *)iqBuffer, this._length * sizeof(Complex));
            }
            this._matchedFilter.Process(this._bufferPtr + this._tailBufferLength, this._length);
            if (this._writeAddress + this._length < this._tempBuffer.Length)
            {
                for (int index = 0; index < this._length; ++index)
                {
                    this._tempBufferPtr[this._writeAddress] = (this._bufferPtr[index + this._tailBufferLength] * this._bufferPtr[index].Conjugate()).ArgumentFast();
                    ++this._writeAddress;
                }
            }
            for (int index = 0; index < this._tailBufferLength; ++index)
            {
                this._bufferPtr[index] = this._bufferPtr[this._length + index];
            }
            if (this._writeAddress < this._windowLength * 2)
            {
                return;
            }
            this._ntsOffset      = burst.Mode == Mode.TMO ? (int)Math.Round(122.0 * this._symbolLength) : (int)Math.Round(115.0 * this._symbolLength);
            this._stsOffset      = (int)Math.Round(107.0 * this._symbolLength);
            this._ndb1minSum     = float.MaxValue;
            this._ndb1Index      = 0;
            this._ndb2minSum     = float.MaxValue;
            this._ndb2Index      = 0;
            this._stsMinSum      = float.MaxValue;
            this._stsIndex       = 0;
            this._trainingWindow = this._syncCounter > 0 ? 6 * this._tailBufferLength : this._windowLength;
            if (this._syncCounter > 0)
            {
                --this._syncCounter;
            }
            for (int index1 = 0; index1 < this._trainingWindow; ++index1)
            {
                this._ndb1sum = 0.0f;
                this._ndb2sum = 0.0f;
                this._stsSum  = 0.0f;
                for (int index2 = 0; index2 < this._nts1Buffer.Length; ++index2)
                {
                    this._sample   = this._tempBufferPtr[index1 + index2 + this._ntsOffset];
                    this._training = this._nts1BufferPtr[index2];
                    this._ndb1sum += (float)(((double)this._training - (double)this._sample) * ((double)this._training - (double)this._sample));
                }
                if ((double)this._ndb1sum < (double)this._ndb1minSum)
                {
                    this._ndb1minSum = this._ndb1sum;
                    this._ndb1Index  = index1;
                }
                for (int index2 = 0; index2 < this._nts2Buffer.Length; ++index2)
                {
                    this._sample   = this._tempBufferPtr[index1 + index2 + this._ntsOffset];
                    this._training = this._nts2BufferPtr[index2];
                    this._ndb2sum += (float)(((double)this._training - (double)this._sample) * ((double)this._training - (double)this._sample));
                }
                if ((double)this._ndb2sum < (double)this._ndb2minSum)
                {
                    this._ndb2minSum = this._ndb2sum;
                    this._ndb2Index  = index1;
                }
                for (int index2 = 0; index2 < this._stsBuffer.Length; ++index2)
                {
                    this._sample   = this._tempBufferPtr[index1 + index2 + this._stsOffset];
                    this._training = this._stsBufferPtr[index2];
                    this._stsSum  += (float)(((double)this._training - (double)this._sample) * ((double)this._training - (double)this._sample));
                }
                if ((double)this._stsSum < (double)this._stsMinSum)
                {
                    this._stsMinSum = this._stsSum;
                    this._stsIndex  = index1;
                }
            }
            this._ndb1minSum /= (float)this._nts1Buffer.Length;
            this._ndb2minSum /= (float)this._nts2Buffer.Length;
            this._stsMinSum  /= (float)this._stsBuffer.Length;
            if ((double)this._ndb1minSum < 1.0 || (double)this._ndb2minSum < 1.0 || (double)this._stsMinSum < 1.0)
            {
                if ((double)this._ndb1minSum < (double)this._ndb2minSum && (double)this._ndb1minSum < (double)this._stsMinSum)
                {
                    this._offset = this._ndb1Index;
                    burst.Type   = BurstType.NDB1;
                }
                else if ((double)this._ndb2minSum < (double)this._ndb1minSum && (double)this._ndb2minSum < (double)this._stsMinSum)
                {
                    this._offset = this._ndb2Index;
                    burst.Type   = BurstType.NDB2;
                }
                else
                {
                    this._offset = this._stsIndex;
                    burst.Type   = BurstType.SYNC;
                }
                this._syncCounter = 8;
            }
            else
            {
                burst.Type   = BurstType.None;
                this._offset = this._tailBufferLength * 2;
            }
            int index3 = 0;
            int num1   = 0;

            for (; index3 < 256; ++index3)
            {
                num1 = (int)Math.Round((double)index3 * this._symbolLength);
                digitalBuffer[index3] = this._tempBufferPtr[this._offset + num1];
            }
            this._offset += num1;
            this._offset -= this._tailBufferLength * 2;
            if (this._offset < 0)
            {
                this._offset = 0;
            }
            this._writeAddress -= this._offset;
            if (this._writeAddress < 0)
            {
                this._writeAddress = 0;
            }
            Radio.Utils.Memcpy((void *)this._tempBufferPtr, (void *)(this._tempBufferPtr + this._offset), this._writeAddress * 4);
            this.AngleToSymbol(burst.Ptr, digitalBuffer, (int)byte.MaxValue);
            burst.Length = 510;
        }
 /// <summary>
 /// Construct BlockConvolver from a specific FIR filter
 /// </summary>
 /// <param name="filter"></param>
 /// <param name="fftSize"></param>
 /// <returns></returns>
 public static OlaBlockConvolver FromFilter(FirFilter filter, int fftSize)
 {
     fftSize = MathUtils.NextPowerOfTwo(fftSize);
     return(new OlaBlockConvolver(filter.ImpulseResponse().ToFloats(), fftSize));
 }
Esempio n. 6
0
 /// <summary>
 /// Method for making LP filter from the linear-phase HP filter
 /// (no different from LpToHp method)
 /// </summary>
 /// <param name="filter"></param>
 /// <returns></returns>
 public static FirFilter HpToLp(FirFilter filter)
 {
     return(LpToHp(filter));
 }
Esempio n. 7
0
 /// <summary>
 /// Simple resampling (as the combination of interpolation and decimation).
 /// </summary>
 /// <param name="signal"></param>
 /// <param name="newSamplingRate"></param>
 /// <param name="filter"></param>
 /// <returns></returns>
 public static DiscreteSignal Resample(DiscreteSignal signal, int newSamplingRate, FirFilter filter = null)
 {
     return(new Resampler().Resample(signal, newSamplingRate, filter));
 }
Esempio n. 8
0
 /// <summary>
 /// Decimation preceded by low-pass filtering
 /// </summary>
 /// <param name="signal"></param>
 /// <param name="factor"></param>
 /// <param name="filter"></param>
 /// <returns></returns>
 public static DiscreteSignal Decimate(DiscreteSignal signal, int factor, FirFilter filter = null)
 {
     return(new Resampler().Decimate(signal, factor, filter));
 }
Esempio n. 9
0
        public void Should_return_the_name_fir_filter()
        {
            target = new FirFilter();

            Assert.AreEqual("FIR Filter", target.Name);
        }
Esempio n. 10
0
        public void Run()
        {
            var output2  = new float[_signal.Length];
            var output4  = new float[_signal.Length];
            var output5  = new float[_signal.Length];
            var outputZi = new float[_signal.Length];

            var samples = _signal.Samples;

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4BiQuad.Process(samples[i]);
                output5[i]  = _filterV5BiQuad.Process(samples[i]);
                outputZi[i] = _filterZiBiQuad.Process(samples[i]);
            }

            var diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            var diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");

            for (var i = 0; i < samples.Length; i++)
            {
                output4[i]  = _filterV4Butterworth6.Process(samples[i]);
                output5[i]  = _filterV5Butterworth6.Process(samples[i]);
                outputZi[i] = _filterZiButterworth6.Process(samples[i]);
            }

            diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average();
            diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average();

            Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}");
            Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}");


            // === MISC ====

            var med  = new MedianFilter();
            var med2 = new MedianFilter2();

            var medOut  = med.ApplyTo(_signal).Samples;
            var medOut2 = med2.ApplyTo(_signal).Samples;

            var diffAverageMed = medOut.Zip(medOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MedianFilter vs. MedianFilter2 : {diffAverageMed}");


            var ma    = new MovingAverageFilter();
            var maRec = new MovingAverageRecursiveFilter();

            var maOut    = ma.ApplyTo(_signal).Samples;
            var maRecOut = maRec.ApplyTo(_signal).Samples;

            var diffAverageMa = maOut.Zip(maRecOut, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference MovingAverageFilter vs. MovingAverageRecursiveFilter : {diffAverageMa}");


            // 32bit vs. 64bit

            var fir32 = new FirFilter(DesignFilter.FirWinLp(7, 0.1));
            var fir64 = new FirFilter64(DesignFilter.FirWinLp(7, 0.1));

            var fir32Out = fir32.ApplyTo(_signal).Samples;
            var fir64Out = fir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageFir = fir64Out.Zip(fir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference FirFilter vs. FirFilter64 : {diffAverageFir}");


            var iir32 = new IirFilter(_filterV5Butterworth6.Tf);
            var iir64 = new IirFilter64(_filterV5Butterworth6.Tf);

            var iir32Out = iir32.ApplyTo(_signal).Samples;
            var iir64Out = iir64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageIir = iir64Out.Zip(iir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference IirFilter vs. IirFilter64 : {diffAverageIir}");


            var zi32 = new ZiFilter(_filterV5Butterworth6.Tf);
            var zi64 = new ZiFilter64(_filterV5Butterworth6.Tf);

            var zi32Out = zi32.ApplyTo(_signal).Samples;
            var zi64Out = zi64.ApplyTo(_signal.Samples.ToDoubles());

            var diffAverageZis = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 : {diffAverageZis}");

            zi32Out = zi32.ZeroPhase(_signal).Samples;
            zi64Out = zi64.ZeroPhase(_signal.Samples.ToDoubles());

            var diffAverageZiZeroPhase = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average();

            Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 (zero-phase): {diffAverageZiZeroPhase}");
        }
Esempio n. 11
0
 /// <summary>
 /// Does simple resampling of <paramref name="signal"/> (as the combination of interpolation and decimation).
 /// </summary>
 /// <param name="signal">Input signal</param>
 /// <param name="up">Interpolation factor</param>
 /// <param name="down">Decimation factor</param>
 /// <param name="filter">Lowpass anti-aliasing filter</param>
 public static DiscreteSignal ResampleUpDown(DiscreteSignal signal, int up, int down, FirFilter filter = null)
 {
     return(new Resampler().ResampleUpDown(signal, up, down, filter));
 }