Mercurial > hg > btrack
comparison src/BTrack.cpp @ 55:5e520f59127f
Changed the interface of the algorithm so that onset detection function samples are calculated internally. This makes the call to the algorithm for most cases much simpler. Also added a static function for calculating beat times in seconds based upon sampling frequency, hop size and the current frame number.
author | Adam Stark <adamstark@users.noreply.github.com> |
---|---|
date | Wed, 22 Jan 2014 18:47:16 +0000 |
parents | 9699024bb3d0 |
children | b6d440942ff6 |
comparison
equal
deleted
inserted
replaced
54:9699024bb3d0 | 55:5e520f59127f |
---|---|
22 #include <cmath> | 22 #include <cmath> |
23 #include <algorithm> | 23 #include <algorithm> |
24 #include "BTrack.h" | 24 #include "BTrack.h" |
25 #include "samplerate.h" | 25 #include "samplerate.h" |
26 | 26 |
27 | 27 //======================================================================= |
28 //======================================================================= | 28 BTrack::BTrack() : odf(512,1024,6,1) |
29 BTrack :: BTrack() | 29 { |
30 initialise(512, 1024); | |
31 } | |
32 | |
33 //======================================================================= | |
34 BTrack::BTrack(int hopSize) : odf(hopSize,2*hopSize,6,1) | |
30 { | 35 { |
31 double rayparam = 43; | 36 initialise(hopSize, 2*hopSize); |
37 } | |
38 | |
39 //======================================================================= | |
40 BTrack::BTrack(int hopSize,int frameSize) : odf(hopSize,frameSize,6,1) | |
41 { | |
42 initialise(hopSize, frameSize); | |
43 } | |
44 | |
45 //======================================================================= | |
46 BTrack::~BTrack() | |
47 { | |
48 | |
49 } | |
50 | |
51 //======================================================================= | |
52 double BTrack::getBeatTimeInSeconds(long frameNumber,int hopSize,int fs) | |
53 { | |
54 double hop = (double) hopSize; | |
55 double samplingFrequency = (double) fs; | |
56 double frameNum = (double) frameNumber; | |
57 | |
58 return ((hop / samplingFrequency) * frameNum); | |
59 } | |
60 | |
61 //======================================================================= | |
62 double BTrack::getBeatTimeInSeconds(int frameNumber,int hopSize,int fs) | |
63 { | |
64 long frameNum = (long) frameNumber; | |
65 | |
66 return getBeatTimeInSeconds(frameNum, hopSize, fs); | |
67 } | |
68 | |
69 | |
70 | |
71 //======================================================================= | |
72 void BTrack::initialise(int hopSize, int frameSize) | |
73 { | |
74 double rayparam = 43; | |
32 double pi = 3.14159265; | 75 double pi = 3.14159265; |
33 | 76 |
34 | 77 |
35 // initialise parameters | 78 // initialise parameters |
36 tightness = 5; | 79 tightness = 5; |
70 { | 113 { |
71 x = j+1; | 114 x = j+1; |
72 t_mu = i+1; | 115 t_mu = i+1; |
73 t_tmat[i][j] = (1 / (m_sig * sqrt(2*pi))) * exp( (-1*pow((x-t_mu),2)) / (2*pow(m_sig,2)) ); | 116 t_tmat[i][j] = (1 / (m_sig * sqrt(2*pi))) * exp( (-1*pow((x-t_mu),2)) / (2*pow(m_sig,2)) ); |
74 } | 117 } |
75 } | 118 } |
76 | 119 |
77 // tempo is not fixed | 120 // tempo is not fixed |
78 tempofix = 0; | 121 tempofix = 0; |
79 } | 122 |
80 | 123 // initialise algorithm given the hopsize |
81 //======================================================================= | 124 setHopSize(hopSize); |
82 BTrack :: ~BTrack() | 125 } |
126 | |
127 //======================================================================= | |
128 void BTrack :: setHopSize(int hopSize) | |
83 { | 129 { |
84 | 130 framesize = hopSize; |
85 } | 131 dfbuffer_size = (512*512)/hopSize; // calculate df buffer size |
86 | 132 |
87 | 133 bperiod = round(60/((((double) hopSize)/44100)*tempo)); |
88 | |
89 //======================================================================= | |
90 void BTrack :: initialise(int fsize) | |
91 { | |
92 framesize = fsize; | |
93 dfbuffer_size = (512*512)/fsize; // calculate df buffer size | |
94 | |
95 bperiod = round(60/((((double) fsize)/44100)*tempo)); | |
96 | 134 |
97 dfbuffer = new double[dfbuffer_size]; // create df_buffer | 135 dfbuffer = new double[dfbuffer_size]; // create df_buffer |
98 cumscore = new double[dfbuffer_size]; // create cumscore | 136 cumscore = new double[dfbuffer_size]; // create cumscore |
99 | 137 |
100 | 138 |
111 } | 149 } |
112 } | 150 } |
113 } | 151 } |
114 | 152 |
115 //======================================================================= | 153 //======================================================================= |
116 void BTrack :: process(double df_sample) | 154 void BTrack::processAudioFrame(double *frame) |
155 { | |
156 // calculate the onset detection function sample for the frame | |
157 double sample = odf.getDFsample(frame); | |
158 | |
159 // add a tiny constant to the sample to stop it from ever going | |
160 // to zero. this is to avoid problems further down the line | |
161 sample = sample + 0.0001; | |
162 | |
163 // process the new onset detection function sample in the beat tracking algorithm | |
164 processOnsetDetectionFunctionSample(sample); | |
165 } | |
166 | |
167 //======================================================================= | |
168 void BTrack::processOnsetDetectionFunctionSample(double newSample) | |
117 { | 169 { |
118 m0--; | 170 m0--; |
119 beat--; | 171 beat--; |
120 playbeat = 0; | 172 playbeat = 0; |
121 | 173 |
124 { | 176 { |
125 dfbuffer[i] = dfbuffer[i+1]; | 177 dfbuffer[i] = dfbuffer[i+1]; |
126 } | 178 } |
127 | 179 |
128 // add new sample at the end | 180 // add new sample at the end |
129 dfbuffer[dfbuffer_size-1] = df_sample; | 181 dfbuffer[dfbuffer_size-1] = newSample; |
130 | 182 |
131 // update cumulative score | 183 // update cumulative score |
132 updatecumscore(df_sample); | 184 updatecumscore(newSample); |
133 | 185 |
134 // if we are halfway between beats | 186 // if we are halfway between beats |
135 if (m0 == 0) | 187 if (m0 == 0) |
136 { | 188 { |
137 predictbeat(); | 189 predictbeat(); |