Low pass filter with directsound implementation issue

420 Views Asked by At

Currently I am developing a c# low pass filter in real time using directsound API. The problem that I've encountered is that various implementations of low pass filters seem not to work with my echo implementation. At the begining of the filtering I have an array of bytes (read) that is read from the capturing buffer. The values of this array are between 0 and 255.

When I subject the array to low-pass filtering algorithm I obtain values that fall between 0 and 1 and as an effect the play array is silent (zeros only). I attach the relevant code.

I imagine that that this approach is wrong and probably the input data should look different as the low pass algorithm seems to kill it completely. Any ideas? Thanks in advance.

Updated relevant code after KillaKem's comments:

//buffer format
var format = new WaveFormat
        {
            SamplesPerSecond = 44100,
            BitsPerSample = 16,
            Channels = 2,
            FormatTag = WaveFormatTag.Pcm
        };

//reading the buffer
         byte[] read = (byte[])_dwCapBuffer.Read(offset, typeof(byte), LockFlag.None, _dwOutputBufferSize);
                    byte[] play = new byte [read.Length];
                    byte[] readL= new byte [read.Length/2];
                    byte[] readR= new byte [read.Length/2];
                    byte[] playL = new byte[read.Length / 2];
                    byte[] playR = new byte[read.Length / 2];
                    float[] readLfloat = new float[read.Length / 4];
                    float[] readRfloat = new float[read.Length / 4];
                    float[] playLfloat = new float[read.Length / 4];
                    float[] playRfloat = new float[read.Length / 4];

//dividing into channels and casting to float
                    for(int i = 0; i<read.Length; i=i+1)
                    {
                        if (i % 4 == 0)
                        {
                            readL[(int)i / 2] = read[i];
                        }
                        if(i%4==1)
                        {
                        readL[(int)i/2]=read[i];
                        readLfloat[(int)i / 4] = (((short)(read[i-1] << 8 | read[i])) / 32768f);
                        }
                        if (i % 4 == 2)
                        {
                            readR[(int)i / 2] = read[i];
                        }
                        if (i % 4 == 3)
                        {
                            readR[(int)i / 2] = read[i];
                            readRfloat[(int)i / 4] = (((short)(read[i - 1] << 8 | read[i])) / 32768f);
                        }

                    }
//filter coefficients
float frequency = 1000f;
                    float sampleRate = (float)_dwCapBuffer.Format.SamplesPerSecond;
                    float resonance = 0.5f;

                    float c = 1.0f / (float)Math.Tan(Math.PI * frequency / sampleRate);
                    float a0 = 1.0f / (1.0f + resonance * c + c * c);
                    float a1 = 2f * a0;
                    float a2 = a0;
                    float b1 = 2.0f * (1.0f - c * c) * a0;
                    float b2 = (1.0f - resonance * c + c * c) * a0;
//filtering
for(int i = 0; i < readLfloat.Length; i++)
                    {

                        float readCurrSample = readLfloat[i];
                        float playCurrSample = playLfloat[i];
                        float filtered=readCurrSample;
                        float readOneSample;
                        float readTwoSample;
                        float playOneSample;
                        float playTwoSample;


                        if (i ==0)
                        {
                            filtered = ((float)a0 * readCurrSample) + ((float)a1 * savelastRead) + ((float)a2 * saveprelastRead) - ((float)b1 * savelastPlay) - ((float)b2 * saveprelastPlay);

                        }
                        else if (i==1)
                        {
                            readOneSample = readLfloat[i-1];
                            playOneSample = playLfloat[i-1];
                            filtered = ((float)a0 * readCurrSample) + ((float)a1 * readOneSample) + ((float)a2 * savelastRead) - ((float)b1 * playOneSample) - ((float)b2 * savelastPlay);

                        }
                        else
                        {
                            readOneSample = readLfloat[i - 1];
                            playOneSample = playLfloat[i - 1];

                            readTwoSample = readLfloat[i - 2];

                            playTwoSample = playLfloat[i - 2];
                            filtered = ((float)a0 * readCurrSample) + ((float)a1 * readOneSample) + ((float)a2 * readTwoSample) - ((float)b1 * playOneSample) - ((float)b2 * playTwoSample);

                        }

                        if (i == readL.Length - 4)
                        {

                            saveprelastPlay = playCurrSample;
                            saveprelastRead = readCurrSample;
                        }
                        if (i == readL.Length-2)
                        {
                            savelastPlay = playCurrSample;
                            savelastRead = readCurrSample;
                        }
                        if (filtered > 1 || filtered < -1)
                        {
                            int x = 0;
                        }

                        playLfloat[i] = filtered;


                    }

                    playRfloat = playLfloat; //ignoring Right channel operations
//Recasting to bytes array

                    for (int i = 0; i < read.Length; i = i + 1)
                    {


                        if (i % 4 == 1)
                        {
                            byte[] bytes;

                            bytes = BitConverter.GetBytes((short)(playLfloat[(int)(i-1)/4] * 32768f));
                            read[i] = bytes[0];
                            read[i - 1] = bytes[1];

                        }

                        if (i % 4 == 3)
                        {
                            byte[] bytes;

                            bytes = BitConverter.GetBytes((short)(playRfloat[(int)(i - 1) / 4] * 32768f));
                            read[i] = bytes[0];
                            read[i - 1] = bytes[1];
                        }

                    }
0

There are 0 best solutions below