示例#1
0
 public static void OnFilterThread(LogEntryEventArgs e)
 {
     FilterThread?.Invoke(null, e);
 }
示例#2
0
        /*
         * Filters the wave by convolution of the given filter
         *
         * params:
         * f - Filter to use on the wave
         * caller - the FrequencyDomain form that requested the filter
         */
        public void filter(float[] f, Form caller)
        {
            // Create new arrays with padded 0s and pull in sample values
            filterResult = new float[samples.Length * 8 / sampleBit + f.Length - 1];
            fSamples     = new int[samples.Length * 8 / sampleBit + f.Length - 1];
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    fSamples[i] = BitConverter.ToInt16(samples, i * 2);
                }
            }
            else
            {
                for (int i = 0; i < samples.Length; i++)
                {
                    fSamples[i] = samples[i];
                }
            }

            Stopwatch time = new Stopwatch();

            time.Start();

            // Start filter based on selected options
            if (main.threaded)
            {
                Thread[]       worker = new Thread[Environment.ProcessorCount];
                FilterThread[] fData  = new FilterThread[worker.Length];
                for (int i = 0; i < worker.Length; i++)
                {
                    fData[i]  = new FilterThread(f, fSamples, i, numSamples / worker.Length, new FilterCallback(filterCallback));
                    worker[i] = new Thread(fData[i].filterProc);
                    worker[i].Start();
                }
                for (int i = 0; i < worker.Length; i++)
                {
                    worker[i].Join();
                }
            }
            else if (main.assembly)
            {
                convolution_filter(f, filterResult, fSamples, f.Length, numSamples);
            }
            else
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    for (int j = 0; j < f.Length; j++)
                    {
                        filterResult[i] += fSamples[i + j] * f[j];
                    }
                }
            }

            time.Stop();

            // Converts sample values back into bytes and stores them in sample array
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    byte[] sample = BitConverter.GetBytes((Int16)filterResult[i]);
                    samples[i * 2]     = sample[0];
                    samples[i * 2 + 1] = sample[1];
                }
            }
            else
            {
                for (int i = 0; i < samples.Length; i++)
                {
                    samples[i] = (byte)filterResult[i];
                }
            }
            caller.Close();
            pLog(main.threaded ? "Convolved Filter (Threaded): " : "Convolved Filter: ",
                 String.Format("{0}", time.ElapsedMilliseconds));
            Invalidate();
        }
示例#3
0
        /*
         * Down-samples given samples to desired sample rate
         *
         * params:
         * samples - samples to down-sample
         * sSR     - sample rate of the source samples
         * dSR     - desired sample rate to down-sample to
         *
         * returns: array of sample bytes after being down-sampled
         */
        private byte[] downSampled(byte[] samples, int sSR, int dSR)
        {
            Stopwatch time = new Stopwatch();

            // Builds filter to remove frequencies more than half the destination sampling rate
            float[] filter = new float[samples.Length / 2];
            filter[0] = 1;
            int fBin = filter.Length * dSR / 2 / sSR;

            for (int i = 1; i <= fBin; i++)
            {
                filter[i] = 1;
                filter[filter.Length - i] = 1;
            }

            // Converts filter to time-domain by Inverse DFT
            float[] f = new float[filter.Length];
            time.Start();
            for (int t = 0; t < f.Length; t++)
            {
                for (int freq = 0; freq < f.Length; freq++)
                {
                    f[t] += (float)(filter[freq] * Math.Cos(2 * Math.PI * t * freq / samples.Length) - filter[freq] * Math.Sin(2 * Math.PI * t * freq / f.Length));
                }
                f[t] /= f.Length;
            }
            time.Stop();
            pLog("IDFT", String.Format("{0}", time.ElapsedMilliseconds));
            time.Reset();

            // Builds arrays to hold samples with padded 0s
            filterResult = new float[samples.Length * 8 / sampleBit + f.Length - 1];
            fSamples     = new int[samples.Length * 8 / sampleBit + f.Length - 1];
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    fSamples[i] = BitConverter.ToInt16(samples, i * 2);
                }
            }
            else
            {
                for (int i = 0; i < samples.Length; i++)
                {
                    fSamples[i] = samples[i];
                }
            }

            time.Start();

            // Filters the samples by convolution based on options
            if (main.threaded)
            {
                Thread[]       worker = new Thread[Environment.ProcessorCount];
                FilterThread[] fData  = new FilterThread[worker.Length];
                for (int i = 0; i < worker.Length; i++)
                {
                    fData[i]  = new FilterThread(f, fSamples, i, (fSamples.Length - f.Length) / worker.Length, new FilterCallback(filterCallback));
                    worker[i] = new Thread(fData[i].filterProc);
                    worker[i].Start();
                }
                for (int i = 0; i < worker.Length; i++)
                {
                    worker[i].Join();
                }
            }
            else
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    for (int j = 0; j < f.Length; j++)
                    {
                        filterResult[i] += fSamples[i + j] * f[j];
                    }
                }
            }

            time.Stop();
            pLog(main.threaded ? "Convolved Filter (Threaded): " : "Convolved Filter: ",
                 String.Format("{0}", time.ElapsedMilliseconds));

            // Creates a ratio in lowest terms of destination samples to source samples
            int gcd = GCD(dSR, sSR);

            sSR /= gcd;
            dSR /= gcd;
            float[] result = new float[(int)(((double)(fSamples.Length - f.Length) / sSR) * dSR)];
            bool    skip   = false;
            int     sCount = 0;

            // Builds sample array by skipping samples to match new sample rate
            for (int i = 1, rCount = 0; i < filterResult.Length - f.Length; i++)
            {
                if (!skip)
                {
                    result[rCount++] = filterResult[i - 1];
                    if (i % dSR == 0)
                    {
                        skip   = true;
                        sCount = 0;
                    }
                }
                else if (++sCount == sSR - dSR)
                {
                    skip = false;
                }
            }

            // Converts samples to byte array and returns the result
            byte[] dsResult = new byte[result.Length * sampleBit / 8];
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    byte[] sample = BitConverter.GetBytes((Int16)result[i]);
                    dsResult[i * 2]     = sample[0];
                    dsResult[i * 2 + 1] = sample[1];
                }
            }
            else
            {
                for (int i = 0; i < result.Length; i++)
                {
                    dsResult[i] = (byte)result[i];
                }
            }
            return(dsResult);
        }
示例#4
0
        /*
         * NOTE: DOESN'T WORK
         *
         * Up-samples given samples to desired sample rate
         *
         * params:
         * samples - samples to down-sample
         * sSR     - sample rate of the source samples
         * dSR     - desired sample rate to up-sample to
         *
         * returns: array of sample bytes after being up-sampled
         */
        private byte[] upSampled(byte[] samples, int sSR, int dSR)
        {
            Stopwatch time = new Stopwatch();

            float[] filter = new float[samples.Length / 2];
            filter[0] = 1;
            int fBin = filter.Length * sSR / 2 / dSR;

            for (int i = 1; i <= fBin; i++)
            {
                filter[i] = 1;
                filter[filter.Length - i] = 1;
            }
            float[] f = new float[filter.Length];
            time.Start();
            for (int t = 0; t < f.Length; t++)
            {
                for (int freq = 0; freq < f.Length; freq++)
                {
                    f[t] += (float)(filter[freq] * Math.Cos(2 * Math.PI * t * freq / samples.Length) - filter[freq] * Math.Sin(2 * Math.PI * t * freq / f.Length));
                }
                f[t] /= f.Length;
            }
            time.Stop();
            pLog("IDFT", String.Format("{0}", time.ElapsedMilliseconds));
            time.Reset();

            filterResult = new float[samples.Length * 8 / sampleBit + f.Length - 1];
            fSamples     = new int[samples.Length * 8 / sampleBit + f.Length - 1];
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    fSamples[i] = BitConverter.ToInt16(samples, i * 2);
                }
            }
            else
            {
                for (int i = 0; i < samples.Length; i++)
                {
                    fSamples[i] = samples[i];
                }
            }

            int gcd = GCD(dSR, sSR);

            sSR /= gcd;
            dSR /= gcd;
            float[] result = new float[(int)(((double)(fSamples.Length - f.Length) / sSR) * dSR) + f.Length];
            bool    skip   = false;
            int     sCount = 0;
            float   last   = 0;

            for (int i = 1, rCount = 0; i < result.Length - f.Length; i++)
            {
                if (!skip)
                {
                    result[i - 1] = filterResult[rCount++];
                    if (i % sSR == 0)
                    {
                        last   = result[i];
                        sCount = 0;
                        skip   = true;
                    }
                }
                else
                {
                    result[i - 1] = last;
                    if (++sCount == dSR - sSR)
                    {
                        skip = false;
                    }
                }
            }

            time.Start();
            if (main.threaded)
            {
                Thread[]       worker = new Thread[Environment.ProcessorCount];
                FilterThread[] fData  = new FilterThread[worker.Length];
                for (int i = 0; i < worker.Length; i++)
                {
                    fData[i]  = new FilterThread(f, fSamples, i, (fSamples.Length - f.Length) / worker.Length, new FilterCallback(filterCallback));
                    worker[i] = new Thread(fData[i].filterProc);
                    worker[i].Start();
                }
                for (int i = 0; i < worker.Length; i++)
                {
                    worker[i].Join();
                }
            }
            else
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    for (int j = 0; j < f.Length; j++)
                    {
                        filterResult[i] += fSamples[i + j] * f[j];
                    }
                }
            }
            time.Stop();
            pLog(main.threaded ? "Convolved Filter (Threaded): " : "Convolved Filter: ",
                 String.Format("{0}", time.ElapsedMilliseconds));


            byte[] usResult = new byte[(fSamples.Length - f.Length) * sampleBit / 8];
            if (sampleBit == 16)
            {
                for (int i = 0; i < fSamples.Length - f.Length + 1; i++)
                {
                    byte[] sample = BitConverter.GetBytes((Int16)fSamples[i]);
                    usResult[i * 2]     = sample[0];
                    usResult[i * 2 + 1] = sample[1];
                }
            }
            else
            {
                for (int i = 0; i < usResult.Length; i++)
                {
                    usResult[i] = (byte)fSamples[i];
                }
            }
            return(usResult);
        }