diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h index bfbd7bac7..9f8ba9b62 100644 --- a/pjmedia/include/pjmedia/port.h +++ b/pjmedia/include/pjmedia/port.h @@ -300,31 +300,26 @@ typedef struct pjmedia_frame_ext_subframe { */ PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm, const void *src, - pj_uint16_t bitlen, - pj_uint16_t samples_cnt) + unsigned bitlen, + unsigned samples_cnt) { + pjmedia_frame_ext_subframe *fsub; pj_uint8_t *p; - unsigned i, tmp; + unsigned i; p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); for (i = 0; i < frm->subframe_cnt; ++i) { - pjmedia_frame_ext_subframe *fsub; fsub = (pjmedia_frame_ext_subframe*) p; - p += sizeof(fsub->bitlen) + (fsub->bitlen >> 3); - if (fsub->bitlen & 0x07) - ++p; + p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3); } - tmp = bitlen >> 3; - if (bitlen & 0x07) - ++tmp; - - pj_memcpy(p, &bitlen, sizeof(bitlen)); - if (tmp) - pj_memcpy(p + sizeof(bitlen), src, tmp); + fsub = (pjmedia_frame_ext_subframe*) p; + fsub->bitlen = (pj_uint16_t)bitlen; + if (bitlen) + pj_memcpy(fsub->data, src, (bitlen+7) >> 3); frm->subframe_cnt++; - frm->samples_cnt = frm->samples_cnt + samples_cnt; + frm->samples_cnt = frm->samples_cnt + (pj_uint16_t)samples_cnt; } /** @@ -348,9 +343,7 @@ PJ_INLINE(pjmedia_frame_ext_subframe*) p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); for (i = 0; i < n; ++i) { sf = (pjmedia_frame_ext_subframe*) p; - p += sizeof(sf->bitlen) + (sf->bitlen >> 3); - if (sf->bitlen & 0x07) - ++p; + p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3); } sf = (pjmedia_frame_ext_subframe*) p; @@ -383,9 +376,7 @@ PJ_INLINE(pj_status_t) move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n); sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1); move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) + - (sf->bitlen >> 3); - if (sf->bitlen & 0x07) - ++move_len; + ((sf->bitlen+7) >> 3); pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext), move_src, move_len); diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h index 440fb9b3d..81707234b 100644 --- a/pjmedia/include/pjmedia/types.h +++ b/pjmedia/include/pjmedia/types.h @@ -196,8 +196,8 @@ typedef union pjmedia_fourcc { * FourCC identifier definitions. */ #define PJMEDIA_FOURCC_L16 PJMEDIA_FOURCC_PACK(' ', 'L', '1', '6') -#define PJMEDIA_FOURCC_G711A PJMEDIA_FOURCC_PACK('G', '7', '1', '1') -#define PJMEDIA_FOURCC_G711U PJMEDIA_FOURCC_PACK('U', 'L', 'A', 'W') +#define PJMEDIA_FOURCC_PCMA PJMEDIA_FOURCC_PACK('A', 'L', 'A', 'W') +#define PJMEDIA_FOURCC_PCMU PJMEDIA_FOURCC_PACK('u', 'L', 'A', 'W') #define PJMEDIA_FOURCC_AMR PJMEDIA_FOURCC_PACK(' ', 'A', 'M', 'R') #define PJMEDIA_FOURCC_G729 PJMEDIA_FOURCC_PACK('G', '7', '2', '9') #define PJMEDIA_FOURCC_ILBC PJMEDIA_FOURCC_PACK('I', 'L', 'B', 'C') diff --git a/pjmedia/src/pjmedia-codec/passthrough.c b/pjmedia/src/pjmedia-codec/passthrough.c index 6f99f4357..3075aa698 100644 --- a/pjmedia/src/pjmedia-codec/passthrough.c +++ b/pjmedia/src/pjmedia-codec/passthrough.c @@ -162,6 +162,8 @@ static struct codec_desc { unsigned def_bitrate; /* Default bitrate of this codec. */ unsigned max_bitrate; /* Maximum bitrate of this codec. */ pj_uint8_t frm_per_pkt; /* Default num of frames per packet.*/ + pj_uint8_t vad; /* VAD enabled/disabled. */ + pj_uint8_t plc; /* PLC enabled/disabled. */ parse_cb parse; /* Callback to parse bitstream. */ pack_cb pack; /* Callback to pack bitstream. */ pjmedia_codec_fmtp dec_fmtp; /* Decoder's fmtp params. */ @@ -172,7 +174,7 @@ codec_desc[] = # if PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR {1, "AMR", PJMEDIA_RTP_PT_AMR, {PJMEDIA_FOURCC_AMR}, 8000, 1, 160, - 12200, 12200, 2, + 7400, 12200, 2, 1, 1, &parse_amr, &pack_amr /*, {1, {{{"octet-align", 11}, {"1", 1}}} } */ }, @@ -181,30 +183,30 @@ codec_desc[] = # if PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 {1, "G729", PJMEDIA_RTP_PT_G729, {PJMEDIA_FOURCC_G729}, 8000, 1, 80, - 8000, 8000, 2 + 8000, 8000, 2, 1, 1 }, # endif # if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC {1, "iLBC", PJMEDIA_RTP_PT_ILBC, {PJMEDIA_FOURCC_ILBC}, 8000, 1, 240, - 13333, 15200, 2, + 13333, 15200, 1, 1, 1, NULL, NULL, {1, {{{"mode", 4}, {"30", 2}}} } }, # endif # if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU - {1, "PCMU", PJMEDIA_RTP_PT_PCMU, {PJMEDIA_FOURCC_G711U}, + {1, "PCMU", PJMEDIA_RTP_PT_PCMU, {PJMEDIA_FOURCC_PCMU}, 8000, 1, 80, - 64000, 64000, 2 + 64000, 64000, 2, 1, 1 }, # endif # if PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA - {1, "PCMA", PJMEDIA_RTP_PT_PCMA, {PJMEDIA_FOURCC_G711A}, + {1, "PCMA", PJMEDIA_RTP_PT_PCMA, {PJMEDIA_FOURCC_PCMA}, 8000, 1, 80, - 64000, 64000, 2 + 64000, 64000, 2, 1, 1 }, # endif }; @@ -246,15 +248,17 @@ static pj_status_t pack_amr ( codec_private_t *codec_data, unsigned len; sf = pjmedia_frame_ext_get_subframe(input, i); - - len = sf->bitlen >> 3; - if (sf->bitlen & 0x07) - ++len; + len = (sf->bitlen + 7) >> 3; info = (pjmedia_codec_amr_bit_info*) &frames[i].bit_info; pj_bzero(info, sizeof(*info)); - info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb, - len); + + if (len == 0) { + info->frame_type = (pj_uint8_t)(enc_setting->amr_nb? 14 : 15); + } else { + info->frame_type = pjmedia_codec_amr_get_mode2(enc_setting->amr_nb, + len); + } info->good_quality = 1; info->mode = setting->enc_mode; @@ -449,9 +453,9 @@ static pj_status_t default_attr ( pjmedia_codec_factory *factory, /* Default flags. */ attr->setting.frm_per_pkt = codec_desc[i].frm_per_pkt; - attr->setting.plc = 0; + attr->setting.plc = codec_desc[i].plc; attr->setting.penh= 0; - attr->setting.vad = 0; + attr->setting.vad = codec_desc[i].vad; attr->setting.cng = attr->setting.vad; attr->setting.dec_fmtp = codec_desc[i].dec_fmtp; @@ -758,14 +762,22 @@ static pj_status_t codec_encode( pjmedia_codec *codec, sf = pjmedia_frame_ext_get_subframe(input_, i); pj_assert(sf); - - sf_len = sf->bitlen >> 3; - if (sf->bitlen & 0x07) - ++sf_len; + + sf_len = (sf->bitlen + 7) >> 3; pj_memcpy(p, sf->data, sf_len); p += sf_len; output->size += sf_len; + +#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729 + /* If there is SID or DTX frame, break the loop. */ + if (desc->pt == PJMEDIA_RTP_PT_G729 && + sf_len < codec_data->avg_frame_size) + { + break; + } +#endif + } } } diff --git a/pjmedia/src/pjmedia/conf_switch.c b/pjmedia/src/pjmedia/conf_switch.c index bef2d1826..41eb04b5a 100644 --- a/pjmedia/src/pjmedia/conf_switch.c +++ b/pjmedia/src/pjmedia/conf_switch.c @@ -51,6 +51,8 @@ #define SLOT_TYPE unsigned #define INVALID_SLOT ((SLOT_TYPE)-1) #define BUFFER_SIZE PJMEDIA_MAX_MTU +#define MAX_LEVEL (32767) +#define MIN_LEVEL (-32768) /* * DON'T GET CONFUSED WITH TX/RX!! @@ -152,6 +154,10 @@ static pj_status_t create_conf_port( pj_pool_t *pool, conf_port->rx_setting = PJMEDIA_PORT_ENABLE; conf_port->tx_setting = PJMEDIA_PORT_ENABLE; + /* Default level adjustment is 128 (which means no adjustment) */ + conf_port->tx_adj_level = NORMAL_LEVEL; + conf_port->rx_adj_level = NORMAL_LEVEL; + /* Create transmit flag array */ conf_port->listener_slots = (SLOT_TYPE*) pj_pool_zalloc(pool, @@ -165,7 +171,6 @@ static pj_status_t create_conf_port( pj_pool_t *pool, /* Init pjmedia_frame structure in the TX buffer. */ f = (pjmedia_frame*)conf_port->tx_buf; f->buf = conf_port->tx_buf + sizeof(pjmedia_frame); - f->size = 0; /* Done */ *p_conf_port = conf_port; @@ -672,6 +677,8 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf, } if (i != src_port->listener_cnt) { + pjmedia_frame_ext *f; + pj_assert(src_port->listener_cnt > 0 && src_port->listener_cnt < conf->max_ports); pj_assert(dst_port->transmitter_cnt > 0 && @@ -682,8 +689,12 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf, --src_port->listener_cnt; --dst_port->transmitter_cnt; - /* Clean up sink TX buffer. */ - pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); + /* Cleanup listener TX buffer. */ + f = (pjmedia_frame_ext*)dst_port->tx_buf; + f->base.type = PJMEDIA_FRAME_TYPE_NONE; + f->base.size = 0; + f->samples_cnt = 0; + f->subframe_cnt = 0; PJ_LOG(4,(THIS_FILE, "Port %d (%.*s) stop transmitting to port %d (%.*s)", @@ -776,6 +787,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf, while (conf_port->listener_cnt) { unsigned dst_slot; struct conf_port *dst_port; + pjmedia_frame_ext *f; dst_slot = conf_port->listener_slots[conf_port->listener_cnt-1]; dst_port = conf->ports[dst_slot]; @@ -784,8 +796,12 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf, pj_assert(conf->connect_cnt > 0); --conf->connect_cnt; - /* Clean up TX buffer. */ - pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); + /* Cleanup & reinit listener TX buffer. */ + f = (pjmedia_frame_ext*)dst_port->tx_buf; + f->base.type = PJMEDIA_FRAME_TYPE_NONE; + f->base.size = 0; + f->samples_cnt = 0; + f->subframe_cnt = 0; } /* Remove the port. */ @@ -856,6 +872,8 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf, info->samples_per_frame = conf_port->info->samples_per_frame; info->bits_per_sample = conf_port->info->bits_per_sample; info->format = conf_port->port->info.format; + info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL; + info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL; return PJ_SUCCESS; } @@ -934,6 +952,11 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf, conf_port = conf->ports[slot]; + /* Level adjustment is applicable only for ports that work with raw PCM. */ + PJ_ASSERT_RETURN(conf_port->info->format.u32 == 0 || + conf_port->info->format.u32 == PJMEDIA_FOURCC_L16, + PJ_EIGNORED); + /* Set normalized adjustment level. */ conf_port->rx_adj_level = adj_level + NORMAL_LEVEL; @@ -964,6 +987,14 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf, conf_port = conf->ports[slot]; + /* Level adjustment is applicable only for ports that work with raw PCM. */ + PJ_ASSERT_RETURN(conf_port->info->format.u32 == 0 || + conf_port->info->format.u32 == PJMEDIA_FOURCC_L16, + PJ_EIGNORED); + + /* Set normalized adjustment level. */ + conf_port->tx_adj_level = adj_level + NORMAL_LEVEL; + return PJ_SUCCESS; } @@ -1032,6 +1063,28 @@ static pj_status_t write_frame(struct conf_port *cport_dst, if (nsamples_to_copy > nsamples_req) nsamples_to_copy = nsamples_req; + /* Adjust TX level. */ + if (cport_dst->tx_adj_level != NORMAL_LEVEL) { + pj_int16_t *p, *p_end; + + p = f_start; + p_end = p + nsamples_to_copy; + while (p < p_end) { + pj_int32_t itemp = *p; + + /* Adjust the level */ + itemp = (itemp * cport_dst->tx_adj_level) >> 7; + + /* Clip the signal if it's too loud */ + if (itemp > MAX_LEVEL) itemp = MAX_LEVEL; + else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL; + + /* Put back in the buffer. */ + *p = (pj_int16_t)itemp; + ++p; + } + } + pjmedia_copy_samples((pj_int16_t*)frm_dst->buf + (frm_dst->size>>1), f_start, nsamples_to_copy); @@ -1131,8 +1184,6 @@ static pj_status_t get_frame(pjmedia_port *this_port, pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata; unsigned ci, i; - PJ_TODO(ADJUST_RX_TX_LEVEL_FOR_PCM_FRAMES); - /* Must lock mutex */ pj_mutex_lock(conf->mutex); @@ -1173,7 +1224,7 @@ static pj_status_t get_frame(pjmedia_port *this_port, pjmedia_frame *f = (pjmedia_frame*)conf->buf; pj_status_t status; unsigned j; - pj_int32_t level; + pj_int32_t level = 0; pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); @@ -1185,18 +1236,41 @@ static pj_status_t get_frame(pjmedia_port *this_port, if (status != PJ_SUCCESS) continue; - /* Calculate RX level. */ + /* Calculate & adjust RX level. */ if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) { - level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf, - f->size >>1 ); + if (cport->rx_adj_level != NORMAL_LEVEL) { + pj_int16_t *p = (pj_int16_t*)f->buf; + pj_int16_t *end; + + end = p + (f->size >> 1); + while (p < end) { + pj_int32_t itemp = *p; + + /* Adjust the level */ + itemp = (itemp * cport->rx_adj_level) >> 7; + + /* Clip the signal if it's too loud */ + if (itemp > MAX_LEVEL) itemp = MAX_LEVEL; + else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL; + + level += PJ_ABS(itemp); + + /* Put back in the buffer. */ + *p = (pj_int16_t)itemp; + ++p; + } + level /= (f->size >> 1); + } else { + level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf, + f->size >> 1); + } } else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) { /* For extended frame, TX level is unknown, so we just set * it to NORMAL_LEVEL. */ level = NORMAL_LEVEL; - } else { /* PJMEDIA_FRAME_TYPE_NONE */ - level = 0; } + cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff; /* Put the frame to all listeners. */ @@ -1220,8 +1294,11 @@ static pj_status_t get_frame(pjmedia_port *this_port, continue; } - /* Set listener TX level equal to transmitter RX level. */ - listener->tx_level = cport->rx_level; + /* Set listener TX level based on transmitter RX level & + * listener TX level. + */ + listener->tx_level = (cport->rx_level * listener->tx_adj_level) + >> 8; } } } @@ -1241,10 +1318,16 @@ static pj_status_t get_frame(pjmedia_port *this_port, if (cport->tx_setting==PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0) { + pjmedia_frame_ext *f; + /* Clear left-over samples in tx_buffer, if any, so that it won't * be transmitted next time we have audio signal. */ - pj_bzero(cport->tx_buf, sizeof(pjmedia_frame_ext)); + f = (pjmedia_frame_ext*)cport->tx_buf; + f->base.type = PJMEDIA_FRAME_TYPE_NONE; + f->base.size = 0; + f->samples_cnt = 0; + f->subframe_cnt = 0; cport->tx_level = 0; @@ -1279,8 +1362,9 @@ static pj_status_t get_frame(pjmedia_port *this_port, pj_uint16_t samples_per_subframe; if (f_src_->samples_cnt < this_cport->info->samples_per_frame) { - pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); - frame->type = PJMEDIA_FRAME_TYPE_NONE; + f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE; + f_dst->samples_cnt = 0; + f_dst->subframe_cnt = 0; break; } @@ -1302,8 +1386,8 @@ static pj_status_t get_frame(pjmedia_port *this_port, } else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) { if ((f_src->size>>1) < this_cport->info->samples_per_frame) { - pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); frame->type = PJMEDIA_FRAME_TYPE_NONE; + frame->size = 0; break; } @@ -1320,9 +1404,12 @@ static pj_status_t get_frame(pjmedia_port *this_port, this_cport->info->samples_per_frame, f_src->size >> 1); } else { /* PJMEDIA_FRAME_TYPE_NONE */ + pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame; + /* Reset TX buffer */ - pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); - frame->type = PJMEDIA_FRAME_TYPE_NONE; + f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE; + f_dst->samples_cnt = 0; + f_dst->subframe_cnt = 0; } } while (0); @@ -1341,7 +1428,7 @@ static pj_status_t put_frame(pjmedia_port *this_port, pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata; struct conf_port *cport = conf->ports[this_port->port_data.ldata]; unsigned j; - pj_int32_t level; + pj_int32_t level = 0; pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); @@ -1357,18 +1444,41 @@ static pj_status_t put_frame(pjmedia_port *this_port, return PJ_SUCCESS; } - /* Calculate RX level. */ + /* Calculate & adjust RX level. */ if (f->type == PJMEDIA_FRAME_TYPE_AUDIO) { - level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf, - f->size >>1 ); + if (cport->rx_adj_level != NORMAL_LEVEL) { + pj_int16_t *p = (pj_int16_t*)f->buf; + pj_int16_t *end; + + end = p + (f->size >> 1); + while (p < end) { + pj_int32_t itemp = *p; + + /* Adjust the level */ + itemp = (itemp * cport->rx_adj_level) >> 7; + + /* Clip the signal if it's too loud */ + if (itemp > MAX_LEVEL) itemp = MAX_LEVEL; + else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL; + + level += PJ_ABS(itemp); + + /* Put back in the buffer. */ + *p = (pj_int16_t)itemp; + ++p; + } + level /= (f->size >> 1); + } else { + level = pjmedia_calc_avg_signal((const pj_int16_t*)f->buf, + f->size >> 1); + } } else if (f->type == PJMEDIA_FRAME_TYPE_EXTENDED) { /* For extended frame, TX level is unknown, so we just set * it to NORMAL_LEVEL. */ level = NORMAL_LEVEL; - } else { /* PJMEDIA_FRAME_TYPE_NONE. */ - level = 0; } + cport->rx_level = pjmedia_linear2ulaw(level) ^ 0xff; /* Put the frame to all listeners. */ @@ -1401,8 +1511,10 @@ static pj_status_t put_frame(pjmedia_port *this_port, continue; } - /* Set listener TX level equal to transmitter RX level. */ - listener->tx_level = cport->rx_level; + /* Set listener TX level based on transmitter RX level & listener + * TX level. + */ + listener->tx_level = (cport->rx_level * listener->tx_adj_level) >> 8; } return PJ_SUCCESS; diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index d765fb120..4951f5342 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -482,7 +482,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame) } if (frame_type == PJMEDIA_JB_MISSING_FRAME) { - PJ_LOG(1,(stream->port.info.name.ptr, "Frame lost!")); + PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost!")); } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { /* Jitter buffer is empty. Check if this is the first "empty" * state. @@ -492,7 +492,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame) /* Report the state of jitter buffer */ pjmedia_jbuf_get_state(stream->jb, &jb_state); - PJ_LOG(1,(stream->port.info.name.ptr, + PJ_LOG(5,(stream->port.info.name.ptr, "Jitter buffer empty (prefetch=%d)", jb_state.prefetch)); } @@ -506,7 +506,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame) pjmedia_jbuf_get_state(stream->jb, &jb_state); if (stream->jb_last_frm != frame_type) { - PJ_LOG(1,(stream->port.info.name.ptr, + PJ_LOG(5,(stream->port.info.name.ptr, "Jitter buffer is bufferring (prefetch=%d)", jb_state.prefetch)); } diff --git a/pjmedia/src/pjmedia/symbian_sound_aps.cpp b/pjmedia/src/pjmedia/symbian_sound_aps.cpp index 822cc167c..e6ada1300 100644 --- a/pjmedia/src/pjmedia/symbian_sound_aps.cpp +++ b/pjmedia/src/pjmedia/symbian_sound_aps.cpp @@ -778,8 +778,8 @@ static void RecCb(TAPSCommBuffer &buf, void *user_data) } break; - case PJMEDIA_FOURCC_G711U: - case PJMEDIA_FOURCC_G711A: + case PJMEDIA_FOURCC_PCMU: + case PJMEDIA_FOURCC_PCMA: { unsigned samples_processed = 0; @@ -857,13 +857,10 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data) /* AMR header for APS is one byte, the format (may be!): * 0xxxxy00, where xxxx:frame type, y:not sure. */ - unsigned len = sf->bitlen>>3; + unsigned len = (sf->bitlen+7)>>3; enum {SID_FT = 8 }; pj_uint8_t amr_header = 4, ft = SID_FT; - if (sf->bitlen & 0x07) - ++len; - if (len >= pjmedia_codec_amrnb_framelen[0]) ft = pjmedia_codec_amr_get_mode2(PJ_TRUE, len); @@ -975,8 +972,8 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data) } break; - case PJMEDIA_FOURCC_G711U: - case PJMEDIA_FOURCC_G711A: + case PJMEDIA_FOURCC_PCMU: + case PJMEDIA_FOURCC_PCMA: { unsigned samples_ready = 0; unsigned samples_req = aps_g711_frame_len; @@ -1104,8 +1101,9 @@ static pj_status_t sound_open(pjmedia_dir dir, if (strm->setting.format.u32 == 0) strm->setting.format.u32 = PJMEDIA_FOURCC_L16; - /* Set audio engine settings. */ - if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || + /* Set audio engine fourcc. */ + if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU || + strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA || strm->setting.format.u32 == PJMEDIA_FOURCC_L16) { aps_setting.fourcc = TFourCC(KMCPFourCCIdG711); @@ -1113,33 +1111,41 @@ static pj_status_t sound_open(pjmedia_dir dir, aps_setting.fourcc = TFourCC(strm->setting.format.u32); } + /* Set audio engine mode. */ if (strm->setting.format.u32 == PJMEDIA_FOURCC_AMR) { aps_setting.mode = (TAPSCodecMode)strm->setting.bitrate; - } else if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || - strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || - (strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC && - strm->setting.mode == 30)) + } + else if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU || + strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || + (strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC && + strm->setting.mode == 30)) { aps_setting.mode = EULawOr30ms; - } else { + } + else if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA || + (strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC && + strm->setting.mode == 20)) + { aps_setting.mode = EALawOr20ms; } /* Disable VAD on L16 and G711. */ - if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || - strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || - strm->setting.format.u32 == PJMEDIA_FOURCC_G711A) + if (strm->setting.format.u32 == PJMEDIA_FOURCC_PCMU || + strm->setting.format.u32 == PJMEDIA_FOURCC_PCMA || + strm->setting.format.u32 == PJMEDIA_FOURCC_L16) { aps_setting.vad = EFalse; } else { aps_setting.vad = strm->setting.vad; } + /* Set other audio engine attributes. */ aps_setting.plc = strm->setting.plc; aps_setting.cng = strm->setting.cng; aps_setting.loudspk = strm->setting.loudspk; + /* Set audio engine callbacks. */ if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16) { aps_play_cb = &PlayCbPcm; aps_rec_cb = &RecCbPcm; @@ -1148,7 +1154,7 @@ static pj_status_t sound_open(pjmedia_dir dir, aps_rec_cb = &RecCb; } - // Create the audio engine. + /* Create the audio engine. */ TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, aps_rec_cb, aps_play_cb, strm, aps_setting));