예제 #1
0
static int vu_decode_update(struct aufilt_dec_st **stp, void **ctx,
			    const struct aufilt *af, struct aufilt_prm *prm,
			    const struct audio *au)
{
	struct vumeter_dec *st;
	(void)ctx;
	(void)prm;
	(void)au;

	if (!stp || !af)
		return EINVAL;

	if (*stp)
		return 0;

	if (prm->fmt != AUFMT_S16LE) {
		warning("vumeter: unsupported sample format (%s)\n",
			aufmt_name(prm->fmt));
		return ENOTSUP;
	}

	st = mem_zalloc(sizeof(*st), vu_dec_destructor);
	if (!st)
		return ENOMEM;

	gdk_threads_enter();
	call_window_got_vu_dec(st);
	gdk_threads_leave();

	*stp = (struct aufilt_dec_st *)st;

	return 0;
}
예제 #2
0
파일: src.c 프로젝트: alfredh/baresip
static int read_stream_open(struct ausrc_st *st, const struct ausrc_prm *prm,
			    unsigned int dev)
{
	WAVEFORMATEX wfmt;
	MMRESULT res;
	uint32_t sampc;
	unsigned format;
	int i, err = 0;

	st->sampsz = aufmt_sample_size(prm->fmt);

	format = winwave_get_format(prm->fmt);
	if (format == WAVE_FORMAT_UNKNOWN) {
		warning("winwave: source: unsupported sample format (%s)\n",
			aufmt_name(prm->fmt));
		return ENOTSUP;
	}

	/* Open an audio INPUT stream. */
	st->wavein = NULL;
	st->pos = 0;
	st->rdy = false;

	sampc = prm->srate * prm->ch * prm->ptime / 1000;

	for (i = 0; i < READ_BUFFERS; i++) {
		memset(&st->bufs[i].wh, 0, sizeof(WAVEHDR));
		st->bufs[i].mb = mbuf_alloc(st->sampsz * sampc);
		if (!st->bufs[i].mb)
			return ENOMEM;
	}

	wfmt.wFormatTag      = format;
	wfmt.nChannels       = prm->ch;
	wfmt.nSamplesPerSec  = prm->srate;
	wfmt.wBitsPerSample  = (WORD)(st->sampsz * 8);
	wfmt.nBlockAlign     = (prm->ch * wfmt.wBitsPerSample) / 8;
	wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
	wfmt.cbSize          = 0;

	res = waveInOpen(&st->wavein, dev, &wfmt,
			  (DWORD_PTR) waveInCallback,
			  (DWORD_PTR) st,
			  CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT);
	if (res != MMSYSERR_NOERROR) {
		warning("winwave: waveInOpen: failed res=%d\n", res);
		return EINVAL;
	}

	/* Prepare enough IN buffers to suite at least 50ms of data */
	for (i = 0; i < READ_BUFFERS; i++)
		err |= add_wave_in(st);

	waveInStart(st->wavein);

	return err;
}
예제 #3
0
파일: auloop.c 프로젝트: alfredh/baresip
static int print_summary(struct re_printf *pf, const struct audio_loop *al)
{
	const double scale = al->srate * al->ch;
	int err;

	err  = re_hprintf(pf, "~~~~~ Audioloop summary: ~~~~~\n");
	err |= re_hprintf(pf, "%u Hz %uch %s\n\n",
			  al->srate, al->ch, aufmt_name(al->fmt));

	/* Source */
	if (al->ausrc) {
		struct ausrc *as = ausrc_get(al->ausrc);

		err |= re_hprintf(pf,
				  "* Source\n"
				  "  module      %s\n"
				  "  samples     %llu\n"
				  "  duration    %.3f sec\n"
				  "\n"
				  ,
				  as->name,
				  al->n_read,
				  (double)al->n_read / scale);
	}

	/* Player */
	if (al->auplay) {
		struct auplay *ap = auplay_get(al->auplay);

		err |= re_hprintf(pf,
				  "* Player\n"
				  "  module      %s\n"
				  "  samples     %llu\n"
				  "  duration    %.3f sec\n"
				  "\n"
				  ,
				  ap->name,
				  al->n_write,
				  (double)al->n_write / scale);
	}

	return err;
}
예제 #4
0
파일: auloop.c 프로젝트: alfredh/baresip
static void print_stats(struct audio_loop *al)
{
	double rw_ratio = 0.0;
	double delay = (double)al->n_read - (double)al->n_write;
	const double scale = al->srate * al->ch;

	if (al->n_write)
		rw_ratio = 1.0 * (double)al->n_read / (double)al->n_write;

	(void)re_fprintf(stdout, "\r%uHz %dch %s "
			 " n_read=%.3f n_write=%.3f rw_delay=%.3f [sec]"
			 " rw_ratio=%f"
			 ,
			 al->srate, al->ch, aufmt_name(al->fmt),
			 (double)al->n_read / scale,
			 (double)al->n_write / scale,
			 delay / scale, rw_ratio);

	(void)re_fprintf(stdout, "          \r");

	fflush(stdout);
}
예제 #5
0
static SNDFILE *openfile(const struct aufilt_prm *prm, bool enc)
{
	char filename[128];
	SF_INFO sfinfo;
	time_t tnow = time(0);
	struct tm *tm = localtime(&tnow);
	SNDFILE *sf;
	int format;

	(void)re_snprintf(filename, sizeof(filename),
			  "%s/dump-%H-%s.wav",
				file_path,
			  timestamp_print, tm, enc ? "enc" : "dec");

	format = get_format(prm->fmt);
	if (!format) {
		warning("sndfile: sample format not supported (%s)\n",
			aufmt_name(prm->fmt));
		return NULL;
	}

	sfinfo.samplerate = prm->srate;
	sfinfo.channels   = prm->ch;
	sfinfo.format     = SF_FORMAT_WAV | format;

	sf = sf_open(filename, SFM_WRITE, &sfinfo);
	if (!sf) {
		warning("sndfile: could not open: %s\n", filename);
		puts(sf_strerror(NULL));
		return NULL;
	}

	info("sndfile: dumping %s audio to %s\n",
	     enc ? "encode" : "decode", filename);

	return sf;
}
예제 #6
0
파일: alsa_src.c 프로젝트: AmesianX/baresip
int alsa_src_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;
	snd_pcm_format_t pcmfmt;
	int num_frames;
	int err;
	(void)ctx;
	(void)errh;

	if (!stp || !as || !prm || !rh)
		return EINVAL;

	if (!str_isset(device))
		device = alsa_dev;

	st = mem_zalloc(sizeof(*st), ausrc_destructor);
	if (!st)
		return ENOMEM;

	err = str_dup(&st->device, device);
	if (err)
		goto out;

	st->prm = *prm;
	st->as  = as;
	st->rh  = rh;
	st->arg = arg;
	st->aufmt = alsa_sample_format;

	st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
	num_frames = st->prm.srate * st->prm.ptime / 1000;

	st->sampv = mem_alloc(2 * st->sampc, NULL);
	if (!st->sampv) {
		err = ENOMEM;
		goto out;
	}

	if (st->aufmt != AUFMT_S16LE) {
		size_t sz = aufmt_sample_size(st->aufmt) * st->sampc;
		st->xsampv = mem_alloc(sz, NULL);
		if (!st->xsampv) {
			err = ENOMEM;
			goto out;
		}
	}

	err = snd_pcm_open(&st->read, st->device, SND_PCM_STREAM_CAPTURE, 0);
	if (err < 0) {
		warning("alsa: could not open ausrc device '%s' (%s)\n",
			st->device, snd_strerror(err));
		goto out;
	}

	pcmfmt = aufmt_to_alsaformat(st->aufmt);
	if (pcmfmt == SND_PCM_FORMAT_UNKNOWN) {
		warning("alsa: unknown sample format '%s'\n",
			aufmt_name(st->aufmt));
		err = EINVAL;
		goto out;
	}

	err = alsa_reset(st->read, st->prm.srate, st->prm.ch, num_frames,
			 pcmfmt);
	if (err) {
		warning("alsa: could not reset source '%s' (%s)\n",
			st->device, snd_strerror(err));
		goto out;
	}

	st->run = true;
	err = pthread_create(&st->thread, NULL, read_thread, st);
	if (err) {
		st->run = false;
		goto out;
	}

	debug("alsa: recording started (%s)\n", st->device);

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #7
0
int alsa_play_alloc(struct auplay_st **stp, const struct auplay *ap,
		    struct auplay_prm *prm, const char *device,
		    auplay_write_h *wh, void *arg)
{
	struct auplay_st *st;
	snd_pcm_format_t pcmfmt;
	int num_frames;
	int err;

	if (!stp || !ap || !prm || !wh)
		return EINVAL;

	if (!str_isset(device))
		device = alsa_dev;

	st = mem_zalloc(sizeof(*st), auplay_destructor);
	if (!st)
		return ENOMEM;

	err = str_dup(&st->device, device);
	if (err)
		goto out;

	st->prm = *prm;
	st->ap  = ap;
	st->wh  = wh;
	st->arg = arg;
	st->aufmt = alsa_sample_format;

	st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
	num_frames = st->prm.srate * st->prm.ptime / 1000;

	st->sampv = mem_alloc(2 * st->sampc, NULL);
	if (!st->sampv) {
		err = ENOMEM;
		goto out;
	}

	if (st->aufmt != AUFMT_S16LE) {
		size_t sz = aufmt_sample_size(st->aufmt) * st->sampc;
		st->xsampv = mem_alloc(sz, NULL);
		if (!st->xsampv) {
			err = ENOMEM;
			goto out;
		}
	}

	err = snd_pcm_open(&st->write, st->device, SND_PCM_STREAM_PLAYBACK, 0);
	if (err < 0) {
		warning("alsa: could not open auplay device '%s' (%s)\n",
			st->device, snd_strerror(err));
		goto out;
	}

	pcmfmt = aufmt_to_alsaformat(st->aufmt);
	if (pcmfmt == SND_PCM_FORMAT_UNKNOWN) {
		warning("alsa: unknown sample format '%s'\n",
			aufmt_name(st->aufmt));
		err = EINVAL;
		goto out;
	}

	err = alsa_reset(st->write, st->prm.srate, st->prm.ch, num_frames,
			 pcmfmt);
	if (err) {
		warning("alsa: could not reset player '%s' (%s)\n",
			st->device, snd_strerror(err));
		goto out;
	}

	st->run = true;
	err = pthread_create(&st->thread, NULL, write_thread, st);
	if (err) {
		st->run = false;
		goto out;
	}

	debug("alsa: playback started (%s)\n", st->device);

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #8
0
파일: auloop.c 프로젝트: alfredh/baresip
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;
}
예제 #9
0
파일: gst.c 프로젝트: alfredh/baresip
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;
}
예제 #10
0
파일: aufile.c 프로젝트: alfredh/baresip
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;

	if (prm->fmt != AUFMT_S16LE) {
		warning("aufile: unsupported sample format (%s)\n",
			aufmt_name(prm->fmt));
		return ENOTSUP;
	}

	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;
}