3

I wrote this simple method using NAudio to create a reverb effect on the current sound device. It's already working.

However, I would like to apply the reverb effect only on the higher frequencies, because otherwise you hear a lot of base drum echoes, which isn't what I want it to sound like.

private void CreateReverb()
{
    WasapiLoopbackCapture waveIn = new WasapiLoopbackCapture();
    BufferedWaveProvider bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
    VolumeSampleProvider volumeProvider = new VolumeSampleProvider(bufferedWaveProvider.ToSampleProvider());
    WasapiOut wasapiOut = new WasapiOut(AudioClientShareMode.Shared, 0);

    wasapiOut.Init(volumeProvider);
    wasapiOut.Play();
    waveIn.StartRecording();

    waveIn.DataAvailable += delegate(object sender, WaveInEventArgs e)
    {
        bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
        volumeProvider.Volume = .8f * ReverbIntensity;
    };
}

I tried some code I found online that creates an equalizer, but I couldn't apply it to my existing code.

Question: How do I change this reverb effect to only affect higher tones using some kind of euqalizer?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
bytecode77
  • 14,163
  • 30
  • 110
  • 141
  • Generally speaking, you'd use the equaliser to set up a hi-pass filter on the sound source, preventing bass frequencies (say 200Hz or lower) getting through and then send that part of the audio stream to your reverb method. – Robert Jun 02 '15 at 16:22
  • 1
    I found and tried `BiQuadFilter`, but it doesn't provide a method that transforms a buffer (only a single float, not byte[]). I have yet to discover that class/method within this weird object model of NAudio. Any idea? – bytecode77 Jun 02 '15 at 16:24
  • Sorry, not familiar with any of that. – Robert Jun 02 '15 at 16:25

1 Answers1

3

I stumbled upon BiQuadFilter and it turns out that it can be used for that purpose.

It converts a sample as a float, while WasapiLoopbackCapture.DataAvailable returns a byte[]. But BitConverter can convert the float into the byte[4] and Buffer.BlockCopy writes it back to the stream.

This is a working reverb including an equalizer.

private void CreateReverb()
{
    WasapiLoopbackCapture waveIn = new WasapiLoopbackCapture();
    BufferedWaveProvider bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
    VolumeSampleProvider volumeProvider = new VolumeSampleProvider(bufferedWaveProvider.ToSampleProvider());
    WasapiOut wasapiOut = new WasapiOut(AudioClientShareMode.Shared, 0);
    BiQuadFilter filter = BiQuadFilter.HighPassFilter(44000, 200, 1);

    wasapiOut.Init(volumeProvider);
    wasapiOut.Play();
    waveIn.StartRecording();

    waveIn.DataAvailable += delegate(object sender, WaveInEventArgs e)
    {
        for (int i = 0; i < e.BytesRecorded; i += 4)
        {
            byte[] transformed = BitConverter.GetBytes(filter.Transform(BitConverter.ToSingle(e.Buffer, i)));
            Buffer.BlockCopy(transformed, 0, e.Buffer, i, 4);
        }
        bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
        volumeProvider.Volume = .8f * ReverbIntensity;
    };
}
bytecode77
  • 14,163
  • 30
  • 110
  • 141