106 lines
2.5 KiB
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;
|
|
}
|