97 lines
2.0 KiB
C
97 lines
2.0 KiB
C
/*
|
|
* 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
|
|
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
*/
|
|
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include "err.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]);
|
|
|
|
for (;;) {
|
|
k = arc4random_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 = arc4random_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;
|
|
}
|