Skip to content

Instantly share code, notes, and snippets.

@CandyGumdrop
Created April 29, 2018 23:02
Show Gist options
  • Save CandyGumdrop/c989508fadc284de71c97c46cbf47c71 to your computer and use it in GitHub Desktop.
Save CandyGumdrop/c989508fadc284de71c97c46cbf47c71 to your computer and use it in GitHub Desktop.
Sound of the C
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define RATE 44100.0
#define PI 3.1415926535897932384626
#define F_DOMAIN_SIZE 64
#define SONG_LENGTH 96
#define CHORD_LENGTH 4
int song[SONG_LENGTH][CHORD_LENGTH + 1] = {
{40, 0, 0, 0, 0},
{40, 44, 0, 0, 0},
{40, 44, 47, 0, 0},
{40, 44, 47, 52, 0},
{35, 0, 0, 0, 0},
{35, 39, 0, 0, 0},
{35, 39, 42, 0, 0},
{35, 39, 42, 47, 0},
{37, 0, 0, 0, 0},
{37, 40, 0, 0, 0},
{37, 40, 44, 0, 0},
{37, 40, 44, 49, 0},
{32, 0, 0, 0, 0},
{32, 35, 0, 0, 0},
{32, 35, 39, 0, 0},
{32, 35, 39, 44, 0},
{33, 0, 0, 0, 0},
{33, 37, 0, 0, 0},
{33, 37, 40, 0, 0},
{33, 37, 40, 45, 0},
{28, 0, 0, 0, 0},
{28, 32, 0, 0, 0},
{28, 32, 35, 0, 0},
{28, 32, 35, 40, 0},
{33, 0, 0, 0, 0},
{33, 37, 0, 0, 0},
{33, 37, 40, 0, 0},
{33, 37, 40, 45, 0},
{35, 0, 0, 0, 0},
{35, 39, 0, 0, 0},
{35, 39, 42, 0, 0},
{35, 39, 42, 47, 0},
{40, 0, 0, 0, 56},
{40, 44, 0, 0, 56},
{40, 44, 47, 0, 56},
{40, 44, 47, 52, 56},
{35, 0, 0, 0, 54},
{35, 39, 0, 0, 54},
{35, 39, 42, 0, 54},
{35, 39, 42, 47, 54},
{37, 0, 0, 0, 52},
{37, 40, 0, 0, 52},
{37, 40, 44, 0, 52},
{37, 40, 44, 49, 52},
{32, 0, 0, 0, 51},
{32, 35, 0, 0, 51},
{32, 35, 39, 0, 51},
{32, 35, 39, 44, 51},
{33, 0, 0, 0, 49},
{33, 37, 0, 0, 49},
{33, 37, 40, 0, 49},
{33, 37, 40, 45, 49},
{28, 0, 0, 0, 47},
{28, 32, 0, 0, 47},
{28, 32, 35, 0, 47},
{28, 32, 35, 40, 47},
{33, 0, 0, 0, 49},
{33, 37, 0, 0, 49},
{33, 37, 40, 0, 49},
{33, 37, 40, 45, 49},
{35, 0, 0, 0, 51},
{35, 39, 0, 0, 51},
{35, 39, 42, 0, 52},
{35, 39, 42, 47, 54},
{40, 0, 0, 0, 56},
{40, 44, 0, 0, 56},
{40, 44, 47, 0, 56},
{40, 44, 47, 52, 56},
{35, 0, 0, 0, 54},
{35, 39, 0, 0, 57},
{35, 39, 42, 0, 56},
{35, 39, 42, 47, 54},
{37, 0, 0, 0, 52},
{37, 40, 0, 0, 52},
{37, 40, 44, 0, 52},
{37, 40, 44, 49, 52},
{32, 0, 0, 0, 51},
{32, 35, 0, 0, 56},
{32, 35, 39, 0, 59},
{32, 35, 39, 44, 61},
{33, 0, 0, 0, 57},
{33, 37, 0, 0, 56},
{33, 37, 40, 0, 54},
{33, 37, 40, 45, 57},
{28, 0, 0, 0, 56},
{28, 32, 0, 0, 54},
{28, 32, 35, 0, 52},
{28, 32, 35, 40, 47},
{33, 0, 0, 0, 49},
{33, 37, 0, 0, 47},
{33, 37, 40, 0, 45},
{33, 37, 40, 45, 52},
{35, 0, 0, 0, 51},
{35, 39, 0, 0, 52},
{35, 39, 42, 0, 51},
{35, 39, 42, 47, 52}
};
struct freq_domain {
double a[F_DOMAIN_SIZE], b[F_DOMAIN_SIZE];
};
static double note_freq(double note)
{
return pow(2, (note - 49) / 12.0) * 440;
}
static void square_domain(double amplitude, struct freq_domain *domain)
{
int n;
domain->a[0] = 0;
for (n = 1; n < F_DOMAIN_SIZE; n++) {
domain->a[n] = n % 2 ? sin(n * PI / 2) * 2 * amplitude / (n * PI) : 0;
domain->b[n] = 0;
}
}
static void lowpass(struct freq_domain *domain, double position)
{
int n;
for (n = 1; n < F_DOMAIN_SIZE; n++) {
double filter;
filter = (1 - exp(n - position));
if (filter < 0) {
filter = 0;
}
domain->a[n] *= filter;
domain->b[n] *= filter;
}
}
static double wave(struct freq_domain *domain, double time, double freq)
{
int n;
double x;
x = domain->a[0];
for (n = 1; n < F_DOMAIN_SIZE; n++) {
x += domain->a[n] * cos(2 * PI * freq * time * n);
x += domain->b[n] * sin(2 * PI * freq * time * n);
}
return x;
}
int main(void)
{
uint64_t i;
uint32_t filesize, datasize, chunk, srate, brate;
uint16_t type, channels, balign, depth;
int n;
struct freq_domain square, thing;
square_domain(INT16_MAX / 4, &square);
thing.a[0] = 0;
for (n = 1; n < F_DOMAIN_SIZE; n++) {
thing.a[n] = n % 2 ? INT16_MAX / 12 / (n + 1) : INT16_MAX / 16 / (n + 1);
thing.b[n] = 0;
}
datasize = 2 * 2 * SONG_LENGTH * 10000;
filesize = datasize + 38;
chunk = 16;
type = 1;
channels = 2;
srate = RATE;
depth = 16;
brate = channels * srate * depth / 8;
balign = channels * depth / 8;
fwrite("RIFF", 1, 4, stdout);
fwrite(&filesize, sizeof filesize, 1, stdout);
fwrite("WAVE", 1, 4, stdout);
fwrite("fmt ", 1, 4, stdout);
fwrite(&chunk, sizeof chunk, 1, stdout);
fwrite(&type, sizeof type, 1, stdout);
fwrite(&channels, sizeof channels, 1, stdout);
fwrite(&srate, sizeof srate, 1, stdout);
fwrite(&brate, sizeof brate, 1, stdout);
fwrite(&balign, sizeof balign, 1, stdout);
fwrite(&depth, sizeof depth, 1, stdout);
fwrite("data", 1, 4, stdout);
fwrite(&datasize, sizeof datasize, 1, stdout);
for (i = 0; i < datasize; i++) {
int16_t left, right;
int cnote, *chord;
left = 0;
right = 0;
chord = song[(i / 10000) % SONG_LENGTH];
for (cnote = 0; cnote < CHORD_LENGTH; cnote++) {
if (chord[cnote]) {
int16_t sound;
sound = wave(&thing, i / RATE, note_freq(chord[cnote]));
left += sound * 0.7;
right += sound * 0.3;
}
}
if (chord[CHORD_LENGTH]) {
int16_t sound;
sound = wave(&square, i / RATE,
note_freq(chord[CHORD_LENGTH]
+ sin(i / 1000.0) * 0.0006));
left += sound;
right += sound;
}
fwrite(&left, sizeof left, 1, stdout);
fwrite(&right, sizeof right, 1, stdout);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment