/** * Start the audio playback and recording * * @param a Audio object * * @return 0 if success, otherwise errorcode */ int audio_start(struct audio *a) { int err; if (!a) return EINVAL; err = stream_start(a->strm); if (err) return err; /* Audio filter */ if (!a->filtl.head && !list_isempty(aufilt_list())) { err = aufilt_setup(a); if (err) return err; } /* configurable order of play/src start */ if (a->cfg.src_first) { err |= start_source(&a->tx, a); err |= start_player(&a->rx, a); } else { err |= start_player(&a->rx, a); err |= start_source(&a->tx, a); } return err; }
/** * Setup the audio-filter chain * * must be called before auplay/ausrc-alloc */ static int aufilt_setup(struct audio *a) { struct aufilt_prm encprm, decprm; struct autx *tx = &a->tx; struct aurx *rx = &a->rx; struct le *le; /* wait until we have both Encoder and Decoder */ if (!tx->ac || !rx->ac) return 0; if (!list_isempty(&tx->filtl) || !list_isempty(&rx->filtl)) return 0; aufilt_param_set(&encprm, tx->ac, tx->ptime); aufilt_param_set(&decprm, rx->ac, rx->ptime); /* Audio filters */ for (le = list_head(aufilt_list()); le; le = le->next) { struct aufilt *af = le->data; struct aufilt_enc_st *encst = NULL; struct aufilt_dec_st *decst = NULL; void *ctx = NULL; int err = 0; if (af->encupdh) { err |= af->encupdh(&encst, &ctx, af, &encprm); if (err) { continue; } encst->af = af; list_append(&tx->filtl, &encst->le, encst); } if (af->decupdh) { err |= af->decupdh(&decst, &ctx, af, &decprm); if (err) { continue; } decst->af = af; list_append(&rx->filtl, &decst->le, decst); } if (err) { DEBUG_WARNING("audio-filter '%s' update failed (%m)\n", af->name, err); break; } } return 0; }
/** * Setup the audio-filter chain * * must be called before auplay/ausrc-alloc */ static int aufilt_setup(struct audio *a) { struct aufilt_prm encprm, decprm; struct autx *tx = &a->tx; struct aurx *rx = &a->rx; struct le *le; int err = 0; aufilt_param_set(&encprm, tx->ac ? tx->ac : rx->ac, tx->ptime); aufilt_param_set(&decprm, rx->ac ? rx->ac : tx->ac, rx->ptime); /* Audio filters */ for (le = list_head(aufilt_list()); le; le = le->next) { struct aufilt *af = le->data; struct aufilt_st *st = NULL; err = af->updh(&st, af, &encprm, &decprm); if (err) { DEBUG_WARNING("audio-filter '%s' update failed (%m)\n", af->name, err); break; } st->af = af; list_append(&a->filtl, &st->le, st); if (le == list_head(aufilt_list())) (void)re_printf("audio filters: (dsp)"); (void)re_printf("<--->[%s]", af->name); if (le == list_tail(aufilt_list())) (void)re_printf("<--->(codec)\n"); } return 0; }
/** * Load all modules from config file * * @return 0 if success, otherwise errorcode * * @note conf_configure must be called first */ int conf_modules(void) { int err; err = module_init(conf_obj); if (err) { warning("conf: configure module parse error (%m)\n", err); goto out; } print_populated("audio codec", list_count(aucodec_list())); print_populated("audio filter", list_count(aufilt_list())); #ifdef USE_VIDEO print_populated("video codec", list_count(vidcodec_list())); print_populated("video filter", list_count(vidfilt_list())); #endif out: return err; }
/** * Start the audio playback and recording * * @param a Audio object * * @return 0 if success, otherwise errorcode */ int audio_start(struct audio *a) { int err; if (!a) return EINVAL; /* Audio filter */ if (!list_isempty(aufilt_list())) { err = aufilt_setup(a); if (err) return err; } /* configurable order of play/src start */ if (a->cfg.src_first) { err = start_source(&a->tx, a); err |= start_player(&a->rx, a); } else { err = start_player(&a->rx, a); err |= start_source(&a->tx, a); } if (err) return err; if (a->tx.ac && a->rx.ac) { if (!a->started) { info("%H%H", autx_print_pipeline, &a->tx, aurx_print_pipeline, &a->rx); } a->started = true; } return err; }