Exemple #1
0
static pj_status_t stereo_get_frame(pjmedia_port *this_port, 
				    pjmedia_frame *frame)
{
    struct stereo_port *sport = (struct stereo_port*) this_port;
    const pjmedia_audio_format_detail *s_afd, *dn_afd;
    pjmedia_frame tmp_frame;
    pj_status_t status;

    /* Return silence if we don't have downstream port */
    if (sport->dn_port == NULL) {
	pj_bzero(frame->buf, frame->size);
	return PJ_SUCCESS;
    }

    s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);
    dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,
						    1);

    tmp_frame.buf = sport->get_buf? sport->get_buf : frame->buf;
    tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&sport->dn_port->info);
    tmp_frame.timestamp.u64 = frame->timestamp.u64;
    tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;

    status = pjmedia_port_get_frame( sport->dn_port, &tmp_frame);
    if (status != PJ_SUCCESS)
	return status;

    if (tmp_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
	frame->type = tmp_frame.type;
	frame->timestamp = tmp_frame.timestamp;
	frame->size = tmp_frame.size;
	if (tmp_frame.size && tmp_frame.buf == sport->get_buf)
	    pj_memcpy(frame->buf, tmp_frame.buf, tmp_frame.size);
	return PJ_SUCCESS;
    }

    if (s_afd->channel_count == 1) {
	pjmedia_convert_channel_nto1((pj_int16_t*)frame->buf, 
				     (const pj_int16_t*)tmp_frame.buf,
				     dn_afd->channel_count,
				     PJMEDIA_AFD_SPF(s_afd),
				     (sport->options & PJMEDIA_STEREO_MIX), 0);
    } else {
	pjmedia_convert_channel_1ton((pj_int16_t*)frame->buf, 
				     (const pj_int16_t*)tmp_frame.buf,
				     s_afd->channel_count,
				     PJMEDIA_AFD_SPF(dn_afd),
				     sport->options);
    }

    frame->size = PJMEDIA_AFD_AVG_FSZ(s_afd);
    frame->type = PJMEDIA_FRAME_TYPE_AUDIO;

    return PJ_SUCCESS;
}
Exemple #2
0
/*
 * Connect a port.
 */
PJ_DEF(pj_status_t) pjmedia_snd_port_connect( pjmedia_snd_port *snd_port,
					      pjmedia_port *port)
{
    pjmedia_audio_format_detail *afd;

    PJ_ASSERT_RETURN(snd_port && port, PJ_EINVAL);

    afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, PJ_TRUE);

    /* Check that port has the same configuration as the sound device
     * port.
     */
    if (afd->clock_rate != snd_port->clock_rate)
	return PJMEDIA_ENCCLOCKRATE;

    if (PJMEDIA_AFD_SPF(afd) != snd_port->samples_per_frame)
	return PJMEDIA_ENCSAMPLESPFRAME;

    if (afd->channel_count != snd_port->channel_count)
	return PJMEDIA_ENCCHANNEL;

    if (afd->bits_per_sample != snd_port->bits_per_sample)
	return PJMEDIA_ENCBITS;

    /* Port is okay. */
    snd_port->port = port;
    return PJ_SUCCESS;
}
Exemple #3
0
PJ_DEF(pj_status_t) pjmedia_bidirectional_port_create( pj_pool_t *pool,
						       pjmedia_port *get_port,
						       pjmedia_port *put_port,
						       pjmedia_port **p_port )
{
    struct bidir_port *port;
    const pjmedia_audio_format_detail *gafd;

    port = PJ_POOL_ZALLOC_T(pool, struct bidir_port);
    gafd = pjmedia_format_get_audio_format_detail(&get_port->info.fmt, 1);

    pjmedia_port_info_init(&port->base.info, &get_port->info.name, SIGNATURE,
			   gafd->clock_rate,
			   gafd->channel_count,
			   gafd->bits_per_sample,
			   PJMEDIA_AFD_SPF(gafd));

    port->get_port = get_port;
    port->put_port = put_port;

    port->base.get_frame = &get_frame;
    port->base.put_frame = &put_frame;

    *p_port = &port->base;

    return PJ_SUCCESS;
}
Exemple #4
0
static pj_status_t stereo_put_frame(pjmedia_port *this_port,
				    pjmedia_frame *frame)
{
    struct stereo_port *sport = (struct stereo_port*) this_port;
    const pjmedia_audio_format_detail *s_afd, *dn_afd;
    pjmedia_frame tmp_frame;

    /* Return if we don't have downstream port. */
    if (sport->dn_port == NULL) {
	return PJ_SUCCESS;
    }

    s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);
    dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,
						    1);

    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
	tmp_frame.buf = sport->put_buf;
	if (dn_afd->channel_count == 1) {
	    pjmedia_convert_channel_nto1((pj_int16_t*)tmp_frame.buf, 
					 (const pj_int16_t*)frame->buf,
					 s_afd->channel_count,
					 PJMEDIA_AFD_SPF(s_afd),
					 (sport->options & PJMEDIA_STEREO_MIX),
					 0);
	} else {
	    pjmedia_convert_channel_1ton((pj_int16_t*)tmp_frame.buf, 
					 (const pj_int16_t*)frame->buf,
					 dn_afd->channel_count,
					 PJMEDIA_AFD_SPF(s_afd),
					 sport->options);
	}
	tmp_frame.size = PJMEDIA_AFD_AVG_FSZ(dn_afd);
    } else {
	tmp_frame.buf = frame->buf;
	tmp_frame.size = frame->size;
    }

    tmp_frame.type = frame->type;
    tmp_frame.timestamp.u64 = frame->timestamp.u64;

    return pjmedia_port_put_frame( sport->dn_port, &tmp_frame );
}
PJ_DEF(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,
					     pjmedia_port *dn_port,
					     unsigned tail_ms,
					     unsigned latency_ms,
					     unsigned options,
					     pjmedia_port **p_port )
{
    const pj_str_t AEC = { "EC", 2 };
    pjmedia_audio_format_detail *afd;
    struct ec *ec;
    pj_status_t status;

    PJ_ASSERT_RETURN(pool && dn_port && p_port, PJ_EINVAL);

    afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, PJ_TRUE);

    PJ_ASSERT_RETURN(afd->bits_per_sample==16 && tail_ms,
		     PJ_EINVAL);

    /* Create the port and the AEC itself */
    ec = PJ_POOL_ZALLOC_T(pool, struct ec);
    
    pjmedia_port_info_init(&ec->base.info, &AEC, SIGNATURE,
			   afd->clock_rate,
			   afd->channel_count,
			   afd->bits_per_sample,
			   PJMEDIA_AFD_SPF(afd));

    status = pjmedia_echo_create2(pool, afd->clock_rate,
				  afd->channel_count,
				  PJMEDIA_AFD_SPF(afd),
				  tail_ms, latency_ms, options, &ec->ec);
    if (status != PJ_SUCCESS)
	return status;

    /* More init */
    ec->dn_port = dn_port;
    ec->base.get_frame = &ec_get_frame;
    ec->base.put_frame = &ec_put_frame;
    ec->base.on_destroy = &ec_on_destroy;

    /* Done */
    *p_port = &ec->base;

    return PJ_SUCCESS;
}
Exemple #6
0
/*
 * Create a master port.
 *
 */
PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool,
						pjmedia_port *u_port,
						pjmedia_port *d_port,
						unsigned options,
						pjmedia_master_port **p_m)
{
    pjmedia_master_port *m;
    unsigned clock_rate;
    unsigned channel_count;
    unsigned samples_per_frame;
    unsigned bytes_per_frame;
    pjmedia_audio_format_detail *u_afd, *d_afd;
    pj_status_t status;

    /* Sanity check */
    PJ_ASSERT_RETURN(pool && u_port && d_port && p_m, PJ_EINVAL);

    u_afd = pjmedia_format_get_audio_format_detail(&u_port->info.fmt, PJ_TRUE);
    d_afd = pjmedia_format_get_audio_format_detail(&d_port->info.fmt, PJ_TRUE);

    /* Both ports MUST have equal clock rate */
    PJ_ASSERT_RETURN(u_afd->clock_rate == d_afd->clock_rate,
		     PJMEDIA_ENCCLOCKRATE);

    /* Both ports MUST have equal samples per frame */
    PJ_ASSERT_RETURN(PJMEDIA_PIA_SPF(&u_port->info)==
			PJMEDIA_PIA_SPF(&d_port->info),
		     PJMEDIA_ENCSAMPLESPFRAME);

    /* Both ports MUST have equal channel count */
    PJ_ASSERT_RETURN(u_afd->channel_count == d_afd->channel_count,
		     PJMEDIA_ENCCHANNEL);


    /* Get clock_rate and samples_per_frame from one of the port. */
    clock_rate = u_afd->clock_rate;
    samples_per_frame = PJMEDIA_PIA_SPF(&u_port->info);
    channel_count = u_afd->channel_count;


    /* Get the bytes_per_frame value, to determine the size of the
     * buffer. We take the larger size of the two ports.
     */
    bytes_per_frame = PJMEDIA_AFD_AVG_FSZ(u_afd);
    if (PJMEDIA_AFD_AVG_FSZ(d_afd) > bytes_per_frame)
	bytes_per_frame = PJMEDIA_AFD_AVG_FSZ(d_afd);


    /* Create the master port instance */
    m = PJ_POOL_ZALLOC_T(pool, pjmedia_master_port);
    m->options = options;
    m->u_port = u_port;
    m->d_port = d_port;

    
    /* Create buffer */
    m->buff_size = bytes_per_frame;
    m->buff = pj_pool_alloc(pool, m->buff_size);
    if (!m->buff)
	return PJ_ENOMEM;

    /* Create lock object */
    status = pj_lock_create_simple_mutex(pool, "mport", &m->lock);
    if (status != PJ_SUCCESS)
	return status;

    /* Create media clock */
    status = pjmedia_clock_create(pool, clock_rate, channel_count, 
				  samples_per_frame, options, &clock_callback,
				  m, &m->clock);
    if (status != PJ_SUCCESS) {
	pj_lock_destroy(m->lock);
	return status;
    }

    /* Done */
    *p_m = m;

    return PJ_SUCCESS;
}
Exemple #7
0
/*
 * Create reverse phase port for the specified channel.
 */
PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
				      pjmedia_port *splitcomb,
				      unsigned ch_num,
				      unsigned options,
				      pjmedia_port **p_chport)
{
    const pj_str_t name = pj_str("scomb-rev");
    struct splitcomb *sc = (struct splitcomb*) splitcomb;
    struct reverse_port *rport;
    unsigned buf_cnt;
    const pjmedia_audio_format_detail *sc_afd, *p_afd;
    pjmedia_port *port;
    pj_status_t status;

    /* Sanity check */
    PJ_ASSERT_RETURN(pool && splitcomb, PJ_EINVAL);

    /* Make sure this is really a splitcomb port */
    PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);

    /* Check the channel number */
    PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);

    /* options is unused for now */
    PJ_UNUSED_ARG(options);

    sc_afd = pjmedia_format_get_audio_format_detail(&splitcomb->info.fmt, 1);

    /* Create the port */
    rport = PJ_POOL_ZALLOC_T(pool, struct reverse_port);
    rport->parent = sc;
    rport->ch_num = ch_num;

    /* Initialize port info... */
    port = &rport->base;
    pjmedia_port_info_init(&port->info, &name, SIGNATURE_PORT, 
			   sc_afd->clock_rate, 1,
			   sc_afd->bits_per_sample,
			   PJMEDIA_PIA_SPF(&splitcomb->info) /
				   sc_afd->channel_count);

    p_afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);

    /* ... and the callbacks */
    port->put_frame = &rport_put_frame;
    port->get_frame = &rport_get_frame;
    port->on_destroy = &rport_on_destroy;

    /* Buffer settings */
    buf_cnt = options & 0xFF;
    if (buf_cnt == 0)
	buf_cnt = MAX_BUF_CNT;

    rport->max_burst = MAX_BURST;
    rport->max_null_frames = MAX_NULL_FRAMES;

    /* Create downstream/put buffers */
    status = pjmedia_delay_buf_create(pool, "scombdb-dn",
				      p_afd->clock_rate,
				      PJMEDIA_PIA_SPF(&port->info),
				      p_afd->channel_count,
				      buf_cnt * p_afd->frame_time_usec / 1000,
				      0, &rport->buf[DIR_DOWNSTREAM].dbuf);
    if (status != PJ_SUCCESS) {
	return status;
    }

    /* Create upstream/get buffers */
    status = pjmedia_delay_buf_create(pool, "scombdb-up",
				      p_afd->clock_rate,
				      PJMEDIA_PIA_SPF(&port->info),
				      p_afd->channel_count,
				      buf_cnt * p_afd->frame_time_usec / 1000,
				      0, &rport->buf[DIR_UPSTREAM].dbuf);
    if (status != PJ_SUCCESS) {
	pjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);
	return status;
    }

    /* And temporary upstream/get buffer */
    rport->tmp_up_buf = (pj_int16_t*)
	                pj_pool_alloc(pool,
				      PJMEDIA_PIA_AVG_FSZ(&port->info));

    /* Save port in the splitcomb */
    sc->port_desc[ch_num].port = &rport->base;
    sc->port_desc[ch_num].reversed = PJ_TRUE;


    /* Done */
    *p_chport = port;
    return status;
}