commit e2232599bef203dff421d7e3b93cf9b5da5da4c7
parent b46a6339de1a547093d2bdf271b2f8b7df8ed4de
Author: glenda <glenda@kobeni>
Date: Tue, 23 Jan 2024 17:19:14 +0000
src/wave: add freqdom
Diffstat:
2 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/src/wave/freqdom.c b/src/wave/freqdom.c
@@ -0,0 +1,78 @@
+#include <u.h>
+#include <libc.h>
+
+#include "freqdom.h"
+
+#define dct_cos(X, U) dct_matrix[U * DCT_N + X]
+
+s16int cos16_table[0x4000];
+
+double dct_alpha0, dct_alpha1, *dct_matrix;
+
+void
+init_cos16_table(void)
+{
+ double i;
+ s16int *p = cos16_table;
+ for (i = 0; p < cos16_table + 0x4000; i += 1.0/(0x4000), p++) {
+ *p = (s16int)(cos(i * PIO2) * 0x7fff);
+ }
+}
+
+s16int
+cos16(u16int t)
+{
+ switch((t/0x4000)){
+ default:
+ case 0:
+ return cos16_table[t&0x3fff];
+ case 1:
+ return -cos16_table[0x3fff - t&0x3fff];
+ case 2:
+ return -cos16_table[t&0x3fff];
+ case 3:
+ return cos16_table[0x3fff - t&0x3fff];
+ }
+}
+
+void
+init_dct(void)
+{
+ dct_matrix = malloc(sizeof(double) * DCT_N * DCT_N);
+ int x, u;
+ for (x = 0; x < DCT_N; x++) {
+ for (u = 0; u < DCT_N; u++) {
+ dct_cos(x, u) = cos(PI * ( 2 * x + 1) * u / (2 * DCT_N));
+ }
+ }
+ dct_alpha0=sqrt(1.0/DCT_N);
+ dct_alpha1=sqrt(2.0/DCT_N);
+}
+
+s16int
+dct(int u, s16int *buf)
+{
+ int x;
+ double f, d = 0;
+ for (x = 0; x < DCT_N; x++) {
+ f = buf[x];
+ d += f * dct_cos(x, u);
+ }
+ if (u == 0) return dct_alpha0 * d;
+ return dct_alpha1 * d;
+}
+
+s16int
+invdct(int x, s16int *buf)
+{
+ int u;
+ double f, p, d = 0;
+ double alpha = dct_alpha0;
+ for (u = 0; u < DCT_N; u++) {
+ f = buf[u];
+ p = alpha * f * dct_cos(x, u);
+ d += p;
+ alpha = dct_alpha1;
+ }
+ return d;
+}
diff --git a/src/wave/freqdom.h b/src/wave/freqdom.h
@@ -0,0 +1,9 @@
+enum {
+ DCT_N = 2048,
+};
+
+void init_cos16_table(void);
+s16int cos16(u16int t);
+void init_dct(void);
+s16int dct(int u, s16int *buf);
+s16int invdct(int x, s16int *buf);