summaryrefslogtreecommitdiff
path: root/tests/test6/compute.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test6/compute.c')
-rw-r--r--tests/test6/compute.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/test6/compute.c b/tests/test6/compute.c
new file mode 100644
index 0000000..017416b
--- /dev/null
+++ b/tests/test6/compute.c
@@ -0,0 +1,138 @@
+#include "compute.h"
+
+#include "fft.h"
+#include <math.h>
+
+#define MIN_SAMPLES 256
+#define MAX_SAMPLES 2048
+
+//#define MAX(a,b) (a>b?a:b)
+//#define MIN(a,b) (a<b?a:b)
+
+//static inline float todB_a(const float *x);
+void compute_spectrum(float *data, int width, float output[PSHalf]);
+
+
+float compute_level(const float *data, size_t nsamples, int rate) {
+
+ size_t i;
+ float input[MAX_SAMPLES], pwrspec[PSHalf];
+ float value;
+ int f, min_f_index, max_f_index;
+
+ if (nsamples >= MAX_SAMPLES) {
+ printf("WARN : nsamples >= MAX_SAMPLES : %i >= %i\n", nsamples, MAX_SAMPLES);
+ nsamples=MAX_SAMPLES;
+ }
+ if (nsamples < MIN_SAMPLES) {
+ printf("WARN : nsamples < MIN_SAMPLES : %i >= %i\n", nsamples, MIN_SAMPLES);
+ // Replicate with symmetry the sound to obtain an input buffer of the minimal len
+ for (i=0;i<MIN_SAMPLES;i++) {
+ if ( (i/nsamples)%2==1 )
+ input[i]=data[i]; // First channel only
+ else
+ input[i]=data[nsamples-i-1];
+ }
+ nsamples=MIN_SAMPLES;
+ } else {
+ for (i=0;i<nsamples;i++) {
+ input[i]=data[i]; // First channel only
+ }
+ }
+
+ compute_spectrum(input, nsamples, pwrspec);
+
+ // Compute the mean power for 200Hz to 2000Hz band
+ min_f_index=((float)PSHalf)*200.f/(((float)rate)/2.f);
+ max_f_index=((float)PSHalf)*2000.f/(((float)rate)/2.f);
+
+ value=0.f;
+ for (f=min_f_index;f<=max_f_index;f++) {
+ value+=pwrspec[f];
+ }
+ // Mean value
+ value=value/(max_f_index-min_f_index+1);
+
+ return value;
+}
+/*
+static inline float todB_a(const float *x){
+ return (float)((*(int32_t *)x)&0x7fffffff) * 7.17711438e-7f -764.6161886f;
+}
+*/
+// Adapted from Audacity
+void compute_spectrum(float *data, int width, float output[PSHalf]) {
+
+ int i, start, windows;
+ float temp;
+ float in[PSNumS];
+ float out[PSHalf];
+ float processed[PSHalf]={0.0f};
+
+ start = 0;
+ windows = 0;
+ while (start + PSNumS <= width) {
+ // Windowing : Hanning
+ for (i=0; i<PSNumS; i++)
+ in[i] = data[start+i] *(0.50-0.50*cos(2*M_PI*i/(PSNumS-1)));
+
+ // Returns only the real part of the result
+ PowerSpectrum(in, out);
+
+ for (i=0; i<PSHalf; i++)
+ processed[i] += out[i];
+
+ start += PSHalf;
+ windows++;
+ }
+ // Convert to decibels
+ // But do it safely; -Inf is nobody's friend
+ for (i = 0; i < PSHalf; i++){
+ temp=(processed[i] / PSNumS / windows);
+ if (temp > 0.0)
+ output[i] = 10*log10(temp);
+ else
+ output[i] = 0;
+ }
+}
+
+void audio2hsv_1(int audio_level, int *light_h, int *light_s, int *light_v) {
+ // Dummy code
+ *light_h=-audio_level;
+ *light_s=audio_level;
+ *light_v=65535;
+}
+
+
+void hsv2rgb(int h, int s, int v, int *r, int *g, int *b) {
+ /*
+ * Purpose:
+ * Convert HSV values to RGB values
+ * All values are in the range [0..65535]
+ */
+ float F, M, N, K;
+ int I;
+
+ if ( s == 0 ) {
+ /*
+ * Achromatic case, set level of grey
+ */
+ *r = v;
+ *g = v;
+ *b = v;
+ } else {
+ I = (int) h/(65535/6); /* should be in the range 0..5 */
+ F = h - I; /* fractional part */
+
+ M = v * (1 - s);
+ N = v * (1 - s * F);
+ K = v * (1 - s * (1 - F));
+
+ if (I == 0) { *r = v; *g = K; *b = M; }
+ if (I == 1) { *r = N; *g = v; *b = M; }
+ if (I == 2) { *r = M; *g = v; *b = K; }
+ if (I == 3) { *r = M; *g = N; *b = v; }
+ if (I == 4) { *r = K; *g = M; *b = v; }
+ if (I == 5) { *r = v; *g = M; *b = N; }
+ }
+}