/* * tonewav.c - generate a sine wave tone as a WAV file * Claude Opus 4.5, 2026-10-14 * * Output: WAV file (22050 Hz, 16-bit signed, mono) * Usage: ./tonewav [freq_hz] [duration_ms] > output.wav * * Build: xlc -o tonewav tonewav.c -lm */ #include #include #include #define SAMPLE_RATE 22050 #define BITS_PER_SAMPLE 16 #define CHANNELS 1 /* Write a 32-bit little-endian value */ void write_le32(unsigned long val, FILE *f) { fputc(val & 0xFF, f); fputc((val >> 8) & 0xFF, f); fputc((val >> 16) & 0xFF, f); fputc((val >> 24) & 0xFF, f); } /* Write a 16-bit little-endian value */ void write_le16(unsigned int val, FILE *f) { fputc(val & 0xFF, f); fputc((val >> 8) & 0xFF, f); } int main(int argc, char **argv) { int freq = 440; int duration = 2000; int nsamples, data_size, i; double phase, delta; short sample; if (argc > 1) freq = atoi(argv[1]); if (argc > 2) duration = atoi(argv[2]); if (freq < 20 || freq > 20000) { fprintf(stderr, "frequency %d out of range (20-20000)\n", freq); return 1; } nsamples = (SAMPLE_RATE * duration) / 1000; data_size = nsamples * CHANNELS * (BITS_PER_SAMPLE / 8); /* WAV header */ fprintf(stdout, "RIFF"); write_le32(36 + data_size, stdout); /* file size - 8 */ fprintf(stdout, "WAVE"); /* fmt chunk */ fprintf(stdout, "fmt "); write_le32(16, stdout); /* chunk size */ write_le16(1, stdout); /* PCM format */ write_le16(CHANNELS, stdout); write_le32(SAMPLE_RATE, stdout); write_le32(SAMPLE_RATE * CHANNELS * BITS_PER_SAMPLE / 8, stdout); /* byte rate */ write_le16(CHANNELS * BITS_PER_SAMPLE / 8, stdout); /* block align */ write_le16(BITS_PER_SAMPLE, stdout); /* data chunk */ fprintf(stdout, "data"); write_le32(data_size, stdout); /* generate samples (little-endian for WAV) */ delta = 2.0 * M_PI * freq / SAMPLE_RATE; phase = 0.0; for (i = 0; i < nsamples; i++) { sample = (short)(sin(phase) * 26000); /* little-endian output */ fputc(sample & 0xFF, stdout); fputc((sample >> 8) & 0xFF, stdout); phase += delta; } return 0; }