diff options
author | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2012-06-16 22:29:33 +0000 |
---|---|---|
committer | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2012-06-16 22:29:33 +0000 |
commit | 797149c5a9ee0c7c70947f72cbaece5efd3dd687 (patch) | |
tree | 1c5a8e9dcb09c08e7741c806650c5ef1163387d0 /src/compute.c | |
parent | 593e1cbe3470f409c19a7f06f5d10c6f5677361a (diff) | |
download | 2012-violon-leds-797149c5a9ee0c7c70947f72cbaece5efd3dd687.tar.gz 2012-violon-leds-797149c5a9ee0c7c70947f72cbaece5efd3dd687.tar.bz2 2012-violon-leds-797149c5a9ee0c7c70947f72cbaece5efd3dd687.zip |
Création du source tree princpal. Les routines de maths pour calculer le gain déconnent encore je trouve.
Reste à intégrer la partie DMX et a améliorer tout ce qui a été laissé de côté...
git-svn-id: file:///var/svn/2012-violon-leds/trunk@20 6be1fa4d-33ac-4c33-becc-79fcb3794bb6
Diffstat (limited to 'src/compute.c')
-rw-r--r-- | src/compute.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/compute.c b/src/compute.c new file mode 100644 index 0000000..272d6f8 --- /dev/null +++ b/src/compute.c @@ -0,0 +1,116 @@ +#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(float audio_level, float *light_h, float *light_s, float *light_v) { + static float hue=0; + + float level_norm=(50.f+audio_level)/30.f; + + if (level_norm<0.f) level_norm=0.f; + if (level_norm>1.f) level_norm=1.f; + hue=(hue+0.0002f); + if (hue>1.f) hue-=1.f; + + printf("%+3.1f %+1.3f\n", audio_level, level_norm); + + // Dummy code + *light_h=hue; + *light_s=1.f; + *light_v=level_norm; +} + |