我的程序中出现的问题如下:
两端收发都没有问题,但却出现了声音不但传送到了对方机器上,同时也在本机发声,这个声音是怎么产生的???
我的代码中waveOutWrite中没有播放自己输入设备传进的音频数据的代码~
求高人指点迷津!!!

解决方案 »

  1.   

    术语叫“Echo Cancellation回音消除”,可以使用speex来做Echo CancellationThe Speex library now includes an echo cancellation algorithm suitable for Acoustic Echo Cancellation (AEC). In order to use the echo canceller, you first need to#include <speex/speex_echo.h>
    Then, an echo canceller state can be created by:
    SpeexEchoState *echo_state = speex_echo_state_init(frame_size, filter_length);
    where frame_size is the amount of data (in samples) you want to process at once and filter_length is the length (in samples) of the echo cancelling filter you want to use (also known as tail length). It is recommended to use a frame size in the order of 20 ms (or equal to the codec frame size) and make sure it is easy to perform an FFT of that size (powers of two are better than prime sizes). The recommended tail length is approximately the third of the room reverberation time. For example, in a small room, reverberation time is in the order of 300 ms, so a tail length of 100 ms is a good choice (800 samples at 8000 Hz sampling rate).
    Once the echo canceller state is created, audio can be processed by:speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame);
    where input_frame is the audio as captured by the microphone, echo_frame is the signal that was played in the speaker (and needs to be removed) and output_frame is the signal with echo removed.
    One important thing to keep in mind is the relationship between input_frame and echo_frame. It is important that, at any time, any echo that is present in the input has already been sent to the echo canceller as echo_frame. In other words, the echo canceller cannot remove a signal that it hasn't yet received. On the other hand, the delay between the input signal and the echo signal must be small enough because otherwise part of the echo cancellation filter is inefficient. In the ideal case, you code would look like:write_to_soundcard(echo_frame, frame_size);
    read_from_soundcard(input_frame, frame_size);speex_echo_cancellation(echo_state, input_frame, echo_frame, output_frame);If you wish to further reduce the echo present in the signal, you can do so by associating the echo canceller to the preprocessor (see Section 5.3). This is done by calling:
    speex_preprocess_ctl(preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE, echo_state);
    in the initialisation.
    As of version 1.2-beta2, there is an alternative, simpler API that can be used instead of speex_echo_cancellation(). When audio capture and playback are handled asynchronously (e.g. in different threads or using the poll() or select() system call), it can be difficult to keep track of what input_frame comes with what echo_frame. Instead, the playback comtext/thread can simply call:speex_echo_playback(echo_state, echo_frame);
    every time an audio frame is played. Then, the capture context/thread calls:
    speex_echo_capture(echo_state, input_frame, output_frame);
    for every frame captured. Internally, speex_echo_playback() simply buffers the playback frame so it can be used by speex_echo_capture() to call speex_echo_cancel(). A side effect of using this alternate API is that the playback audio is delayed by two frames, which is the normal delay caused by the soundcard. When capture and playback are already synchronised, speex_echo_cancellation() is preferable since it gives better control on the exact input/echo timing.
    The echo cancellation state can be destroyed with:speex_echo_state_destroy(echo_state);
    It is also possible to reset the state of the echo canceller so it can be reused without the need to create another state with:
    speex_echo_state_reset(echo_state);
      

  2.   

    参见下面文章:
    http://www.joyvc.cn/GraphicAndMedia/GraphicAndMedia00009.html
      

  3.   

    看看设置,是不是把mic回放打开了,如果这个选项打开,mic进来的数据直接就会被扔到输出。这个选项是用来监听录音设备是否正常工作用的。