Skip to content

Instantly share code, notes, and snippets.

@AaronM04
Created May 26, 2020 03:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AaronM04/06abdda5d6d45acf4e75a9a62dad8161 to your computer and use it in GitHub Desktop.
Save AaronM04/06abdda5d6d45acf4e75a9a62dad8161 to your computer and use it in GitHub Desktop.
sndio test
#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
);
}
@AaronM04
Copy link
Author

Compile with:

gcc -lsndio test.c -o test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment