From e5c5a94c3db7ed4b71be2f15aa149829d45afbb9 Mon Sep 17 00:00:00 2001
From: Jari Vetoniemi <mailroxas@gmail.com>
Date: Sat, 3 Nov 2018 04:58:49 +0200
Subject: saner transcoding, + f32 encoding support

---
 src/util/dsp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/dsp.h |  1 +
 2 files changed, 56 insertions(+)

(limited to 'src/util')

diff --git a/src/util/dsp.c b/src/util/dsp.c
index 3b156d1..8c3ae5c 100644
--- a/src/util/dsp.c
+++ b/src/util/dsp.c
@@ -440,6 +440,61 @@ resamp_init(struct resamp *p, unsigned int iblksz,
 #endif
 }
 
+static inline unsigned int
+adata_to_f32(int x)
+{
+	union {
+		float f; // assumes ieee754
+		unsigned int x;
+	} u = { .f = (float)x / ADATA_UNIT };
+	return u.x;
+}
+
+void
+enc_do_float(struct conv *p, unsigned char *in, unsigned char *out, int todo)
+{
+	unsigned int f;
+	adata_t *idata;
+	unsigned int s;
+	unsigned int obps;
+	unsigned int i;
+	unsigned char *odata;
+	int obnext;
+	int osnext;
+
+#ifdef DEBUG
+	if (log_level >= 4) {
+		log_puts("enc: copying ");
+		log_putu(todo);
+		log_puts(" frames\n");
+	}
+#endif
+	/*
+	 * Partially copy structures into local variables, to avoid
+	 * unnecessary indirections; this also allows the compiler to
+	 * order local variables more "cache-friendly".
+	 */
+	idata = (adata_t *)in;
+	odata = out;
+	obps = p->bps;
+	obnext = p->bnext;
+	osnext = p->snext;
+
+	/*
+	 * Start conversion.
+	 */
+	odata += p->bfirst;
+	for (f = todo * p->nch; f > 0; f--) {
+		s = adata_to_f32((int)*idata++);
+		for (i = obps; i > 0; i--) {
+			*odata = (unsigned char)s;
+			s >>= 8;
+			odata += obnext;
+		}
+		odata += osnext;
+	}
+}
+
 /*
  * encode "todo" frames from native to foreign encoding
  */
diff --git a/src/util/dsp.h b/src/util/dsp.h
index d057d37..c23f461 100644
--- a/src/util/dsp.h
+++ b/src/util/dsp.h
@@ -149,6 +149,7 @@ int aparams_native(struct aparams *);
 void resamp_getcnt(struct resamp *, int *, int *);
 void resamp_do(struct resamp *, adata_t *, adata_t *, int, int);
 void resamp_init(struct resamp *, unsigned int, unsigned int, int);
+void enc_do_float(struct conv *, unsigned char *, unsigned char *, int);
 void enc_do(struct conv *, unsigned char *, unsigned char *, int);
 void enc_sil_do(struct conv *, unsigned char *, int);
 void enc_init(struct conv *, struct aparams *, int);
-- 
cgit v1.2.3-70-g09d2