Search code examples
c#signal-processingwav

How do I get a strict/sharp cut from Frequency A to Frequency B of a WAV audio using NWaves (or any other library)?


I need to get a sharp "cut" of a WAV audio file from frequency A (500 Hz) to Frequency B (800 Hz) and put it into a new file.

This is how it is done in Adobe Audition

I tried using NWaves.Filters.Butterworth.BandPassFilter but it does not do the trick the way I want it: BandPassFilter. Not sharp enough

        DiscreteSignal signal = waveContainer[Channels.Average];

        int samplingRate = signal.SamplingRate;

        int lowerFrequencyHz = 500;
        int upperFrequencyHz = 800;
        double lowerFrequency = (double)lowerFrequencyHz / samplingRate;
        double upperFrequency = (double)upperFrequencyHz / samplingRate;

        var tf = new NWaves.Filters.Butterworth.BandPassFilter(lowerFrequency, upperFrequency, 3).Tf;
        var filter = new NWaves.Filters.Base64.IirFilter64(tf);
        var filtered = signal.Samples.Select(s => (float)filter.Process(s));
        DiscreteSignal outSignal = new DiscreteSignal(signal.SamplingRate, filtered);

How do I achieve it using C# and possibly NWaves library making it as sharp as Adobe does it with exact selection, copy and paste?


Solution

  • I found out how to do it:

            DiscreteSignal signal = waveContainer[Channels.Average];
    
            int samplingRate = signal.SamplingRate;
    
            int lowerFrequencyHz = 500;
            int upperFrequencyHz = 800;
            double lowerFrequency = (double)lowerFrequencyHz / samplingRate;
            double upperFrequency = (double)upperFrequencyHz / samplingRate;
    
            var tf = new NWaves.Filters.Butterworth.BandPassFilter(lowerFrequency, upperFrequency, 5).Tf;
            var filter = new NWaves.Filters.Base64.IirFilter64(tf);
            var filtered = signal.Samples.Select(s => (float)filter.Process(s));
            DiscreteSignal outSignal = new DiscreteSignal(signal.SamplingRate, filtered);
    
            for (int i = 0; i < 5; i++) // 1 + 5 iterations makes it very clear and sharp
            {
                filtered = outSignal.Samples.Select(s => (float)filter.Process(s));
                outSignal = new DiscreteSignal(outSignal.SamplingRate, filtered);
            }
    

    The main things are:

    • BANDPASS FILTER order of 5
    • 6 iterations of filtering makes it clear and sharp