ref: 50eb0bd1a7fbc67d69a9acedb1b15be2c7154465
parent: e41744273f75f23a5dc9d1d705bb517fff51b7b1
parent: b6c4ec4579a2f9bce76ae66ac09812947fa12896
author: Christopher Snowhill <[email protected]>
date: Thu Feb 4 12:09:57 EST 2016
Merge pull request #24 from dmitrykos/master Compatibility and usability improvements.
--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -228,6 +228,8 @@
long duh_get_length(DUH *duh);
const char *duh_get_tag(DUH *duh, const char *key);
+int duh_get_tag_iterator_size(DUH *duh);
+int duh_get_tag_iterator_get(DUH *duh, const char **key, const char **tag, int i);
/* Signal Rendering Functions */
@@ -317,14 +319,40 @@
/* DUH Rendering Functions */
-long duh_render(
+/* For packed integers: 8, 16, 24-bit wide.
+ * Intermediary buffer sig_samples must be freed with destroy_sample_buffer()
+ * in the end of the rendering loop.
+ */
+long duh_render_int(
DUH_SIGRENDERER *sigrenderer,
+ sample_t ***sig_samples,
+ long *sig_samples_size,
int bits, int unsign,
float volume, float delta,
long size, void *sptr
);
+/* For floats: 32, 64-bit wide.
+ * Intermediary buffer sig_samples must be freed with destroy_sample_buffer()
+ * in the end of the rendering loop.
+ */
+long duh_render_float(
+ DUH_SIGRENDERER *sigrenderer,
+ sample_t ***sig_samples,
+ long *sig_samples_size,
+ int bits,
+ float volume, float delta,
+ long size, void *sptr
+);
+
#ifdef DUMB_DECLARE_DEPRECATED
+
+long duh_render(
+ DUH_SIGRENDERER *sigrenderer,
+ int bits, int unsign,
+ float volume, float delta,
+ long size, void *sptr
+) DUMB_DEPRECATED;
long duh_render_signal(
DUH_SIGRENDERER *sigrenderer,
--- a/dumb/src/core/duhtag.c
+++ b/dumb/src/core/duhtag.c
@@ -36,3 +36,23 @@
return NULL;
}
+
+
+
+int duh_get_tag_iterator_size(DUH *duh)
+{
+ return (duh && duh->tag ? duh->n_tags : 0);
+}
+
+
+int duh_get_tag_iterator_get(DUH *duh, const char **key, const char **tag, int i)
+{
+ ASSERT(key);
+ ASSERT(value);
+ if (!duh || !duh->tag || i >= duh->n_tags) return -1;
+
+ *key = duh->tag[i][0];
+ *tag = duh->tag[i][1];
+
+ return 0;
+}
--- a/dumb/src/core/rendduh.c
+++ b/dumb/src/core/rendduh.c
@@ -70,8 +70,23 @@
#endif
+#define CONVERT24(src, pos) { \
+ signed int f = src; \
+ f = MID(-8388608, f, 8388607); \
+ ((unsigned char*)sptr)[pos ] = (f) & 0xFF; \
+ ((unsigned char*)sptr)[pos+1] = (f >> 8) & 0xFF; \
+ ((unsigned char*)sptr)[pos+2] = (f >> 16) & 0xFF; \
+}
+#define CONVERT32F(src, pos) { \
+ ((float*)sptr)[pos] = (float)((signed int)src) * (1.0f/(float)(0xffffff/2+1)); \
+}
+#define CONVERT64F(src, pos) { \
+ ((double*)sptr)[pos] = (double)((signed int)src) * (1.0/(double)(0xffffff/2+1)); \
+}
+
+
/* DEPRECATED */
DUH_SIGRENDERER *duh_start_renderer(DUH *duh, int n_channels, long pos)
{
@@ -79,7 +94,7 @@
}
-
+/* DEPRECATED */
long duh_render(
DUH_SIGRENDERER *sigrenderer,
int bits, int unsign,
@@ -135,6 +150,138 @@
return size;
}
+
+long duh_render_int(
+ DUH_SIGRENDERER *sigrenderer,
+ sample_t ***sig_samples,
+ long *sig_samples_size,
+ int bits, int unsign,
+ float volume, float delta,
+ long size, void *sptr
+)
+{
+ long n;
+
+ sample_t **sampptr;
+
+ int n_channels;
+
+ ASSERT(bits == 8 || bits == 16 || bits == 24);
+ ASSERT(sptr);
+ ASSERT(sig_samples);
+ ASSERT(sig_samples_size);
+
+ if (!sigrenderer)
+ return 0;
+
+ n_channels = duh_sigrenderer_get_n_channels(sigrenderer);
+
+ ASSERT(n_channels > 0);
+ /* This restriction will be removed when need be. At the moment, tightly
+ * optimised loops exist for exactly one or two channels.
+ */
+ ASSERT(n_channels <= 2);
+
+ if ((*sig_samples == NULL) || (*sig_samples_size != size))
+ {
+ destroy_sample_buffer(*sig_samples);
+ *sig_samples = allocate_sample_buffer(n_channels, size);
+ *sig_samples_size = size;
+ }
+ sampptr = *sig_samples;
+
+ if (!sampptr)
+ return 0;
+
+ dumb_silence(sampptr[0], n_channels * size);
+
+ size = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, sampptr);
+
+ if (bits == 24) {
+ long i = 0;
+ ASSERT(unsign == 0);
+
+ for (n = 0; n < size * n_channels; n++, i += 3) {
+ CONVERT24(sampptr[0][n], i);
+ }
+ } else
+ if (bits == 16) {
+ int signconv = unsign ? 0x8000 : 0x0000;
+
+ for (n = 0; n < size * n_channels; n++) {
+ CONVERT16(sampptr[0][n], n, signconv);
+ }
+ } else {
+ char signconv = unsign ? 0x80 : 0x00;
+
+ for (n = 0; n < size * n_channels; n++) {
+ CONVERT8(sampptr[0][n], n, signconv);
+ }
+ }
+
+ return size;
+}
+
+
+long duh_render_float(
+ DUH_SIGRENDERER *sigrenderer,
+ sample_t ***sig_samples,
+ long *sig_samples_size,
+ int bits,
+ float volume, float delta,
+ long size, void *sptr
+)
+{
+ long n;
+
+ sample_t **sampptr;
+
+ int n_channels;
+
+ ASSERT(bits == 32 || bits == 64);
+ ASSERT(sptr);
+ ASSERT(sig_samples);
+ ASSERT(sig_samples_size);
+
+ if (!sigrenderer)
+ return 0;
+
+ n_channels = duh_sigrenderer_get_n_channels(sigrenderer);
+
+ ASSERT(n_channels > 0);
+ /* This restriction will be removed when need be. At the moment, tightly
+ * optimised loops exist for exactly one or two channels.
+ */
+ ASSERT(n_channels <= 2);
+
+ if ((*sig_samples == NULL) || (*sig_samples_size != size))
+ {
+ destroy_sample_buffer(*sig_samples);
+ *sig_samples = allocate_sample_buffer(n_channels, size);
+ *sig_samples_size = size;
+ }
+ sampptr = *sig_samples;
+
+ if (!sampptr)
+ return 0;
+
+ dumb_silence(sampptr[0], n_channels * size);
+
+ size = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, sampptr);
+
+ if (bits == 64) {
+ for (n = 0; n < size * n_channels; n++) {
+ CONVERT64F(sampptr[0][n], n);
+ }
+ } else
+ if (bits == 32) {
+ for (n = 0; n < size * n_channels; n++) {
+ CONVERT32F(sampptr[0][n], n);
+ }
+ }
+
+ return size;
+}
/* DEPRECATED */
--- a/dumb/src/helpers/resampler.c
+++ b/dumb/src/helpers/resampler.c
@@ -11,6 +11,8 @@
#if TARGET_CPU_ARM || TARGET_CPU_ARM64
#define RESAMPLER_NEON
#endif
+#elif (defined(__arm__) && defined(__ARM_NEON__))
+#define RESAMPLER_NEON
#endif
#ifdef RESAMPLER_NEON
#include <arm_neon.h>