#define _GNU_SOURCE #include #include #include #include char stop = 0; char decay = 0; char thread_started = 0; pthread_t worker_thread; void* worker(void *z){ // mostly lifted from https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm__min_8c-example.html static char *device = "default"; unsigned char click[4]; unsigned char blank[4]; int err; unsigned int i; snd_pcm_t *handle; snd_pcm_sframes_t frames; for (i = 0; i < sizeof(click); i++){ click[i] = 0; blank[i] = 0; } click[0] = 250; if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(stderr, "Playback open error: %s\n", snd_strerror(err)); pthread_exit(NULL); } if ((err = snd_pcm_set_params(handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 8000, 1, 125)) < 0) { fprintf(stderr, "Playback open error: %s\n", snd_strerror(err)); pthread_exit(NULL); } fprintf(stderr, "Starting!\n"); while (!stop) { // Frame selection if (decay) { frames = snd_pcm_writei(handle, click, sizeof(click)); decay = 0; } else { frames = snd_pcm_writei(handle, blank, sizeof(click)); } // Handle mis-plays if (frames < 0) { frames = snd_pcm_recover(handle, frames, 0); } if (frames < 0) { fprintf(stderr, "snd_pcm_writei failed: %s\n", snd_strerror(err)); break; } if (frames > 0 && frames < (long)sizeof(click)) { fprintf(stderr, "Short write (expected %li, wrote %li)\n", (long)sizeof(click), frames); } } snd_pcm_close(handle); fprintf(stderr, "Stopping from workers\n"); pthread_exit(NULL); } void init(void) __attribute__((constructor)); void init(void){ int rc = pthread_create(&worker_thread, NULL, worker, (void *)NULL); if (rc) { fprintf(stderr, "Whoops!\n"); } else { thread_started = 1; } return; } void deinit(void) __attribute__((destructor)); void deinit(void){ stop = 1; fprintf(stderr, "Stopping: %d\n", stop); if (thread_started) pthread_join(worker_thread, NULL); return; } #include void* malloc(size_t size) { static void* (*real_malloc)(size_t) = NULL; if (!real_malloc) { real_malloc = dlsym(RTLD_NEXT, "malloc"); } void *p = real_malloc(size); decay = 1; return p; }