Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 72 additions & 50 deletions rec.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,94 +13,116 @@ struct input_event {
unsigned int value;
};

#define HISTSIZE 60
/* We keep recording all the time, creating a history of BUF_HIST bytes.
* Once a key action has been registered, we store our history and
* record another BUF_POST bytes.
*
* Those exact values depend on your machine. We don't do
* auto-detection. */
#define BUF_HIST (44100 / 32)
#define BUF_POST (44100 / 2)

void
samplename(char *buf, size_t buf_len, unsigned short code, unsigned int value)
{
int i;

for (i = 0; i < 10; i++)
{
snprintf(buf, buf_len, "wav-new/%02x-%d-%d.wav", code, value, i);
if (access(buf, R_OK) == -1)
return;
}

fprintf(stderr, "Damn, you recorded too many samples for %02x %d\n", code, value);
exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
struct input_event event;
char cmd[256];
char fname[256];
FILE *f;
int fd_ev, fd_snd;
int samples = 0;
int fd_snd;
int triggered = 0;
FILE *fout = NULL;
int head = 0;
int16_t hist[HISTSIZE];

if(argc < 2) {
fprintf(stderr, "usage: %s </dev/input/event#>\n", argv[0]);
exit(1);
}
int16_t hist[BUF_HIST], post[BUF_POST];
size_t hist_at = 0;

/* Run like:
*
* $ (sleep 2; sudo stdbuf -i0 -o0 cat /dev/input/event5) | ./rec
*
* Begin with a sleep, so we don't catch the "Return, released"
* event that started this command. */
fprintf(stderr, "Waiting for evdev data on stdin ...\n");

//f = popen("arecord -D plughw:1,0 -f cd -r 44100 -c 1", "r");
f = popen("parec --rate=44100 --format=s16le --channels=1", "r");
f = popen("parec --rate=44100 --format=s16le --channels=1 --latency=2", "r");
fd_snd = fileno(f);

fd_ev = open(argv[1], O_RDONLY);
if(fd_ev == -1) {
perror("Could not open event input");
exit(1);
}

fd_set fds;
while(1) {
FD_ZERO(&fds);
FD_SET(fd_ev, &fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(fd_snd, &fds);

select(16, &fds, NULL, NULL, NULL);

if(FD_ISSET(fd_ev, &fds)) {
if(FD_ISSET(STDIN_FILENO, &fds)) {

read(fd_ev, &event, sizeof event);
read(STDIN_FILENO, &event, sizeof event);

if(event.type != 1) continue;
if(event.value == 2) continue;

if(triggered == 0) {
snprintf(fname, sizeof fname, "wav-new/%02x-%d.wav", event.code, event.value);
samplename(fname, sizeof fname, event.code, event.value);
snprintf(cmd, sizeof cmd, "sox -qq -r 44100 -e signed -b 16 -c 1 -t raw - %s", fname);
printf("%02x %d: ", event.code, event.value);
fflush(stdout);
fout = popen(cmd, "w");
samples = 0;
triggered = 1;
printf("%02x %d ", event.code, event.value);
fflush(stdout);
}
}

if(FD_ISSET(fd_snd, &fds)) {
int16_t buf;
read(fd_snd, &buf, sizeof buf);

if(triggered) {
if(samples == 0) {
if(buf < -2000 || buf > 2000) {
samples = 1;
printf(">");
fflush(stdout);
}
}

if(fout && samples) {
fwrite(&hist[head], 1, sizeof hist[head], fout);
if(samples > 44000/3) {
fclose(fout);
snprintf(cmd, sizeof(cmd), "paplay %s &", fname);
system(cmd);
printf(".\n");
fout = NULL;
triggered = 0;
}
}

if(samples) samples ++;
if (triggered)
{
size_t history_i = 0;
printf(">");
fflush(stdout);

/* Write history. */
for (history_i = 0; history_i < BUF_HIST; history_i++)
{
hist_at++;
hist_at %= BUF_HIST;
fwrite(&hist[hist_at], sizeof (int16_t), 1, fout);
}

hist[head] = buf;
head = (head + 1) % HISTSIZE;
/* Record additional samples. */
fread(&post, BUF_POST, 1, f);
fwrite(&post, BUF_POST, 1, fout);

/* Close pipe and play back for examination. */
fclose(fout);
snprintf(cmd, sizeof(cmd), "paplay %s &", fname);
system(cmd);
printf(".\n");
fout = NULL;
triggered = 0;
hist_at = 0;
}

if(FD_ISSET(fd_snd, &fds)) {
/* Audio data ready to read but we haven't registered a key,
* so add those two bytes to our history. */
read(fd_snd, &hist[hist_at], sizeof (int16_t));
hist_at++;
hist_at %= BUF_HIST;
}

}
Expand Down