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