mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
36
dsp/core/byte2double.c
Normal file
36
dsp/core/byte2double.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
void *byte2double(long n, const void *p, double weight, double bias) {
|
||||
long i;
|
||||
double f, *dst;
|
||||
unsigned char *src;
|
||||
if ((dst = valloc(n * sizeof(double)))) {
|
||||
for (src = p, i = 0; i < n; ++i) {
|
||||
f = src[i];
|
||||
f -= bias;
|
||||
f *= 1 / weight;
|
||||
dst[i] = f;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
22
dsp/core/c11.h
Normal file
22
dsp/core/c11.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C11_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C11_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Fixed-point 8-bit rounded mean kernel.
|
||||
*
|
||||
* @define (a + b) / 2
|
||||
*/
|
||||
static inline pureconst artificial unsigned char C11(unsigned char al,
|
||||
unsigned char bl) {
|
||||
short ax;
|
||||
ax = al;
|
||||
ax += bl;
|
||||
ax += 1;
|
||||
ax /= 2;
|
||||
al = ax;
|
||||
return al;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C11_H_ */
|
21
dsp/core/c121.h
Normal file
21
dsp/core/c121.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C121_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C121_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
forceinline pureconst artificial unsigned char C121(unsigned char al,
|
||||
unsigned char bl,
|
||||
unsigned char cl) {
|
||||
unsigned short ax, bx;
|
||||
ax = al;
|
||||
ax += bl;
|
||||
ax += bl;
|
||||
ax += cl;
|
||||
ax += 2;
|
||||
ax >>= 2;
|
||||
return ax;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C121_H_ */
|
19
dsp/core/c121s.h
Normal file
19
dsp/core/c121s.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C121S_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C121S_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline pureconst artificial signed char C121S(signed char al,
|
||||
signed char bl,
|
||||
signed char cl) {
|
||||
short ax, bx;
|
||||
ax = al;
|
||||
ax += bl;
|
||||
ax += bl;
|
||||
ax += cl;
|
||||
ax += 2;
|
||||
ax >>= 2;
|
||||
return ax;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C121S_H_ */
|
30
dsp/core/c1331.h
Normal file
30
dsp/core/c1331.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C1331_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C1331_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Byte sized kernel for resampling memory in half.
|
||||
*
|
||||
* @define (1*𝑎 + 3*𝑏 + 3*𝑐 + 1*𝑑) / (1 + 3 + 3 + 1)
|
||||
* @see C161() afterward for superior sin(𝑥)/𝑥
|
||||
* @limit [0,255] → [0..2,044] → [0..255]
|
||||
*/
|
||||
forceinline pureconst artificial unsigned char C1331(unsigned char al,
|
||||
unsigned char bl,
|
||||
unsigned char cl,
|
||||
unsigned char dl) {
|
||||
short ax, bx;
|
||||
bx = bl;
|
||||
bx += cl;
|
||||
bx *= 3;
|
||||
ax = al;
|
||||
ax += dl;
|
||||
ax += bx;
|
||||
ax += 4;
|
||||
ax >>= 3;
|
||||
al = ax;
|
||||
return al;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C1331_H_ */
|
28
dsp/core/c1331s.h
Normal file
28
dsp/core/c1331s.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C1331S_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C1331S_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Byte sized kernel for resampling difference samples in half.
|
||||
*
|
||||
* @define (1*(a-128)+3*(a-128)+3*(a-128)+1*(a-128))/(1+3+3+1)+128
|
||||
* @see C1331(), Y420CbCr2RgbScale()
|
||||
*/
|
||||
forceinline pureconst artificial signed char C1331S(signed char al,
|
||||
signed char bl,
|
||||
signed char cl,
|
||||
signed char dl) {
|
||||
short ax, bx;
|
||||
bx = bl;
|
||||
bx += cl;
|
||||
bx *= 3;
|
||||
ax = al;
|
||||
ax += dl;
|
||||
ax += bx;
|
||||
ax += 4;
|
||||
ax >>= 3;
|
||||
return ax;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C1331S_H_ */
|
33
dsp/core/c161.h
Normal file
33
dsp/core/c161.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C161_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C161_H_
|
||||
#include "libc/macros.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define EXTRA_SHARP 2
|
||||
|
||||
/**
|
||||
* Byte sized kernel for restoring sharpness of resampled memory.
|
||||
*
|
||||
* @define CLAMP[(-1*𝑎 + 6*𝑏 + -1*𝑐) / (-1 + 6 + -1)]
|
||||
* @limit [0..255] → [-510..1,532] → [-127..383] → [0..255]
|
||||
* @see C1331()
|
||||
*/
|
||||
forceinline pureconst artificial unsigned char C161(unsigned char al,
|
||||
unsigned char bl,
|
||||
unsigned char cl) {
|
||||
short ax, bx, cx;
|
||||
ax = al;
|
||||
bx = bl;
|
||||
cx = cl;
|
||||
ax *= -1;
|
||||
bx *= +6;
|
||||
cx *= -1;
|
||||
ax += bx;
|
||||
ax += cx;
|
||||
ax += 2;
|
||||
ax >>= 2;
|
||||
return MIN(255, MAX(0, ax));
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C161_H_ */
|
26
dsp/core/c161s.h
Normal file
26
dsp/core/c161s.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C161S_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C161S_H_
|
||||
#include "dsp/core/c161.h"
|
||||
#include "libc/macros.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline pureconst artificial signed char C161S(signed char al,
|
||||
signed char bl,
|
||||
signed char cl) {
|
||||
short ax, bx, cx;
|
||||
ax = al;
|
||||
bx = bl;
|
||||
cx = cl;
|
||||
ax *= -1 * EXTRA_SHARP;
|
||||
bx *= 6 * EXTRA_SHARP;
|
||||
cx *= -1 * EXTRA_SHARP;
|
||||
ax += bx;
|
||||
ax += cx;
|
||||
ax += 2 * EXTRA_SHARP;
|
||||
ax /= 4 * EXTRA_SHARP;
|
||||
al = MIN(112, MAX(-112, ax));
|
||||
return al;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C161S_H_ */
|
30
dsp/core/c331.h
Normal file
30
dsp/core/c331.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_C331_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_C331_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* Fixed-point 8-bit magic edge resampling kernel.
|
||||
*
|
||||
* @define (3*a + 3*b + 1*c) / 7
|
||||
* @see C1331()
|
||||
*/
|
||||
static inline pureconst artificial unsigned char C331(unsigned char al,
|
||||
unsigned char bl,
|
||||
unsigned char cl) {
|
||||
unsigned eax, ebx, ecx;
|
||||
eax = al;
|
||||
ebx = bl;
|
||||
ecx = cl;
|
||||
eax += ebx;
|
||||
eax *= 3 * 2350;
|
||||
ecx *= 1 * 2350;
|
||||
eax += ecx;
|
||||
eax >>= 14;
|
||||
al = eax;
|
||||
return al;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_C331_H_ */
|
37
dsp/core/core.h
Normal file
37
dsp/core/core.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_CORE_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_CORE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* @fileoverview Cosmopolitan Digital Signal Processing.
|
||||
*/
|
||||
|
||||
int mulaw(int);
|
||||
void *double2byte(long, const void *, double, double) vallocesque;
|
||||
void *byte2double(long, const void *, double, double) vallocesque;
|
||||
|
||||
void *dct(float[8][8], float, float, float, float, float);
|
||||
void *dctjpeg(float[8][8]);
|
||||
|
||||
double det3(const double[3][3]) nosideeffect;
|
||||
void *inv3(double[restrict 3][3], const double[restrict 3][3], double);
|
||||
void *matmul3(double[restrict 3][3], const double[3][3], const double[3][3]);
|
||||
void *vmatmul3(double[restrict 3], const double[3], const double[3][3]);
|
||||
void *matvmul3(double[restrict 3], const double[3][3], const double[3]);
|
||||
|
||||
double rgb2stdtv(double) pureconst;
|
||||
double rgb2lintv(double) pureconst;
|
||||
double rgb2stdpc(double, double) pureconst;
|
||||
double rgb2linpc(double, double) pureconst;
|
||||
double tv2pcgamma(double, double) pureconst;
|
||||
|
||||
#ifndef __cplusplus
|
||||
void sad16x8n(size_t n, short[n][8], const short[n][8]);
|
||||
void float2short(size_t n, short[n][8], const float[n][8]);
|
||||
void scalevolume(size_t n, int16_t[n][8], int);
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_CORE_H_ */
|
69
dsp/core/core.mk
Normal file
69
dsp/core/core.mk
Normal file
|
@ -0,0 +1,69 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += DSP_CORE
|
||||
|
||||
DSP_CORE_ARTIFACTS += DSP_CORE_A
|
||||
DSP_CORE = $(DSP_CORE_A_DEPS) $(DSP_CORE_A)
|
||||
DSP_CORE_A = o/$(MODE)/dsp/core/core.a
|
||||
DSP_CORE_A_FILES := $(wildcard dsp/core/*)
|
||||
DSP_CORE_A_HDRS = $(filter %.h,$(DSP_CORE_A_FILES))
|
||||
DSP_CORE_A_SRCS_S = $(filter %.S,$(DSP_CORE_A_FILES))
|
||||
DSP_CORE_A_SRCS_C = $(filter %.c,$(DSP_CORE_A_FILES))
|
||||
|
||||
DSP_CORE_A_SRCS = \
|
||||
$(DSP_CORE_A_SRCS_S) \
|
||||
$(DSP_CORE_A_SRCS_C)
|
||||
|
||||
DSP_CORE_A_OBJS = \
|
||||
$(DSP_CORE_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(DSP_CORE_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(DSP_CORE_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
DSP_CORE_A_CHECKS = \
|
||||
$(DSP_CORE_A).pkg \
|
||||
$(DSP_CORE_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
DSP_CORE_A_DIRECTDEPS = \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_MEM \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_STUBS
|
||||
|
||||
DSP_CORE_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(DSP_CORE_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(DSP_CORE_A): dsp/core/ \
|
||||
$(DSP_CORE_A).pkg \
|
||||
$(DSP_CORE_A_OBJS)
|
||||
|
||||
$(DSP_CORE_A).pkg: \
|
||||
$(DSP_CORE_A_OBJS) \
|
||||
$(foreach x,$(DSP_CORE_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/dsp/core/dct.o \
|
||||
o/$(MODE)/dsp/core/c1331.o \
|
||||
o/$(MODE)/dsp/core/magikarp.o \
|
||||
o/$(MODE)/dsp/core/c93654369.o \
|
||||
o/$(MODE)/dsp/core/float2short.o \
|
||||
o/$(MODE)/dsp/core/scalevolume.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
$(MATHEMATICAL)
|
||||
|
||||
o/tiny/dsp/core/scalevolume.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
o/$(MODE)/dsp/core/det3.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffast-math
|
||||
|
||||
DSP_CORE_LIBS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)))
|
||||
DSP_CORE_SRCS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_SRCS))
|
||||
DSP_CORE_HDRS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_HDRS))
|
||||
DSP_CORE_CHECKS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_CHECKS))
|
||||
DSP_CORE_OBJS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_OBJS))
|
||||
$(DSP_CORE_OBJS): $(BUILD_FILES) dsp/core/core.mk
|
||||
|
||||
.PHONY: o/$(MODE)/dsp/core
|
||||
o/$(MODE)/dsp/core: $(DSP_CORE_CHECKS)
|
85
dsp/core/dct.c
Normal file
85
dsp/core/dct.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
#define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \
|
||||
do { \
|
||||
T z1, z2, z3, z4, z5, z11, z13; \
|
||||
T t0, t1, t2, t3, t4, t5, t6, t7, t8, t10, t11, t12, t13; \
|
||||
t0 = A + H; \
|
||||
t7 = A - H; \
|
||||
t1 = B + G; \
|
||||
t6 = B - G; \
|
||||
t2 = C + F; \
|
||||
t5 = C - F; \
|
||||
t3 = D + E; \
|
||||
t4 = D - E; \
|
||||
t10 = t0 + t3; \
|
||||
t13 = t0 - t3; \
|
||||
t11 = t1 + t2; \
|
||||
t12 = t1 - t2; \
|
||||
A = t10 + t11; \
|
||||
E = t10 - t11; \
|
||||
z1 = (t12 + t13) * C0; \
|
||||
C = t13 + z1; \
|
||||
G = t13 - z1; \
|
||||
t10 = t4 + t5; \
|
||||
t11 = t5 + t6; \
|
||||
t12 = t6 + t7; \
|
||||
z5 = (t10 - t12) * C1; \
|
||||
z2 = t10 * C2 + z5; \
|
||||
z4 = t12 * C3 + z5; \
|
||||
z3 = t11 * C4; \
|
||||
z11 = t7 + z3; \
|
||||
z13 = t7 - z3; \
|
||||
F = z13 + z2; \
|
||||
D = z13 - z2; \
|
||||
B = z11 + z4; \
|
||||
H = z11 - z4; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Performs float forward discrete cosine transform.
|
||||
*
|
||||
* This takes a tiny block of image data and shoves the information it
|
||||
* represents into the top left corner. It can be reversed using idct().
|
||||
* It matters because iterating the result in a serpentine pattern makes
|
||||
* run-length delta encoding super effective. Furthermore, data downward
|
||||
* rightly may be divided away for lossy compression.
|
||||
*
|
||||
* @cost ~100ns
|
||||
*/
|
||||
void *dct(float M[8][8], float c0, float c1, float c2, float c3, float c4) {
|
||||
unsigned y, x;
|
||||
for (y = 0; y < 8; ++y) {
|
||||
DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7],
|
||||
float, c0, c1, c2, c3, c4);
|
||||
}
|
||||
for (x = 0; x < 8; ++x) {
|
||||
DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x],
|
||||
float, c0, c1, c2, c3, c4);
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
void *dctjpeg(float M[8][8]) {
|
||||
return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f,
|
||||
.707106781f);
|
||||
}
|
36
dsp/core/det3.c
Normal file
36
dsp/core/det3.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
#define LEIBNIZ_FORMULA(a, b, c, d, e, f, g, h, i) \
|
||||
(a * e * i + b * f * g + c * d * h - c * e * g - b * d * i - a * f * h)
|
||||
|
||||
/**
|
||||
* Computes determinant of 3×3 matrix.
|
||||
* i.e. how much space is inside the cube
|
||||
*
|
||||
* @param 𝐀 is input matrix
|
||||
* @param 𝑑 is det(𝐀)
|
||||
* @return |𝐀| or 0 if degenerate
|
||||
*/
|
||||
double det3(const double A[3][3]) {
|
||||
return LEIBNIZ_FORMULA(A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], A[1][2],
|
||||
A[2][0], A[2][1], A[2][2]);
|
||||
}
|
67
dsp/core/differsumsq.c
Normal file
67
dsp/core/differsumsq.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
/**
|
||||
* Computes Σ𝑥ᵢΣ𝑥ⱼΣ𝑥ₖΣ𝑥ₗΣ𝑥ₘΣ𝑥ₙ(δ₁𝑥ᵢ+δ₂𝑥ⱼ+δ₃𝑥ₖ+δ₄𝑥ₗ+δ₅𝑥ₘ+δ₆𝑥ₙ)² over 𝐿..𝐻
|
||||
*
|
||||
* “As soon as an Analytical Engine exists, it will necessarily
|
||||
* guide the future course of the science. Whenever any result
|
||||
* is sought by its aid, the question will then arise — by what
|
||||
* course of calculation can these results be arrived at by the
|
||||
* machine in the shortest time?
|
||||
*
|
||||
* — Charles Babbage (Life of a Philosopher, 1864)
|
||||
*
|
||||
* @see itu.int/rec/R-REC-BT.601/
|
||||
*/
|
||||
double DifferSumSq(const double D[static 6], double L, double H) {
|
||||
double T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T2, T20, T21, T22,
|
||||
T23, T24, T25, T26, T27, T3, T4, T5, T6, T7, T8, T9;
|
||||
T2 = H * H, T3 = (H * H * H), T4 = (H * H * H * H), T5 = (H * H * H * H * H),
|
||||
T6 = (H * H * H * H * H * H), T7 = -10 * H, T8 = (H * H * H * H * H * H * H),
|
||||
T9 = (L * L * L * L * L * L * L * L), T10 = (L * L * L * L * L * L * L),
|
||||
T11 = (L * L * L * L * L * L), T12 = (L * L * L * L * L), T13 = -45 * T2,
|
||||
T14 = (L * L * L * L), T15 = 180 * T3, T16 = 120 * T2, T17 = (L * L * L),
|
||||
T18 = L * L, T19 = 18 * T2, T20 = (H * H * H * H * H * H * H * H);
|
||||
T21 = 45 * T4;
|
||||
T22 = 3 * T9 + (-12 * H - 18) * T10 + (12 * T2 + 54 * H + 45) * T11 +
|
||||
(12 * T3 - T19 - 90 * H - 60) * T12 +
|
||||
(-30 * T4 - 90 * T3 + T13 + 60 * H + 45) * T14 +
|
||||
(12 * T5 + 90 * T4 + T15 + T16 - 18) * T17 +
|
||||
(12 * T6 + 18 * T5 - T21 - 120 * T3 - 90 * T2 - 18 * H + 3) * T18 +
|
||||
(-12 * T8 - 54 * T6 - 90 * T5 - 60 * T4 + T19 + 6 * H) * L + 3 * T20 +
|
||||
18 * T8 + 45 * T6 + 60 * T5 + T21 + 18 * T3 + 3 * T2;
|
||||
T23 =
|
||||
2 * T9 + (T7 - 13) * T10 + (20 * T2 + 55 * H + 36) * T11 +
|
||||
(-22 * T3 - 93 * T2 - 126 * H - 55) * T12 +
|
||||
(20 * T4 + 95 * T3 + 180 * T2 + 155 * H + 50) * T14 +
|
||||
(-22 * T5 - 95 * T4 - T15 - 190 * T2 - 110 * H - 27) * T17 +
|
||||
(20 * T6 + 93 * T5 + 180 * T4 + 190 * T3 + T16 + 45 * H + 8) * T18 +
|
||||
(-10 * T8 - 55 * T6 - 126 * T5 - 155 * T4 - 110 * T3 + T13 + T7 - 1) * L +
|
||||
2 * T20 + 13 * T8 + 36 * T6 + 55 * T5 + 50 * T4 + 27 * T3 + 8 * T2 + H;
|
||||
T24 = T22 * D[3], T25 = T22 * D[2], T26 = T22 * D[1], T27 = T22 * D[0];
|
||||
return (T23 * D[5] * D[5] + (T22 * D[4] + T24 + T25 + T26 + T27) * D[5] +
|
||||
T23 * D[4] * D[4] + (T24 + T25 + T26 + T27) * D[4] +
|
||||
T23 * D[3] * D[3] + (T25 + T26 + T27) * D[3] + T23 * D[2] * D[2] +
|
||||
(T26 + T27) * D[2] + T23 * D[1] * D[1] + T22 * D[0] * D[1] +
|
||||
T23 * D[0] * D[0]) /
|
||||
6;
|
||||
}
|
463
dsp/core/differsumsq8.c
Normal file
463
dsp/core/differsumsq8.c
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/q.h"
|
||||
|
||||
/**
|
||||
* Computes Σ𝑥ᵢΣ𝑥ⱼΣ𝑥ₖΣ𝑥ₗΣ𝑥ₘΣ𝑥ₙΣ𝑥ₚΣ𝑥ₛ(δ₁𝑥ᵢ+δ₂𝑥ⱼ+δ₃𝑥ₖ+δ₄𝑥ₗ+δ₅𝑥ₘ+δ₆𝑥ₙ+δₚ𝑥ₚ+δₛ𝑥ₛ)²
|
||||
*
|
||||
* “As soon as an Analytical Engine exists, it will necessarily
|
||||
* guide the future course of the science. Whenever any result
|
||||
* is sought by its aid, the question will then arise — by what
|
||||
* course of calculation can these results be arrived at by the
|
||||
* machine in the shortest time?
|
||||
*
|
||||
* — Charles Babbage (Life of a Philosopher, 1864)
|
||||
*
|
||||
*/
|
||||
double DifferSumSq8(const double D[static 8], double L, double H) {
|
||||
double T10, T100, T101, T102, T103, T104, T105, T106, T107, T108, T109, T11;
|
||||
double T110, T111, T112, T113, T114, T115, T116, T117, T118, T119, T12, T120;
|
||||
double T121, T122, T123, T124, T125, T126, T127, T128, T129, T13, T130, T131;
|
||||
double T132, T133, T134, T135, T136, T137, T138, T139, T14, T140, T141, T142;
|
||||
double T143, T144, T145, T146, T147, T148, T149, T15, T150, T151, T152, T153;
|
||||
double T154, T155, T156, T157, T158, T159, T16, T160, T161, T162, T163, T164;
|
||||
double T165, T166, T167, T168, T169, T17, T170, T171, T172, T173, T174, T175;
|
||||
double T176, T177, T178, T179, T18, T180, T181, T182, T183, T184, T185, T186;
|
||||
double T187, T188, T189, T19, T190, T191, T192, T193, T194, T195, T196, T197;
|
||||
double T198, T199, T2, T20, T200, T201, T202, T203, T204, T205, T206, T207;
|
||||
double T208, T209, T21, T210, T211, T212, T213, T214, T215, T216, T217, T218;
|
||||
double T219, T22, T220, T221, T222, T223, T224, T225, T226, T227, T228, T229;
|
||||
double T230, T231, T232, T233, T234, T235, T236, T237, T238, T239, T24, T240;
|
||||
double T241, T242, T243, T244, T245, T246, T247, T248, T249, T25, T250, T251;
|
||||
double T252, T253, T254, T255, T256, T257, T258, T259, T26, T260, T261, T262;
|
||||
double T263, T264, T265, T266, T267, T268, T269, T27, T270, T271, T272, T273;
|
||||
double T274, T275, T276, T277, T278, T279, T28, T280, T281, T282, T283, T284;
|
||||
double T285, T286, T287, T288, T289, T29, T290, T291, T292, T293, T294, T295;
|
||||
double T296, T297, T298, T299, T3, T30, T300, T301, T302, T303, T304, T305;
|
||||
double T307, T308, T309, T31, T310, T311, T312, T313, T314, T315, T316, T317;
|
||||
double T318, T319, T32, T320, T321, T322, T323, T324, T325, T326, T327, T328;
|
||||
double T329, T33, T330, T331, T332, T333, T334, T335, T336, T337, T338, T339;
|
||||
double T34, T340, T341, T342, T343, T344, T345, T346, T347, T348, T349, T35;
|
||||
double T350, T351, T352, T353, T354, T355, T356, T357, T358, T359, T36, T360;
|
||||
double T361, T362, T363, T364, T365, T366, T367, T368, T369, T37, T370, T371;
|
||||
double T372, T373, T374, T375, T376, T377, T378, T379, T38, T380, T381, T382;
|
||||
double T383, T384, T385, T386, T387, T388, T389, T39, T390, T391, T392, T393;
|
||||
double T394, T395, T396, T397, T398, T399, T4, T40, T400, T401, T402, T403;
|
||||
double T405, T406, T407, T41, T42, T43, T44, T45, T46, T47, T48, T49, T5, T50;
|
||||
double T51, T52, T53, T54, T55, T56, T57, T58, T59, T6, T60, T61, T62, T63;
|
||||
double T65, T66, T67, T68, T69, T7, T70, T71, T72, T73, T74, T75, T76, T77;
|
||||
double T79, T8, T80, T81, T82, T83, T84, T85, T86, T87, T88, T89, T9, T90;
|
||||
double T92, T93, T94, T95, T96, T97, T98, T99, T23, T306, T91, T78, T64, T404;
|
||||
T2 = 4 * D[5], T3 = 3 * D[4], T4 = 3 * D[3], T5 = 3 * D[2], T6 = 3 * D[1],
|
||||
T7 = 3 * D[0], T8 = D[7] * D[7], T9 = D[6] * D[6], T10 = -28 * D[5],
|
||||
T11 = -18 * D[4], T12 = -18 * D[3], T13 = -18 * D[2], T14 = -18 * D[1],
|
||||
T15 = -18 * D[0], T16 = D[5] * D[5], T17 = D[4] * D[4], T18 = D[3] * D[3],
|
||||
T19 = D[2] * D[2], T20 = D[1] * D[1], T21 = D[0] * D[0], T22 = -34 * D[5],
|
||||
T23 = -24 * D[4], T24 = -24 * D[3], T25 = -24 * D[2], T26 = -24 * D[1],
|
||||
T27 = -24 * D[0], T28 = 84 * D[5], T29 = 39 * D[4], T30 = 39 * D[3],
|
||||
T31 = 39 * D[2], T32 = 39 * D[1], T33 = 39 * D[0], T34 = 210 * D[5],
|
||||
T35 = 120 * D[4], T36 = 120 * D[3], T37 = 120 * D[2], T38 = 120 * D[1],
|
||||
T39 = 120 * D[0], T40 = 128 * D[5], T41 = 84 * D[4], T42 = 84 * D[3],
|
||||
T43 = 84 * D[2], T44 = 84 * D[1], T45 = 84 * D[0];
|
||||
T46 = -144 * D[5], T47 = (T23 + T24 + T25 + T26 + T27) * D[5],
|
||||
T48 = (T24 + T25 + T26 + T27) * D[4], T49 = (T25 + T26 + T27) * D[3],
|
||||
T50 = (T26 + T27) * D[2], T51 = -24 * D[0] * D[1], T52 = -552 * D[5],
|
||||
T53 = -192 * D[4], T54 = -192 * D[3], T55 = -192 * D[2], T56 = -192 * D[1],
|
||||
T57 = -192 * D[0], T58 = H * H, T59 = -688 * D[5], T60 = -336 * D[4],
|
||||
T61 = -336 * D[3], T62 = -336 * D[2], T63 = -336 * D[1], T64 = -336 * D[0],
|
||||
T65 = -280 * D[5], T66 = -168 * D[4], T67 = -168 * D[3], T68 = -168 * D[2],
|
||||
T69 = -168 * D[1], T70 = -168 * D[0], T71 = 168 * D[5], T72 = -42 * D[4],
|
||||
T73 = -42 * D[3], T74 = -42 * D[2], T75 = -42 * D[1], T76 = -42 * D[0],
|
||||
T77 = (H * H * H), T78 = 336 * D[4], T79 = 336 * D[3], T80 = 336 * D[2],
|
||||
T81 = 336 * D[1], T82 = 336 * D[0], T83 = 1568 * D[5],
|
||||
T84 = 336 * D[0] * D[1], T85 = 1288 * D[5], T86 = 504 * D[4],
|
||||
T87 = 504 * D[3], T88 = 504 * D[2], T89 = 504 * D[1], T90 = 504 * D[0],
|
||||
T91 = 392 * D[5], T92 = 210 * D[4], T93 = 210 * D[3], T94 = 210 * D[2],
|
||||
T95 = 210 * D[1], T96 = 210 * D[0], T97 = 84 * T8, T98 = 168 * D[6],
|
||||
T99 = 84 * T9, T100 = 84 * T16, T101 = (T41 + T42 + T43 + T44 + T45) * D[5],
|
||||
T102 = 84 * T17, T103 = (T42 + T43 + T44 + T45) * D[4], T104 = 84 * T18,
|
||||
T105 = (T43 + T44 + T45) * D[3], T106 = 84 * T19, T107 = (T44 + T45) * D[2],
|
||||
T108 = 84 * T20, T109 = 84 * D[0] * D[1], T110 = 84 * T21, T111 = -924 * D[5],
|
||||
T112 = (T78 + T79 + T80 + T81 + T82) * D[5],
|
||||
T113 = (T79 + T80 + T81 + T82) * D[4], T114 = (T80 + T81 + T82) * D[3],
|
||||
T115 = (T81 + T82) * D[2], T116 = (H * H * H * H), T117 = -2128 * D[5],
|
||||
T118 = -2520 * D[5], T119 = (T66 + T67 + T68 + T69 + T70) * D[5],
|
||||
T120 = (T67 + T68 + T69 + T70) * D[4], T121 = (T68 + T69 + T70) * D[3],
|
||||
T122 = (T69 + T70) * D[2], T123 = -168 * D[0] * D[1], T124 = -1512 * D[5],
|
||||
T125 = -420 * D[4], T126 = -420 * D[3], T127 = -420 * D[2],
|
||||
T128 = -420 * D[1], T129 = -420 * D[0], T130 = -364 * D[5];
|
||||
T131 = T97 + (T98 + T71 + T72 + T73 + T74 + T75 + T76) * D[7] + T99 +
|
||||
(T71 + T72 + T73 + T74 + T75 + T76) * D[6] + T100 +
|
||||
(T72 + T73 + T74 + T75 + T76) * D[5] + T102 +
|
||||
(T73 + T74 + T75 + T76) * D[4] + T104 + (T74 + T75 + T76) * D[3] +
|
||||
T106 + (T75 + T76) * D[2] + T108 - 42 * D[0] * D[1] + T110;
|
||||
T132 = 462 * T8, T133 = 924 * D[6], T134 = 924 * D[5], T135 = 462 * T9,
|
||||
T136 = 462 * T16, T137 = (T60 + T61 + T62 + T63 + T64) * D[5],
|
||||
T138 = 462 * T17, T139 = (T61 + T62 + T63 + T64) * D[4], T140 = 462 * T18,
|
||||
T141 = (T62 + T63 + T64) * D[3], T142 = 462 * T19, T143 = (T63 + T64) * D[2],
|
||||
T144 = 462 * T20, T145 = 462 * T21, T146 = (H * H * H * H * H),
|
||||
T147 = 2240 * D[5], T148 = -840 * D[4], T149 = -840 * D[3],
|
||||
T150 = -840 * D[2], T151 = -840 * D[1], T152 = -840 * D[0],
|
||||
T153 = 3080 * D[5], T154 = (T148 + T149 + T150 + T151 + T152) * D[5],
|
||||
T155 = (T149 + T150 + T151 + T152) * D[4], T156 = (T150 + T151 + T152) * D[3],
|
||||
T157 = (T151 + T152) * D[2], T158 = -840 * D[0] * D[1], T159 = 1260 * T8,
|
||||
T160 = 2520 * D[6], T161 = 2520 * D[5], T162 = 1260 * T9, T163 = 1260 * T16,
|
||||
T164 = 1260 * T17, T165 = 1260 * T18, T166 = 1260 * T19, T167 = 1260 * T20,
|
||||
T168 = 210 * D[0] * D[1], T169 = 1260 * T21, T170 = 168 * D[4],
|
||||
T171 = 168 * D[3], T172 = 168 * D[2], T173 = 168 * D[1], T174 = 168 * D[0],
|
||||
T175 = 1148 * D[5], T176 = 168 * D[0] * D[1], T177 = 224 * D[5];
|
||||
T178 = -72 * T8 + (-144 * D[6] + T46 + T23 + T24 + T25 + T26 + T27) * D[7] -
|
||||
72 * T9 + (T46 + T23 + T24 + T25 + T26 + T27) * D[6] - 72 * T16 + T47 -
|
||||
72 * T17 + T48 - 72 * T18 + T49 - 72 * T19 + T50 - 72 * T20 + T51 -
|
||||
72 * T21;
|
||||
T179 = 420 * T8, T180 = 840 * D[6], T181 = 840 * D[5], T182 = 420 * T9,
|
||||
T183 = 840 * D[5] * D[6], T184 = 420 * T16, T185 = 420 * T17,
|
||||
T186 = 420 * T18, T187 = 420 * T19, T188 = 420 * T20, T189 = 420 * T21,
|
||||
T190 = (H * H * H * H * H * H);
|
||||
T191 = -1064 * T8 +
|
||||
(-2128 * D[6] + T117 + T78 + T79 + T80 + T81 + T82) * D[7] -
|
||||
1064 * T9 + (T117 + T78 + T79 + T80 + T81 + T82) * D[6] - 1064 * T16 +
|
||||
T112 - 1064 * T17 + T113 - 1064 * T18 + T114 - 1064 * T19 + T115 -
|
||||
1064 * T20 + T84 - 1064 * T21;
|
||||
T192 = 1540 * T8, T193 = 3080 * D[6], T194 = 840 * D[4], T195 = 840 * D[3],
|
||||
T196 = 840 * D[2], T197 = 840 * D[1], T198 = 840 * D[0], T199 = 1540 * T9,
|
||||
T200 = 1540 * T16, T201 = 1540 * T17, T202 = 1540 * T18, T203 = 1540 * T19,
|
||||
T204 = 1540 * T20, T205 = 840 * D[0] * D[1], T206 = 1540 * T21,
|
||||
T207 = -2800 * D[5], T208 = (T194 + T195 + T196 + T197 + T198) * D[5],
|
||||
T209 = (T195 + T196 + T197 + T198) * D[4], T210 = (T196 + T197 + T198) * D[3],
|
||||
T211 = (T197 + T198) * D[2], T212 = -1624 * D[5], T213 = -88 * D[5];
|
||||
T214 = 42 * T8 + (84 * D[6] + T28 + T29 + T30 + T31 + T32 + T33) * D[7] +
|
||||
42 * T9 + (T28 + T29 + T30 + T31 + T32 + T33) * D[6] + 42 * T16 +
|
||||
(T29 + T30 + T31 + T32 + T33) * D[5] + 42 * T17 +
|
||||
(T30 + T31 + T32 + T33) * D[4] + 42 * T18 + (T31 + T32 + T33) * D[3] +
|
||||
42 * T19 + (T32 + T33) * D[2] + 42 * T20 + 39 * D[0] * D[1] + 42 * T21;
|
||||
T215 = 276 * T8, T216 = 552 * D[6], T217 = 552 * D[5], T218 = 192 * D[4],
|
||||
T219 = 192 * D[3], T220 = 192 * D[2], T221 = 192 * D[1], T222 = 192 * D[0],
|
||||
T223 = 276 * T9, T224 = 276 * T16, T225 = 276 * T17, T226 = 276 * T18,
|
||||
T227 = 276 * T19, T228 = 276 * T20, T229 = 192 * D[0] * D[1],
|
||||
T230 = 276 * T21, T231 = (H * H * H * H * H * H * H);
|
||||
T232 = 784 * T8 + (1568 * D[6] + T83 + T78 + T79 + T80 + T81 + T82) * D[7] +
|
||||
784 * T9 + (T83 + T78 + T79 + T80 + T81 + T82) * D[6] + 784 * T16 +
|
||||
T112 + 784 * T17 + T113 + 784 * T18 + T114 + 784 * T19 + T115 +
|
||||
784 * T20 + T84 + 784 * T21;
|
||||
T233 = (T170 + T171 + T172 + T173 + T174) * D[5];
|
||||
T234 = (T171 + T172 + T173 + T174) * D[4];
|
||||
T235 = (T172 + T173 + T174) * D[3];
|
||||
T236 = (T173 + T174) * D[2];
|
||||
T237 = T159 + (T160 + T161 - T92 - T93 - T94 - T95 - T96) * D[7] + T162 +
|
||||
(T161 - T92 - T93 - T94 - T95 - T96) * D[6] + T163 +
|
||||
(-T92 - T93 - T94 - T95 - T96) * D[5] + T164 +
|
||||
(-T93 - T94 - T95 - T96) * D[4] + T165 + (-T94 - T95 - T96) * D[3] +
|
||||
T166 + (-T95 - T96) * D[2] + T167 - T168 + T169;
|
||||
T238 = 812 * T8, T239 = 1624 * D[6], T240 = 1624 * D[5], T241 = 812 * T9,
|
||||
T242 = 812 * T16, T243 = 812 * T17, T244 = 812 * T18, T245 = 812 * T19,
|
||||
T246 = 812 * T20, T247 = 812 * T21, T248 = 672 * D[5], T249 = 20 * D[5],
|
||||
T250 = (T3 + T4 + T5 + T6 + T7) * D[5], T251 = (T4 + T5 + T6 + T7) * D[4],
|
||||
T252 = (T5 + T6 + T7) * D[3], T253 = (T6 + T7) * D[2], T254 = 3 * D[0] * D[1];
|
||||
T255 = -14 * T8 + (-28 * D[6] + T10 + T11 + T12 + T13 + T14 + T15) * D[7] -
|
||||
14 * T9 + (T10 + T11 + T12 + T13 + T14 + T15) * D[6] - 14 * T16 +
|
||||
(T11 + T12 + T13 + T14 + T15) * D[5] - 14 * T17 +
|
||||
(T12 + T13 + T14 + T15) * D[4] - 14 * T18 + (T13 + T14 + T15) * D[3] -
|
||||
14 * T19 + (T14 + T15) * D[2] - 14 * T20 - 18 * D[0] * D[1] - 14 * T21;
|
||||
T256 = 105 * T8, T257 = 210 * D[6], T258 = 105 * T9, T259 = 105 * T16,
|
||||
T260 = 105 * T17, T261 = 105 * T18, T262 = 105 * T19, T263 = 105 * T20,
|
||||
T264 = 120 * D[0] * D[1], T265 = 105 * T21,
|
||||
T266 = (H * H * H * H * H * H * H * H);
|
||||
T267 = -344 * T8 + (-688 * D[6] + T59 + T60 + T61 + T62 + T63 + T64) * D[7] -
|
||||
344 * T9 + (T59 + T60 + T61 + T62 + T63 + T64) * D[6] - 344 * T16 +
|
||||
T137 - 344 * T17 + T139 - 344 * T18 + T141 - 344 * T19 + T143 -
|
||||
344 * T20 - T84 - 344 * T21;
|
||||
T268 = 644 * T8, T269 = 1288 * D[6], T270 = 644 * T9, T271 = 644 * T16,
|
||||
T272 = 644 * T17, T273 = 644 * T18, T274 = 644 * T19, T275 = 644 * T20,
|
||||
T276 = 504 * D[0] * D[1], T277 = 644 * T21;
|
||||
T278 = -756 * T8 +
|
||||
(-1512 * D[6] + T124 + T125 + T126 + T127 + T128 + T129) * D[7] -
|
||||
756 * T9 + (T124 + T125 + T126 + T127 + T128 + T129) * D[6] -
|
||||
756 * T16 + (T125 + T126 + T127 + T128 + T129) * D[5] - 756 * T17 +
|
||||
(T126 + T127 + T128 + T129) * D[4] - 756 * T18 +
|
||||
(T127 + T128 + T129) * D[3] - 756 * T19 + (T128 + T129) * D[2] -
|
||||
756 * T20 - 420 * D[0] * D[1] - 756 * T21;
|
||||
T279 = 574 * T8, T280 = 1148 * D[6], T281 = 574 * T9, T282 = 574 * T16,
|
||||
T283 = 574 * T17, T284 = 574 * T18, T285 = 574 * T19, T286 = 574 * T20,
|
||||
T287 = 574 * T21;
|
||||
T288 = -280 * T8 + (-560 * D[6] - 560 * D[5]) * D[7] - 280 * T9 -
|
||||
560 * D[5] * D[6] - 280 * T16 - 280 * T17 - 280 * T18 - 280 * T19 -
|
||||
280 * T20 - 280 * T21;
|
||||
T289 = 24 * D[4], T290 = 24 * D[3], T291 = 24 * D[2], T292 = 24 * D[1],
|
||||
T293 = 24 * D[0], T294 = 24 * D[0] * D[1], T295 = -14 * T8, T296 = -28 * D[6],
|
||||
T297 = -14 * T9, T298 = 6 * D[4], T299 = 6 * D[3], T300 = 6 * D[2],
|
||||
T301 = 6 * D[1], T302 = 6 * D[0], T303 = -14 * T16, T304 = -14 * T17,
|
||||
T305 = -14 * T18, T306 = -14 * T19, T307 = -14 * T20, T308 = -14 * T21;
|
||||
T309 = 2 * T8 + (4 * D[6] + T2 + T3 + T4 + T5 + T6 + T7) * D[7] + 2 * T9 +
|
||||
(T2 + T3 + T4 + T5 + T6 + T7) * D[6] + 2 * T16 + T250 + 2 * T17 +
|
||||
T251 + 2 * T18 + T252 + 2 * T19 + T253 + 2 * T20 + T254 + 2 * T21;
|
||||
T310 = 17 * T8, T311 = 34 * D[6], T312 = 34 * D[5], T313 = 17 * T9,
|
||||
T314 = 17 * T16, T315 = (T289 + T290 + T291 + T292 + T293) * D[5];
|
||||
T316 = 17 * T17, T317 = (T290 + T291 + T292 + T293) * D[4];
|
||||
T318 = 17 * T18, T319 = (T291 + T292 + T293) * D[3];
|
||||
T320 = 17 * T19, T321 = (T292 + T293) * D[2];
|
||||
T322 = 17 * T20, T323 = 17 * T21, T324 = (H * H * H * H * H * H * H * H * H);
|
||||
T325 = 64 * T8,
|
||||
T326 = (128 * D[6] + T40 + T41 + T42 + T43 + T44 + T45) * D[7];
|
||||
T327 = 64 * T9, T328 = (T40 + T41 + T42 + T43 + T44 + T45) * D[6];
|
||||
T329 = 64 * T16, T330 = 64 * T17, T331 = 64 * T18, T332 = 64 * T19,
|
||||
T333 = 64 * T20, T334 = 64 * T21, T335 = 140 * T8, T336 = 280 * D[6],
|
||||
T337 = 280 * D[5], T338 = 140 * T9, T339 = 140 * T16, T340 = 140 * T17,
|
||||
T341 = 140 * T18, T342 = 140 * T19, T343 = 140 * T20, T344 = 140 * T21,
|
||||
T345 = 196 * T8;
|
||||
T346 = (392 * D[6] + T91 + T92 + T93 + T94 + T95 + T96) * D[7];
|
||||
T347 = 196 * T9;
|
||||
T348 = (T91 + T92 + T93 + T94 + T95 + T96) * D[6];
|
||||
T349 = 196 * T16;
|
||||
T350 = (T92 + T93 + T94 + T95 + T96) * D[5];
|
||||
T351 = 196 * T17;
|
||||
T352 = (T93 + T94 + T95 + T96) * D[4];
|
||||
T353 = 196 * T18;
|
||||
T354 = (T94 + T95 + T96) * D[3];
|
||||
T355 = 196 * T19;
|
||||
T356 = (T95 + T96) * D[2];
|
||||
T357 = 196 * T20, T358 = 196 * T21, T359 = 182 * T8, T360 = 364 * D[6],
|
||||
T361 = 364 * D[5], T362 = 182 * T9, T363 = 182 * T16, T364 = 182 * T17,
|
||||
T365 = 182 * T18, T366 = 182 * T19, T367 = 182 * T20, T368 = 182 * T21,
|
||||
T369 = 112 * T8;
|
||||
T370 = (224 * D[6] + T177 + T41 + T42 + T43 + T44 + T45) * D[7];
|
||||
T371 = 112 * T9;
|
||||
T372 = (T177 + T41 + T42 + T43 + T44 + T45) * D[6];
|
||||
T373 = 112 * T16, T374 = 112 * T17, T375 = 112 * T18, T376 = 112 * T19,
|
||||
T377 = 112 * T20, T378 = 112 * T21, T379 = 44 * T8, T380 = 88 * D[6],
|
||||
T381 = 88 * D[5], T382 = 44 * T9, T383 = 44 * T16, T384 = 44 * T17,
|
||||
T385 = 44 * T18, T386 = 44 * T19, T387 = 44 * T20, T388 = 44 * T21,
|
||||
T389 = 10 * T8, T390 = (20 * D[6] + T249 + T3 + T4 + T5 + T6 + T7) * D[7];
|
||||
T391 = 10 * T9, T392 = (T249 + T3 + T4 + T5 + T6 + T7) * D[6];
|
||||
T393 = 10 * T16, T394 = 10 * T17, T395 = 10 * T18, T396 = 10 * T19,
|
||||
T397 = 10 * T20, T398 = 10 * T21, T399 = 2 * D[6], T400 = 2 * D[5],
|
||||
T401 = 2 * D[5] * D[6];
|
||||
T402 = T309 * (L * L * L * L * L * L * L * L * L * L) +
|
||||
(T255 * H - T310 + (-T311 + T22 + T23 + T24 + T25 + T26 + T27) * D[7] -
|
||||
T313 + (T22 + T23 + T24 + T25 + T26 + T27) * D[6] - T314 + T47 -
|
||||
T316 + T48 - T318 + T49 - T320 + T50 - T322 + T51 - T323) *
|
||||
(L * L * L * L * L * L * L * L * L) +
|
||||
(T214 * T58 +
|
||||
(T256 + (T257 + T34 + T35 + T36 + T37 + T38 + T39) * D[7] + T258 +
|
||||
(T34 + T35 + T36 + T37 + T38 + T39) * D[6] + T259 +
|
||||
(T35 + T36 + T37 + T38 + T39) * D[5] + T260 +
|
||||
(T36 + T37 + T38 + T39) * D[4] + T261 + (T37 + T38 + T39) * D[3] +
|
||||
T262 + (T38 + T39) * D[2] + T263 + T264 + T265) *
|
||||
H +
|
||||
T325 + T326 + T327 + T328 + T329 + T101 + T330 + T103 + T331 + T105 +
|
||||
T332 + T107 + T333 + T109 + T334) *
|
||||
(L * L * L * L * L * L * L * L) +
|
||||
(T178 * T77 +
|
||||
(-T215 + (-T216 + T52 + T53 + T54 + T55 + T56 + T57) * D[7] - T223 +
|
||||
(T52 + T53 + T54 + T55 + T56 + T57) * D[6] - T224 +
|
||||
(T53 + T54 + T55 + T56 + T57) * D[5] - T225 +
|
||||
(T54 + T55 + T56 + T57) * D[4] - T226 + (T55 + T56 + T57) * D[3] -
|
||||
T227 + (T56 + T57) * D[2] - T228 - T229 - T230) *
|
||||
T58 +
|
||||
T267 * H - T335 + (-T336 + T65 + T66 + T67 + T68 + T69 + T70) * D[7] -
|
||||
T338 + (T65 + T66 + T67 + T68 + T69 + T70) * D[6] - T339 + T119 -
|
||||
T340 + T120 - T341 + T121 - T342 + T122 - T343 + T123 - T344) *
|
||||
(L * L * L * L * L * L * L);
|
||||
T403 =
|
||||
T402 +
|
||||
(T131 * T116 +
|
||||
(T179 + (T180 + T181) * D[7] + T182 + T183 + T184 + T185 + T186 + T187 +
|
||||
T188 + T189) *
|
||||
T77 +
|
||||
T232 * T58 +
|
||||
(T268 + (T269 + T85 + T86 + T87 + T88 + T89 + T90) * D[7] + T270 +
|
||||
(T85 + T86 + T87 + T88 + T89 + T90) * D[6] + T271 +
|
||||
(T86 + T87 + T88 + T89 + T90) * D[5] + T272 +
|
||||
(T87 + T88 + T89 + T90) * D[4] + T273 + (T88 + T89 + T90) * D[3] +
|
||||
T274 + (T89 + T90) * D[2] + T275 + T276 + T277) *
|
||||
H +
|
||||
T345 + T346 + T347 + T348 + T349 + T350 + T351 + T352 + T353 + T354 +
|
||||
T355 + T356 + T357 + T168 + T358) *
|
||||
(L * L * L * L * L * L) +
|
||||
((-T97 + (-T98 - T71 + T41 + T42 + T43 + T44 + T45) * D[7] - T99 +
|
||||
(-T71 + T41 + T42 + T43 + T44 + T45) * D[6] - T100 + T101 - T102 +
|
||||
T103 - T104 + T105 - T106 + T107 - T108 + T109 - T110) *
|
||||
T146 +
|
||||
(-T132 + (-T133 + T111 + T78 + T79 + T80 + T81 + T82) * D[7] - T135 +
|
||||
(T111 + T78 + T79 + T80 + T81 + T82) * D[6] - T136 + T112 - T138 +
|
||||
T113 - T140 + T114 - T142 + T115 - T144 + T84 - T145) *
|
||||
T116 +
|
||||
T191 * T77 +
|
||||
(-T159 + (-T160 + T118 + T66 + T67 + T68 + T69 + T70) * D[7] - T162 +
|
||||
(T118 + T66 + T67 + T68 + T69 + T70) * D[6] - T163 + T119 - T164 +
|
||||
T120 - T165 + T121 - T166 + T122 - T167 + T123 - T169) *
|
||||
T58 +
|
||||
T278 * H - T359 + (-T360 + T130 + T66 + T67 + T68 + T69 + T70) * D[7] -
|
||||
T362 + (T130 + T66 + T67 + T68 + T69 + T70) * D[6] - T363 + T119 - T364 +
|
||||
T120 - T365 + T121 - T366 + T122 - T367 + T123 - T368) *
|
||||
(L * L * L * L * L);
|
||||
T404 =
|
||||
T403 +
|
||||
(T131 * T190 +
|
||||
(T132 + (T133 + T134 + T60 + T61 + T62 + T63 + T64) * D[7] + T135 +
|
||||
(T134 + T60 + T61 + T62 + T63 + T64) * D[6] + T136 + T137 + T138 +
|
||||
T139 + T140 + T141 + T142 + T143 + T144 - T84 + T145) *
|
||||
T146 +
|
||||
(1120 * T8 +
|
||||
(2240 * D[6] + T147 + T148 + T149 + T150 + T151 + T152) * D[7] +
|
||||
1120 * T9 + (T147 + T148 + T149 + T150 + T151 + T152) * D[6] +
|
||||
1120 * T16 + T154 + 1120 * T17 + T155 + 1120 * T18 + T156 + 1120 * T19 +
|
||||
T157 + 1120 * T20 + T158 + 1120 * T21) *
|
||||
T116 +
|
||||
(T192 + (T193 + T153 + T148 + T149 + T150 + T151 + T152) * D[7] + T199 +
|
||||
(T153 + T148 + T149 + T150 + T151 + T152) * D[6] + T200 + T154 + T201 +
|
||||
T155 + T202 + T156 + T203 + T157 + T204 + T158 + T206) *
|
||||
T77 +
|
||||
T237 * T58 +
|
||||
(T279 + (T280 + T175 + T170 + T171 + T172 + T173 + T174) * D[7] + T281 +
|
||||
(T175 + T170 + T171 + T172 + T173 + T174) * D[6] + T282 + T233 + T283 +
|
||||
T234 + T284 + T235 + T285 + T236 + T286 + T176 + T287) *
|
||||
H +
|
||||
T369 + T370 + T371 + T372 + T373 + T101 + T374 + T103 + T375 + T105 +
|
||||
T376 + T107 + T377 + T109 + T378) *
|
||||
(L * L * L * L) +
|
||||
(T178 * T231 +
|
||||
(-T179 + (-T180 - T181) * D[7] - T182 - T183 - T184 - T185 - T186 -
|
||||
T187 - T188 - T189) *
|
||||
T190 +
|
||||
T191 * T146 +
|
||||
(-T192 + (-T193 - T153 + T194 + T195 + T196 + T197 + T198) * D[7] -
|
||||
T199 + (-T153 + T194 + T195 + T196 + T197 + T198) * D[6] - T200 + T208 -
|
||||
T201 + T209 - T202 + T210 - T203 + T211 - T204 + T205 - T206) *
|
||||
T116 +
|
||||
(-1400 * T8 +
|
||||
(-2800 * D[6] + T207 + T194 + T195 + T196 + T197 + T198) * D[7] -
|
||||
1400 * T9 + (T207 + T194 + T195 + T196 + T197 + T198) * D[6] -
|
||||
1400 * T16 + T208 - 1400 * T17 + T209 - 1400 * T18 + T210 - 1400 * T19 +
|
||||
T211 - 1400 * T20 + T205 - 1400 * T21) *
|
||||
T77 +
|
||||
(-T238 + (-T239 + T212 + T78 + T79 + T80 + T81 + T82) * D[7] - T241 +
|
||||
(T212 + T78 + T79 + T80 + T81 + T82) * D[6] - T242 + T112 - T243 +
|
||||
T113 - T244 + T114 - T245 + T115 - T246 + T84 - T247) *
|
||||
T58 +
|
||||
T288 * H - T379 + (-T380 + T213 + T23 + T24 + T25 + T26 + T27) * D[7] -
|
||||
T382 + (T213 + T23 + T24 + T25 + T26 + T27) * D[6] - T383 + T47 - T384 +
|
||||
T48 - T385 + T49 - T386 + T50 - T387 + T51 - T388) *
|
||||
(L * L * L);
|
||||
T405 =
|
||||
T214 * T266 +
|
||||
(T215 + (T216 + T217 + T218 + T219 + T220 + T221 + T222) * D[7] + T223 +
|
||||
(T217 + T218 + T219 + T220 + T221 + T222) * D[6] + T224 +
|
||||
(T218 + T219 + T220 + T221 + T222) * D[5] + T225 +
|
||||
(T219 + T220 + T221 + T222) * D[4] + T226 + (T220 + T221 + T222) * D[3] +
|
||||
T227 + (T221 + T222) * D[2] + T228 + T229 + T230) *
|
||||
T231 +
|
||||
T232 * T190 +
|
||||
(T159 + (T160 + T161 + T170 + T171 + T172 + T173 + T174) * D[7] + T162 +
|
||||
(T161 + T170 + T171 + T172 + T173 + T174) * D[6] + T163 + T233 + T164 +
|
||||
T234 + T165 + T235 + T166 + T236 + T167 + T176 + T169) *
|
||||
T146 +
|
||||
T237 * T116 +
|
||||
(T238 + (T239 + T240 + T60 + T61 + T62 + T63 + T64) * D[7] + T241 +
|
||||
(T240 + T60 + T61 + T62 + T63 + T64) * D[6] + T242 + T137 + T243 + T139 +
|
||||
T244 + T141 + T245 + T143 + T246 - T84 + T247) *
|
||||
T77 +
|
||||
(336 * T8 + (672 * D[6] + T248 + T66 + T67 + T68 + T69 + T70) * D[7] +
|
||||
336 * T9 + (T248 + T66 + T67 + T68 + T69 + T70) * D[6] + 336 * T16 +
|
||||
T119 + 336 * T17 + T120 + 336 * T18 + T121 + 336 * T19 + T122 +
|
||||
336 * T20 - T176 + 336 * T21) *
|
||||
T58 +
|
||||
(T97 + (T98 + T71 + T23 + T24 + T25 + T26 + T27) * D[7] + T99 +
|
||||
(T71 + T23 + T24 + T25 + T26 + T27) * D[6] + T100 + T47 + T102 + T48 +
|
||||
T104 + T49 + T106 + T50 + T108 + T51 + T110) *
|
||||
H +
|
||||
T389 + T390 + T391;
|
||||
T406 = T255 * T324 +
|
||||
(-T256 + (-T257 - T34 - T35 - T36 - T37 - T38 - T39) * D[7] - T258 +
|
||||
(-T34 - T35 - T36 - T37 - T38 - T39) * D[6] - T259 +
|
||||
(-T35 - T36 - T37 - T38 - T39) * D[5] - T260 +
|
||||
(-T36 - T37 - T38 - T39) * D[4] - T261 + (-T37 - T38 - T39) * D[3] -
|
||||
T262 + (-T38 - T39) * D[2] - T263 - T264 - T265) *
|
||||
T266 +
|
||||
T267 * T231 +
|
||||
(-T268 + (-T269 - T85 - T86 - T87 - T88 - T89 - T90) * D[7] - T270 +
|
||||
(-T85 - T86 - T87 - T88 - T89 - T90) * D[6] - T271 +
|
||||
(-T86 - T87 - T88 - T89 - T90) * D[5] - T272 +
|
||||
(-T87 - T88 - T89 - T90) * D[4] - T273 + (-T88 - T89 - T90) * D[3] -
|
||||
T274 + (-T89 - T90) * D[2] - T275 - T276 - T277) *
|
||||
T190 +
|
||||
T278 * T146 +
|
||||
(-T279 + (-T280 - T175 + T66 + T67 + T68 + T69 + T70) * D[7] - T281 +
|
||||
(-T175 + T66 + T67 + T68 + T69 + T70) * D[6] - T282 + T119 - T283 +
|
||||
T120 - T284 + T121 - T285 + T122 - T286 - T176 - T287) *
|
||||
T116 +
|
||||
T288 * T77 +
|
||||
(-T97 + (-T98 - T71 + T289 + T290 + T291 + T292 + T293) * D[7] - T99 +
|
||||
(-T71 + T289 + T290 + T291 + T292 + T293) * D[6] - T100 + T315 -
|
||||
T102 + T317 - T104 + T319 - T106 + T321 - T108 + T294 - T110) *
|
||||
T58;
|
||||
T407 = T404 +
|
||||
(T405 + T392 + T393 + T250 + T394 + T251 + T395 + T252 + T396 + T253 +
|
||||
T397 + T254 + T398) *
|
||||
L * L +
|
||||
(T406 +
|
||||
(T295 + (T296 + T10 + T298 + T299 + T300 + T301 + T302) * D[7] +
|
||||
T297 + (T10 + T298 + T299 + T300 + T301 + T302) * D[6] + T303 +
|
||||
(T298 + T299 + T300 + T301 + T302) * D[5] + T304 +
|
||||
(T299 + T300 + T301 + T302) * D[4] + T305 +
|
||||
(T300 + T301 + T302) * D[3] + T306 + (T301 + T302) * D[2] + T307 +
|
||||
6 * D[0] * D[1] + T308) *
|
||||
H -
|
||||
T8 + (-T399 - T400) * D[7] - T9 - T401 - T16 - T17 - T18 - T19 - T20 -
|
||||
T21) *
|
||||
L +
|
||||
T309 * (H * H * H * H * H * H * H * H * H * H) +
|
||||
(T310 + (T311 + T312 + T289 + T290 + T291 + T292 + T293) * D[7] +
|
||||
T313 + (T312 + T289 + T290 + T291 + T292 + T293) * D[6] + T314 +
|
||||
T315 + T316 + T317 + T318 + T319 + T320 + T321 + T322 + T294 + T323) *
|
||||
T324 +
|
||||
(T325 + T326 + T327 + T328 + T329 + T101 + T330 + T103 + T331 + T105 +
|
||||
T332 + T107 + T333 + T109 + T334) *
|
||||
T266 +
|
||||
(T335 + (T336 + T337 + T170 + T171 + T172 + T173 + T174) * D[7] +
|
||||
T338 + (T337 + T170 + T171 + T172 + T173 + T174) * D[6] + T339 +
|
||||
T233 + T340 + T234 + T341 + T235 + T342 + T236 + T343 + T176 + T344) *
|
||||
T231 +
|
||||
(T345 + T346 + T347 + T348 + T349 + T350 + T351 + T352 + T353 + T354 +
|
||||
T355 + T356 + T357 + T168 + T358) *
|
||||
T190;
|
||||
return (T407 +
|
||||
(T359 + (T360 + T361 + T170 + T171 + T172 + T173 + T174) * D[7] +
|
||||
T362 + (T361 + T170 + T171 + T172 + T173 + T174) * D[6] + T363 +
|
||||
T233 + T364 + T234 + T365 + T235 + T366 + T236 + T367 + T176 +
|
||||
T368) *
|
||||
T146 +
|
||||
(T369 + T370 + T371 + T372 + T373 + T101 + T374 + T103 + T375 + T105 +
|
||||
T376 + T107 + T377 + T109 + T378) *
|
||||
T116 +
|
||||
(T379 + (T380 + T381 + T289 + T290 + T291 + T292 + T293) * D[7] +
|
||||
T382 + (T381 + T289 + T290 + T291 + T292 + T293) * D[6] + T383 +
|
||||
T315 + T384 + T317 + T385 + T319 + T386 + T321 + T387 + T294 +
|
||||
T388) *
|
||||
T77 +
|
||||
(T389 + T390 + T391 + T392 + T393 + T250 + T394 + T251 + T395 + T252 +
|
||||
T396 + T253 + T397 + T254 + T398) *
|
||||
T58 +
|
||||
(T8 + (T399 + T400) * D[7] + T9 + T401 + T16 + T17 + T18 + T19 + T20 +
|
||||
T21) *
|
||||
H) /
|
||||
6;
|
||||
}
|
35
dsp/core/double2byte.c
Normal file
35
dsp/core/double2byte.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
void *double2byte(long n, const void *p, double weight, double bias) {
|
||||
long i;
|
||||
const double *src;
|
||||
unsigned char *dst;
|
||||
if ((dst = valloc(n * sizeof(unsigned char)))) {
|
||||
for (src = p, i = 0; i < n; ++i) {
|
||||
dst[i] = MIN(255, MAX(0, rint(src[i] * weight + bias)));
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
41
dsp/core/float2short.c
Normal file
41
dsp/core/float2short.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Converts floating point audio samples to pulse code modulation.
|
||||
*
|
||||
* @param rdi is number of sample chunks
|
||||
* @param rsi points to aligned pcm [-32k,+32k] output memory
|
||||
* @param rdx points to aligned float32 [-1,+1] input memory
|
||||
*/
|
||||
void float2short(size_t n, short pcm16[n][8], const float binary32[n][8]) {
|
||||
size_t i, j;
|
||||
float f[8], w[8];
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
pcm16[i][j] =
|
||||
MIN(SHRT_MAX, MAX(SHRT_MIN, floorf(binary32[i][j] * (SHRT_MAX + 1))));
|
||||
}
|
||||
}
|
||||
}
|
40
dsp/core/gamma.c
Normal file
40
dsp/core/gamma.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/gamma.h"
|
||||
#include "libc/math.h"
|
||||
|
||||
double rgb2stdpc(double x, double g) {
|
||||
return COMPANDLUMA_SRGB(x, g);
|
||||
}
|
||||
double rgb2linpc(double x, double g) {
|
||||
return UNCOMPANDLUMA_SRGB(x, g);
|
||||
}
|
||||
|
||||
double rgb2stdtv(double x) {
|
||||
return COMPANDLUMA_BT1886(x);
|
||||
}
|
||||
double rgb2lintv(double x) {
|
||||
return UNCOMPANDLUMA_BT1886(x);
|
||||
}
|
||||
|
||||
double tv2pcgamma(double x, double g) {
|
||||
return rgb2stdpc(rgb2lintv(x), g);
|
||||
}
|
23
dsp/core/gamma.h
Normal file
23
dsp/core/gamma.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_GAMMA_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_GAMMA_H_
|
||||
#include "libc/math.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define COMPANDLUMA(X, ...) COMPANDLUMA_(X, __VA_ARGS__)
|
||||
#define COMPANDLUMA_(X, K1, K2, K3, K4) \
|
||||
((X) > (K3) / (K4) ? (1 + (K2)) * pow((X), 1 / (K1)) - (K2) : (X) * (K4))
|
||||
|
||||
#define UNCOMPANDLUMA(X, ...) UNCOMPANDLUMA_(X, __VA_ARGS__)
|
||||
#define UNCOMPANDLUMA_(X, K1, K2, K3, K4) \
|
||||
((X) > (K3) ? pow(1 / (1 + (K2)) * ((X) + (K2)), K1) : (X) / (K4))
|
||||
|
||||
#define COMPANDLUMA_SRGB_MAGNUM .055, .04045, 12.92
|
||||
#define COMPANDLUMA_SRGB(X, G) COMPANDLUMA(X, G, COMPANDLUMA_SRGB_MAGNUM)
|
||||
#define UNCOMPANDLUMA_SRGB(X, G) UNCOMPANDLUMA(X, G, COMPANDLUMA_SRGB_MAGNUM)
|
||||
|
||||
#define COMPANDLUMA_BT1886_MAGNUM 1 / .45, .099, .081, 4.5
|
||||
#define COMPANDLUMA_BT1886(X) COMPANDLUMA(X, COMPANDLUMA_BT1886_MAGNUM)
|
||||
#define UNCOMPANDLUMA_BT1886(X) UNCOMPANDLUMA(X, COMPANDLUMA_BT1886_MAGNUM)
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_GAMMA_H_ */
|
113
dsp/core/getintegercoefficients.c
Normal file
113
dsp/core/getintegercoefficients.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/q.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Precomputes integers that can replace floating-point operands.
|
||||
*
|
||||
* “G-d made the integers, all else is the work of man.
|
||||
* — Leopold Kronecker
|
||||
*
|
||||
* This function shifts the decimal point to the left:
|
||||
*
|
||||
* 𝑛ᵢ ← ROUND[𝑐ᵢ × 2ᵐ] + φᵢ
|
||||
*
|
||||
* With extra effort to compute φ which is normally all zeroes but gives
|
||||
* us better rounding when it isn't. It's assumed optimized coefficients
|
||||
* will be used like this:
|
||||
*
|
||||
* (Σᵢ𝑥ᵢ𝑛ᵢ + 2⁽ᵐ⁻¹⁾) / 2ᵐ where 𝑥∈[𝐿,𝐻] and 𝑖∈[0,6)
|
||||
*
|
||||
* Intended to compute this
|
||||
*
|
||||
* ROUND[Σᵢ𝑥ᵢ𝑐ᵢ]
|
||||
*
|
||||
* As accurately or approximately as you want it to be. Popular scaling
|
||||
* factors are 7, 15, 16, 22, and 31. Building this code under MODE=tiny
|
||||
* will DCE the math.
|
||||
*
|
||||
* @param N receives optimized integers
|
||||
* @param C provides ideal coefficients
|
||||
* @param M is log₂ scaling factor, e.g. 7
|
||||
* @param L is minimum input data size, e.g. 0
|
||||
* @param H is maximum input data size, e.g. 255
|
||||
* @return sum of errors for all inputs
|
||||
* @see en.wikipedia.org/wiki/Binary_scaling
|
||||
* @see o/tool/build/coefficients.com
|
||||
* @cost ~300ns
|
||||
*/
|
||||
long GetIntegerCoefficients(long N[static 6], const double C[static 6], long M,
|
||||
long L, long H) {
|
||||
int i;
|
||||
int j[6], J[6];
|
||||
int O[6] = {0};
|
||||
int S[3] = {0, -1, +1};
|
||||
double R[6], K[6], D[6], HM, HL, least, error;
|
||||
least = 1;
|
||||
HM = 1L << M;
|
||||
HL = H - L + 1;
|
||||
assert(H >= L);
|
||||
assert(HL <= HM);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
least *= HL;
|
||||
if (fabs(C[i]) > DBL_MIN) {
|
||||
J[i] = ARRAYLEN(S);
|
||||
R[i] = C[i] * HM;
|
||||
K[i] = rint(R[i]);
|
||||
N[i] = K[i];
|
||||
} else {
|
||||
J[i] = 1;
|
||||
R[i] = 0;
|
||||
K[i] = 0;
|
||||
N[i] = 0;
|
||||
}
|
||||
}
|
||||
if (!IsTiny() && least > 1) {
|
||||
for (j[0] = 0; j[0] < J[0]; ++j[0]) {
|
||||
for (j[1] = 0; j[1] < J[1]; ++j[1]) {
|
||||
for (j[2] = 0; j[2] < J[2]; ++j[2]) {
|
||||
for (j[3] = 0; j[3] < J[3]; ++j[3]) {
|
||||
for (j[4] = 0; j[4] < J[4]; ++j[4]) {
|
||||
for (j[5] = 0; j[5] < J[5]; ++j[5]) {
|
||||
for (i = 0; i < ARRAYLEN(J); ++i) {
|
||||
D[i] = S[j[i]] + K[i] - R[i];
|
||||
}
|
||||
if ((error = DifferSumSq(D, L, H) / HM) < least) {
|
||||
least = error;
|
||||
memcpy(O, j, sizeof(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 6; ++i) {
|
||||
N[i] += S[O[i]];
|
||||
}
|
||||
}
|
||||
return lround(least);
|
||||
}
|
83
dsp/core/getintegercoefficients8.c
Normal file
83
dsp/core/getintegercoefficients8.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/q.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Same as GetIntegerCoefficients() but with eight terms.
|
||||
* @cost ~3ms
|
||||
*/
|
||||
long GetIntegerCoefficients8(long N[static 8], const double C[static 8], long M,
|
||||
long L, long H) {
|
||||
int i;
|
||||
int j[8], J[8];
|
||||
int O[8] = {0};
|
||||
int S[3] = {0, -1, +1};
|
||||
double R[8], K[8], D[8], Z, least, error;
|
||||
least = 1;
|
||||
Z = 1L << M;
|
||||
for (i = 0; i < ARRAYLEN(J); ++i) {
|
||||
least *= H - L;
|
||||
if (fabs(C[i]) > DBL_MIN) {
|
||||
J[i] = ARRAYLEN(S);
|
||||
R[i] = C[i] * Z;
|
||||
K[i] = rint(R[i]);
|
||||
N[i] = K[i];
|
||||
} else {
|
||||
J[i] = 1;
|
||||
R[i] = 0;
|
||||
K[i] = 0;
|
||||
N[i] = 0;
|
||||
}
|
||||
}
|
||||
if (least > 1) {
|
||||
for (j[0] = 0; j[0] < J[0]; ++j[0]) {
|
||||
for (j[1] = 0; j[1] < J[1]; ++j[1]) {
|
||||
for (j[2] = 0; j[2] < J[2]; ++j[2]) {
|
||||
for (j[3] = 0; j[3] < J[3]; ++j[3]) {
|
||||
for (j[4] = 0; j[4] < J[4]; ++j[4]) {
|
||||
for (j[5] = 0; j[5] < J[5]; ++j[5]) {
|
||||
for (j[6] = 0; j[6] < J[6]; ++j[6]) {
|
||||
for (j[7] = 0; j[7] < J[7]; ++j[7]) {
|
||||
for (i = 0; i < ARRAYLEN(J); ++i) {
|
||||
D[i] = S[j[i]] + K[i] - R[i];
|
||||
}
|
||||
if ((error = DifferSumSq8(D, L, H) / Z) < least) {
|
||||
least = error;
|
||||
memcpy(O, j, sizeof(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
N[i] += S[O[i]];
|
||||
}
|
||||
}
|
||||
return lround(least);
|
||||
}
|
12
dsp/core/half.h
Normal file
12
dsp/core/half.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_HALF_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_HALF_H_
|
||||
#include "libc/macros.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Divides integer in half w/ rounding.
|
||||
*/
|
||||
#define HALF(X) (((X) + 1) / (2 / TYPE_INTEGRAL(typeof(X))))
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_HALF_H_ */
|
79
dsp/core/illumination.c
Normal file
79
dsp/core/illumination.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/illumination.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
const double kIlluminantA[3] = {1.0985, 1, 0.35585};
|
||||
const double kIlluminantAD10[3] = {1.11144, 1, 0.35200};
|
||||
const double kIlluminantC[3] = {0.98074, 1, 1.18232};
|
||||
const double kIlluminantCD10[3] = {0.97285, 1, 1.16145};
|
||||
const double kIlluminantD50[3] = {0.96422, 1, 0.82521};
|
||||
const double kIlluminantD50D10[3] = {0.9672, 1, 0.81427};
|
||||
const double kIlluminantD55[3] = {0.95682, 1, 0.92149};
|
||||
const double kIlluminantD55D10[3] = {0.95799, 1, 0.90926};
|
||||
const double kIlluminantD65[3] = {0.95047, 1, 1.08883};
|
||||
const double kIlluminantD65D10[3] = {0.94811, 1, 1.07304};
|
||||
const double kIlluminantD75[3] = {0.94972, 1, 1.22638};
|
||||
const double kIlluminantD75D10[3] = {0.94416, 1, 1.20641};
|
||||
const double kIlluminantF2[3] = {0.99187, 1, 0.67395};
|
||||
const double kIlluminantF2D10[3] = {1.0328, 1, 0.69026};
|
||||
const double kIlluminantF7[3] = {0.95044, 1, 1.08755};
|
||||
const double kIlluminantF7D10[3] = {0.95792, 1, 1.07687};
|
||||
const double kIlluminantF11[3] = {1.00966, 1, 0.6437};
|
||||
const double kIlluminantF11D10[3] = {1.03866, 1, 0.65627};
|
||||
|
||||
/**
|
||||
* System of equations used for changing illumination.
|
||||
*
|
||||
* @see brucelindbloom.com/Eqn_ChromAdapt.html “The Bradford method is
|
||||
* the newest of the three methods, and is considered by most
|
||||
* experts to be the best of them. This is the method used in Adobe
|
||||
* Photoshop. A related article comparing the chromatic adaptation
|
||||
* algorithms may be found here.” ─Quoth Bruce Lindbloom
|
||||
*/
|
||||
const double kBradford[3][3] = {
|
||||
{0.8951, 0.2664, -.1614},
|
||||
{-.7502, 1.7135, 0.0367},
|
||||
{0.0389, -.0685, 1.0296},
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes lightbulb changing coefficients.
|
||||
*
|
||||
* @param R will store result
|
||||
* @param S has intended input illuminant primaries
|
||||
* @param D has desired output illuminant primaries
|
||||
* @return R
|
||||
* @see brucelindbloom.com/Eqn_ChromAdapt.html
|
||||
* @see fluxometer.com/rainbow/
|
||||
*/
|
||||
void *GetChromaticAdaptationMatrix(double R[3][3], const double S[3],
|
||||
const double D[3]) {
|
||||
double M[3][3], T[3][3], U[3][3], V[3], W[3];
|
||||
matvmul3(V, kBradford, S);
|
||||
matvmul3(W, kBradford, D);
|
||||
memset(M, 0, sizeof(M));
|
||||
M[0][0] = W[0] / V[0];
|
||||
M[1][1] = W[1] / V[1];
|
||||
M[2][2] = W[2] / V[2];
|
||||
return matmul3(R, matmul3(T, kBradford, M),
|
||||
inv3(U, kBradford, det3(kBradford)));
|
||||
}
|
31
dsp/core/illumination.h
Normal file
31
dsp/core/illumination.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const double kBradford[3][3];
|
||||
extern const double kIlluminantA[3];
|
||||
extern const double kIlluminantAD10[3];
|
||||
extern const double kIlluminantC[3];
|
||||
extern const double kIlluminantCD10[3];
|
||||
extern const double kIlluminantD50[3];
|
||||
extern const double kIlluminantD50D10[3];
|
||||
extern const double kIlluminantD55[3];
|
||||
extern const double kIlluminantD55D10[3];
|
||||
extern const double kIlluminantD65[3];
|
||||
extern const double kIlluminantD65D10[3];
|
||||
extern const double kIlluminantD75[3];
|
||||
extern const double kIlluminantD75D10[3];
|
||||
extern const double kIlluminantF2[3];
|
||||
extern const double kIlluminantF2D10[3];
|
||||
extern const double kIlluminantF7[3];
|
||||
extern const double kIlluminantF7D10[3];
|
||||
extern const double kIlluminantF11[3];
|
||||
extern const double kIlluminantF11D10[3];
|
||||
|
||||
void *GetChromaticAdaptationMatrix(double[3][3], const double[3],
|
||||
const double[3]);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_ILLUMINANT_H_ */
|
46
dsp/core/inv3.c
Normal file
46
dsp/core/inv3.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Computes 𝐀⁻¹ inverted 3×3 matrix, if it exists.
|
||||
*
|
||||
* @param 𝐁 is destination memory
|
||||
* @param 𝐀 is input matrix, which can't overlap 𝐁
|
||||
* @param 𝑑 is |𝐀| the determinant scalar or 0 if degenerate
|
||||
* @return 𝐀⁻¹ stored inside 𝐁 or NaNs if 𝑑=0
|
||||
* @define 𝐀⁻¹=𝐁 such that 𝐀×𝐁=𝐁×𝐀=𝐈ₙ
|
||||
* @see det3()
|
||||
*/
|
||||
void *inv3(double B[restrict 3][3], const double A[restrict 3][3], double d) {
|
||||
d = d ? 1 / d : NAN;
|
||||
B[0][0] = (A[1][1] * A[2][2] - A[2][1] * A[1][2]) * d;
|
||||
B[0][1] = (A[2][1] * A[0][2] - A[0][1] * A[2][2]) * d;
|
||||
B[0][2] = (A[0][1] * A[1][2] - A[1][1] * A[0][2]) * d;
|
||||
B[1][0] = (A[2][0] * A[1][2] - A[1][0] * A[2][2]) * d;
|
||||
B[1][1] = (A[0][0] * A[2][2] - A[2][0] * A[0][2]) * d;
|
||||
B[1][2] = (A[1][0] * A[0][2] - A[0][0] * A[1][2]) * d;
|
||||
B[2][0] = (A[1][0] * A[2][1] - A[2][0] * A[1][1]) * d;
|
||||
B[2][1] = (A[2][0] * A[0][1] - A[0][0] * A[2][1]) * d;
|
||||
B[2][2] = (A[0][0] * A[1][1] - A[1][0] * A[0][1]) * d;
|
||||
return B;
|
||||
}
|
23
dsp/core/ituround.h
Normal file
23
dsp/core/ituround.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_ITUROUND_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_ITUROUND_H_
|
||||
#include "libc/math.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* An ITU recommended rounding function.
|
||||
*
|
||||
* 1. Negative numbers round toward zero
|
||||
* 2. Positive numbers round toward infinity
|
||||
*
|
||||
* @see round(), rint()
|
||||
*/
|
||||
static inline pureconst artificial long ituround(double x) {
|
||||
return floor(x + .5);
|
||||
}
|
||||
|
||||
static inline pureconst artificial int ituroundf(float x) {
|
||||
return floorf(x + .5f);
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_ITUROUND_H_ */
|
47
dsp/core/ks8.h
Normal file
47
dsp/core/ks8.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_KS8_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_KS8_H_
|
||||
#include "libc/macros.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Performs 16-bit scaled rounded madd w/ eight coefficients or fewer.
|
||||
*
|
||||
* (Σᵢ₌₀₋₈𝑘ᵢ𝑥ᵢ + 2ᵐ⁻¹)/2ᵐ
|
||||
*
|
||||
* @note intent is avoiding type promotion
|
||||
*/
|
||||
#define KS8(M, K1, K2, K3, K4, K5, K6, K7, K8, X1, X2, X3, X4, X5, X6, X7, X8) \
|
||||
({ \
|
||||
short x1, x2, x3, x4, x5, x6, x7, x8; \
|
||||
x1 = X1; \
|
||||
x2 = X2; \
|
||||
x3 = X3; \
|
||||
x4 = X4; \
|
||||
x5 = X5; \
|
||||
x6 = X6; \
|
||||
x7 = X7; \
|
||||
x8 = X8; \
|
||||
x1 *= K1; \
|
||||
x2 *= K2; \
|
||||
x3 *= K3; \
|
||||
x4 *= K4; \
|
||||
x5 *= K5; \
|
||||
x6 *= K6; \
|
||||
x7 *= K7; \
|
||||
x8 *= K8; \
|
||||
x1 += x2; \
|
||||
x3 += x4; \
|
||||
x5 += x6; \
|
||||
x7 += x8; \
|
||||
x1 += x3; \
|
||||
x5 += x7; \
|
||||
x1 += x5; \
|
||||
if (M) { \
|
||||
x1 += 1 << MAX(0, M - 1); \
|
||||
x1 >>= M; \
|
||||
} \
|
||||
x1; \
|
||||
})
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_KS8_H_ */
|
43
dsp/core/kss8.h
Normal file
43
dsp/core/kss8.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_KSS8_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_KSS8_H_
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* Performs 16-bit scaled rounded saturated madd w/ eight coefficients or fewer.
|
||||
*
|
||||
* (Σᵢ₌₀₋₈𝑘ᵢ𝑥ᵢ + 2ᵐ⁻¹)/2ᵐ
|
||||
*
|
||||
* @note compiler struggles with this
|
||||
*/
|
||||
#define KSS8(M, K1, K2, K3, K4, K5, K6, K7, K8, X1, X2, X3, X4, X5, X6, X7, \
|
||||
X8) \
|
||||
({ \
|
||||
short x1, x2, x3, x4, x5, x6, x7, x8; \
|
||||
x1 = X1, x2 = X2, x3 = X3, x4 = X4; \
|
||||
x5 = X5, x6 = X6, x7 = X7, x8 = X8; \
|
||||
x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 * K1)); \
|
||||
x2 = MIN(SHRT_MAX, MAX(SHRT_MIN, x2 * K2)); \
|
||||
x3 = MIN(SHRT_MAX, MAX(SHRT_MIN, x3 * K3)); \
|
||||
x4 = MIN(SHRT_MAX, MAX(SHRT_MIN, x4 * K4)); \
|
||||
x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 * K5)); \
|
||||
x6 = MIN(SHRT_MAX, MAX(SHRT_MIN, x6 * K6)); \
|
||||
x7 = MIN(SHRT_MAX, MAX(SHRT_MIN, x7 * K7)); \
|
||||
x8 = MIN(SHRT_MAX, MAX(SHRT_MIN, x8 * K8)); \
|
||||
x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x2)); \
|
||||
x3 = MIN(SHRT_MAX, MAX(SHRT_MIN, x3 + x4)); \
|
||||
x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 + x6)); \
|
||||
x7 = MIN(SHRT_MAX, MAX(SHRT_MIN, x7 + x8)); \
|
||||
x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x3)); \
|
||||
x5 = MIN(SHRT_MAX, MAX(SHRT_MIN, x5 + x7)); \
|
||||
x1 = MIN(SHRT_MAX, MAX(SHRT_MIN, x1 + x5)); \
|
||||
if (M) { \
|
||||
x1 += 1 << MAX(0, M - 1); \
|
||||
x1 >>= M; \
|
||||
} \
|
||||
x1; \
|
||||
})
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_KSS8_H_ */
|
38
dsp/core/matmul3.c
Normal file
38
dsp/core/matmul3.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Multiplies 3×3 matrices.
|
||||
*/
|
||||
void *matmul3(double R[restrict 3][3], const double A[3][3],
|
||||
const double B[3][3]) {
|
||||
int i, j, k;
|
||||
memset(R, 0, sizeof(double) * 3 * 3);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (j = 0; j < 3; ++j) {
|
||||
for (k = 0; k < 3; ++k) {
|
||||
R[i][j] += A[k][j] * B[i][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return R;
|
||||
}
|
32
dsp/core/matvmul3.c
Normal file
32
dsp/core/matvmul3.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
/**
|
||||
* Computes M×V.
|
||||
*
|
||||
* @see vmatmul3() for noncommutative corollary
|
||||
*/
|
||||
void *matvmul3(double R[restrict 3], const double M[3][3], const double V[3]) {
|
||||
R[0] = V[0] * M[0][0] + V[1] * M[0][1] + V[2] * M[0][2];
|
||||
R[1] = V[0] * M[1][0] + V[1] * M[1][1] + V[2] * M[1][2];
|
||||
R[2] = V[0] * M[2][0] + V[1] * M[2][1] + V[2] * M[2][2];
|
||||
return R;
|
||||
}
|
64
dsp/core/mulaw.S
Normal file
64
dsp/core/mulaw.S
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
#define BIAS 0x84
|
||||
|
||||
/ Encodes audio sample with µ-Law.
|
||||
/
|
||||
/ This is both the highest quality and most widely supported
|
||||
/ telephony codec, whose use was phased out in the 2000's in
|
||||
/ favor of cost-saving GSM audio compression that was so bad
|
||||
/ consumers were willing to pay more cash, for the privilege
|
||||
/ of saving telcos even more money w/ text messaging. Mu Law
|
||||
/ reduces PCM data to half its original size, by diminishing
|
||||
/ audio bands not vocalized by human voice.
|
||||
/
|
||||
/ @param %edi is pcm sample
|
||||
/ @return %eax is uint8_t encoded sample
|
||||
mulaw: .leafprologue
|
||||
.profilable
|
||||
mov $BIAS,%eax
|
||||
xor %edx,%edx
|
||||
test %edi,%edi
|
||||
js 1f
|
||||
lea (%edi,%eax),%eax
|
||||
mov $0xFF,%dl
|
||||
jmp 2f
|
||||
1: sub %edi,%eax
|
||||
mov $0x7F,%dl
|
||||
2: mov %eax,%esi
|
||||
or $0xFF,%sil
|
||||
bsr %esi,%esi
|
||||
sub $7,%esi
|
||||
cmp $8,%esi
|
||||
jge 4f
|
||||
lea 3(%rdx),%ecx
|
||||
sar %cl,%eax
|
||||
and $0xF,%eax
|
||||
shl $4,%esi
|
||||
or %esi,%eax
|
||||
xor %edx,%eax
|
||||
3: .leafepilogue
|
||||
4: xor $0x7F,%dl
|
||||
mov %edx,%eax
|
||||
jmp 3b
|
||||
.endfn mulaw,globl
|
||||
.yoink __FILE__
|
27
dsp/core/q.h
Normal file
27
dsp/core/q.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_Q_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_Q_H_
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/**
|
||||
* @fileoverview Fixed point arithmetic macros.
|
||||
* @see en.wikipedia.org/wiki/Q_(number_format)
|
||||
*/
|
||||
|
||||
#define F2Q(Q, I) MIN((1 << Q) - 1, roundf((I) * (1.f * ((1 << Q) - 1))))
|
||||
#define Q2F(Q, I) ((I) * (1.f / ((1 << Q) - 1)))
|
||||
#define QRS(Q, X) (((X) + (1 << (Q - 1))) >> Q)
|
||||
#define LQRS(Q, X) (((X) + (1L << (Q - 1))) >> Q)
|
||||
|
||||
double DifferSumSq(const double[static 6], double, double);
|
||||
double DifferSumSq8(const double[static 8], double, double);
|
||||
|
||||
long GetIntegerCoefficients(long[static 6], const double[static 6], long, long,
|
||||
long);
|
||||
long GetIntegerCoefficients8(long[static 8], const double[static 8], long, long,
|
||||
long);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_Q_H_ */
|
41
dsp/core/sad16x8n.S
Normal file
41
dsp/core/sad16x8n.S
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.align 16
|
||||
|
||||
/ Mixes audio.
|
||||
/
|
||||
/ @param rdi is # aligned int16[16] sample chunks to process
|
||||
/ @param rsi points to aligned pcm s16le input/output memory
|
||||
/ @param rdx points to aligned pcm s16le [0..1] input memory
|
||||
sad16x8n:
|
||||
.leafprologue
|
||||
.profilable
|
||||
test %rdi,%rdi
|
||||
jz 1f
|
||||
shl $3,%rdi
|
||||
0: sub $8,%rdi
|
||||
movdqa (%rsi,%rdi,2),%xmm0
|
||||
paddsw (%rdx,%rdi,2),%xmm0
|
||||
movdqa %xmm0,(%rsi,%rdi,2)
|
||||
jnz 0b
|
||||
1: .leafepilogue
|
||||
.endfn sad16x8n,globl,hidden
|
||||
.yoink __FILE__
|
50
dsp/core/scalevolume.c
Normal file
50
dsp/core/scalevolume.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/limits.h"
|
||||
|
||||
/**
|
||||
* Increases or decreases audio volume.
|
||||
*
|
||||
* @param 𝑝 is two-power w/ effective range [-15,15]
|
||||
*/
|
||||
void scalevolume(size_t n, int16_t pcm[n][8], int p) {
|
||||
/* TODO(jart): This isn't acceptable. */
|
||||
size_t i, j;
|
||||
if (p > 0) {
|
||||
if (p > 15) p = 15;
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
pcm[i][j] =
|
||||
MIN(SHRT_MAX, MAX(SHRT_MIN, (int)((unsigned)pcm[i][j] << p)));
|
||||
}
|
||||
}
|
||||
} else if (p < 0) {
|
||||
p = -p;
|
||||
if (p > 15) p = 15;
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
pcm[i][j] = SAR(pcm[i][j], p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
dsp/core/twixt8.h
Normal file
24
dsp/core/twixt8.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef COSMOPOLITAN_DSP_CORE_TWIXT8_H_
|
||||
#define COSMOPOLITAN_DSP_CORE_TWIXT8_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* 8-bit linear interpolation kernel.
|
||||
*/
|
||||
static inline pureconst artificial unsigned char twixt8(unsigned char al,
|
||||
unsigned char bl,
|
||||
unsigned char p) {
|
||||
short bx;
|
||||
bx = bl;
|
||||
bx -= al;
|
||||
bx *= p;
|
||||
bx >>= 8;
|
||||
bx += al;
|
||||
al = bx;
|
||||
return al;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_CORE_TWIXT8_H_ */
|
32
dsp/core/vmatmul3.c
Normal file
32
dsp/core/vmatmul3.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
|
||||
/**
|
||||
* Computes V×M.
|
||||
*
|
||||
* @see matvmul3() for noncommutative corollary
|
||||
*/
|
||||
void *vmatmul3(double R[restrict 3], const double V[3], const double M[3][3]) {
|
||||
R[0] = V[0] * M[0][0] + V[1] * M[1][0] + V[2] * M[2][0];
|
||||
R[1] = V[0] * M[0][1] + V[1] * M[1][1] + V[2] * M[2][1];
|
||||
R[2] = V[0] * M[0][2] + V[1] * M[1][2] + V[2] * M[2][2];
|
||||
return R;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue