Index: chan_mobile.c =================================================================== --- chan_mobile.c (revision 417) +++ chan_mobile.c (working copy) @@ -141,6 +141,7 @@ int skip_frames; char sent_answer; char hangup_count; + struct ast_smoother *smoother; AST_LIST_ENTRY(mbl_pvt) entry; }; @@ -548,6 +549,11 @@ ast->tech_pvt = NULL; ast_setstate(ast, AST_STATE_DOWN); + if (pvt->smoother) { + ast_smoother_free(pvt->smoother); + pvt->smoother = NULL; + } + return 0; } @@ -699,28 +705,41 @@ return 0; } - if (frame->datalen > sizeof(pvt->sco_out_buf) - pvt->sco_out_len) { - frame->datalen = sizeof(pvt->sco_out_buf) - pvt->sco_out_len; - ast_debug(1, "Overrun on sco_out_buf detected.\n"); + if (!pvt->smoother) { + /* 320 bytes for 20 ms of SLINEAR 8kHz audio */ + pvt->smoother = ast_smoother_new(320); + if (!pvt->smoother) + return 0; + + ast_smoother_set_flags(pvt->smoother, AST_SMOOTHER_FLAG_BE); } - memmove(pvt->sco_out_ptr, frame->data, frame->datalen); - pvt->sco_out_len += frame->datalen; - num_frames = pvt->sco_out_len / 48; + ast_smoother_feed_be(pvt->smoother, frame); - pfr = pvt->sco_out_buf; - for (i=0; isco_socket, pfr, 48)) == -1) { - close(pvt->sco_socket); - pvt->sco_socket = -1; + while ((frame = ast_smoother_read(pvt->smoother)) && frame->data) { + if (frame->datalen > sizeof(pvt->sco_out_buf) - pvt->sco_out_len) { + frame->datalen = sizeof(pvt->sco_out_buf) - pvt->sco_out_len; + ast_debug(1, "Overrun on sco_out_buf detected.\n"); } - pfr += 48; + + memmove(pvt->sco_out_ptr, frame->data, frame->datalen); + pvt->sco_out_len += frame->datalen; + num_frames = pvt->sco_out_len / 48; + + pfr = pvt->sco_out_buf; + for (i=0; isco_socket, pfr, 48)) == -1) { + close(pvt->sco_socket); + pvt->sco_socket = -1; + } + pfr += 48; + } + + pvt->sco_out_len = pvt->sco_out_len - (num_frames * 48); + memmove(pvt->sco_out_buf, pfr, pvt->sco_out_len); + pvt->sco_out_ptr = pvt->sco_out_buf + pvt->sco_out_len; } - pvt->sco_out_len = pvt->sco_out_len - (num_frames * 48); - memmove(pvt->sco_out_buf, pfr, pvt->sco_out_len); - pvt->sco_out_ptr = pvt->sco_out_buf + pvt->sco_out_len; - return 0; } @@ -1697,7 +1716,7 @@ type = ast_variable_retrieve(cfg, cat, "type"); skip = ast_variable_retrieve(cfg, cat, "dtmfskip"); if (address && port) { - if ((pvt = ast_malloc(sizeof(struct mbl_pvt)))) { + if ((pvt = ast_calloc(1, sizeof(*pvt)))) { if (type && !strcmp(type, "headset")) pvt->type = MBL_TYPE_HEADSET; else @@ -1705,23 +1724,17 @@ ast_copy_string(pvt->id, cat, sizeof(pvt->id)); ast_copy_string(pvt->bdaddr, address, sizeof(pvt->bdaddr)); ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context)); - pvt->connected = 0; pvt->state = MBL_STATE_INIT; pvt->rfcomm_socket = -1; pvt->rfcomm_port = atoi(port); - pvt->rfcomm_buf[0] = 0x00; pvt->sco_socket = -1; pvt->monitor_thread = AST_PTHREADT_NULL; - pvt->owner = NULL; - pvt->no_callsetup = 0; - pvt->has_sms = 0; pvt->dsp = ast_dsp_new(); if (skip) { if ((pvt->dtmf_skip = atoi(skip)) == 0) pvt->dtmf_skip = 200; } else pvt->dtmf_skip = 200; - pvt->skip_frames = 0; ast_dsp_set_features(pvt->dsp, DSP_FEATURE_DTMF_DETECT); ast_dsp_digitmode(pvt->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); AST_LIST_INSERT_HEAD(&devices, pvt, entry); @@ -1785,6 +1798,8 @@ close(pvt->rfcomm_socket); } ast_dsp_free(pvt->dsp); + if (pvt->smoother) + ast_smoother_free(pvt->smoother); free(pvt); }