working dos vga writes!
This commit is contained in:
1 parent
5789cafd4e
commit
55ac075e4d
25 files changed
+454
-149
No files matched your search
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Simple fixed point bitcrash.
|
||||
https://github.com/schollz/fpfx
|
||||
*/
|
||||
|
||||
#ifndef COM_SND_BITCRSH_H
|
||||
#define COM_SND_BITCRSH_H
|
||||
|
||||
#include "../fix.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct com_snd_bitcrsh {
|
||||
uint8_t bits; /* How much to trim when triggered. */
|
||||
uint8_t reduce; /* Every Nth sample frame. */
|
||||
};
|
||||
|
||||
static void com_snd_bitcrsh_process(Bitcrush *bitcrush, int32_t *buf,
|
||||
unsigned int nr_samples) {
|
||||
for (int i = 0; i < nr_samples; i++) {
|
||||
if (i % bitcrush->reduce == 0) {
|
||||
// bitcrush fixedpoint
|
||||
buf[i] = buf[i] >> (16 - bitcrush->bits) << (16 - bitcrush->bits);
|
||||
} else {
|
||||
buf[i] = buf[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Dinky fixed point oscillators.
|
||||
https://git.poto.cafe/veclavtalica/stfu/src/branch/master/Source/oscillators.c
|
||||
*/
|
||||
|
||||
#ifndef COM_SND_OSCS_H
|
||||
#define COM_SND_OSCS_H
|
||||
|
||||
#include "../cfg.h"
|
||||
#include "../fix.h"
|
||||
#include "../std.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Intended to be executed offline with values then embedded in the binary. */
|
||||
struct com_snd_swave {
|
||||
uint16_t f, s, c;
|
||||
};
|
||||
|
||||
static struct com_snd_swave
|
||||
com_snd_swave_init(com_fix_t frequency, uint16_t phase, uint16_t amplitude) {
|
||||
com_std_assert(frequency > 0);
|
||||
struct com_snd_swave r;
|
||||
r.f = 2.f * sinf((float)M_PI * frequency / STFU_AUDIO_FRAME_RATE);
|
||||
r.s = amplitude * sinf(phase);
|
||||
r.c = amplitude * cosf(phase);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline int16_t com_snd_swave_pump(struct com_snd_swave *wave) {
|
||||
int16_t const f = com_fix_sin(com_fix_mul(
|
||||
wave->phase, com_fix_div(com_fix_mul(wave->frequency, COM_FIX_PI2),
|
||||
COM_CFG_SNDFRMRATE)));
|
||||
wave->phase += 1;
|
||||
return f;
|
||||
}
|
||||
|
||||
/* Implemented over sinewave */
|
||||
// struct com_snd_oscs_sqrtwave {
|
||||
// struct com_snd_swave w;
|
||||
// union {
|
||||
// float f;
|
||||
// uint32_t u;
|
||||
// } v;
|
||||
// } com_snd_oscs_init_sqrtwave(float frequency, float phase, float amplitude) {
|
||||
// struct com_snd_oscs_sqrtwave r;
|
||||
// union {
|
||||
// float f;
|
||||
// uint32_t u;
|
||||
// } v, a;
|
||||
// r.w = com_snd_oscs_init_sinewave(frequency, phase, 1.f);
|
||||
// v.f = r.w.s;
|
||||
// a.f = amplitude;
|
||||
// r.v.u = (a.u & 0x7fffffff) | (v.u & 0x80000000);
|
||||
// return r;
|
||||
// }
|
||||
|
||||
// /* Use floating point bit representation to infer sign, all other bits are
|
||||
// set
|
||||
// * to amplitude */
|
||||
// struct com_snd_oscs_sqrtwave
|
||||
// com_snd_oscs_pump_sqrtwave(struct com_snd_oscs_sqrtwave wave) {
|
||||
// union {
|
||||
// float f;
|
||||
// uint32_t u;
|
||||
// } v;
|
||||
// com_snd_oscs_pump_sinewave(wave.w);
|
||||
// v.f = wave.w.s;
|
||||
// wave.v.u = (wave.v.u & 0x7fffffff) | (v.u & 0x80000000);
|
||||
// return wave;
|
||||
// }
|
||||
|
||||
// struct com_snd_oscs_sawtooth {
|
||||
// float v, a, i;
|
||||
// } com_snd_oscs_init_sawtooth(float frequency, float phase, float amplitude) {
|
||||
// struct com_snd_oscs_sawtooth r;
|
||||
// r.v = sinf(phase) * amplitude;
|
||||
// r.a = amplitude;
|
||||
// r.i = 2.f * frequency / STFU_AUDIO_FRAME_RATE * amplitude;
|
||||
// return r;
|
||||
// }
|
||||
|
||||
// /* Simple amplitude overflow check with truncation */
|
||||
// struct com_snd_oscs_sawtooth
|
||||
// com_snd_oscs_pump_sawtooth(struct com_snd_oscs_sawtooth wave) {
|
||||
// wave.v += wave.i;
|
||||
// if (wave.v > wave.a)
|
||||
// wave.v -= wave.a * 2.f;
|
||||
// return wave;
|
||||
// }
|
||||
|
||||
#endif
|
||||
+2
-1
@@ -1,5 +1,4 @@
|
||||
#include "../std.h"
|
||||
#include "any.c"
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
#include <stdarg.h>
|
||||
@@ -10,6 +9,8 @@
|
||||
#include <sys/un.h>
|
||||
#include <tgmath.h>
|
||||
|
||||
#include "any.c"
|
||||
|
||||
void *com_std_alloc(void *ptr, size_t size) {
|
||||
return size != 0 ? realloc(ptr, size) : (free(ptr), NULL);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ size_t strlen(char const *s) {
|
||||
return p - s;
|
||||
}
|
||||
|
||||
#if COM_DEF_CPU == COM_DEF_CPU_AMD64 || COM_DEF_CPU == COM_DEF_CPU_X86
|
||||
|
||||
double sin(double v) {
|
||||
double r;
|
||||
__asm__ __volatile__("fsin" : "=t"(r) : "0"(v));
|
||||
@@ -49,3 +51,17 @@ double sqrt(double v) {
|
||||
__asm__ volatile("sqrtss %1, %0" : "=x"(r) : "x"(v));
|
||||
return r;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
double sin(double v) { return __builtin_sin(v); }
|
||||
|
||||
double cos(double v) { return __builtin_cos(v); }
|
||||
|
||||
void sincos(double v, double *s, double *c) {
|
||||
return __builtin_sincos(v, s, c);
|
||||
}
|
||||
|
||||
double sqrt(double v) { return __builtin_sqrt(v); }
|
||||
|
||||
#endif
|
||||
+2
-12
@@ -1,23 +1,13 @@
|
||||
#include "../std.h"
|
||||
|
||||
#include "any.c"
|
||||
#include "nolibc.c"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void *com_std_alloc(void *ptr, size_t size) { return NULL; }
|
||||
|
||||
double com_std_sqrt(double v) { return __builtin_sqrt(v); }
|
||||
double com_std_fabs(double v) { return __builtin_fabs(v); }
|
||||
#if COM_DEF_COMPILER == COM_DEF_COMPILER_CLANG
|
||||
double com_std_sin(double v) { return __builtin_sin(v); }
|
||||
double com_std_cos(double v) { return __builtin_cos(v); }
|
||||
#else
|
||||
/* TODO: Use fsin/fcos, no matter how slow. */
|
||||
double com_std_sin(double v) { return 0; }
|
||||
double com_std_cos(double v) { return 0; }
|
||||
#endif
|
||||
|
||||
com_std_fd com_std_open(char const *path, uint32_t flags) { return NULL; }
|
||||
bool com_std_write(com_std_fd fd, void const *data, uint32_t bytes) {
|
||||
return false;
|
||||
@@ -28,7 +18,7 @@ com_std_fd com_std_socket(bool isnetwork) { return NULL; }
|
||||
bool com_std_connect(com_std_fd fd, bool isnetwork, char const *address) {
|
||||
return false;
|
||||
}
|
||||
void com_std_exit(uint32_t status) {
|
||||
void com_std_exit(int32_t status) {
|
||||
__builtin_trap();
|
||||
while (1) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Centralized benchmark suite.
|
||||
*/
|
||||
|
||||
#include "fix.h"
|
||||
#include "std.h"
|
||||
#include "time.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define TEST(p_e) \
|
||||
do { \
|
||||
if (!(p_e)) { \
|
||||
com_std_print('c', COM_DEF_STRLIT(p_e) " failed!"); \
|
||||
anyfail = true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void com_bnch_fix(void) {
|
||||
uint64_t start = com_timer_count_ns();
|
||||
for (int i = 5000000; i--;) {
|
||||
com_fix_t sqrt = com_fix_sqrt(i);
|
||||
com_def_profile_sink(sqrt);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sqrt");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t sin = com_fix_sin(i);
|
||||
com_def_profile_sink(sin);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sin");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t cos = com_fix_cos(i);
|
||||
com_def_profile_sink(cos);
|
||||
}
|
||||
com_timer_profile(start, "fixed: cos");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t sin, cos;
|
||||
com_fix_sincos(i, &sin, &cos);
|
||||
com_fix_t sinv = sin;
|
||||
com_fix_t cosv = cos;
|
||||
com_def_profile_sink(sinv);
|
||||
com_def_profile_sink(cosv);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sincos");
|
||||
}
|
||||
|
||||
static void com_bnch_run(void) { com_bnch_fix(); }
|
||||
|
||||
#undef TEST
|
||||
@@ -19,4 +19,9 @@
|
||||
|
||||
#define COM_CFG_FBSIZE (COM_CFG_WIDTH * COM_CFG_HEIGHT * COM_CFG_COLORS)
|
||||
|
||||
#define COM_CFG_SNDFRMRATE 44100
|
||||
|
||||
/* TODO: Generate file with precompiled note frequencies. */
|
||||
#define COM_CFG_A4FIX (440 << COM_FIX_FRACBITS)
|
||||
|
||||
#endif
|
||||
@@ -70,37 +70,3 @@ com_fix_t com_fix_sqrt(com_fix_t a) {
|
||||
return final_shift > 0 ? (int32_t)(x << final_shift)
|
||||
: (int32_t)(x >> (-final_shift));
|
||||
}
|
||||
|
||||
void com_fix_run_bench(void) {
|
||||
uint64_t start = com_timer_count_ns();
|
||||
for (int i = 5000000; i--;) {
|
||||
com_fix_t sqrt = com_fix_sqrt(i);
|
||||
com_def_profile_sink(sqrt);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sqrt");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t sin = com_fix_sin(i);
|
||||
com_def_profile_sink(sin);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sin");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t cos = com_fix_cos(i);
|
||||
com_def_profile_sink(cos);
|
||||
}
|
||||
com_timer_profile(start, "fixed: cos");
|
||||
|
||||
start = com_timer_count_ns();
|
||||
for (int i = 50000000; i--;) {
|
||||
com_fix_t sin, cos;
|
||||
com_fix_sincos(i, &sin, &cos);
|
||||
com_fix_t sinv = sin;
|
||||
com_fix_t cosv = cos;
|
||||
com_def_profile_sink(sinv);
|
||||
com_def_profile_sink(cosv);
|
||||
}
|
||||
com_timer_profile(start, "fixed: sincos");
|
||||
}
|
||||
+5
-5
@@ -23,9 +23,6 @@ typedef int32_t com_fix_t;
|
||||
|
||||
extern const uint16_t com_fix_sin_lut[128];
|
||||
|
||||
void com_fix_run_tests(void);
|
||||
void com_fix_run_bench(void);
|
||||
|
||||
static inline com_fix_t com_fix_add(com_fix_t a, com_fix_t b) { return a + b; }
|
||||
|
||||
static inline com_fix_t com_fix_sub(com_fix_t a, com_fix_t b) { return a - b; }
|
||||
@@ -64,6 +61,7 @@ static inline com_fix_t com_fix_floor(com_fix_t const a) {
|
||||
com_fix_t com_fix_sqrt(com_fix_t a);
|
||||
|
||||
/* Approximated using LUT. */
|
||||
/* Integer part only houses sign. */
|
||||
/* TODO: test whether linearly interpolated version could be default. */
|
||||
/* things like camera movement can be jarring if done without.*/
|
||||
/* https://namoseley.wordpress.com/2015/07/26/sincos-generation-using-table-lookup-and-iterpolation/
|
||||
@@ -90,9 +88,11 @@ static inline com_fix_t com_fix_sin(com_fix_t q) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline com_fix_t com_fix_sin_from_lut(uint8_t l) {
|
||||
return com_fix_sin_lut[l];
|
||||
}
|
||||
|
||||
/* Implemented over sin, as to share one single LUT. */
|
||||
/* Additionally, optimizer probably can collapse some math for combined sincos
|
||||
* case. */
|
||||
static inline com_fix_t com_fix_cos(com_fix_t a) {
|
||||
return com_fix_sin(a + COM_FIX_PIHALF);
|
||||
}
|
||||
|
||||
+18
-14
@@ -6,6 +6,8 @@
|
||||
#ifndef COM_STD_H
|
||||
#define COM_STD_H
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -40,20 +42,6 @@ void com_std_close(com_std_fd fd);
|
||||
/* Note: Freeing is done by passing 0 size to pointer. */
|
||||
void *com_std_alloc(void *ptr, size_t size);
|
||||
|
||||
/* Note: Functions listed below are only available for dev builds. */
|
||||
/* Trigonometry functions are for reference testing of our own fixed point
|
||||
* implementations. Do not use otherwise. */
|
||||
#define com_std_assert(p_h) \
|
||||
do { \
|
||||
if (!(p_h)) { \
|
||||
const char msg[] = \
|
||||
"Assertion failed at "__FILE__ \
|
||||
":" COM_DEF_STRLIT(__LINE__) ": " COM_DEF_STRLIT(p_h); \
|
||||
com_std_print_str(msg, sizeof msg, true); \
|
||||
com_std_exit(-1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
Basic printing utility that doesn't utilize format string.
|
||||
Instead a vector of arguments is passed and concatenated, based on type.
|
||||
@@ -81,9 +69,25 @@ void com_std_print_(int32_t start, ...);
|
||||
#define com_std_print(...) com_std_print_(__VA_ARGS__, '.')
|
||||
void com_std_print_str(char const *str, uint32_t len, bool newline);
|
||||
|
||||
#define COM_STD_PIF ((float)3.14159265358979323846)
|
||||
|
||||
double com_std_sqrt(double v);
|
||||
double com_std_fabs(double v);
|
||||
double com_std_sin(double v);
|
||||
double com_std_cos(double v);
|
||||
|
||||
/* Note: Functions listed below are only available for dev builds. */
|
||||
/* Trigonometry functions are for reference testing of our own fixed point
|
||||
* implementations. Do not use otherwise. */
|
||||
#define com_std_assert(p_h) \
|
||||
do { \
|
||||
if (!(p_h)) { \
|
||||
const char msg[] = \
|
||||
"Assertion failed at "__FILE__ \
|
||||
":" COM_DEF_STRLIT(__LINE__) ": " COM_DEF_STRLIT(p_h); \
|
||||
com_std_print_str(msg, sizeof msg, true); \
|
||||
com_std_exit(-1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -49,7 +49,7 @@ static inline int32_t com_str_ext_find_char(char const *s, char ch) {
|
||||
static inline bool com_str_ext_prefixed(char const *__restrict a,
|
||||
struct com_str const *prefix) {
|
||||
uint32_t n = prefix->len;
|
||||
char *b = prefix->data;
|
||||
char const *b = prefix->data;
|
||||
while (n && *a && (*a == *b)) {
|
||||
++a;
|
||||
++b;
|
||||
|
||||
Reference in new issue
Block a user