Initial commit

This commit is contained in:
thib8956 committed 2026-10-27 22:10:43 +01:00
commit 91a1e2e312
22 files changed
+885

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
*.o
*.wasm
+16
View File
@@ -0,0 +1,16 @@
CFLAGS = -Wall -Wextra -pedantic -std=c23 \
-Wconversion -Wdouble-promotion \
-Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion \
-fsanitize=undefined \
--target=wasm32 -O1 -flto -ffreestanding -fno-builtin -nostdlib
math.o: math.c
clang $(CFLAGS) -c math.c -o math.o
beep.wasm: beep.c math.o
clang $(CFLAGS) \
-Wl,--no-entry \
-Wl,--export=beep \
-Wl,--export=get_samples \
beep.c math.o \
-o beep.wasm
+13
View File
@@ -0,0 +1,13 @@
#include <stdint.h>
#include "math.h"
#define SAMPLE_COUNT 44100
static float SAMPLES[SAMPLE_COUNT];
float* get_samples() { return SAMPLES; }
void beep(uint32_t sample_rate, float freq) {
for (int i = 0; i < SAMPLE_COUNT; ++i) {
SAMPLES[i] = sintau((float)i * freq / (float)sample_rate);
}
}
+23
View File
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #000000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
</style>
</head>
<body>
</body>
<script src="index.js" type="module"></script>
</html>
+23
View File
@@ -0,0 +1,23 @@
const { instance } = await WebAssembly.instantiateStreaming(fetch("beep.wasm"));
let ctx = undefined;
const count = 44100;
const ptr = instance.exports.get_samples();
async function playTone(frequency = 440) {
ctx ??= new AudioContext();
await ctx.resume();
instance.exports.beep(ctx.sampleRate, frequency);
const audioBuffer = ctx.createBuffer(1, count, ctx.sampleRate);
const audioChannel = audioBuffer.getChannelData(0);
audioChannel.set(new Float32Array(instance.exports.memory.buffer, ptr, count));
const src = ctx.createBufferSource();
src.buffer = audioBuffer;
src.connect(ctx.destination);
src.start();
}
window.addEventListener("click", () => playTone(440));
+59
View File
@@ -0,0 +1,59 @@
#include "math.h"
__attribute__((always_inline))
static float fminf(float a, float b) {
return a < b ? a : b;
}
/* Approach 1: polynomial; input in radians. */
static float sin_poly_radians(float x)
{
x *= 0.159155f; /* approximately 1 / (2*pi) */
x -= __builtin_floorf(x); /* reduce to [0, 1) */
float xx = x * x;
float y = -6.87897f;
y = y * xx + 33.7755f;
y = y * xx - 72.5257f;
y = y * xx + 80.5874f;
y = y * xx - 41.2408f;
y = y * xx + 6.28077f;
return x * y;
}
// Approach 2: rational approximation; input in turns (1.0 = 2*pi radians)
// Calculate sin(tau x) (where x is in the range [0, 1]) using Bhaskara I's approximation
// https://en.wikipedia.org/wiki/Bhaskara_I%27s_sine_approximation_formula
// Accurate to about 0.2%
static float sin_rational_tau(float x)
{
float frac = x - __builtin_floorf(x);
float sign = 0.5f - frac;
float y = 2.0f * fminf(frac, 1.0f - frac);
float q = y * (1.0f - y);
float approximation = (16.0f * q) / (5.0f - 4.0f * q);
return __builtin_copysignf(approximation, sign);
}
/* Approach 3: folded polynomial; input in turns (1.0 = 2*pi radians). */
static float sin_folded_poly_tau(float x)
{
union { uint32_t i; float f; } coeffs[6] = {
{ 0x4261c73fu }, { 0x4113e0d9u }, { 0xc22aaa4bu },
{ 0x3da6b273u }, { 0x40c90140u }, { 0x36d0957eu }
};
float frac = x - __builtin_floorf(x);
float x1 = __builtin_fabsf(frac - 0.5f);
float t = fminf(0.5f - x1, x1); /* fold to [0, 0.25] */
float y = 0.0f;
for (int i = 0; i < 6; ++i) {
y = y * t + coeffs[i].f;
}
return __builtin_copysignf(y, 0.5f - frac);
}
float sintau(float x) {
return sin_rational_tau(x);
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef _MATH_H
#define _MATH_H
#include <stdint.h>
#define PI 3.14159265358979323846
float sintau(float x);
#endif