Search code examples
c#audionaudiolowpass-filter

C# How does the following code for Low Pass Filter run?


I have the following C# code for Low pass filter found on NAudio site:

    public void setValues(ISampleProvider sourceProvider,int cutOffFreq)
    {
        this.sourceProvider = sourceProvider;
        this.cutOffFreq = cutOffFreq;

        filter_LowPass();
    }

    private void filter_LowPass()
    {
        channels = sourceProvider.WaveFormat.Channels;
        filters = new BiQuadFilter[channels];

        for (int n = 0; n < channels; n++)
            if (filters[n] == null)
                filters[n] = BiQuadFilter.LowPassFilter(44100, cutOffFreq, 1);
            else
                filters[n].SetLowPassFilter(44100, cutOffFreq, 1);
    }

    public WaveFormat WaveFormat { get { return sourceProvider.WaveFormat; } }

    public int Read(float[] buffer, int offset, int count)
    {
        int samplesRead = sourceProvider.Read(buffer, offset, count);

        for (int i = 0; i < samplesRead; i++)
            buffer[offset + i] = filters[(i % channels)].Transform(buffer[offset + i]);

        return samplesRead;
    }

Where is my read function being called?

Why do I need it?

I am calling the function filter_LowPass this way:

        myFilter.setValues(audioFileReader, currentCutOff);

        waveOut.Init(myFilter);

If I want to multiply each of my samples with a constant value after passing it through the low pass filter, where do I write the code?


Solution

  • NAudio is using a pull model here. The waveOut is going to be demanded samples by the sound card so it is going to call upstream to myFilter.Read(), which in turn is going to call audioFileReader.Read().

    If you want to add some extra gain you could either create a new ISampleProvider following the same pattern or inline it into the low pass filter's read function:

    public int Read(float[] buffer, int offset, int count)
    {
        int samplesRead = sourceProvider.Read(buffer, offset, count);
    
        for (int i = 0; i < samplesRead; i++)
            buffer[offset + i] = gain * filters[(i % channels)].Transform(buffer[offset + i]);
            //                   ^^^^
    
        return samplesRead;
    }