serial_audio_catcher/serial_capture.c

106 lines
2.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#define SERIAL_PORT "/dev/ttyACM1"
#define BAUD_RATE B1500000
#define RATE 16000
#define CHANNELS 2
#define SAMPLE_WIDTH 2 // 16-bit
#define CHUNK_SIZE 256 // frames per block
#define DURATION 3 // seconds
// Write a simple WAV header
void write_wav_header(FILE *f, int data_size) {
int byte_rate = RATE * CHANNELS * SAMPLE_WIDTH;
int block_align = CHANNELS * SAMPLE_WIDTH;
// RIFF header
fwrite("RIFF", 1, 4, f);
int chunk_size = 36 + data_size;
fwrite(&chunk_size, 4, 1, f);
fwrite("WAVE", 1, 4, f);
// fmt subchunk
fwrite("fmt ", 1, 4, f);
int subchunk1_size = 16;
fwrite(&subchunk1_size, 4, 1, f);
short audio_format = 1; // PCM
fwrite(&audio_format, 2, 1, f);
short num_channels = CHANNELS;
fwrite(&num_channels, 2, 1, f);
int sample_rate = RATE;
fwrite(&sample_rate, 4, 1, f);
fwrite(&byte_rate, 4, 1, f);
fwrite(&block_align, 2, 1, f);
short bits_per_sample = SAMPLE_WIDTH * 8;
fwrite(&bits_per_sample, 2, 1, f);
// data subchunk
fwrite("data", 1, 4, f);
fwrite(&data_size, 4, 1, f);
}
int main() {
// Open serial port
int fd = open(SERIAL_PORT, O_RDONLY | O_NOCTTY);
if (fd < 0) {
perror("open");
return 1;
}
// Configure serial
struct termios tty;
memset(&tty, 0, sizeof tty);
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return 1;
}
cfsetospeed(&tty, BAUD_RATE);
cfsetispeed(&tty, BAUD_RATE);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tcsetattr(fd, TCSANOW, &tty);
FILE *out = fopen("capture.wav", "wb");
if (!out) {
perror("fopen");
return 1;
}
// Reserve space for header
fseek(out, 44, SEEK_SET);
int total_bytes = 0;
char buf[CHUNK_SIZE * CHANNELS * SAMPLE_WIDTH];
time_t start = time(NULL);
while (time(NULL) - start < DURATION) {
int n = read(fd, buf, sizeof(buf));
if (n > 0) {
fwrite(buf, 1, n, out);
total_bytes += n;
}
}
// Write header at beginning
fseek(out, 0, SEEK_SET);
write_wav_header(out, total_bytes);
fclose(out);
close(fd);
printf("Saved capture.wav (%d bytes of audio)\n", total_bytes);
return 0;
}