Ignore:
Timestamp:
Aug 4, 2006 6:27:19 PM (18 years ago)
Author:
bennylp
Message:

More work on the AEC (including changes in PJSUA), embed the AEC in sound_port, reduce DirectSound? buffer from 32 to 16, and fixed ARM compilation for MSVC WinCE target.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/aec_speex.c

    r646 r648  
    2727#include <pj/pool.h> 
    2828#include <speex/speex_echo.h> 
     29#include <speex/speex_preprocess.h> 
    2930 
    3031 
    3132#define THIS_FILE   "aec_speex.c" 
    32 #define BUF_COUNT   16 
     33#define BUF_COUNT   8 
    3334 
    3435 
     
    4041struct pjmedia_aec 
    4142{ 
    42     SpeexEchoState  *state; 
     43    SpeexEchoState       *state; 
     44    SpeexPreprocessState *preprocess; 
     45 
    4346    unsigned         samples_per_frame; 
    4447    unsigned         options; 
    4548    pj_int16_t      *tmp_frame; 
     49    spx_int32_t     *residue; 
    4650 
    4751    pj_lock_t       *lock;              /* To protect buffers, if required  */ 
     
    6064                                        unsigned clock_rate, 
    6165                                        unsigned samples_per_frame, 
    62                                         unsigned tail_size, 
     66                                        unsigned tail_ms, 
    6367                                        unsigned options, 
    6468                                        pjmedia_aec **p_aec ) 
     
    6973    pj_status_t status; 
    7074 
     75    *p_aec = NULL; 
     76 
    7177    aec = pj_pool_zalloc(pool, sizeof(pjmedia_aec)); 
    7278    PJ_ASSERT_RETURN(aec != NULL, PJ_ENOMEM); 
     
    7985    aec->options = options; 
    8086 
    81     aec->state = speex_echo_state_init(samples_per_frame,tail_size); 
     87    aec->state = speex_echo_state_init(samples_per_frame, 
     88                                        clock_rate * tail_ms / 1000); 
    8289    if (aec->state == NULL) { 
     90        pj_lock_destroy(aec->lock); 
     91        return PJ_ENOMEM; 
     92    } 
     93 
     94    aec->preprocess = speex_preprocess_state_init(samples_per_frame,  
     95                                                  clock_rate); 
     96    if (aec->preprocess == NULL) { 
     97        speex_echo_state_destroy(aec->state); 
    8398        pj_lock_destroy(aec->lock); 
    8499        return PJ_ENOMEM; 
     
    91106 
    92107    /* Create temporary frame for echo cancellation */ 
    93     aec->tmp_frame = pj_pool_zalloc(pool, sizeof(pj_int16_t) * 
     108    aec->tmp_frame = pj_pool_zalloc(pool, 2 * samples_per_frame); 
     109    PJ_ASSERT_RETURN(aec->tmp_frame != NULL, PJ_ENOMEM); 
     110 
     111    /* Create temporary frame to receive residue */ 
     112    aec->residue = pj_pool_zalloc(pool, sizeof(spx_int32_t) *  
    94113                                            samples_per_frame); 
    95     PJ_ASSERT_RETURN(aec->tmp_frame != NULL, PJ_ENOMEM); 
     114    PJ_ASSERT_RETURN(aec->residue != NULL, PJ_ENOMEM); 
    96115 
    97116    /* Create internal playback buffers */ 
     
    109128                         clock_rate, 
    110129                         samples_per_frame, 
    111                          tail_size * 1000 / clock_rate)); 
     130                         tail_ms)); 
    112131    return PJ_SUCCESS; 
    113132 
     
    121140{ 
    122141    PJ_ASSERT_RETURN(aec && aec->state, PJ_EINVAL); 
     142 
     143    if (aec->lock) 
     144        pj_lock_acquire(aec->lock); 
    123145 
    124146    if (aec->state) { 
    125147        speex_echo_state_destroy(aec->state); 
    126148        aec->state = NULL; 
     149    } 
     150 
     151    if (aec->preprocess) { 
     152        speex_preprocess_state_destroy(aec->preprocess); 
     153        aec->preprocess = NULL; 
    127154    } 
    128155 
     
    225252                                             void *reserved ) 
    226253{ 
    227     unsigned level0, level1; 
    228  
    229254    /* Sanity checks */ 
    230255    PJ_ASSERT_RETURN(aec && rec_frm && play_frm && options==0 && 
     
    234259    speex_echo_cancel(aec->state, (const spx_int16_t*)rec_frm,  
    235260                      (const spx_int16_t*)play_frm,  
    236                       (spx_int16_t*)aec->tmp_frame, NULL); 
    237  
    238 #if 0 
    239     level0 = pjmedia_calc_avg_signal(rec_frm, aec->samples_per_frame); 
    240     level1 = pjmedia_calc_avg_signal(aec->tmp_frame, aec->samples_per_frame); 
    241  
    242     if (level1 < level0) { 
    243         PJ_LOG(5,(THIS_FILE, "Input signal reduced from %d to %d", 
    244                   level0, level1)); 
    245     } 
    246 #else 
    247     PJ_UNUSED_ARG(level0); 
    248     PJ_UNUSED_ARG(level1); 
    249 #endif 
     261                      (spx_int16_t*)aec->tmp_frame,  
     262                      aec->residue); 
     263 
     264 
     265    /* Preprocess output */ 
     266    speex_preprocess(aec->preprocess, (spx_int16_t*)aec->tmp_frame,  
     267                     aec->residue); 
    250268 
    251269    /* Copy temporary buffer back to original rec_frm */ 
Note: See TracChangeset for help on using the changeset viewer.