static int start_player(struct aurx *rx, struct audio *a) { const struct aucodec *ac = rx->ac; uint32_t srate_dsp = get_srate(ac); int err; if (!ac) return 0; /* Optional resampler, if configured */ if (a->cfg.srate_play && a->cfg.srate_play != srate_dsp && !rx->resamp) { srate_dsp = a->cfg.srate_play; (void)re_printf("enable auplay resampler: %u --> %u Hz\n", get_srate(ac), srate_dsp); rx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL); if (!rx->sampv_rs) return ENOMEM; err = auresamp_alloc(&rx->resamp, AUDIO_SAMPSZ, get_srate(ac), ac->ch, srate_dsp, ac->ch); if (err) return err; } /* Start Audio Player */ if (!rx->auplay && auplay_find(NULL)) { struct auplay_prm prm; prm.fmt = AUFMT_S16LE; prm.srate = srate_dsp; prm.ch = ac->ch; prm.frame_size = calc_nsamp(prm.srate, prm.ch, rx->ptime); if (!rx->ab) { const size_t psize = 2 * prm.frame_size; err = aubuf_alloc(&rx->ab, psize * 1, psize * 8); if (err) return err; } err = auplay_alloc(&rx->auplay, a->cfg.play_mod, &prm, a->cfg.play_dev, auplay_write_handler, rx); if (err) { DEBUG_WARNING("start_player failed (%s.%s): %m\n", a->cfg.play_mod, a->cfg.play_dev, err); return err; } } return 0; }
static int gst_alloc(struct ausrc_st **stp, struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; int err; (void)ctx; if (!device) device = gst_uri; if (!prm) return EINVAL; prm->fmt = AUFMT_S16LE; st = mem_zalloc(sizeof(*st), gst_destructor); if (!st) return ENOMEM; st->as = mem_ref(as); st->rh = rh; st->errh = errh; st->arg = arg; err = str_dup(&st->uri, device); if (err) goto out; st->prm = *prm; st->ptime = prm->frame_size * 1000 / (prm->srate * prm->ch); st->psize = 2 * prm->frame_size; err = aubuf_alloc(&st->aubuf, st->psize, 0); if (err) goto out; err = gst_setup(st); if (err) goto out; st->run = true; err = pthread_create(&st->tid, NULL, thread, st); if (err) { st->run = false; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }
static int auloop_reset(struct audio_loop *al) { struct auplay_prm auplay_prm; struct ausrc_prm ausrc_prm; const struct config *cfg = conf_config(); int err; if (!cfg) return ENOENT; /* Optional audio codec */ if (str_isset(aucodec)) start_codec(al, aucodec); al->auplay = mem_deref(al->auplay); al->ausrc = mem_deref(al->ausrc); al->ab = mem_deref(al->ab); al->srate = configv[al->index].srate; al->ch = configv[al->index].ch; al->fs = al->srate * al->ch * PTIME / 1000; (void)re_printf("Audio-loop: %uHz, %dch\n", al->srate, al->ch); err = aubuf_alloc(&al->ab, 320, 0); if (err) return err; auplay_prm.fmt = AUFMT_S16LE; auplay_prm.srate = al->srate; auplay_prm.ch = al->ch; auplay_prm.frame_size = al->fs; err = auplay_alloc(&al->auplay, cfg->audio.play_mod, &auplay_prm, cfg->audio.play_dev, write_handler, al); if (err) { DEBUG_WARNING("auplay %s,%s failed: %m\n", cfg->audio.play_mod, cfg->audio.play_dev, err); return err; } ausrc_prm.fmt = AUFMT_S16LE; ausrc_prm.srate = al->srate; ausrc_prm.ch = al->ch; ausrc_prm.frame_size = al->fs; err = ausrc_alloc(&al->ausrc, NULL, cfg->audio.src_mod, &ausrc_prm, cfg->audio.src_dev, read_handler, error_handler, al); if (err) { DEBUG_WARNING("ausrc %s,%s failed: %m\n", cfg->audio.src_mod, cfg->audio.src_dev, err); return err; } return err; }
static int alloc_handler(struct ausrc_st **stp, const struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *dev, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; struct aufile_prm fprm; int err; (void)ctx; if (!stp || !as || !prm || !rh) return EINVAL; info("aufile: loading input file '%s'\n", dev); st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; st->as = as; st->rh = rh; st->errh = errh; st->arg = arg; err = aufile_open(&st->aufile, &fprm, dev, AUFILE_READ); if (err) { warning("aufile: failed to open file '%s' (%m)\n", dev, err); goto out; } info("aufile: %s: %u Hz, %d channels\n", dev, fprm.srate, fprm.channels); if (fprm.srate != prm->srate) { warning("aufile: input file (%s) must have sample-rate" " %u Hz\n", dev, prm->srate); err = ENODEV; goto out; } if (fprm.channels != prm->ch) { warning("aufile: input file (%s) must have channels = %d\n", dev, prm->ch); err = ENODEV; goto out; } if (fprm.fmt != AUFMT_S16LE) { warning("aufile: input file must have format S16LE\n"); err = ENODEV; goto out; } st->sampc = prm->srate * prm->ch * prm->ptime / 1000; st->ptime = prm->ptime; info("aufile: audio ptime=%u sampc=%zu aubuf=[%u:%u]\n", st->ptime, st->sampc, prm->srate * prm->ch * 2, prm->srate * prm->ch * 40); /* 1 - inf seconds of audio */ err = aubuf_alloc(&st->aubuf, prm->srate * prm->ch * 2, 0); if (err) goto out; err = read_file(st); if (err) goto out; tmr_start(&st->tmr, 1000, timeout, st); st->run = true; err = pthread_create(&st->thread, NULL, play_thread, st); if (err) { st->run = false; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }
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 auloop_reset(struct audio_loop *al) { struct auplay_prm auplay_prm; struct ausrc_prm ausrc_prm; const struct config *cfg = conf_config(); int err; if (!cfg) return ENOENT; /* Optional audio codec */ if (str_isset(aucodec)) start_codec(al, aucodec); /* audio player/source must be stopped first */ al->auplay = mem_deref(al->auplay); al->ausrc = mem_deref(al->ausrc); al->sampv = mem_deref(al->sampv); al->ab = mem_deref(al->ab); al->srate = configv[al->index].srate; al->ch = configv[al->index].ch; if (str_isset(aucodec)) { al->sampc = al->srate * al->ch * PTIME / 1000; al->sampv = mem_alloc(al->sampc * 2, NULL); if (!al->sampv) return ENOMEM; } info("Audio-loop: %uHz, %dch\n", al->srate, al->ch); err = aubuf_alloc(&al->ab, 320, 0); if (err) return err; auplay_prm.srate = al->srate; auplay_prm.ch = al->ch; auplay_prm.ptime = PTIME; err = auplay_alloc(&al->auplay, cfg->audio.play_mod, &auplay_prm, cfg->audio.play_dev, write_handler, al); if (err) { warning("auloop: auplay %s,%s failed: %m\n", cfg->audio.play_mod, cfg->audio.play_dev, err); return err; } ausrc_prm.srate = al->srate; ausrc_prm.ch = al->ch; ausrc_prm.ptime = PTIME; err = ausrc_alloc(&al->ausrc, NULL, cfg->audio.src_mod, &ausrc_prm, cfg->audio.src_dev, read_handler, error_handler, al); if (err) { warning("auloop: ausrc %s,%s failed: %m\n", cfg->audio.src_mod, cfg->audio.src_dev, err); return err; } return err; }
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; }
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; }
static int auloop_reset(struct audio_loop *al, uint32_t srate, uint32_t ch) { struct auplay_prm auplay_prm; struct ausrc_prm ausrc_prm; const struct config *cfg = conf_config(); int err; if (!cfg) return ENOENT; if (cfg->audio.src_fmt != cfg->audio.play_fmt) { warning("auloop: ausrc_format and auplay_format" " must be the same\n"); return EINVAL; } al->fmt = cfg->audio.src_fmt; /* audio player/source must be stopped first */ al->auplay = mem_deref(al->auplay); al->ausrc = mem_deref(al->ausrc); al->aubuf = mem_deref(al->aubuf); al->srate = srate; al->ch = ch; info("Audio-loop: %uHz, %dch, %s\n", al->srate, al->ch, aufmt_name(al->fmt)); err = aubuf_alloc(&al->aubuf, 320, 0); if (err) return err; auplay_prm.srate = al->srate; auplay_prm.ch = al->ch; auplay_prm.ptime = PTIME; auplay_prm.fmt = al->fmt; err = auplay_alloc(&al->auplay, baresip_auplayl(), cfg->audio.play_mod, &auplay_prm, cfg->audio.play_dev, write_handler, al); if (err) { warning("auloop: auplay %s,%s failed: %m\n", cfg->audio.play_mod, cfg->audio.play_dev, err); return err; } ausrc_prm.srate = al->srate; ausrc_prm.ch = al->ch; ausrc_prm.ptime = PTIME; ausrc_prm.fmt = al->fmt; err = ausrc_alloc(&al->ausrc, baresip_ausrcl(), NULL, cfg->audio.src_mod, &ausrc_prm, cfg->audio.src_dev, read_handler, error_handler, al); if (err) { warning("auloop: ausrc %s,%s failed: %m\n", cfg->audio.src_mod, cfg->audio.src_dev, err); return err; } return err; }
static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; int err; (void)ctx; if (!device) device = gst_uri; if (!prm) return EINVAL; if (prm->fmt != AUFMT_S16LE) { warning("gst: unsupported sample format (%s)\n", aufmt_name(prm->fmt)); return ENOTSUP; } st = mem_zalloc(sizeof(*st), gst_destructor); if (!st) return ENOMEM; st->as = as; st->rh = rh; st->errh = errh; st->arg = arg; err = str_dup(&st->uri, device); if (err) goto out; st->prm = *prm; st->sampc = prm->srate * prm->ch * prm->ptime / 1000; st->psize = 2 * st->sampc; err = aubuf_alloc(&st->aubuf, st->psize, 0); if (err) goto out; err = gst_setup(st); if (err) goto out; st->run = true; err = pthread_create(&st->tid, NULL, thread, st); if (err) { st->run = false; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }
static int alloc_handler(struct ausrc_st **stp, const struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *dev, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; int err; if (!stp || !as || !prm || !rh) return EINVAL; st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; st->as = as; st->rh = rh; st->errh = errh; st->arg = arg; st->mp3 = mpg123_new(NULL, &err); if (!st->mp3) { err = ENODEV; goto out; } err = mpg123_open_feed(st->mp3); if (err != MPG123_OK) { warning("rst: mpg123_open_feed: %s\n", mpg123_strerror(st->mp3)); err = ENODEV; goto out; } /* Set wanted output format */ mpg123_format_none(st->mp3); mpg123_format(st->mp3, prm->srate, prm->ch, aufmt_to_encoding(prm->fmt)); mpg123_volume(st->mp3, 0.3); st->sampc = prm->srate * prm->ch * prm->ptime / 1000; st->sampsz = aufmt_sample_size(prm->fmt); st->ptime = prm->ptime; info("rst: audio ptime=%u sampc=%zu aubuf=[%u:%u]\n", st->ptime, st->sampc, prm->srate * prm->ch * 2, prm->srate * prm->ch * 40); /* 1 - 20 seconds of audio */ err = aubuf_alloc(&st->aubuf, prm->srate * prm->ch * st->sampsz, prm->srate * prm->ch * st->sampsz * 20); if (err) goto out; if (ctx && *ctx && (*ctx)->id && !strcmp((*ctx)->id, "rst")) { st->rst = mem_ref(*ctx); } else { err = rst_alloc(&st->rst, dev); if (err) goto out; if (ctx) *ctx = (struct media_ctx *)st->rst; } rst_set_audio(st->rst, st); st->run = true; err = pthread_create(&st->thread, NULL, play_thread, st); if (err) { st->run = false; goto out; } out: if (err) mem_deref(st); else *stp = st; return err; }