Created
January 17, 2023 04:09
-
-
Save marler8997/e8e66aa9d2dc7d4b5850b92a3fd878f5 to your computer and use it in GitHub Desktop.
DOOM sndserver linux aplay
This file contains 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
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