1

UPDATED: Overall code that I use

For this, you really have to look at Mark Heath article here: how to play and record at the sametime. With that, you can really directly understood the problem right? Which is, the played sound from mic, will be recorded back to mic .. in a loop. Hence, echo effect.

I start the record and play action within a btnRecord event:

private void btnRecord_Click(object sender, EventArgs e)
        {

            // set up the recorder
            btnRecord.Enabled = false;
            btnStop.Enabled = true;
            

            recorder = new WaveIn();
            recorder.DataAvailable += RecorderOnDataAvailable;

            // set up our signal chain
            bufferedWaveProvider = new BufferedWaveProvider(recorder.WaveFormat);
            savingWaveProvider = new SavingWaveProvider(bufferedWaveProvider, "tempx.wav");

            // set up playback
            player = new WaveOut();
            player.Volume = 1;
            player.Init(savingWaveProvider);

            // begin playback & record
            player.Play();
            recorder.StartRecording();

            
        }

And here is the code that get called when recoreded data available:

 private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
        {
            //incoming data, process it
            //TODO: AEC should be done here
            IntPtr unmanagedPointer = Marshal.AllocHGlobal(waveInEventArgs.Buffer.Length);
            Marshal.Copy(waveInEventArgs.Buffer, 0, unmanagedPointer, waveInEventArgs.Buffer.Length);
            speex_preprocess_run(speex_state, unmanagedPointer);
            
            byte[] b = new byte[waveInEventArgs.Buffer.Length];
            Marshal.Copy(unmanagedPointer, b, 0, waveInEventArgs.Buffer.Length);

            // play it back
            bufferedWaveProvider.AddSamples(b, 0, waveInEventArgs.BytesRecorded);
        }

In the last line you can see that I put the resultant buffer from speex processing to be played again in the bufferedWaveProvider. Unfortunately, it is still the same: still the same echo effect.

swdev
  • 4,997
  • 8
  • 64
  • 106
  • 1
    Could you share the code you have? Check [this](https://dsp.stackexchange.com/a/73484/55891) to understand in a high level how the phenomenon occurs and how it can be cancelled. My guess is that the recording is not synchronized with the playback. Then it does not identify what to cancel. – Bob Mar 17 '21 at 10:21
  • For AEC, I actually really want to use libspeexdsp.dll, as depicted in https://stackoverflow.com/questions/10826902/easiest-way-to-use-speex-preprocessor-in-c but turn out, the latest libspeexdsp source code don't have that functions that I really want to use the trivial `speex_echo_cancellation` So.. I think I kinda stuck with this approach. Meaning, I really have to use opus instead of speex. – swdev Mar 17 '21 at 15:25
  • I understand that you want to use speex. What I was asking for is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). For instance you don't show how you are initializing the library, or how you are storing your buffers, my guess is that what happens is you start to play independently from the record, then the separation between the recorded echo and the originally played samples is too big and this will prevent the echo cancellation, unless you use an unsupervised echo cancelation (that I think is not the case). – Bob Mar 18 '21 at 10:13
  • Aah right. Okay. Be back to you shortly and will update the code in post – swdev Mar 19 '21 at 11:28
  • @user12750353 I add the code :) Thanks! – swdev Mar 21 '21 at 01:04
  • Thank you, this is better. Are you playing the data you receive from the microphone? – Bob Mar 21 '21 at 07:33
  • Yes, exactly. That `player.Play();` does that. Hence, the echo effect started... – swdev Mar 21 '21 at 14:11
  • @user12750353 Btw, I just found the correct Speex with AEC functions https://github.com/Yuchen-95/speex-1.2rc1-VS2010 1.2rc1 thankfully that version existed in github! I am now on the process of implementing AEC using this code https://stackoverflow.com/questions/12748277/speex-echo-cancellation-configuration and https://stackoverflow.com/questions/10826902/easiest-way-to-use-speex-preprocessor-in-c I'll let you know how it goes! – swdev Mar 21 '21 at 16:00

0 Answers0