summaryrefslogtreecommitdiff
path: root/src/audio/ola.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/ola.cc')
-rw-r--r--src/audio/ola.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/audio/ola.cc b/src/audio/ola.cc
new file mode 100644
index 0000000..738df85
--- /dev/null
+++ b/src/audio/ola.cc
@@ -0,0 +1,34 @@
+// This file is part of the 64k demo project.
+// Implements batch OLA encode/decode shared by spectool and tests.
+// See ola.h for API documentation.
+
+#include "audio/ola.h"
+#include "audio/window.h"
+#include <string.h>
+
+void ola_encode(const float* pcm, int n_samples, float* spec, int num_frames) {
+ float win[DCT_SIZE];
+ hann_window_512(win);
+ float chunk[DCT_SIZE];
+ for (int f = 0; f < num_frames; ++f) {
+ const int start = f * OLA_HOP_SIZE;
+ const int avail =
+ (start + DCT_SIZE <= n_samples) ? DCT_SIZE : n_samples - start;
+ for (int i = 0; i < avail; ++i)
+ chunk[i] = pcm[start + i] * win[i];
+ memset(chunk + avail, 0, (DCT_SIZE - avail) * sizeof(float));
+ fdct_512(chunk, spec + f * DCT_SIZE);
+ }
+}
+
+void ola_decode(const float* spec, int num_frames, float* pcm) {
+ float overlap[OLA_OVERLAP] = {};
+ float tmp[DCT_SIZE];
+ for (int f = 0; f < num_frames; ++f) {
+ idct_512(spec + f * DCT_SIZE, tmp);
+ for (int j = 0; j < OLA_HOP_SIZE; ++j)
+ pcm[f * OLA_HOP_SIZE + j] = tmp[j] + overlap[j];
+ for (int j = 0; j < OLA_OVERLAP; ++j)
+ overlap[j] = tmp[OLA_HOP_SIZE + j];
+ }
+}