Пример #1
0
        private static int[] createFreqShiftMap(FFTs stft, int indexShift, SelectedWindowIndices indices = null, int order = 0, double thresh = 0.9)
        {
            (_, _, int freqIndex1, int freqIndex2) =
                indices != null?indices.Indices() : (0, stft.Count, 0, stft.fftSize);

            /**
             * Explanation of algorithm:
             * We basically want one half cycle of a cos(ang_freq * (centerIndex-i))^(order)
             * First we calculation the attenuation we want at the window boundaries, ie
             *      cos(ang_freq*(centerIndex-freq1))^(order) = thresh
             *      Then we solve for ang_freq to find the angular frequency of the window
             *      Then we use that angular frequency for arbitrary values of i
             *
             * And then, depending on the shift direction, we don't care about shifts on the opposite side of the direction
             *
             * If order is zero, it results in a Linear Frequency Shifter
             */
            int centerIndex = (freqIndex2 + freqIndex1) / 2;

            int[] shift_map = new int[stft.fftSize];
            for (int i = 0; i < shift_map.Length / 2; i++)
            {
                double angular_freq = Math.Acos(Math.Pow(thresh, (1d / ((double)order)))) / (centerIndex - freqIndex1);
                double angle        = angular_freq * (i - centerIndex);
                double mod          = Math.Pow(Math.Cos(angle), order);

                //Don't care about values outside of the half period window
                if (Math.Abs(angle) >= Math.PI / 2)
                {
                    mod = 0;
                }

                //Don't care about values past the window in the direction it's not shifting
                else if (indexShift > 0 && i < freqIndex1)
                {
                    mod = 0;
                }
                else if (indexShift < 0 && i > freqIndex2)
                {
                    mod = 0;
                }

                int shift = (int)(indexShift * mod);
                if (i >= freqIndex1 && i < freqIndex2)
                {
                    shift_map[i] = indexShift;                         //first side
                    shift_map[shift_map.Length - i - 1] = -indexShift; //mirrored side
                }
                else
                {
                    shift_map[i] = shift;
                }
            }


            return(shift_map);
        }
Пример #2
0
 private static double[] createFreqShiftModulation(FFTs stft, int shiftIndex, SelectedWindowIndices indices, bool freqDependent = false)
 {
     if (freqDependent)
     {
         ;                //todo, implement createFreqDependentShiftMap first
     }
     double[] shift_mod = new double[stft.fftSize];
     Array.Fill(shift_mod, 1);
     return(shift_mod);
 }
Пример #3
0
        public void ApplyGain(double dbGain, bool applyToWindow = false)
        {
            FFTs stft = parentRef.GetSTFT();
            SelectedWindowIndices indices = parentRef.GetSelectedWindowIndices();

            if (applyToWindow)
            {
                if (!indices.Exists())
                {
                    MessageBox.Show("There is no window selected!");
                    return;
                }
                Processing.AddGain(stft, dbGain, indices, dB: true);
            }
            else
            {
                Processing.AddGain(stft, dbGain, dB: true);
            }
        }
Пример #4
0
        public void ApplyWhiteNoiseFilter(double threshold, bool applyToWindow = false)
        {
            FFTs stft = parentRef.GetSTFT();
            SelectedWindowIndices indices = parentRef.GetSelectedWindowIndices();

            if (applyToWindow)
            {
                if (!indices.Exists())
                {
                    MessageBox.Show("There is no window selected!");
                    return;
                }
                Filters.WhiteNoiseFilter(stft, threshold, indices);
            }
            else
            {
                Filters.WhiteNoiseFilter(stft, threshold);
            }
        }
Пример #5
0
        public static void AddGain(FFTs stft, double gain = 0, SelectedWindowIndices indices = null, bool dB = true)
        {
            (int timeIndex1, int timeIndex2, int freqIndex1, int freqIndex2) =
                indices != null?indices.Indices() : (0, stft.Count, 0, stft.fftSize);

            //Defaults to dB
            //Converts to linear gain for multiplying gain to data
            gain = dB ? Math.Pow(10, gain / 20) : gain;

            List <Complex[]> data = stft.GetFFTs();

            for (int n = timeIndex1; n < timeIndex2; n++)
            {
                for (int k = freqIndex1; k < freqIndex2; k++)
                {
                    data[n][k].Real      *= gain;
                    data[n][k].Imaginary *= gain;
                }
            }
        }
Пример #6
0
        public static void WhiteNoiseFilter(FFTs stft, double threshold, SelectedWindowIndices indices = null, bool dB = true)
        {
            List <Complex[]> data = stft.GetFFTs();

            (int timeIndex1, int timeIndex2, int freqIndex1, int freqIndex2) =
                indices != null?indices.Indices() : (0, data.Count, 0, stft.fftSize);

            threshold = dB ? Math.Pow(10, threshold / 20) : threshold;
            for (int n = timeIndex1; n < timeIndex2; n++)
            {
                for (int k = freqIndex1; k < freqIndex2; k++)
                {
                    if (data[n][k].Magnitude < threshold)
                    {
                        data[n][k].Real      = 0;
                        data[n][k].Imaginary = 0;
                    }
                }
            }
        }
Пример #7
0
        private static void HighPassFilter(FFTs stft, double cutoff, SelectedWindowIndices indices = null)
        {
            (int timeIndex1, int timeIndex2, int freqIndex1, int freqIndex2) =
                indices != null?indices.Indices() : (0, stft.Count, 0, stft.fftSize / 2);

            List <Complex[]> data = stft.GetFFTs();
            int index_cutoff      = (int)(cutoff / stft.FreqResolution);

            for (int n = timeIndex1; n < timeIndex2; n++)
            {
                for (int k = freqIndex1; k < freqIndex2; k++)
                {
                    if (k <= index_cutoff)
                    {
                        data[n][k] = new Complex();
                        data[n][stft.fftSize - 1 - k] = new Complex(); //Mirrored side
                    }
                }
            }
        }
Пример #8
0
        public static void FrequencyShifter(FFTs stft, int freq_shift, SelectedWindowIndices indices = null, int order = 0, double thresh = 0.9)
        {
            int indexShift = freq_shift / stft.FreqResolution;

            if (indexShift == 0)
            {
                return;
            }

            (int timeIndex1, int timeIndex2, int freqIndex1, int freqIndex2) =
                indices != null?indices.Indices() : (0, stft.Count, 0, stft.fftSize);


            //Shift map tells how far each index is going to shift
            //Order of 0 results in a linear shifter
            //shift_mod gives a scaling factor to each shifted index
            int[]    shift_map = createFreqShiftMap(stft, indexShift, indices, order, thresh);
            double[] shift_mod = createFreqShiftModulation(stft, indexShift, indices);


            List <Complex[]> ffts = stft.GetFFTs();

            for (int n = timeIndex1; n < timeIndex2; n++)
            {
                Complex[] fft         = ffts[n];
                Complex[] shifted_fft = new Complex[fft.Length];
                for (int k = 0; k < fft.Length; k++)
                {
                    if (k + shift_map[k] >= 0 && k + shift_map[k] < fft.Length) //Ignore the ones that get shifted too far
                    {
                        shifted_fft[k + shift_map[k]] += fft[k] * shift_mod[k];
                    }
                }
                Array.Copy(shifted_fft, fft, fft.Length);
            }
        }
Пример #9
0
 private static int[] createRecursiveBandShiftMap(FFTs stft, int indexShift, SelectedWindowIndices indices = null)
 {
     throw new NotImplementedException();
 }
Пример #10
0
 private void PaintGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
 {
     selectedWindow.FinishDrawing();
     (int t1, int t2, int f1, int f2) = WindowPoints();
     selectedIndices = new SelectedWindowIndices(t1, t2, f1, f2);
 }
Пример #11
0
 private void RemoveSelectedSpecWindow()
 {
     PaintGrid.Children.Remove(selectedWindow.windowToDraw);
     selectedWindow  = new SelectedSpecWindow();
     selectedIndices = new SelectedWindowIndices();
 }