summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-11-03 04:58:49 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-11-03 04:58:49 +0200
commite5c5a94c3db7ed4b71be2f15aa149829d45afbb9 (patch)
treec3eee5f303854890f10e9e04db501ff7eb0120d4 /src/util
parentabf068e9f37d8f150c438ded3b56f63de6954bcf (diff)
saner transcoding, + f32 encoding support
Diffstat (limited to 'src/util')
-rw-r--r--src/util/dsp.c55
-rw-r--r--src/util/dsp.h1
2 files changed, 56 insertions, 0 deletions
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);