コード例 #1
0
ファイル: sndio.c プロジェクト: DragonFlyBSD/DPorts
/*
 *  Re-opens device with read-mode and starts recording (half-duplex).
 *  Returns the DMA buffer size if successful.
 */
static int
sndio_rec_start(int rate, int bits, int stereo)
{
	sndio_save_bits = _sound_bits;
	sndio_save_stereo = _sound_stereo;
	sndio_save_freq = _sound_freq;

	_unix_bg_man->unregister_func(sndio_update);

	if (hdl != NULL)
		sio_close(hdl);
	hdl = NULL;

	_sound_bits = bits;
	_sound_stereo = stereo;
	_sound_freq = rate;

	if (open_sndio_device(1) != 0)
		return 0;

	sndio_volume = 127;
	sio_onvol(hdl, volcb, NULL);

	if (!sio_start(hdl)) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not start sndio for recording"));
		sio_close(hdl);
		return 0;
	}

	return sndio_rec_bufsize;
}
コード例 #2
0
ファイル: sndio.c プロジェクト: DragonFlyBSD/DPorts
/* Stops recording and switches the device back to the original mode. */
static void
sndio_rec_stop(void)
{
	if (hdl != NULL)
		sio_close(hdl);
	hdl = NULL;

	_sound_bits = sndio_save_bits;
	_sound_stereo = sndio_save_stereo;
	_sound_freq = sndio_save_freq;

	if (open_sndio_device(0) != 0)
		return;

	sndio_realpos = sndio_playpos = 0;
	sio_onmove(hdl, movecb, NULL);

	sndio_volume = 127;
	sio_onvol(hdl, volcb, NULL);

	if (!sio_start(hdl)) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not start sndio"));
		sio_close(hdl);
		return;
	}

	_unix_bg_man->register_func(sndio_update);
}
コード例 #3
0
ファイル: vol.c プロジェクト: SylvestreG/bitrig
int
main(int argc, char **argv) {
	int ch;
	int tty;
	struct sio_hdl *hdl;
	struct termios tio;
	struct pollfd pfd[2];
	char cmd;
	ssize_t n, len;
	
	/*
	 * defaults parameters
	 */
	sio_initpar(&par);
	par.sig = 1;
	par.bits = 16;
	par.pchan = 2;
	par.rate = 44100;

	if (isatty(STDIN_FILENO)) {
		fprintf(stderr, "stdin can't be a tty\n");
		exit(1);
	}
	tty = open("/dev/tty", O_RDWR);
	if (tty < 0) {
		perror("/dev/tty");
		exit(1);
	}
	if (tcgetattr(tty, &tio) < 0) {
		perror("tcsetattr");
		exit(1);
	}
	tio.c_lflag &= ~ICANON;
	tio.c_lflag &= ~ECHO;
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(tty, TCSAFLUSH, &tio) < 0) {
		perror("tcsetattr");
		exit(1);
	}

	while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) {
		switch(ch) {
		case 'r':
			if (sscanf(optarg, "%u", &par.rate) != 1) {
				fprintf(stderr, "%s: bad rate\n", optarg);
				exit(1);
			}
			break;
		case 'c':
			if (sscanf(optarg, "%u", &par.pchan) != 1) {
				fprintf(stderr, "%s: bad channels\n", optarg);
				exit(1);
			}
			break;
		case 'e':
			if (!sio_strtoenc(&par, optarg)) {
				fprintf(stderr, "%s: bad encoding\n", optarg);
				exit(1);
			}
			break;
		default:
			usage();
			exit(1);
			break;
		}
	}

	hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0);
	if (hdl == NULL) {
		fprintf(stderr, "sio_open() failed\n");
		exit(1);
	}
	if (!sio_setpar(hdl, &par)) {
		fprintf(stderr, "sio_setpar() failed\n");
		exit(1);
	}
	if (!sio_onvol(hdl, onvol, NULL))
		fprintf(stderr, "warning: no volume knob on this device\n");
	fprintf(stderr, "use ``+'' and ``-'' to adjust the volume\n");
	if (!sio_start(hdl)) {
		fprintf(stderr, "sio_start() failed\n");
		exit(1);
	}
	for (;;) {
		pfd[0].fd = tty;
		pfd[0].events = POLLIN;
		sio_pollfd(hdl, &pfd[1], POLLOUT);
		if (poll(pfd, 2, -1) < 0) {
			perror("poll");
			exit(1);
		}
		if (pfd[0].revents & POLLIN) {
			if (read(tty, &cmd, 1) < 0) {
				perror("read(tty)");
				exit(1);
			}
			switch (cmd) {
			case '+':
				if (vol < SIO_MAXVOL) {
					vol++;
					sio_setvol(hdl, vol);
				}
				break;
			case '-':
				if (vol > 0) {
					vol--;
					sio_setvol(hdl, vol);
				}
				break;
			}
		}
		if (sio_revents(hdl, &pfd[1]) & POLLOUT) {
			len = read(STDIN_FILENO, buf, BUFSZ);
			if (len < 0) {
				perror("stdin");
				exit(1);
			}
			if (len == 0)
				break;
			n = sio_write(hdl, buf, len);
			if (n == 0) {
				fprintf(stderr, "sio_write: failed\n");
				exit(1);
			}
		}
	}
	sio_close(hdl);
	return 0;
}
コード例 #4
0
ファイル: ao_sndio.c プロジェクト: enkore/mpv
/*
 * open device and setup parameters
 * return: 0=success -1=fail
 */
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;

    struct af_to_par {
        int format, bits, sig, le;
    } static const af_to_par[] = {
        {AF_FORMAT_U8,      8, 0, 0},
        {AF_FORMAT_S8,      8, 1, 0},
        {AF_FORMAT_U16_LE, 16, 0, 1},
        {AF_FORMAT_U16_BE, 16, 0, 0},
        {AF_FORMAT_S16_LE, 16, 1, 1},
        {AF_FORMAT_S16_BE, 16, 1, 0},
        {AF_FORMAT_U24_LE, 16, 0, 1},
        {AF_FORMAT_U24_BE, 24, 0, 0},
        {AF_FORMAT_S24_LE, 24, 1, 1},
        {AF_FORMAT_S24_BE, 24, 1, 0},
        {AF_FORMAT_U32_LE, 32, 0, 1},
        {AF_FORMAT_U32_BE, 32, 0, 0},
        {AF_FORMAT_S32_LE, 32, 1, 1},
        {AF_FORMAT_S32_BE, 32, 1, 0}
    }, *ap;
    int i;

    p->hdl = sio_open(p->dev, SIO_PLAY, 0);
    if (p->hdl == NULL) {
        MP_ERR(ao, "can't open sndio %s\n", p->dev);
        goto error;
    }

    ao->format = af_fmt_from_planar(ao->format);

    sio_initpar(&p->par);
    for (i = 0, ap = af_to_par;; i++, ap++) {
        if (i == sizeof(af_to_par) / sizeof(struct af_to_par)) {
            MP_VERBOSE(ao, "unsupported format\n");
            p->par.bits = 16;
            p->par.sig = 1;
            p->par.le = SIO_LE_NATIVE;
            break;
        }
        if (ap->format == ao->format) {
            p->par.bits = ap->bits;
            p->par.sig = ap->sig;
            if (ap->bits > 8)
                p->par.le = ap->le;
            if (ap->bits != SIO_BPS(ap->bits))
                p->par.bps = ap->bits / 8;
            break;
        }
    }
    p->par.rate = ao->samplerate;

    struct mp_chmap_sel sel = {0};
    for (int n = 0; n < MP_NUM_CHANNELS+1; n++)
        mp_chmap_sel_add_map(&sel, &sndio_layouts[n]);

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto error;

    p->par.pchan = ao->channels.num;
    p->par.appbufsz = p->par.rate * 250 / 1000;    /* 250ms buffer */
    p->par.round = p->par.rate * 10 / 1000;    /*  10ms block size */
    if (!sio_setpar(p->hdl, &p->par)) {
        MP_ERR(ao, "couldn't set params\n");
        goto error;
    }
    if (!sio_getpar(p->hdl, &p->par)) {
        MP_ERR(ao, "couldn't get params\n");
        goto error;
    }
    if (p->par.bits == 8 && p->par.bps == 1) {
        ao->format = p->par.sig ? AF_FORMAT_S8 : AF_FORMAT_U8;
    } else if (p->par.bits == 16 && p->par.bps == 2) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S16_LE : AF_FORMAT_S16_BE) :
            (p->par.le ? AF_FORMAT_U16_LE : AF_FORMAT_U16_BE);
    } else if ((p->par.bits == 24 || p->par.msb) && p->par.bps == 3) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S24_LE : AF_FORMAT_S24_BE) :
            (p->par.le ? AF_FORMAT_U24_LE : AF_FORMAT_U24_BE);
    } else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S32_LE : AF_FORMAT_S32_BE) :
            (p->par.le ? AF_FORMAT_U32_LE : AF_FORMAT_U32_BE);
    } else {
        MP_ERR(ao, "couldn't set format\n");
        goto error;
    }

    ao->bps = p->par.bps * p->par.pchan * p->par.rate;
    p->havevol = sio_onvol(p->hdl, volcb, p);
    sio_onmove(p->hdl, movecb, p);
    p->delay = 0;
    if (!sio_start(p->hdl))
        MP_ERR(ao, "init: couldn't start\n");

    p->pfd = calloc (sio_nfds(p->hdl), sizeof (struct pollfd));
    if (!p->pfd)
        goto error;

    return 0;

error:
    if (p->hdl)
      sio_close(p->hdl);

    return -1;
}
コード例 #5
0
ファイル: sndio.c プロジェクト: DragonFlyBSD/DPorts
static int
sndio_init(int input, int voices)
{
	char tmp1[128], tmp2[128];

	if (input) {
		digi_driver->rec_cap_bits = 16;
		digi_driver->rec_cap_stereo = TRUE;
		return 0;
	}

	if (open_sndio_device(0) != 0)
		return -1;

	sndio_play_bufdata = _AL_MALLOC_ATOMIC(sndio_play_bufsize);
	if (sndio_play_bufdata == 0) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not allocate audio buffer"));
		sio_close(hdl);
		return -1;
	}

	sndio_realpos = sndio_playpos = 0;
	sio_onmove(hdl, movecb, NULL);

	sndio_volume = 127;
	sio_onvol(hdl, volcb, NULL);

	if (!sio_start(hdl)) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not start sndio"));
		sio_close(hdl);
		return -1;
	}

	digi_sndio.voices = voices;

	/* first arg is total number of samples */
	if (_mixer_init(sndio_play_round * (_sound_stereo ? 2 : 1),
	    _sound_freq, _sound_stereo, ((_sound_bits == 16) ? 1 : 0),
	    &digi_sndio.voices) != 0) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not init software mixer"));
		sio_close(hdl);
		return -1;
	}

	_mix_some_samples((uintptr_t) sndio_play_bufdata, 0, sndio_signed);

	/* Add audio interrupt.  */
	_unix_bg_man->register_func(sndio_update);

	uszprintf(sndio_desc, sizeof(sndio_desc),
	    get_config_text("%s: %d bits, %s, %d Hz, %s"),
	    "sndio device",
	    _sound_bits,
	    uconvert_ascii((sndio_signed ? "signed" : "unsigned"), tmp1),
	    _sound_freq,
	    uconvert_ascii((par.pchan == 2 ? "stereo" : "mono"), tmp2));

	digi_driver->desc = sndio_desc;

	return 0;
}