Sunday, May 31, 2020

Re: sndio: troubleshooting no input

Do you have sysctl kern.audio.record=1 ?

Jan

On May 30 18:17:02, aaron@iforgotmy.name wrote:
> Hello,
>
> I have an amd64 laptop with OpenBSD 6.7 and I am only getting
> zero-valued samples when recording. Is there any checklist I can
> go through to ensure nothing is muted and that I am reading from
> the correct input device?
>
> I have tried both aucat and a C program I wrote (attached).
>
> Thanks,
> Aaron Miller

> #include <stdio.h>
> #include <sndio.h>
> #include <stdlib.h>
> #include <errno.h>
>
> #define BUF_SAMPLES 4800
> #define OUTFILE "recorded.pcm"
> #define ITERATIONS 500
>
> // ffmpeg -y -f s16le -ar 48000 -ac 1 -i recorded.pcm recorded.mp3 && mpv recorded.mp3
>
> void print_par(struct sio_par *par);
>
> int main(int argc, char* argv[]) {
> short *sample_buf = NULL;
> struct sio_hdl *h;
> int fail = 0;
> int started = 0;
> size_t total_bytes_read = 0;
> int i;
> size_t bytes_read;
> FILE *out = NULL;
> h = sio_open(SIO_DEVANY, SIO_REC, 0);
> if (h == NULL) {
> fprintf(stderr, "%s: we're fucked man\n", argv[0]);
> fail = 1; goto done;
> }
>
> struct sio_par par;
> sio_initpar(&par);
>
> par.bits = 8*sizeof(short);
> //par.bps = sizeof(short);
> par.sig = 1;
> par.le = 1;
> par.rchan = 1;
> par.pchan = 2; // unused
> par.rate = 48000;
> par.xrun = SIO_IGNORE;
>
> //print_par(&par);
> printf("running sio_setpar...\n");
> if (sio_setpar(h, &par) == 0) {
> fprintf(stderr, "%s: sio_setpar failed\n", argv[0]);
> fail = 1; goto done;
> };
> //print_par(&par);
>
> printf("running sio_getpar...\n");
> if (sio_getpar(h, &par) == 0) {
> fprintf(stderr, "%s: sio_getpar failed\n", argv[0]);
> fail = 1; goto done;
> };
> print_par(&par);
>
> if (BUF_SAMPLES % par.round != 0) {
> fprintf(stderr, "%s: samples in buf (%d) not mult of round (%d)\n", argv[0], BUF_SAMPLES, par.round);
> fail = 1; goto done;
> }
>
> if ((sample_buf = malloc(BUF_SAMPLES * sizeof(short))) == NULL) {
> fprintf(stderr, "%s: oh we are sooo fucked. GAME OVER MAN\n", argv[0]);
> fail = 1; goto done;
> }
>
> if ((out = fopen(OUTFILE, "wb")) == NULL) {
> fprintf(stderr, "%s: failed to open %s for writing\n", argv[0], OUTFILE);
> fail = 1; goto done;
> }
>
> if (sio_start(h) == 0) {
> fprintf(stderr, "%s: failed to sio_start\n", argv[0]);
> fail = 1; goto done;
> }
> started = 1;
> int retries = 0;
> printf("START\n");
> for (i = 0; i < ITERATIONS; i++) {
> if ((bytes_read = sio_read(h, sample_buf, BUF_SAMPLES * sizeof(short))) == 0) {
> fprintf(stderr, "%s: failed to sio_read\n", argv[0]);
> fail = 1; goto done;
> }
> total_bytes_read += bytes_read;
>
> size_t bytes_written;
> size_t bw;
> char* buf_ptr = (char *) sample_buf;
> for (bytes_written = 0; bytes_written < bytes_read; bytes_written += bw) {
> size_t bytes_left = bytes_read - bytes_written;
> bw = fwrite(buf_ptr, 1, bytes_left, out);
> if (bw < bytes_left && errno != EAGAIN) {
> fprintf(stderr, "%s: failed to write to file\n", argv[0]);
> perror(argv[0]);
> fail = 1; goto done;
> }
> buf_ptr += bw;
> }
> }
> printf("TOTAL BYTES READ: %d\n", total_bytes_read);
>
> // cleanup
> done:
> if (started) {
> sio_stop(h);
> }
> if (out != NULL) {
> fclose(out);
> }
> if (sample_buf != NULL) {
> free(sample_buf);
> }
> if (h != NULL) {
> sio_close(h);
> }
> return fail;
> }
>
> void print_par(struct sio_par *par) {
> char *xrun;
> switch (par->xrun) {
> default:
> xrun = "<unknown xrun val>";
> break;
> case 0:
> xrun = "SIO_IGNORE";
> break;
> case 1:
> xrun = "SIO_SYNC";
> break;
> case 2:
> xrun = "SIO_ERROR";
> break;
> }
> printf("&sio_par{\n"
> " bits: %d,\n"
> " bps: %d,\n"
> " sig: %d,\n"
> " le: %d,\n"
> " msb: %d,\n"
> " rchan: %d,\n"
> " pchan: %d,\n"
> " rate: %d,\n"
> " appbufsz: %d,\n"
> " bufsz: %d,\n"
> " round: %d,\n"
> " xrun: %s (%d),\n"
> "}\n",
> par->bits, /* bits per sample */
> par->bps, /* bytes per sample */
> par->sig, /* 1 = signed, 0 = unsigned int */
> par->le, /* 1 = LE, 0 = BE byte order */
> par->msb, /* 1 = MSB, 0 = LSB aligned */
> par->rchan, /* number channels for recording */
> par->pchan, /* number channels for playback */
> par->rate, /* frames per second */
> par->appbufsz, /* minimum buffer size without xruns */
> par->bufsz, /* end-to-end buffer size (read-only) */
> par->round, /* optimal buffer size divisor */
> xrun, /* what to do on overrun/underrun */
> par->xrun
> );
> }

No comments:

Post a Comment