diff options
author | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2012-06-16 21:16:46 +0000 |
---|---|---|
committer | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2012-06-16 21:16:46 +0000 |
commit | 593e1cbe3470f409c19a7f06f5d10c6f5677361a (patch) | |
tree | 94ef0cbc5e13e71e11a13629b64ecfc126faa5a1 /tests/test6/compute.c | |
parent | 8f2cf274f4101ed1d05ea3401bdd54c5949e2420 (diff) | |
download | 2012-violon-leds-593e1cbe3470f409c19a7f06f5d10c6f5677361a.tar.gz 2012-violon-leds-593e1cbe3470f409c19a7f06f5d10c6f5677361a.tar.bz2 2012-violon-leds-593e1cbe3470f409c19a7f06f5d10c6f5677361a.zip |
Bon, calcul du niveau sonore dans la plage 200 à 2000Hz en reprennant les choses calmement. Il n'est pas impossible que les valeurs soient bonnes :P
git-svn-id: file:///var/svn/2012-violon-leds/trunk@19 6be1fa4d-33ac-4c33-becc-79fcb3794bb6
Diffstat (limited to 'tests/test6/compute.c')
-rw-r--r-- | tests/test6/compute.c | 138 |
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; } + } +} |