/*  Method to extract spectral features.
 Input arguments are the magnitude spectrum and block size */
void SpectralFeatures::extractFeatures(float* spectrum)
{
    power = 0.0;
    spectrum_sum = 0.0;
    spectrum_abs_sum = 0.0;
    halfwave = 0.0;
    log_spectrum_sum = 0.0;
    float diff_sum = 0.0;
    
    for (int i=minBin; i<maxBin; i++) {
        // Get power difference between consecutive spectra
        //diff_sum += (spectrum[i] - fifo[i])*(spectrum[i] - fifo[i]);
        diff_sum  += ((spectrum[i] - fifo[i] + fabsf(spectrum[i] - fifo[i]))/2.0)*((spectrum[i] - fifo[i] + fabsf(spectrum[i] - fifo[i]))/2.0);
        
//        // Half wave recitify the diff.
        halfwave += ((spectrum[i] - fifo[i] + fabsf(spectrum[i] - fifo[i]))/2.0);
        //Calculate the square
        power += spectrum[i] * spectrum[i];
        
        //Sum of the magnitude spectrum
        spectrum_sum += spectrum[i];
        
        //Sum of the absolute value of the magnitude spectrum
        spectrum_abs_sum += fabsf(spectrum[i]);
        
        //Logarithmic sum of the magnitude spectrum
        log_spectrum_sum += log(spectrum[i]);
        
        //Square of the magnitude spectrum
        spectrum_sq[i] = spectrum[i] * spectrum[i];
    }
    
    /* Update fifo */
    setFifo(spectrum,binSize);
    
    if (!checkSilence(power)){
        // Calculate Spectral Flux
        calculateSpectralFlux(halfwave);
        
        // Calculate Spectral Roloff
        calculateSpectralRolloff(spectrum, spectrum_sum, 0.85);
        
        //Calculate RMS
        calculateRMS(power);
        
        //Calculate Spectral Crest
        calculateSpectralCrest(spectrum, spectrum_abs_sum);
        
        //Calculate Spectral Centroid
        calculateSpectralCentroid(spectrum, power, minBin, maxBin);
        
        //Calculate Spectral Flatness
        calculateSpectralFlatness(log_spectrum_sum, spectrum_sum);
        
    }
}
Esempio n. 2
0
/*! @brief Runs calculations on meter use statistics.
 *
 *  After all the samples over a period have been collected, this routine is invoked.
 */
static void runCalculations(void)
{
  uint8_t i;

  //Loop through the samples to -1 the total sample length
  for(i = 0; i < 15; i++)
  {
    calculateEnergy(VoltageSamples[i], CurrentSamples[i], bFALSE);
    calculateRMS(VoltageSamples[i], bFALSE, RMS_VOLTAGE);
    calculateRMS(CurrentSamples[i], bFALSE, RMS_CURRENT);
  }

  //Calculate the final values, indicating to the functions that all samples have been accounted for
  calculateEnergy(VoltageSamples[15], CurrentSamples[15], bTRUE);
  calculateRMS(VoltageSamples[15], bTRUE, RMS_VOLTAGE);
  calculateRMS(CurrentSamples[15], bTRUE, RMS_CURRENT);

  PerformingCalculations = bFALSE;
}