/** * Allocate an Audio Source state * * @param stp Pointer to allocated Audio Source state * @param ausrcl List of Audio Sources * @param ctx Media context (optional) * @param name Name of Audio Source * @param prm Audio Source parameters * @param device Name of Audio Source device (driver specific) * @param rh Read handler * @param errh Error handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int ausrc_alloc(struct ausrc_st **stp, struct list *ausrcl, struct media_ctx **ctx, const char *name, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc *as; as = (struct ausrc *)ausrc_find(ausrcl, name); if (!as) return ENOENT; return as->alloch(stp, as, ctx, prm, device, rh, errh, arg); }
static int start_source(struct autx *tx, struct audio *a) { const struct aucodec *ac = tx->ac; uint32_t srate_dsp = get_srate(tx->ac); int err; if (!ac) return 0; /* Optional resampler, if configured */ if (a->cfg.srate_src && a->cfg.srate_src != srate_dsp && !tx->resamp) { srate_dsp = a->cfg.srate_src; (void)re_printf("enable ausrc resampler: %u --> %u Hz\n", get_srate(ac), srate_dsp); tx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL); if (!tx->sampv_rs) return ENOMEM; err = auresamp_alloc(&tx->resamp, AUDIO_SAMPSZ, srate_dsp, ac->ch, get_srate(ac), ac->ch); if (err) return err; } /* Start Audio Source */ if (!tx->ausrc && ausrc_find(NULL)) { struct ausrc_prm prm; prm.fmt = AUFMT_S16LE; prm.srate = srate_dsp; prm.ch = ac->ch; prm.frame_size = calc_nsamp(prm.srate, prm.ch, tx->ptime); tx->psize = 2 * prm.frame_size; if (!tx->ab) { err = aubuf_alloc(&tx->ab, tx->psize * 2, tx->psize * 30); if (err) return err; } err = ausrc_alloc(&tx->ausrc, NULL, a->cfg.src_mod, &prm, a->cfg.src_dev, ausrc_read_handler, ausrc_error_handler, a); if (err) { DEBUG_WARNING("start_source failed: %m\n", 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; }
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; }