Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,123 @@
#include <stdint.h>
#include "fft.h"
#define PI_FLOAT 3.14159265358979323846f
static uint32_t bitReverseUint32(uint32_t value, uint32_t log2N);
static uint32_t log2Unsigned(uint32_t n) {
uint32_t res = 0;
while (n >>= 1) {
res++;
}
return res;
}
void aura_ditfft2(const aura_complex_t * times, int t, aura_complex_t * freqs, int f, int n, int step, bool inverse) {
if (n == 1) {
aura_copy_complex_elem(freqs, f, times, t);
}
else {
const int halfLen = n >> 1;
aura_ditfft2(times, t, freqs, f, halfLen, step << 1, inverse);
aura_ditfft2(times, t + step, freqs, f + halfLen, halfLen, step << 1, inverse);
const float t_exp = ((inverse ? 1.0f : -1.0f) * 2.0f * PI_FLOAT) / n;
for (int k = 0; k < halfLen; k++) {
aura_complex_t even = { 0 };
aura_complex_t odd = { 0 };
aura_copy_complex(&even, freqs[f + k]);
aura_copy_complex(&odd, freqs[f + k + halfLen]);
const aura_complex_t twiddle = aura_cmult(aura_cexp(t_exp * k), odd);
aura_copy_complex(&(freqs[f + k]), aura_cadd(even, twiddle));
aura_copy_complex(&(freqs[f + k + halfLen]), aura_csub(even, twiddle));
}
}
}
void aura_ditfft2_iterative(const aura_complex_t * times, aura_complex_t * freqs, int n, bool inverse, const aura_complex_t * exp_lut) {
// Decimate
const uint32_t log2N = log2Unsigned(n);
for (uint32_t i = 0; i < ((uint32_t) n); i++) {
uint32_t reversedI = bitReverseUint32(i, log2N);
if (reversedI >= i) {
aura_copy_complex(&freqs[i], times[reversedI]);
aura_copy_complex(&freqs[reversedI], times[i]);
}
else if (reversedI == i) {
aura_copy_complex(&freqs[reversedI], times[i]);
}
}
int halfLayerIdx = 0;
for (int layerSize = 2; layerSize <= n; layerSize <<= 1) {
const int halfLayerSize = layerSize >> 1;
aura_complex_t expRotationStep;
aura_copy_complex(&expRotationStep, exp_lut[halfLayerIdx]);
if (inverse) {
expRotationStep = aura_cconj(expRotationStep);
}
for (int sectionOffset = 0; sectionOffset < n; sectionOffset += layerSize) {
aura_complex_t currentExpRotation = {.real = 1.0, .imag = 0.0};
for (int i = 0; i < halfLayerSize; i++) {
aura_complex_t even;
aura_complex_t odd;
aura_copy_complex(&even, freqs[sectionOffset + i]);
aura_copy_complex(&odd, freqs[sectionOffset + i + halfLayerSize]);
const aura_complex_t twiddle = aura_cmult(currentExpRotation, odd);
aura_copy_complex(&(freqs[sectionOffset + i]), aura_cadd(even, twiddle));
aura_copy_complex(&(freqs[sectionOffset + i + halfLayerSize]), aura_csub(even, twiddle));
aura_copy_complex(&currentExpRotation, aura_cmult(currentExpRotation, expRotationStep));
}
}
halfLayerIdx++;
}
}
/**
The following bit reversal code is taken (and slightly changed) from
https://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable.
The original sources are released in the public domain.
**/
// Lookup table for bit reversal where each entry is one possible byte
static const uint8_t bitReverseTable[] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
static uint32_t bitReverseUint32(uint32_t value, uint32_t log2N) {
return ((uint32_t)(
(bitReverseTable[ value & 0xff] << 24) |
(bitReverseTable[(value >> 8 ) & 0xff] << 16) |
(bitReverseTable[(value >> 16) & 0xff] << 8 ) |
(bitReverseTable[(value >> 24) & 0xff] )
) >> (32 - log2N));
}

View File

@ -0,0 +1,16 @@
#pragma once
#include <stdbool.h>
#include "common_c/types/complex_t.h"
#ifdef __cplusplus
extern "C" {
#endif
void aura_ditfft2(const aura_complex_t * times, int t, aura_complex_t * freqs, int f, int n, int step, bool inverse);
void aura_ditfft2_iterative(const aura_complex_t * times, aura_complex_t * freqs, int n, bool inverse, const aura_complex_t * exp_lut);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,21 @@
#include <stdlib.h>
#include "complex_array.h"
aura_complex_t* aura_complex_array_alloc(int length) {
return calloc(length, sizeof(aura_complex_t));
}
void aura_complex_array_free(aura_complex_t* complex_array) {
free(complex_array);
}
aura_complex_t* aura_complex_array_set(aura_complex_t* complex_array, int index, float real, float imag) {
complex_array[index].real = real;
complex_array[index].imag = imag;
return &(complex_array[index]);
}
aura_complex_t* aura_complex_array_get(aura_complex_t* complex_array, int index) {
return &(complex_array[index]);
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "common_c/types/complex_t.h"
#ifdef __cplusplus
extern "C" {
#endif
aura_complex_t* aura_complex_array_alloc(int length);
void aura_complex_array_free(aura_complex_t* complex_array);
aura_complex_t* aura_complex_array_set(aura_complex_t* complex_array, int index, float real, float imag);
aura_complex_t* aura_complex_array_get(aura_complex_t* complex_array, int index);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,41 @@
#include <math.h>
#include "complex_t.h"
void aura_copy_complex_elem(aura_complex_t *to, const int toIndex, const aura_complex_t *from, const int fromIndex) {
to[toIndex].real = from[fromIndex].real;
to[toIndex].imag = from[fromIndex].imag;
}
void aura_copy_complex(aura_complex_t *to, const aura_complex_t from) {
to->real = from.real;
to->imag = from.imag;
}
aura_complex_t aura_cexp(const float w) {
const aura_complex_t out = {.real = cosf(w), .imag = sinf(w)};
return out;
}
aura_complex_t aura_cadd(const aura_complex_t a, const aura_complex_t b) {
const aura_complex_t out = {.real = a.real + b.real, .imag = a.imag + b.imag};
return out;
}
aura_complex_t aura_csub(const aura_complex_t a, const aura_complex_t b) {
const aura_complex_t out = {.real = a.real - b.real, .imag = a.imag - b.imag};
return out;
}
aura_complex_t aura_cmult(const aura_complex_t a, const aura_complex_t b) {
const aura_complex_t out = {
.real = a.real * b.real - a.imag * b.imag,
.imag = a.real * b.imag + a.imag * b.real
};
return out;
}
aura_complex_t aura_cconj(const aura_complex_t val) {
const aura_complex_t out = {.real = val.real, .imag = -val.imag};
return out;
}

View File

@ -0,0 +1,24 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct aura_complex_t {
float real;
float imag;
} aura_complex_t;
void aura_copy_complex_elem(aura_complex_t *to, const int toIndex, const aura_complex_t *from, const int fromIndex);
void aura_copy_complex(aura_complex_t *to, const aura_complex_t from);
aura_complex_t aura_cexp(const float w);
aura_complex_t aura_cadd(const aura_complex_t a, const aura_complex_t b);
aura_complex_t aura_csub(const aura_complex_t a, const aura_complex_t b);
aura_complex_t aura_cmult(const aura_complex_t a, const aura_complex_t b);
aura_complex_t aura_cconj(const aura_complex_t val);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
// Keep this file so that the headers are included in the compilation
#include "hl/aura/math/fft.h"
#include "hl/aura/types/complex_array.h"

View File

@ -0,0 +1,3 @@
#pragma once
#define AURA_HL_FUNC(n) aura_hl_##n

View File

@ -0,0 +1,28 @@
#pragma once
#include <hl.h>
#include <aura/types/_ComplexArray/HL_ComplexArrayImpl.h>
#include "hl/aura/aurahl.h"
#include "common_c/math/fft.h"
#include "common_c/types/complex_t.h"
HL_PRIM void AURA_HL_FUNC(ditfft2)(aura__types___ComplexArray__HL_ComplexArrayImpl time_array, int t, aura__types___ComplexArray__HL_ComplexArrayImpl freq_array, int f, int n, int step, bool inverse) {
const aura_complex_t *times = (aura_complex_t*) time_array->self;
aura_complex_t *freqs = (aura_complex_t*) freq_array->self;
aura_ditfft2(times, t, freqs, f, n, step, inverse);
}
HL_PRIM void AURA_HL_FUNC(ditfft2_iterative)(aura__types___ComplexArray__HL_ComplexArrayImpl time_array, aura__types___ComplexArray__HL_ComplexArrayImpl freq_array, int n, bool inverse, aura__types___ComplexArray__HL_ComplexArrayImpl exp_rotation_step_table) {
const aura_complex_t *times = (aura_complex_t*) time_array->self;
aura_complex_t *freqs = (aura_complex_t*) freq_array->self;
const aura_complex_t *exp_lut = (aura_complex_t*) exp_rotation_step_table->self;
aura_ditfft2_iterative(times, freqs, n, inverse, exp_lut);
}
DEFINE_PRIM(_VOID, ditfft2, _BYTES _I32 _BYTES _I32 _I32 _I32 _BOOL)
DEFINE_PRIM(_VOID, ditfft2_iterative, _BYTES _BYTES _I32 _BOOL _BYTES)

View File

@ -0,0 +1,29 @@
#pragma once
#include <hl.h>
#include "hl/aura/aurahl.h"
#include "common_c/types/complex_array.h"
#include "common_c/types/complex_t.h"
HL_PRIM vbyte* AURA_HL_FUNC(complex_array_alloc)(int length) {
return (vbyte*) aura_complex_array_alloc(length);
}
HL_PRIM void AURA_HL_FUNC(complex_array_free)(vbyte* complex_array) {
aura_complex_array_free((aura_complex_t*) complex_array);
}
HL_PRIM aura_complex_t* AURA_HL_FUNC(complex_array_set)(vbyte* complex_array, int index, float real, float imag) {
return aura_complex_array_set((aura_complex_t *) complex_array, index, real, imag);
}
HL_PRIM aura_complex_t* AURA_HL_FUNC(complex_array_get)(vbyte* complex_array, int index) {
return aura_complex_array_get((aura_complex_t*) complex_array, index);
}
DEFINE_PRIM(_BYTES, complex_array_alloc, _I32)
DEFINE_PRIM(_VOID, complex_array_free, _BYTES)
DEFINE_PRIM(_REF(_aura__types___Complex__ComplexImpl), complex_array_set, _BYTES _I32 _F32 _F32)
DEFINE_PRIM(_REF(_aura__types___Complex__ComplexImpl), complex_array_get, _BYTES _I32)

View File

@ -0,0 +1,8 @@
const project = new Project("aura-hl");
project.addIncludeDir("../");
project.addFile("../common_c/**");
project.addFile("aura/**");
resolve(project);

View File

@ -0,0 +1,41 @@
# Aura Backends
The `/Backends` directory contains target-specific code that may be used on some
targets to improve performance.
The backends are enabled by default, but if you want to only use the generic
Haxe sources (for performance comparisons e.g.), compile your Kha project with
the command line flag `--aura-no-backend`.
## Folder Structure
- `/common_c`:
Pure C code that can be used by multiple backends.
- `/hl`:
Sources/headers for the Hashlink/C backend. The header files are mostly
Hashlink API wrappers around the code in `/common_c`.
Most of the backend sources mirror the respective Haxe code, so please don't
expect much documentation for the individual functions.
The Haxe implementation/glue code for the backends is in Aura's source files in
`/Sources`. There are no Haxe files in the `/backend` folder that shadow
original sources to reduce redundancy and ensure completeness of the API.
Instead, there is usually a static class per backend implementation at the
bottom of a Haxe source module, whose methods are then called and inlined from
the original class if the [backend specific define is set](#defines). This way
all the Haxe functionality for a module stays inside a module and is not
distributed in many per-backend Haxe files, which also keeps the API consistent
for each target.
## Defines
If the backends are enabled, Aura sets some defines before compilation which are
based on the Haxe target to which the project is compiled. They should only be
used internally, but for the sake of completeness they are documented here:
- `AURA_NO_BACKEND`: Defined if backends are disabled.
- `AURA_BACKEND_HL`: Defined if backends are enabled and the project is compiled
to a Hashlink target.