예제 #1
0
/*
 * main.c
 * Author: Kevin Cooper
 * Date: 16 Oct 13
 * Description: Tests the MyMath functions to simulate the rolling average of several data points
 */
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    int i ;
    avgArray_t test = buildMovingAverage(N_AVG_SAMPLES);
    int array[10] = {45, 42, 41, 40, 43, 45, 46, 47, 49, 45};
    volatile int junk=0;
    for( i =0;i < 10;i++){
    	addSample(&test, array[i]);
    	junk = movingAverage(&test);
    }
    junk = maxValue(&test);
    junk = minValue(&test);
    junk = range(&test);

	return 0;
}
예제 #2
0
Rhythm::FeatureSet Rhythm::getRemainingFeatures() {
  FeatureSet output;
  int frames = intensity.size();

  if (frames == 0)
    return output;

  // find envelope by convolving each subband with half-hanning window
  vector<vector<float> > envelope;
  halfHannConvolve(envelope);

  // find onset curve by convolving each subband of envelope with canny window
  vector<float> onset;
  cannyConvolve(envelope, onset);

  // normalise onset curve
  vector<float> onsetNorm;
  normalise(onset, onsetNorm);

  // push normalised onset curve
  Feature f_onset;
  f_onset.hasTimestamp = true;
  for (unsigned i = 0; i < onsetNorm.size(); i++) {
    f_onset.timestamp = Vamp::RealTime::frame2RealTime(i * m_stepSize,
                                                       m_sampleRate);
    f_onset.values.clear();
    f_onset.values.push_back(onsetNorm.at(i));
    output[0].push_back(f_onset);
  }

  // find moving average of onset curve and difference
  vector<float> onsetAverage;
  vector<float> onsetDiff;
  movingAverage(onsetNorm, average_window, threshold, onsetAverage, onsetDiff);

  // push moving average
  Feature f_avg;
  f_avg.hasTimestamp = true;
  for (unsigned i = 0; i < onsetAverage.size(); i++) {
    f_avg.timestamp = Vamp::RealTime::frame2RealTime(i * m_stepSize,
                                                     m_sampleRate);
    f_avg.values.clear();
    f_avg.values.push_back(onsetAverage.at(i));
    output[1].push_back(f_avg);
  }

  // push difference from average
  Feature f_diff;
  f_diff.hasTimestamp = true;
  for (unsigned i = 0; i < onsetDiff.size(); i++) {
    f_diff.timestamp = Vamp::RealTime::frame2RealTime(i * m_stepSize,
                                                      m_sampleRate);
    f_diff.values.clear();
    f_diff.values.push_back(onsetDiff.at(i));
    output[2].push_back(f_diff);
  }

  // choose peaks
  vector<int> peaks;
  findOnsetPeaks(onsetDiff, peak_window, peaks);
  int onsetCount = (int) peaks.size();

  // push peaks
  Feature f_peak;
  f_peak.hasTimestamp = true;
  for (unsigned i = 0; i < peaks.size(); i++) {
    f_peak.timestamp = Vamp::RealTime::frame2RealTime(peaks.at(i) * m_stepSize,
                                                      m_sampleRate);
    output[3].push_back(f_peak);
  }

  // calculate average onset frequency
  float averageOnsetFreq = (float) onsetCount
      / (float) (frames * m_stepSize / m_sampleRate);
  Feature f_avgOnsetFreq;
  f_avgOnsetFreq.hasTimestamp = true;
  f_avgOnsetFreq.timestamp = Vamp::RealTime::fromSeconds(0.0);
  f_avgOnsetFreq.values.push_back(averageOnsetFreq);
  output[4].push_back(f_avgOnsetFreq);

  // calculate rhythm strength
  float rhythmStrength = findMeanPeak(onset, peaks, 0);
  Feature f_rhythmStrength;
  f_rhythmStrength.hasTimestamp = true;
  f_rhythmStrength.timestamp = Vamp::RealTime::fromSeconds(0.0);
  f_rhythmStrength.values.push_back(rhythmStrength);
  output[5].push_back(f_rhythmStrength);

  // find shift range for autocor
  float firstShift = (int) round(60.f / max_bpm * m_sampleRate / m_stepSize);
  float lastShift = (int) round(60.f / min_bpm * m_sampleRate / m_stepSize);

  // autocorrelation
  vector<float> autocor;
  autocorrelation(onsetDiff, firstShift, lastShift, autocor);
  Feature f_autoCor;
  f_autoCor.hasTimestamp = true;
  for (float shift = firstShift; shift < lastShift; shift++) {
    f_autoCor.timestamp = Vamp::RealTime::frame2RealTime(shift * m_stepSize,
                                                         m_sampleRate);
    f_autoCor.values.clear();
    f_autoCor.values.push_back(autocor.at(shift - firstShift));
    output[6].push_back(f_autoCor);
  }

  // find peaks in autocor
  float percentile = 95;
  int autocorWindowLength = 3;
  vector<int> autocorPeaks;
  vector<int> autocorValleys;
  findCorrelationPeaks(autocor, percentile, autocorWindowLength, firstShift,
                       autocorPeaks, autocorValleys);

  // find average corrolation peak
  float meanCorrelationPeak = findMeanPeak(autocor, autocorPeaks, firstShift);
  Feature f_meanCorrelationPeak;
  f_meanCorrelationPeak.hasTimestamp = true;
  f_meanCorrelationPeak.timestamp = Vamp::RealTime::fromSeconds(0.0);
  f_meanCorrelationPeak.values.push_back(meanCorrelationPeak);
  output[7].push_back(f_meanCorrelationPeak);

  // find peak/valley ratio
  float meanCorrelationValley = findMeanPeak(autocor, autocorValleys,
                                             firstShift) + 0.0001;
  Feature f_peakValleyRatio;
  f_peakValleyRatio.hasTimestamp = true;
  f_peakValleyRatio.timestamp = Vamp::RealTime::fromSeconds(0.0);
  f_peakValleyRatio.values.push_back(
      meanCorrelationPeak / meanCorrelationValley);
  output[8].push_back(f_peakValleyRatio);

  // find tempo from peaks
  float tempo = findTempo(autocorPeaks);
  Feature f_tempo;
  f_tempo.hasTimestamp = true;
  f_tempo.timestamp = Vamp::RealTime::fromSeconds(0.0);
  f_tempo.values.push_back(tempo);
  output[9].push_back(f_tempo);

  return output;
}
예제 #3
0
movingAverage::movingAverage() {
    movingAverage(1,0);
}
예제 #4
0
파일: aux.c 프로젝트: brandtd/eyeblink
int *findPossibleBlinks( int *num_blinks, const NUMTYPE *channel,
                         int len_channel, const BlinkParams *params )
{
  unsigned int i, j, max_level, len_coef, lengths[8];
  int cor_length, temp_start, len_template;
  NUMTYPE *coefs, *chan_a, *chan_d, *chan_r, *thresh, *templ;
  NUMTYPE min;

  int above, min_index, num_indices, *indices, steps_1, index, *blinks;
  NUMTYPE *cors;

  // Pull out the parameters that we'll be using.
  NUMTYPE t_1   = params->t_1;
  NUMTYPE t_cor = params->t_cor;

  // Make sure that we are capable of taking the 5th, 6th, and 7th level
  // decompositions.
  max_level = wavedecMaxLevel( len_channel, COIF3.len_filter );
  if (max_level < 7) {
    fprintf( stderr, "Channel too short for processing!\n" );
    (*num_blinks) = 0;
    return NULL;
  }

  //////////////////////////////////////////////////////////////////////////////
  // Allocate memory.
  //////////////////////////////////////////////////////////////////////////////

  len_coef = wavedecResultLength( len_channel, COIF3.len_filter, 7 );
  coefs    = (NUMTYPE*) malloc( sizeof(NUMTYPE) * len_coef );
  chan_a   = (NUMTYPE*) malloc( sizeof(NUMTYPE) * len_channel );
  chan_d   = (NUMTYPE*) malloc( sizeof(NUMTYPE) * len_channel );
  chan_r   = (NUMTYPE*) malloc( sizeof(NUMTYPE) * len_channel );
  thresh   = (NUMTYPE*) malloc( sizeof(NUMTYPE) * len_channel );

  //////////////////////////////////////////////////////////////////////////////
  // Extract the appropriate approximation and detail signals.
  //////////////////////////////////////////////////////////////////////////////
  wavedec( coefs, lengths, channel, len_channel, COIF3, 7 );
  wrcoef( chan_a, coefs, lengths, 8, RECON_APPROX, COIF3, 3 );

  // Sum the enveloped 5th, 6th, and 7th level details.
  for (i = 0; i < len_channel; i++) { chan_d[i] = 0.0; }
  for (i = 5; i <= 7; i++) {
    wrcoef( chan_r, coefs, lengths, 8, RECON_DETAIL, COIF3, i );
    envelope( chan_r, len_channel );
    for (j = 0; j < len_channel; j++) {
      chan_d[j] += chan_r[j];
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  // Generate the first guess at eyeblink locations.
  //////////////////////////////////////////////////////////////////////////////

  // Compute the moving average threshold.
  movingAverage( thresh, chan_d, len_channel );
  for (i = 0; i < len_channel; i++) { thresh[i] += t_1; }

  // Find the minimums of the original channel between rising/falling edge pairs
  // of the enveloped channel details.
  above = 0; num_indices = 0; min = INFINITY; min_index = 0; indices = NULL;
  for (i = 1; i < len_channel; i++) {
    // Check to see if we crossed the threshold.
    if (!above && chan_d[i] > thresh[i] && chan_d[i-1] <= thresh[i-1]) {
      above = 1;

      // Reset the 'min' value so that we can find a new minimum.
      min = INFINITY;
    } else if (above && chan_d[i] < thresh[i] && chan_d[i-1] >= thresh[i-1]) {
      above = 0;

      // We just found the falling edge of a pair. Record the index of the
      // minimum value that we found within the pair.
      num_indices++;
      indices = (int*) realloc( indices, sizeof(int) * num_indices );
      indices[num_indices-1] = min_index;
    }

    // If we're above the threshold, keep track of the minimum value that we
    // see.
    if (above) {
      if (min > chan_a[i]) {
        min = chan_a[i];
        min_index = i;
      }
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  // Refine our first guess, getting our final guess at eyeblink locations.
  //////////////////////////////////////////////////////////////////////////////
  cors = (NUMTYPE*) malloc( sizeof(NUMTYPE) * num_indices );

  // Generate the eyeblink template to correlate with the eyeblink locations.
  templ = getTemplate( &steps_1, &len_template, params );

  // Calculate the correlations of the original channel around the minimum
  // points.
  (*num_blinks) = num_indices;
  for (i = 0; i < num_indices; i++) {
    index = indices[i] - steps_1; temp_start = 0; cor_length = len_template;

    // Make sure the correlation function will not access beyond the bounds
    // of our arrays.
    if (index < 0) {
      temp_start = -index;
      cor_length = len_template + index;
      index = 0;
    } else if (index + len_template >= len_channel) {
      cor_length = len_template - (index + len_template - len_channel);
    }

    cors[i] = correlate( chan_a + index, templ + temp_start, cor_length );

    // Mark for elimination the indices with correlations below the threshold.
    if (cors[i] < t_cor) {
      indices[i] = -1;
      (*num_blinks)--;
    }
  }

  // If we still have blinks after all this, allocate memory for them.
  if ((*num_blinks) == 0) {
    blinks = NULL;
  } else {
    blinks = (int*) malloc( sizeof(int) * (*num_blinks) );
    index = 0;
    for (i = 0; i < num_indices; i++) {
      if (indices[i] > 0) {
        blinks[index] = indices[i];
        index++;
      }
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  // Clean up and return.
  //////////////////////////////////////////////////////////////////////////////
  free( indices ); free( cors ); free( coefs );
  free( chan_a ); free( chan_d ); free( chan_r );
  free( thresh ); free( templ );

  return blinks;
}