#include "compute.h" #include "fft.h" #include <math.h> #define MIN_SAMPLES 256 #define MAX_SAMPLES 2048 //static inline float todB_a(const float *x); void compute_spectrum(float * data, int width, double rate, float *output); gfloat compute_level(const float *data, size_t nsamples, size_t nchan) { double rate=44100; //TODO dynamique size_t i; float input[MAX_SAMPLES], output[128]; float value; int gain=20, range=80; 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); for (i=0;i<MIN_SAMPLES;i++) { if ( (i/nsamples)%2==1 ) input[i]=data[i/**nchan*/]; else input[i]=data[nsamples-i-1]; } nsamples=MIN_SAMPLES; } else { for (i=0;i<nsamples;i++) { input[i]=data[i/**nchan*/]; } } compute_spectrum(input, nsamples, rate, output); //printf("%f\n", output[0]); value=0.f; for (i=1;i<128;i++) { value+=output[i]; } // Mean value value/=127.f; // 0.0 to 1.0 range value=(value + gain + range) / (double)range; value=MAX(0.f,value); value=MIN(value,1.f); // printf("DEBUG: nsamples=%8i value==%f\n", nsamples, value); 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, double rate, float *output) { int i; float processed[256]={0.0f}; //TODO : remove init here(handy for step by step debug) float in[256]={0.0f}; float out[256]={0.0f}; int start = 0; int windows = 0; while (start + 256 <= width) { for (i=0; i<256; i++) in[i] = data[start + i]; // Windowing : Hanning for (i=0; i<256; i++) in[i] *= 0.50 - 0.50 * cos(2 * M_PI * i / (256 - 1)); PowerSpectrum(in, out); // Take real part of result for (i=0; i<256/2; i++) processed[i] += out[i]; start += 256/2; windows++; } // Convert to decibels // But do it safely; -Inf is nobody's friend for (i = 0; i < 256/2; i++){ float temp=(processed[i] / 256 / windows); if (temp > 0.0) processed[i] = 10*log10(temp); else processed[i] = 0; } for(i=0;i<256/2;i++) output[i] = processed[i]; } void audio2hsv_1(gint audio_level, gint *light_h, gint *light_s, gint *light_v) { // Dummy code *light_h=-audio_level; *light_s=audio_level; *light_v=65535; } void hsv2rgb(gint h, gint s, gint v, gint *r, gint *g, gint *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; } } }