andrew@0
|
1 /*
|
andrew@0
|
2 * AubioPitch.cpp
|
andrew@0
|
3 * fileLoaderAndOnsetDetection
|
andrew@0
|
4 *
|
andrew@0
|
5 * Created by Andrew on 24/01/2012.
|
andrew@0
|
6 * Copyright 2012 QMUL. All rights reserved.
|
andrew@0
|
7 *
|
andrew@0
|
8 */
|
andrew@0
|
9
|
andrew@0
|
10 #include "AubioPitch.h"
|
andrew@0
|
11
|
andrew@0
|
12
|
andrew@0
|
13
|
andrew@0
|
14 //HERE I'm using doPitchDetection as it avoids the buffering problem
|
andrew@0
|
15 //I just fill the buffer with what samples I want and get pitch returned.
|
andrew@0
|
16
|
andrew@0
|
17
|
andrew@0
|
18 AubioPitch::AubioPitch(){
|
andrew@0
|
19 bufsize = 4096;
|
andrew@0
|
20 hopsize = bufsize / 2;
|
andrew@0
|
21 pitch = 0.0;
|
andrew@0
|
22
|
andrew@0
|
23 aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;// now changed
|
andrew@0
|
24 aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
|
andrew@0
|
25 // bufsize*4 below
|
andrew@0
|
26 pitchDetect = new_aubio_pitchdetection(bufsize, hopsize, 1, 44100., type_pitch, mode_pitch);
|
andrew@0
|
27
|
andrew@0
|
28 aubio_pitchdetection_set_yinthresh(pitchDetect, 0.85);
|
andrew@0
|
29
|
andrew@0
|
30 vec = (fvec_t *)new_fvec(hopsize,1);//anr changed from hopsize
|
andrew@0
|
31
|
andrew@0
|
32 pos = 0;
|
andrew@0
|
33 }
|
andrew@0
|
34
|
andrew@0
|
35 AubioPitch::~AubioPitch(){
|
andrew@0
|
36 del_aubio_pitchdetection(pitchDetect);
|
andrew@0
|
37 del_fvec(vec);
|
andrew@0
|
38 aubio_cleanup();
|
andrew@0
|
39 //delk fvec
|
andrew@0
|
40
|
andrew@0
|
41 }
|
andrew@0
|
42
|
andrew@0
|
43 bool AubioPitch::processFrame(float* frame, int size){//
|
andrew@0
|
44 //note this no longer called
|
andrew@0
|
45 int j;
|
andrew@0
|
46 bool pitchDetected = false;
|
andrew@0
|
47 //smpl_t pitch;
|
andrew@0
|
48
|
andrew@0
|
49 for (j=0;j<size;j++) {
|
andrew@0
|
50
|
andrew@0
|
51 fvec_write_sample(vec, frame[j], 0, pos);
|
andrew@0
|
52
|
andrew@0
|
53 if (pos == hopsize-1) { //anr recent change from hopsize
|
andrew@0
|
54 // block loop /
|
andrew@0
|
55
|
andrew@0
|
56 pitch = aubio_pitchdetection(pitchDetect, vec);
|
andrew@0
|
57 pitchDetected = true;
|
andrew@0
|
58 printf("PITCH IS %f\n", pitch);
|
andrew@0
|
59
|
andrew@0
|
60 // printf("Pitch detected %f\n", pitch);
|
andrew@0
|
61 // outlet_float(x->pitchOutlet, pitch);
|
andrew@0
|
62
|
andrew@0
|
63 // end of block loop
|
andrew@0
|
64 pos = -1; // so it will be zero next j loop //
|
andrew@0
|
65 }
|
andrew@0
|
66 pos++;
|
andrew@0
|
67
|
andrew@0
|
68 }
|
andrew@0
|
69 return pitchDetected;
|
andrew@0
|
70
|
andrew@0
|
71 }
|
andrew@0
|
72
|
andrew@0
|
73 //anr idea of adding to buffer
|
andrew@0
|
74 void AubioPitch::addToBuffer(float* tmpFrame, const int& n){
|
andrew@0
|
75 for (int j=0;j < n;j++) {
|
andrew@0
|
76 fvec_write_sample(vec, tmpFrame[j], 0, pos);
|
andrew@0
|
77
|
andrew@0
|
78 if (pos == hopsize - 1){
|
andrew@0
|
79 //pitch = aubio_pitchdetection(x->o,x->vec);
|
andrew@0
|
80 //outlet_float(x->pitchOutlet, pitch);
|
andrew@0
|
81
|
andrew@0
|
82 pitch = aubio_pitchdetection(pitchDetect, vec);
|
andrew@0
|
83 pos = -1;
|
andrew@0
|
84 }
|
andrew@0
|
85
|
andrew@0
|
86 pos++;
|
andrew@0
|
87 }
|
andrew@0
|
88 }
|
andrew@0
|
89
|
andrew@0
|
90 float AubioPitch::getPitch(){
|
andrew@0
|
91 //float newPitch = aubio_pitchdetection(pitchDetect, vec);
|
andrew@0
|
92 // return newPitch;
|
andrew@0
|
93 return pitch;
|
andrew@0
|
94 }
|
andrew@0
|
95
|
andrew@0
|
96 //this function is more useful here
|
andrew@0
|
97 //can process a frame - by converting it into an fvec_t type used by aubio
|
andrew@0
|
98 //but since only do this once, better for our purposes than the more iterative method above
|
andrew@0
|
99 //we just store the float frames and when needed, call this for our pitch calculation on the whole
|
andrew@0
|
100 //buffer - checking that length below is in fact bufsize
|
andrew@0
|
101
|
andrew@0
|
102 float AubioPitch::doPitchDetection(float* frame, const int& length){
|
andrew@0
|
103 //fn to do pitch detection without all the buffering etc
|
andrew@0
|
104 float newPitch = -1.0;
|
andrew@0
|
105 if (length == bufsize){
|
andrew@0
|
106 fvec_t* tmpVec;
|
andrew@0
|
107 tmpVec = new_fvec(bufsize,1);
|
andrew@0
|
108 for (int j =0;j < length;j++){
|
andrew@0
|
109 fvec_write_sample(tmpVec, frame[j], 0, j);
|
andrew@0
|
110 // printf("vec[%i] = %.3f\n", j, frame[j]);
|
andrew@0
|
111 }
|
andrew@0
|
112 newPitch = aubio_pitchdetection(pitchDetect, tmpVec);
|
andrew@0
|
113 // printf("NEW PITCH FOUND %f\n", newPitch);
|
andrew@0
|
114 }
|
andrew@0
|
115 return newPitch;
|
andrew@0
|
116 }
|
andrew@0
|
117
|
andrew@0
|
118
|
andrew@0
|
119 //float AubioPitch::getPitchDetectedFromBuffer(float* frame, const int& length){
|
andrew@0
|
120
|
andrew@0
|
121 // smpl_t pitch = 0.;
|
andrew@0
|
122 /* fvec_t * buf;
|
andrew@0
|
123 for (int i = 0;i < length;i++){
|
andrew@0
|
124 buf[i] = frame[i];
|
andrew@0
|
125 }
|
andrew@0
|
126 */
|
andrew@0
|
127
|
andrew@0
|
128 /* if (length == bufsize){
|
andrew@0
|
129 pitch = aubio_pitchyinfft_detect(pitchDetect->yinfft, buf, pitchDetect->yinthres);
|
andrew@0
|
130
|
andrew@0
|
131 if (pitch > 0){
|
andrew@0
|
132 pitch = pitchDetect->srate/(pitch + 0.);
|
andrew@0
|
133 } else {
|
andrew@0
|
134 pitch = 0.;
|
andrew@0
|
135 }
|
andrew@0
|
136
|
andrew@0
|
137 }//end if right size
|
andrew@0
|
138 */
|
andrew@0
|
139 // return pitch;
|
andrew@0
|
140
|
andrew@0
|
141 //}
|
andrew@0
|
142
|
andrew@0
|
143
|
andrew@0
|
144
|
andrew@0
|
145
|
andrew@0
|
146
|
andrew@0
|
147
|
andrew@0
|
148 /*This is the fvec_t defn from aubio:
|
andrew@0
|
149 AUBIO f_vec
|
andrew@0
|
150 struct _fvec_t {
|
andrew@0
|
151 ba_uint_t length; /**< length of buffer
|
andrew@0
|
152 ba_uint_t channels; /**< number of channels
|
andrew@0
|
153 smpl_t **data; /**< data array of size [length] * [channels]
|
andrew@0
|
154 */
|