Compare commits

..

No commits in common. "ef176941257ca7ebe33d8fb78cdfbc54463c7547" and "a3f3b3410f62afe1ec360072b9be983baf13e9d5" have entirely different histories.

4 changed files with 15 additions and 101 deletions

View File

@ -1,89 +0,0 @@
Title: Programmatic Oscillators
Brief: Sine, cosine, saw and square oscillators with minimal binary footprint.
Date: 1684748529
Tags: Programming, Music, C
CSS: /style.css
Wanted to have some beep bops for my [4mb-jam](https://itch.io/jam/4mb-jam-2023) entry, so
I ended up with implementations of three oscillators that would require minimal amount of calculations.
Idea is to precalculate initial state offline and only have short frame generation procedure in final binary.
Thinking about using it in tracker format of sorts that would have runtime generated samples.
Inspirations are taken from [musicdsp](https://www.musicdsp.org/).
### Sine/Cosine ###
```c
/* Intended to be executed offline with values then embedded in the binary.
* By having usage of glibc sin and cos functions strictly offline it's easier to have it freestanding
*/
struct sinewave {
float f, s, c;
} init_sinewave(float frequency, float phase, float amplitude) {
struct sinewave r;
r.f = 2.f * sinf((float)M_PI * frequency / AUDIO_FRAME_RATE);
r.s = amplitude * sinf(phase);
r.c = amplitude * cosf(phase);
return r;
}
/* Use `s` for sine value and `c` for cosine on caller side */
void pump_sinewave(struct sinewave *wave) {
wave->s -= wave->f * wave->c;
wave->c += wave->f * wave->s;
}
```
### Square ###
```c
/* Implemented over sinewave */
struct sqrtwave {
struct sinewave w;
union {
float f;
uint32_t u;
} v;
} init_sqrtwave(float frequency, float phase, float amplitude) {
struct sqrtwave r;
r.w = init_sinewave(frequency, phase, 1.f);
r.v.f = amplitude;
return r;
}
/* Use floating point bit representation to infer sign, all other bits are set to amplitude */
void pump_sqrtwave(struct sqrtwave *wave) {
union {
float f;
uint32_t u;
} v;
pump_sinewave(&wave->w);
v.f = wave->w.s;
wave->v.u = (wave->v.u & 0x7fffffff) | (v.u & 0x80000000);
}
```
### Saw ###
```c
struct sawtwave {
float v, a, i;
} init_sawtwave(float frequency, float phase, float amplitude) {
struct sawtwave r;
r.v = sinf(phase) * amplitude;
r.a = amplitude;
r.i = frequency / AUDIO_FRAME_RATE * amplitude;
return r;
}
/* Simple amplitude overflow check with truncation */
void pump_sawtwave(struct sawtwave *wave) {
wave->v += wave->i;
if (wave->v > wave->a)
wave->v -= wave->a;
}
```

14
compile.py Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/python3
from os import walk
import subprocess
subprocess.run("./tools/main_page_generator.py ./articles | ./tools/mmd/build/multimarkdown > ./html/index.html", shell=True)
subprocess.run("mkdir -p ./html/articles", shell=True)
for root, dirs, _ in walk("./articles"):
for d in dirs:
subprocess.run(
f"""./tools/article_wrapper.py ./articles/{d}/page.mmd | ./tools/mmd/build/multimarkdown > ./html/articles/{d}.html""",
shell=True
)

View File

@ -1,11 +0,0 @@
#!/bin/sh
mkdir -p ./html/articles
./tools/main_page_generator.py ./articles | ./tools/mmd/build/multimarkdown > ./html/index.html
for d in ./articles/*; do
if [ -d "$d" ]; then
./tools/article_wrapper.py "$d/page.mmd" | ./tools/mmd/build/multimarkdown > "./html/articles/$(basename -- $d).html"
fi
done

View File

@ -40,6 +40,6 @@ for root, dirs, _ in walk(argv[1]):
page += f""">*{','.join(metadata["Tags"])}*\n---\n"""
curtime = time.gmtime(int(time.time()))
page += f"Last compiled: *{MONTHS[curtime.tm_mon]} {curtime.tm_mday}, {curtime.tm_year} {curtime.tm_hour}:{curtime.tm_min:02d}*\n\n"
page += f"Last compiled: *{MONTHS[curtime.tm_mon]} {curtime.tm_mday}, {curtime.tm_year} {curtime.tm_hour}:{curtime.tm_min:2}*\n\n"
print(page_metadata + wrap_page(page))