Example #1
0
/*
 * @note This function has REAL-TIME properties
 */
static void poll_aubuf_tx(struct audio *a)
{
	struct autx *tx = &a->tx;
	int16_t *sampv = tx->sampv;
	size_t sampc;
	struct le *le;
	int err = 0;

	sampc = tx->psize / 2;

	/* timed read from audio-buffer */
	aubuf_read_samp(tx->aubuf, tx->sampv, sampc);

	/* optional resampler */
	if (tx->resamp.resample) {
		size_t sampc_rs = AUDIO_SAMPSZ;

		err = auresamp(&tx->resamp,
			       tx->sampv_rs, &sampc_rs,
			       tx->sampv, sampc);
		if (err)
			return;

		sampv = tx->sampv_rs;
		sampc = sampc_rs;
	}

	/* Process exactly one audio-frame in list order */
	for (le = tx->filtl.head; le; le = le->next) {
		struct aufilt_enc_st *st = le->data;

		if (st->af && st->af->ench)
			err |= st->af->ench(st, sampv, &sampc);
	}
	if (err) {
		warning("audio: aufilter encode: %m\n", err);
	}

	/* Encode and send */
	encode_rtp_send(a, tx, sampv, sampc);
}
Example #2
0
static int aurx_stream_decode(struct aurx *rx, struct mbuf *mb)
{
	size_t sampc = AUDIO_SAMPSZ;
	int16_t *sampv;
	struct le *le;
	int err = 0;

	/* No decoder set */
	if (!rx->ac)
		return 0;

	if (mbuf_get_left(mb)) {
		err = rx->ac->dech(rx->dec, rx->sampv, &sampc,
				   mbuf_buf(mb), mbuf_get_left(mb));
	}
	else if (rx->ac->plch) {
		err = rx->ac->plch(rx->dec, rx->sampv, &sampc);
	}
	else {
		/* no PLC in the codec, might be done in filters below */
		sampc = 0;
	}

	if (err) {
		warning("audio: %s codec decode %u bytes: %m\n",
			rx->ac->name, mbuf_get_left(mb), err);
		goto out;
	}

	/* Process exactly one audio-frame in reverse list order */
	for (le = rx->filtl.tail; le; le = le->prev) {
		struct aufilt_dec_st *st = le->data;

		if (st->af && st->af->dech)
			err |= st->af->dech(st, rx->sampv, &sampc);
	}

	if (!rx->aubuf)
		goto out;

	sampv = rx->sampv;

	/* optional resampler */
	if (rx->resamp.resample) {
		size_t sampc_rs = AUDIO_SAMPSZ;

		err = auresamp(&rx->resamp,
			       rx->sampv_rs, &sampc_rs,
			       rx->sampv, sampc);
		if (err)
			return err;

		sampv = rx->sampv_rs;
		sampc = sampc_rs;
	}

	err = aubuf_write_samp(rx->aubuf, sampv, sampc);
	if (err)
		goto out;

 out:
	return err;
}
Example #3
0
static void *device_thread(void *arg)
{
	uint64_t now, ts = tmr_jiffies();
	struct device *dev = arg;
	struct auresamp rs;
	int16_t *sampv_in, *sampv_out;
	size_t sampc_in;
	size_t sampc_out;
	int err;

	sampc_in = dev->auplay->prm.srate * dev->auplay->prm.ch * PTIME/1000;
	sampc_out = dev->ausrc->prm.srate * dev->ausrc->prm.ch * PTIME/1000;

	auresamp_init(&rs);

	sampv_in  = mem_alloc(2 * sampc_in, NULL);
	sampv_out = mem_alloc(2 * sampc_out, NULL);
	if (!sampv_in || !sampv_out)
		goto out;

	err = auresamp_setup(&rs,
			     dev->auplay->prm.srate, dev->auplay->prm.ch,
			     dev->ausrc->prm.srate, dev->ausrc->prm.ch);
	if (err)
		goto out;

	while (dev->run) {

		(void)sys_msleep(4);

		if (!dev->run)
			break;

		now = tmr_jiffies();

		if (ts > now)
			continue;

		if (dev->auplay && dev->auplay->wh) {
			dev->auplay->wh(sampv_in, sampc_in, dev->auplay->arg);
		}

		err = auresamp(&rs,
			       sampv_out, &sampc_out,
			       sampv_in, sampc_in);
		if (err) {
			warning("aubridge: auresamp error: %m\n", err);
		}

		if (dev->ausrc && dev->ausrc->rh) {
			dev->ausrc->rh(sampv_out, sampc_out,
				       dev->ausrc->arg);
		}

		ts += PTIME;
	}

 out:
	mem_deref(sampv_in);
	mem_deref(sampv_out);

	return NULL;
}