/* * arngment - random music generator * * Written in 2020 by Lucas * * To the extent possible under law, the author(s) have dedicated all * copyright and related and neighboring rights to this software to the * public domain worldwide. This software is distributed without any * warranty. * * You should have received a copy of the CC0 Public Domain Dedication * along with this software. If not, see * . */ /* getopt, srand48, visibility for glibc */ #if !defined(__OpenBSD__) #define _DEFAULT_SOURCE #endif #include #include #include #include #include #include #include "err.h" #include "lrand48_uniform.h" #include "note.h" #include "synth.h" #define nelems(_a) (sizeof(_a) / sizeof((_a)[0])) #define GAIN 1.4 #define RATE 48000 static void usage(void) { fprintf(stderr, "Usage: %s base_note\n", __progname); exit(1); } int main(int argc, char *argv[]) { int16_t buf[RATE]; int scale[] = { 0, 2, 3, 5, 7, 8, 10, 12, 0, 2, 3, 5, 7, 8, 10, 12, 12, 14, 15, 17, 19, 20, 22, 24, }; struct note base_note, note; double l, r, t; size_t i; uint32_t k; int ch; while ((ch = getopt(argc, argv, "")) != -1) switch (ch) { default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); if (!note_parse(&base_note, argv[0])) errx(1, "Invalid note %s", argv[0]); srand48(time(NULL)); for (;;) { k = lrand48_uniform(nelems(scale)); note = base_note; note.offset += scale[k]; for (i = 0; i < RATE / 2; i += 2) { t = i / (double)RATE; l = synth_distortion(GAIN, synth_sinewave(t, note_pitch(note))); r = synth_distortion(GAIN, synth_trianglewave(t, note_pitch(note))); buf[i] = l * INT16_MAX; buf[i + 1] = r * INT16_MAX; } k = lrand48_uniform(nelems(scale)); note = base_note; note.offset += scale[k]; for (; i < RATE; i += 2) { t = i / (double)RATE; l = synth_distortion(GAIN, synth_sinewave(t, note_pitch(note))); r = synth_distortion(GAIN, synth_trianglewave(t, note_pitch(note))); buf[i] = l * INT16_MAX; buf[i + 1] = r * INT16_MAX; } fwrite(buf, sizeof(buf[0]), RATE, stdout); } return 0; }