Skip to content

Instantly share code, notes, and snippets.

@marler8997
Created January 17, 2023 04:09
Show Gist options
  • Save marler8997/e8e66aa9d2dc7d4b5850b92a3fd878f5 to your computer and use it in GitHub Desktop.
Save marler8997/e8e66aa9d2dc7d4b5850b92a3fd878f5 to your computer and use it in GitHub Desktop.
DOOM sndserver linux aplay
static void InitAplay(int samplesize)
{
int pipefd[2];
if (0 != pipe2(pipefd, O_DIRECT)) {
fprintf(stderr, "pipe failed, errno=%d\n", errno);
exit(-1);
}
// pipefd[0] read
pid_t pid = fork();
if (pid == -1) {
fprintf(stderr, "fork failed, errno=%d\n", errno);
exit(-1);
}
// if parent process
if (pid != 0) {
fprintf(stderr, "aplay pid=%d\n", pid);
close(pipefd[0]); // close read end of pipe
audio_fd = pipefd[1];
return;
}
close(pipefd[1]); // close write end of pipe
// is child process
if (pipefd[0] != 0) {
close(0);
if (0 != dup2(pipefd[0], 0)) {
fprintf(stderr, "dup2 failed, errno=%d\n", errno);
exit(-1);
}
close(pipefd[0]);
}
// Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
// --duration?
// --samples?
char rate_arg[30];
sprintf(rate_arg, "--rate=%d", samplerate);
char *format_arg;
if (samplesize == 16) {
format_arg = "--format=S16_LE";
} else {
fprintf(stderr, "unsupported samplesize %d\n", samplesize);
exit(-1);
}
const char *argv[] = { "aplay", "--channels=2", format_arg, rate_arg, /*"--buffer-size=1200",*/ "--disable-resample", NULL};
int result = execvp(argv[0], argv);
fprintf(stderr, "exec aplay failed, result=%d, errno=%d\n", result, errno);
exit(-1);
}
void SubmitBuffer()
{ static int got_first_time = 0;
static struct timespec last_time;
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
if (got_first_time) {
struct timespec diff = {
.tv_sec = now.tv_sec - last_time.tv_sec,
.tv_nsec = now.tv_nsec - last_time.tv_nsec,
};
fprintf(stderr, "time diff %ld secs %d nsecs\n", (long)diff.tv_sec, diff.tv_nsec);
} else {
got_first_time = 1;
}
last_time = now;
// we need to delay ourselves because linux pipes don't
// do that for us
int time_samples = samplecount / 2; // 2 channels
float time_seconds = ((float)time_samples) / samplerate;
// leave a few milliseconds?
if (time_seconds > 0.009) {
time_seconds -= 0.009;
//fprintf(stderr, "TODO: delay samples=%d time=%.3f\n", time_seconds);
static const float ns_per_s = 1000000;
usleep(ns_per_s * time_seconds);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment