File: comp_chroma.cpp

package info (click to toggle)
audacity 1.3.12-6
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 41,528 kB
  • ctags: 30,395
  • sloc: cpp: 166,518; ansic: 105,310; sh: 24,447; lisp: 7,842; makefile: 1,701; python: 240; perl: 31; xml: 8
file content (92 lines) | stat: -rw-r--r-- 2,310 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

#include <fstream>
#include "allegro.h"
#include "audioreader.h"
#include "gen_chroma.h"
#include  "comp_chroma.h"

using namespace std;

/*				NORM_CHROMA
 *
 * This function normalizes the chroma for each frame of the
 * chrom_energy to mean 0 and std. dev. 1. But if this is a
 * "silent frame", set the 13th element to 1.
 */
void norm_chroma( int len, float *chrom_energy ) {

  float avg = 0;
  float dev = 0;
  float sum = 0;

  for( int i = 0; i < len; i++ ) {

    /* Calculate avg for this frame */
    sum = 0;
    for ( int j = 0; j < 12; j++ )
        sum += AREF2(chrom_energy, i, j);
    avg = sum / 12.0;

	/* Silence detection: */ 
	float silence = 0.0F;
	if (avg < SILENCE_THRESHOLD) { /* assume silent */
		silence = 1.0F;
	}
    AREF2(chrom_energy, i, 12) = silence;
	
	// printf("avg at %g: %g\n", i * 0.25, avg);

    /* Normalize this frame to avg. 0 */
    for ( int j = 0; j < 12; j++ )
        AREF2(chrom_energy, i, j) -= avg;

    /* Calculate std. dev. for this frame */
    sum = 0;
    for ( int j = 0; j < 12; j++ ) {
        float x = AREF2(chrom_energy, i, j);
        sum += x * x;
    }
    dev = sqrt( sum / 12.0 );
	if (dev == 0.0) dev = 1.0F; /* don't divide by zero */

    /* Normalize this frame to std. dev. 1*/
    for ( int j = 0; j < 12; j++ )
        AREF2(chrom_energy, i, j) /= dev;
  }
}

/* Returns the minimum of two values */
double min2( double x, double y ) {
    return (x < y ? x : y);
}

/*				GEN_DIST
 *
 * This function generates the Euclidean distance for points i
 * and j in two chroma vectors for use with dynamic time warping of 
 * the chroma vectors.
 */
float gen_dist( int i, int j, float *chrom_energy1, 
	       float *chrom_energy2 ) {

  float sum = 0;
  float MAX = 12.0;

  if (AREF2(chrom_energy1, i, CHROMA_BIN_COUNT) !=
	  AREF2(chrom_energy2, j, CHROMA_BIN_COUNT)) {
      //printf("gd%g ", SILENCE_DISTANCE); // print result
      return SILENCE_DISTANCE;
  }
  /* Determine the distance between these vectors 
     chroma1[i] and chroma2[j] to return */
  for (int k = 0; k < 12; k++) {
      float x = AREF2(chrom_energy1, i, k);
      float y = AREF2(chrom_energy2, j, k);
      float diff = x - y;

      sum += diff*diff ;
  }
  sum = min2( sqrt( sum ), MAX );
  //printf("gd%g ", sum); // print the result
  return sum;
}