具有directsound实现问题的低通滤波器

时间:2014-12-15 17:20:00

标签: c# audio signal-processing directsound lowpass-filter

目前我正在使用directsound API实时开发c#低通滤波器。我遇到的问题是低通滤波器的各种实现似乎不适用于我的echo实现。在过滤开始时,我有一个从捕获缓冲区读取的字节数组(读取)。该数组的值介于0和255之间。

当我对数组进行低通滤波算法时,我获得的值介于0和1之间,并且播放数组是静音的(仅为零)。我附上相关代码。

我认为这种方法是错误的,输入数据可能看起来不同,因为低通算法似乎完全杀了它。有任何想法吗?提前谢谢。

在KillaKem的评论之后更新了相关代码:

//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 个答案:

没有答案