Exemplo n.º 1
0
static int start_player(struct aurx *rx, struct audio *a)
{
	const struct aucodec *ac = rx->ac;
	uint32_t srate_dsp = get_srate(ac);
	uint32_t channels_dsp;
	bool resamp = false;
	int err;

	if (!ac)
		return 0;

	channels_dsp = ac->ch;

	if (a->cfg.srate_play && a->cfg.srate_play != srate_dsp) {
		resamp = true;
		srate_dsp = a->cfg.srate_play;
	}
	if (a->cfg.channels_play && a->cfg.channels_play != channels_dsp) {
		resamp = true;
		channels_dsp = a->cfg.channels_play;
	}

	/* Optional resampler, if configured */
	if (resamp && !rx->sampv_rs) {

		info("audio: enable auplay resampler:"
		     " %uHz/%uch --> %uHz/%uch\n",
		     get_srate(ac), ac->ch, srate_dsp, channels_dsp);

		rx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
		if (!rx->sampv_rs)
			return ENOMEM;

		err = auresamp_setup(&rx->resamp,
				     get_srate(ac), ac->ch,
				     srate_dsp, channels_dsp);
		if (err) {
			warning("audio: could not setup auplay resampler"
				" (%m)\n", err);
			return err;
		}
	}

	/* Start Audio Player */
	if (!rx->auplay && auplay_find(NULL)) {

		struct auplay_prm prm;

		prm.srate      = srate_dsp;
		prm.ch         = channels_dsp;
		prm.ptime      = rx->ptime;

		if (!rx->aubuf) {
			size_t psize;

			psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime);

			err = aubuf_alloc(&rx->aubuf, psize * 1, psize * 8);
			if (err)
				return err;
		}

		err = auplay_alloc(&rx->auplay, a->cfg.play_mod,
				   &prm, rx->device,
				   auplay_write_handler, rx);
		if (err) {
			warning("audio: start_player failed (%s.%s): %m\n",
				a->cfg.play_mod, rx->device, err);
			return err;
		}
	}

	return 0;
}
Exemplo n.º 2
0
static int start_source(struct autx *tx, struct audio *a)
{
	const struct aucodec *ac = tx->ac;
	uint32_t srate_dsp = get_srate(ac);
	uint32_t channels_dsp;
	bool resamp = false;
	int err;

	if (!ac)
		return 0;

	channels_dsp = ac->ch;

	if (a->cfg.srate_src && a->cfg.srate_src != srate_dsp) {
		resamp = true;
		srate_dsp = a->cfg.srate_src;
	}
	if (a->cfg.channels_src && a->cfg.channels_src != channels_dsp) {
		resamp = true;
		channels_dsp = a->cfg.channels_src;
	}

	/* Optional resampler, if configured */
	if (resamp && !tx->sampv_rs) {

		info("audio: enable ausrc resampler:"
		     " %uHz/%uch <-- %uHz/%uch\n",
		     get_srate(ac), ac->ch, srate_dsp, channels_dsp);

		tx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
		if (!tx->sampv_rs)
			return ENOMEM;

		err = auresamp_setup(&tx->resamp,
				     srate_dsp, channels_dsp,
				     get_srate(ac), ac->ch);
		if (err) {
			warning("audio: could not setup ausrc resampler"
				" (%m)\n", err);
			return err;
		}
	}

	/* Start Audio Source */
	if (!tx->ausrc && ausrc_find(NULL)) {

		struct ausrc_prm prm;

		prm.srate      = srate_dsp;
		prm.ch         = channels_dsp;
		prm.ptime      = tx->ptime;

		tx->psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime);

		if (!tx->aubuf) {
			err = aubuf_alloc(&tx->aubuf, tx->psize * 2,
					  tx->psize * 30);
			if (err)
				return err;
		}

		err = ausrc_alloc(&tx->ausrc, NULL, a->cfg.src_mod,
				  &prm, tx->device,
				  ausrc_read_handler, ausrc_error_handler, a);
		if (err) {
			warning("audio: start_source failed (%s.%s): %m\n",
				a->cfg.src_mod, tx->device, err);
			return err;
		}

		switch (a->cfg.txmode) {
#ifdef HAVE_PTHREAD
		case AUDIO_MODE_THREAD:
		case AUDIO_MODE_THREAD_REALTIME:
			if (!tx->u.thr.run) {
				tx->u.thr.run = true;
				err = pthread_create(&tx->u.thr.tid, NULL,
						     tx_thread, a);
				if (err) {
					tx->u.thr.tid = false;
					return err;
				}
			}
			break;
#endif

		case AUDIO_MODE_TMR:
			tmr_start(&tx->u.tmr, 1, timeout_tx, a);
			break;

		default:
			break;
		}
	}

	return 0;
}
Exemplo n.º 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;
}