Created
May 26, 2020 03:39
-
-
Save AaronM04/06abdda5d6d45acf4e75a9a62dad8161 to your computer and use it in GitHub Desktop.
sndio test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compile with: