#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
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 <dlfcn.h>
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;
}