//taken from Vortex
void AnalyzeSound()
{

    int m_fps = 60;

    // sum (left channel) spectrum up into 3 bands
    // [note: the new ranges do it so that the 3 bands are equally spaced, pitch-wise]
    float min_freq = 200.0f;
    float max_freq = 11025.0f;
    float net_octaves = (logf(max_freq / min_freq) / logf(2.0f));     // 5.7846348455575205777914165223593
    float octaves_per_band = net_octaves / 3.0f;                    // 1.9282116151858401925971388407864
    float mult = powf(2.0f, octaves_per_band); // each band's highest freq. divided by its lowest freq.; 3.805831305510122517035102576162
    // [to verify: min_freq * mult * mult * mult should equal max_freq.]
    //    for (int ch=0; ch<2; ch++)
    {
        for (int i = 0; i<3; i++)
        {
            // old guesswork code for this:
            //   float exp = 2.1f;
            //   int start = (int)(NUM_FREQUENCIES*0.5f*powf(i/3.0f, exp));
            //   int end   = (int)(NUM_FREQUENCIES*0.5f*powf((i+1)/3.0f, exp));
            // results:
            //          old range:      new range (ideal):
            //   bass:  0-1097          200-761
            //   mids:  1097-4705       761-2897
            //   treb:  4705-11025      2897-11025
            int start = (int)(NUM_FREQUENCIES * min_freq*powf(mult, (float)i) / 11025.0f);
            int end = (int)(NUM_FREQUENCIES * min_freq*powf(mult, (float)i + 1) / 11025.0f);
            if (start < 0) start = 0;
            if (end > NUM_FREQUENCIES) end = NUM_FREQUENCIES;

            g_sound.imm[0][i] = 0;
            for (int j = start; j<end; j++)
            {
                g_sound.imm[0][i] += g_sound.fSpectrum[0][j];
                g_sound.imm[0][i] += g_sound.fSpectrum[1][j];
            }
            g_sound.imm[0][i] /= (float)(end - start) * 2;
        }
    }



    // multiply by long-term, empirically-determined inverse averages:
    // (for a trial of 244 songs, 10 seconds each, somewhere in the 2nd or 3rd minute,
    //  the average levels were: 0.326781557	0.38087377	0.199888934
    for (int ch = 0; ch<2; ch++)
    {
        g_sound.imm[ch][0] /= 0.326781557f;//0.270f;
        g_sound.imm[ch][1] /= 0.380873770f;//0.343f;
        g_sound.imm[ch][2] /= 0.199888934f;//0.295f;
    }

    // do temporal blending to create attenuated and super-attenuated versions
    for (int ch = 0; ch<2; ch++)
    {
        for (int i = 0; i<3; i++)
        {
            // g_sound.avg[i]
            {
                float avg_mix;
                if (g_sound.imm[ch][i] > g_sound.avg[ch][i])
                    avg_mix = AdjustRateToFPS(0.2f, 14.0f, (float)m_fps);
                else
                    avg_mix = AdjustRateToFPS(0.5f, 14.0f, (float)m_fps);
                //                if (g_sound.imm[ch][i] > g_sound.avg[ch][i])
                //                  avg_mix = 0.5f;
                //                else
                //                  avg_mix = 0.8f;
                g_sound.avg[ch][i] = g_sound.avg[ch][i] * avg_mix + g_sound.imm[ch][i] * (1 - avg_mix);
            }

            {
                float med_mix = 0.91f;//0.800f + 0.11f*powf(t, 0.4f);    // primarily used for velocity_damping
                float long_mix = 0.96f;//0.800f + 0.16f*powf(t, 0.2f);    // primarily used for smoke plumes
                med_mix = AdjustRateToFPS(med_mix, 14.0f, (float)m_fps);
                long_mix = AdjustRateToFPS(long_mix, 14.0f, (float)m_fps);
                g_sound.med_avg[ch][i] = g_sound.med_avg[ch][i] * (med_mix)+g_sound.imm[ch][i] * (1 - med_mix);
                //                g_sound.long_avg[ch][i] = g_sound.long_avg[ch][i]*(long_mix) + g_sound.imm[ch][i]*(1-long_mix);
            }
        }
    }

    float newBass = ((g_sound.avg[0][0] - g_sound.med_avg[0][0]) / g_sound.med_avg[0][0]) * 2;
    float newMiddle = ((g_sound.avg[0][1] - g_sound.med_avg[0][1]) / g_sound.med_avg[0][1]) * 2;
    float newTreble = ((g_sound.avg[0][2] - g_sound.med_avg[0][2]) / g_sound.med_avg[0][2]) * 2;
    newBass = std::max(std::min(newBass, 1.0f), -1.0f);
    newMiddle = std::max(std::min(newMiddle, 1.0f), -1.0f);
    newTreble = std::max(std::min(newTreble, 1.0f), -1.0f);

    g_bassLast = g_bass;
    g_middleLast = g_middle;

    float avg_mix;
    if (newTreble > g_treble)
        avg_mix = 0.5f;
    else
        avg_mix = 0.5f;

    //dealing with NaN's in linux
    if (g_bass != g_bass) g_bass = 0;
    if (g_middle != g_middle) g_middle = 0;
    if (g_treble != g_treble) g_treble = 0;

    g_bass = g_bass*avg_mix + newBass*(1 - avg_mix);
    g_middle = g_middle*avg_mix + newMiddle*(1 - avg_mix);
    //g_treble = g_treble*avg_mix + newTreble*(1 - avg_mix);

    g_bass = std::max(std::min(g_bass, 1.0f), -1.0f);
    g_middle = std::max(std::min(g_middle, 1.0f), -1.0f);
    //g_treble = std::max(std::min(g_treble, 1.0f), -1.0f);

    if (g_middle < 0) g_middle = g_middle * -1.0f;
    if (g_bass < 0) g_bass = g_bass * -1.0f;

    if (((g_middle - g_middleLast) > beatThreshold ||
            (g_bass - g_bassLast > beatThreshold))
            && ((fAppTime - fLightTime) > 0.3f))
    {
        //beat
        FastBeatLights();
        CycleHue(1500);
        //changed lights
        fLightTime = fAppTime;
    }
}
Beispiel #2
0
 void AudioVis::AnalyzeNewSound(long rsize)
 {
     // we get 576 samples in from winamp.
     // the output of the fft has 'num_frequencies' samples,
     //   and represents the frequency range 0 hz - 22,050 hz.
     // usually, plugins only use half of this output (the range 0 hz - 11,025 hz),
     //   since >10 khz doesn't usually contribute much.
     
     int i;
     float temp_wave[2][576];
     
     int samp=0;
     int old_i = 0;
     
     AudioVisData *data = this->data;
     AudioVis *rd = this;
     FFT *m_fftobj = data->fft;
     
     for (i=0; i<576; i++, samp+=2)
     {
         //		rd->fWaveform[0][i] = (float)(((float)C816(rd->cWaveformL[i]))/32768.0f);
         //        rd->fWaveform[1][i] = (float)(((float)C816(rd->cWaveformR[i]))/32768.0f);
         
         rd->fWaveform[0][i] = (float)((rd->cWaveformL[i]) -128);
         rd->fWaveform[1][i] = (float)((rd->cWaveformR[i]) -128);
         
         //		fWaveform[0][i] = (float)((pWave[samp]/(0x8000)));
         //        fWaveform[1][i] = (float)((pWave[samp+1]/(0x8000)));
         
         // simulating single frequencies from 200 to 11,025 Hz:
         //float freq = 1.0f + 11050*(GetFrame() % 100)*0.01f;
         //rd->fWaveform[0][i] = 10*sinf(i*freq*6.28f/44100.0f);
         
         // damp the input into the FFT a bit, to reduce high-frequency noise:
         temp_wave[0][i] = 0.5f*(rd->fWaveform[0][i] + rd->fWaveform[0][old_i]);
         temp_wave[1][i] = 0.5f*(rd->fWaveform[1][i] + rd->fWaveform[1][old_i]);
         old_i = i;
     }
     
     m_fftobj->time_to_frequency_domain(temp_wave[0], rd->fSpectrum[0]);
     m_fftobj->time_to_frequency_domain(temp_wave[1], rd->fSpectrum[1]);
     
     // sum (left channel) spectrum up into 3 bands
     // [note: the new ranges do it so that the 3 bands are equally spaced, pitch-wise]
     float min_freq = 60.0f;
     float max_freq = 11025.0f;
     float net_octaves = (logf(max_freq/min_freq) / logf(2.0f));     // 5.7846348455575205777914165223593
     float octaves_per_band = net_octaves / 16.0f;                    // 1.9282116151858401925971388407864
     float mult = powf(2.0f, octaves_per_band); // each band's highest freq. divided by its lowest freq.; 3.805831305510122517035102576162
     // [to verify: min_freq * mult * mult * mult should equal max_freq.]
     for (int ch=0; ch<2; ch++)
     {
         for (i=0; i<16; i++)
         {
             // old guesswork code for this:
             //   float exp = 2.1f;
             //   int start = (int)(NUM_FREQUENCIES*0.5f*powf(i/3.0f, exp));
             //   int end   = (int)(NUM_FREQUENCIES*0.5f*powf((i+1)/3.0f, exp));
             // results:
             //          old range:      new range (ideal):
             //   bass:  0-1097          200-761
             //   mids:  1097-4705       761-2897
             //   treb:  4705-11025      2897-11025
             int start = (int)(NUM_FREQUENCIES * min_freq*powf(mult, i  )/11025.0f);
             int end   = (int)(NUM_FREQUENCIES * min_freq*powf(mult, i+1)/11025.0f);
             if (start < 0) start = 0;
             if (end > NUM_FREQUENCIES) end = NUM_FREQUENCIES;
             
             rd->imm[ch][i] = 0;
             for (int j=start; j<end; j++)
                 rd->imm[ch][i] += rd->fSpectrum[ch][j];
             rd->imm[ch][i] /= (float)(end-start);
         }
     }
     
     // do temporal blending to create attenuated and super-attenuated versions
     for (int ch=0; ch<2; ch++)
     {
         for (i=0; i<16; i++)
         {
             // rd->avg[i]
             {
                 float avg_mix;
                 if (rd->imm[ch][i] > rd->avg[ch][i])
                     avg_mix = AdjustRateToFPS(0.2f, 76.0f, m_fps);
                 else
                     avg_mix = AdjustRateToFPS(0.5f, 76.0f, m_fps);
                 rd->avg[ch][i] = rd->avg[ch][i]*avg_mix + rd->imm[ch][i]*(1-avg_mix);
             }
             
             // rd->med_avg[i]
             // rd->long_avg[i]
             {
                 float med_mix  = 0.91f;//0.800f + 0.11f*powf(t, 0.4f);    // primarily used for velocity_damping
                 float long_mix = 0.96f;//0.800f + 0.16f*powf(t, 0.2f);    // primarily used for smoke plumes
                 med_mix  = AdjustRateToFPS( med_mix, 76.0f, m_fps);
                 long_mix = AdjustRateToFPS(long_mix, 76.0f, m_fps);
                 rd->med_avg[ch][i]  =  rd->med_avg[ch][i]*(med_mix ) + rd->imm[ch][i]*(1-med_mix );
                 rd->long_avg[ch][i] = rd->long_avg[ch][i]*(long_mix) + rd->imm[ch][i]*(1-long_mix);
             }
         }
     }
     
     BeatDetect();
     
     this->updateCount++;
 }