1 /*
2 	SuperCollider real time audio synthesis system
3  Copyright (c) 2002 James McCartney. All rights reserved.
4 	http://www.audiosynth.com
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 //This file is part of The BBCut Library. Copyright (C) 2001  Nick M.Collins distributed under the terms of the GNU General Public License full notice in file BBCutLibrary.help
22 
23 //last revisions pre release 1.0 Nick Collins 15 June 2004
24 
25 #include "SC_PlugIn.h"
26 #include "SC_fftlib.h"
27 #include <stdio.h>
28 
29 //helpful constants
30 #define PI 3.1415926535898f
31 #define TWOPI 6.28318530717952646f
32 
33 //FFT data
34 #define N 1024  //FFT size
35 #define NOVER2 512  //FFT size
36 #define NOVER4 256  //FFT size
37 #define OVERLAP 512
38 #define OVERLAPINDEX 512
39 #define HOPSIZE 512
40 #define FS 44100 //assumes fixed sampling rate
41 #define FRAMESR 86.1328
42 #define FRAMEPERIOD 0.01161 //seconds
43 
44 //algorithm quantities NR tempo hypotheses, ND num phase hypotheses
45 
46 //used to be TEMPOLOW 90 TEMPOHIGH 180 TEMPOSTEP 0.9 INTEGRATIONTIME 3.4 LOUDNESSFRAMESSTORED 293
47 //used to be TEMPOLOW 80 TEMPOHIGH 200 TEMPOSTEP 1.2 INTEGRATIONTIME 4 LOUDNESSFRAMESSTORED 350
48 #define TEMPOLOW 90
49 //#define TEMPOHIGH 190
50 #define NR 100
51 #define ND 20
52 #define NDOVER2 10
53 #define NRD 2000
54 #define NDRECIP 0.05
55 #define TEMPOSTEP 1.0
56 #define INTEGRATIONTIME 3.4
57 //#define NUMBEATS 4
58 
59 //MINPERIOD 0.33 MAXPERIOD 0.66 MINDIFF 28 MAXDIFF 58
60 //MINPERIOD 0.3 MAXPERIOD 0.75 MINDIFF 25 MAXDIFF 65
61 #define MINPERIOD 0.315
62 #define MAXPERIOD 0.66
63 #define MINDIFF 27
64 #define MAXDIFF 58
65 
66 
67 //ceil(INTEGRATIONTIME*FRAMESR)
68 #define LOUDNESSFRAMESSTORED 293
69 //can calculate after frame 293 then
70 
71 //these values assume TEMPOLOW 90 and sample rate 44100 with 1024 FFT
72 //#define FFTSTOREMEM 350
73 //#define FFTSTORESIZE 8400
74 //about 4 seconds of FFT powers stored between 0 and 1000 Hz (bin indices 1 to 24 for aforementioned FFT size)
75 
76 //about once per second, now made quicker update
77 
78 //old values SKIP 28 TIMEELAPSED 0.3250794
79 #define SKIP 24
80 //28/86.1328
81 #define TIMEELAPSED 0.2786395
82 //just quicker than one beat at 180bpm 1.9969164 //0.9984582
83 
84 #define tempoconsistency 2
85 #define phaseconsistency 2
86 //#define tempotestvalue 0.25
87 //#define phasetestvalue 0.4
88 
89 #define MAXONSETS 50
90 
91 //const int toptempi=5;
92 
93 const float subbeats[8]= {0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5};
94 //const float subbeats[2][16]= {{0.0,0.25,0.5,0.75,1.0,1.25,1.5,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,3.75},{0.0,0.32,0.5,0.82,1.0,1.32,1.5,1.82,2.0,2.32,2.5,2.82,3.0,3.32,3.5,3.82}};
95 //const float subbeats[16]={0.0,0.25,0.5,0.75,1.0,1.25,1.5,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,3.75};
96 const float beats[4]= {0.0,1.0,2.0,3.0};
97 
98 //weights
99 const float sbtemplate[8]= {1.0,0.5,1.0,0.5,1.0,0.5,1.0,0.5};
100 
101 //could be different templates based on a parameter
102 //const float sbtemplate[16]= {1.0,0.1,0.8,0.2,1.0,0.1,0.8,0.2,1.0,0.1,0.8,0.2,1.0,0.1,0.8,0.2};
103 
104 //phase matching conditions
105 //float required[4]={1.0, 0.5, 0.3, 0.5};
106 
107 
108 //use integrationtime for maxwindow
109 //#define MAXWINDOW    //(numbeats+1)*lowperiod;
110 
111 
112 //for hanning window, constructed in plugin initialisation
113 float hanning[N];
114 
115 
116 int eqlbandbins[43]= {1,2,3,4,5,6,7,8,9,11,13,15,17,19,22,25,28,32,36,41,46,52,58,65,73,82,92,103,116,129,144,161,180,201,225,251,280,312,348,388,433,483,513};
117 int eqlbandsizes[42]= {1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,4,4,5,5,6,6,7,8,9,10,11,13,13,15,17,19,21,24,26,29,32,36,40,45,50,30};
118 
119 //this loudness conversion was removed since it worked better without transient detection but just using current energy
120 //float contours[42][11]= {{ 47.88, 59.68, 68.55, 75.48, 81.71, 87.54, 93.24, 98.84,104.44,109.94,115.31},{ 29.04, 41.78, 51.98, 60.18, 67.51, 74.54, 81.34, 87.97, 94.61,101.21,107.74},{ 20.72, 32.83, 43.44, 52.18, 60.24, 67.89, 75.34, 82.70, 89.97, 97.23,104.49},{ 15.87, 27.14, 37.84, 46.94, 55.44, 63.57, 71.51, 79.34, 87.14, 94.97,102.37},{ 12.64, 23.24, 33.91, 43.27, 52.07, 60.57, 68.87, 77.10, 85.24, 93.44,100.90},{ 10.31, 20.43, 31.03, 40.54, 49.59, 58.33, 66.89, 75.43, 83.89, 92.34,100.80},{  8.51, 18.23, 28.83, 38.41, 47.65, 56.59, 65.42, 74.16, 82.89, 91.61,100.33},{  7.14, 16.55, 27.11, 36.79, 46.16, 55.27, 64.29, 73.24, 82.15, 91.06, 99.97},{  5.52, 14.58, 25.07, 34.88, 44.40, 53.73, 62.95, 72.18, 81.31, 90.44, 99.57},{  3.98, 12.69, 23.10, 32.99, 42.69, 52.27, 61.66, 71.15, 80.54, 89.93, 99.31},{  2.99, 11.43, 21.76, 31.73, 41.49, 51.22, 60.88, 70.51, 80.11, 89.70, 99.30},{  2.35, 10.58, 20.83, 30.86, 40.68, 50.51, 60.33, 70.08, 79.83, 89.58, 99.32},{  2.05, 10.12, 20.27, 30.35, 40.22, 50.10, 59.97, 69.82, 79.67, 89.52, 99.38},{  2.00,  9.93, 20.00, 30.07, 40.00, 49.93, 59.87, 69.80, 79.73, 89.67, 99.60},{  2.19, 10.00, 20.00, 30.00, 40.00, 50.00, 59.99, 69.99, 79.98, 89.98, 99.97},{  2.71, 10.56, 20.61, 30.71, 40.76, 50.81, 60.86, 70.96, 81.01, 91.06,101.17},{  3.11, 11.05, 21.19, 31.41, 41.53, 51.64, 61.75, 71.95, 82.05, 92.15,102.33},{  2.39, 10.69, 21.14, 31.52, 41.73, 51.95, 62.11, 72.31, 82.46, 92.56,102.59},{  1.50, 10.11, 20.82, 31.32, 41.62, 51.92, 62.12, 72.32, 82.52, 92.63,102.56},{ -0.17,  8.50, 19.27, 29.77, 40.07, 50.37, 60.57, 70.77, 80.97, 91.13,101.23},{ -1.80,  6.96, 17.77, 28.29, 38.61, 48.91, 59.13, 69.33, 79.53, 89.71, 99.86},{ -3.42,  5.49, 16.36, 26.94, 37.31, 47.61, 57.88, 68.08, 78.28, 88.41, 98.39},{ -4.73,  4.38, 15.34, 25.99, 36.39, 46.71, 57.01, 67.21, 77.41, 87.51, 97.41},{ -5.73,  3.63, 14.74, 25.48, 35.88, 46.26, 56.56, 66.76, 76.96, 87.06, 96.96},{ -6.24,  3.33, 14.59, 25.39, 35.84, 46.22, 56.52, 66.72, 76.92, 87.04, 97.00},{ -6.09,  3.62, 15.03, 25.83, 36.37, 46.70, 57.00, 67.20, 77.40, 87.57, 97.68},{ -5.32,  4.44, 15.90, 26.70, 37.28, 47.60, 57.90, 68.10, 78.30, 88.52, 98.78},{ -3.49,  6.17, 17.52, 28.32, 38.85, 49.22, 59.52, 69.72, 79.92, 90.20,100.61},{ -0.81,  8.58, 19.73, 30.44, 40.90, 51.24, 61.52, 71.69, 81.87, 92.15,102.63},{  2.91, 11.82, 22.64, 33.17, 43.53, 53.73, 63.96, 74.09, 84.22, 94.45,104.89},{  6.68, 15.19, 25.71, 36.03, 46.25, 56.31, 66.45, 76.49, 86.54, 96.72,107.15},{ 10.43, 18.65, 28.94, 39.02, 49.01, 58.98, 68.93, 78.78, 88.69, 98.83,109.36},{ 13.56, 21.65, 31.78, 41.68, 51.45, 61.31, 71.07, 80.73, 90.48,100.51,111.01},{ 14.36, 22.91, 33.19, 43.09, 52.71, 62.37, 71.92, 81.38, 90.88,100.56,110.56},{ 15.06, 23.90, 34.23, 44.05, 53.48, 62.90, 72.21, 81.43, 90.65, 99.93,109.34},{ 15.36, 23.90, 33.89, 43.31, 52.40, 61.42, 70.29, 79.18, 88.00, 96.69,105.17},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70},{ 15.60, 23.90, 33.60, 42.70, 51.50, 60.20, 68.70, 77.30, 85.80, 94.00,101.70}};
121 //double phons[11]={2,10,20,30,40,50,60,70,80,90,100};
122 
123 
124 extern "C"
125 {
126 }
127 
128 InterfaceTable *ft;
129 
130 
131 
132 struct DrumTrack : Unit {
133 
134 	//FFT data
135 	int m_bufWritePos;
136 	float * m_prepareFFTBuf;
137 	float * m_FFTBuf;
138 
139 	scfft *m_scfft;
140 
141 	//time positions
142 	long m_frame;
143 
144 	//loudness measure
145 	float m_loudness[LOUDNESSFRAMESSTORED];
146 	int m_loudnesscounter;
147 	float m_loudbands[40];
148 
149 	//for bass onset detections
150 	float m_bassonsets[LOUDNESSFRAMESSTORED];
151 
152 	//tempo
153 
154 	float m_currtempo;
155 	float m_lasttempo;
156 	float m_tempodiff[tempoconsistency]; //initialise to ones
157 	int m_tdindex;
158 
159 	//phase
160 
161 	float m_currphase;
162 	float m_lastphasewinner;
163 	float m_phasediffs[phaseconsistency]; //initialise to ones
164 	int m_pdindex;
165 
166 	//phasor, trigger beat and modulo when >1.0
167 	float m_phase, m_phaseperblock;
168 
169 	//phasor output separate so can have it lock and keep going when don't want to track
170 	float m_outputphase, m_outputtempo, m_outputphaseperblock;
171 
172 	int halftrig;
173     int q1trig;
174 	int q2trig;
175 
176 	//can make twice as many including groove, or just test eighth note positions for now
177 
178 	//dynamic programming
179 	float m_lastscore[40];
180 	float m_lastcandidatetempo[10]; //indices
181 	float m_lastcandidatephase[40];
182 
183 	//candidate scores
184 	//float m_scores[NRD]; //2000 possibles
185 	float m_bestscores[10];
186 	float m_besttemposcores[10]; //store tempi
187 	float m_bestphasescores[40]; //store phases four for each, always best two and two antiphase
188 	float m_phasescores[40]; //store the actual scores for use in the the dyn prog cost function
189 
190 	//amortization
191 	int m_amortisationstate;
192 	int m_storeloudnesscounter;
193 	float m_scorenorm; //normalise all scores in a sweep by the maximum
194 
195 	//chord detection- Goto histogramming requires storing fft bins 1 to 24 over last 4 seconds (see workbook 15 dec 04)
196 //	float * m_fftstore;
197 //	int m_fftstorepos;
198 //	int m_fftstoreposhold;
199 //	float m_chordhistogram[24];
200 //	float m_chordhistogramprev[24];
201 //
202 
203 
204 	//bass/chord normalisation
205 	float m_bassmax;
206 
207 	//,m_chordmax;
208 
209 	//final consistency requirement
210 	float m_prevphase,m_prevtempo;
211 	float m_consistency;
212 
213 
214 	//goto onset spotting
215 	float * m_powerbuf[3];
216 	int m_powerbufcount;
217 
218 	float m_maxsnaresig;
219 	long m_lastsnaredetect;
220 
221 	float m_maxkicksig;
222 	long m_lastkickdetect;
223 
224 	//0 for nothing, 1 for snare, 2 for kick, same counter as m_loudnesscounter
225 	int m_onsets[LOUDNESSFRAMESSTORED];
226 	//int onsetposition[50];
227 	int m_onsetposition[MAXONSETS]; //no more than this
228 	float m_patternphase; //if
229 	float m_patternscore;
230 	float m_patterntempo;
231 
232 	float * m_prior;
233 
234 	int m_debugmode;
235 
236 };
237 
238 
239 
240 extern "C"
241 {
242 	//required interface functions
243 	void DrumTrack_next(DrumTrack *unit, int wrongNumSamples);
244 	void DrumTrack_Ctor(DrumTrack *unit);
245 	void DrumTrack_Dtor(DrumTrack *unit);
246 }
247 
248 //other functions
249 void preparefft(DrumTrack *unit, float* in, int n);
250 void dofft(DrumTrack *unit);
251 void calculateloudness(DrumTrack *unit);
252 void updatetempophase(DrumTrack *unit, float tempowinner,float phasewinner);
253 float phasematchesbassonsets(DrumTrack *unit, float phase, float bps);
254 //float comparechordetect(DrumTrack *unit, float phase, float bps);
255 
256 void snaredetection(DrumTrack *unit);
257 void kickdetection(DrumTrack *unit);
258 int findarchetype(DrumTrack *unit, float tempowinner);
259 void testpattern(DrumTrack * unit, int &bestindex, float &bestscore, int &besttempo, int first, int diff, int firstval);
260 
261 //amortisation
262 void do100thscoring(DrumTrack *unit,int j);
263 float calcphasediff(float prevphase, float phase, float prevtempo, float tempo);
264 void do40thpath(DrumTrack *unit,int i);
265 void finaldecision(DrumTrack *unit);
266 
267 //old
268 void tempoassess(DrumTrack *unit, float *, float *);
269 
DrumTrack_Ctor(DrumTrack * unit)270 void DrumTrack_Ctor(DrumTrack* unit) {
271 	int i,j;
272 
273 	unit->m_debugmode=(int)ZIN0(10);
274 
275 	////prior//////
276 
277 	unit->m_prior=NULL;
278 
279 	World *world = unit->mWorld;
280 
281 	int bufnum = (int)ZIN0(7);
282 
283 	//if (bufnum >= world->mNumSndBufs) bufnum = 0;
284 
285 	//printf("bufnum%d\n",bufnum);
286 
287 	if (bufnum>=0) {
288 	SndBuf *buf = world->mSndBufs + bufnum;
289 
290 	int priorbufsize = buf->samples;
291 
292 	if(priorbufsize!=100) {printf("buffer for tempo weightings prior not size 100  bufnum%d\n",bufnum);}
293 	else {
294 	unit->m_prior= buf->data;
295 
296 	//for (int h=0; h<100; ++h) {
297 //	printf("%f\n",unit->m_prior[h]);
298 	//}
299 	}
300 	}
301 
302 
303 	////////FFT data///////////
304 
305 	unit->m_prepareFFTBuf = (float*)RTAlloc(unit->mWorld, N * sizeof(float));
306 	unit->m_FFTBuf = (float*)RTAlloc(unit->mWorld, N * sizeof(float));
307 	unit->m_bufWritePos = 0;
308 
309 	//N=1024
310 	SCWorld_Allocator alloc(ft, unit->mWorld);
311 	//no overlap
312 	unit->m_scfft = scfft_create(N, N, kHannWindow, unit->m_FFTBuf, unit->m_FFTBuf, kForward, alloc);
313 
314 	////////time positions//////////
315 	unit->m_frame=0;
316 
317 	/////////loudness measure////////
318 	unit->m_loudnesscounter=LOUDNESSFRAMESSTORED-1;
319 	//zero loudness store
320 	for(j=0;j<LOUDNESSFRAMESSTORED;++j) {
321 		unit->m_loudness[j]=0.0;
322 		unit->m_bassonsets[j]=0.0;
323 	}
324 
325 	//zero previous specific loudness in Bark bands
326 	for(j=0;j<40;++j) {
327 		unit->m_loudbands[j]=0.0;
328 	}
329 
330 	/////////tempo assess///////////
331 	unit->m_currtempo=2;
332 	unit->m_lasttempo=2;
333 
334 	for(j=0;j<tempoconsistency;++j)
335 		unit->m_tempodiff[j]=1.0;		//if 0.0 biases taking first tempo estimate it can!
336 
337 	unit->m_tdindex=0;
338 
339 
340 	////////phase assess///////////
341 
342 	unit->m_currphase=0.0;
343 
344 	unit->m_lastphasewinner=0.0;
345 
346 	for(j=0;j<phaseconsistency;++j)
347 		unit->m_phasediffs[j]=1.0; //take first phase you can? No, wait
348 
349 	unit->m_pdindex=0;
350 
351 	unit->m_phase=0.0;
352 
353 	//default of 2bps
354 	unit->m_phaseperblock= (unit->mWorld->mFullRate.mBufLength*2)/(FS);
355 
356 	unit->m_outputphase= unit->m_phase;
357 	unit->m_outputtempo= unit->m_currtempo;
358 	unit->m_outputphaseperblock= unit->m_phaseperblock;
359 
360 	unit->mCalcFunc = (UnitCalcFunc)&DrumTrack_next;
361 
362 	unit->halftrig=0;
363     unit->q1trig=0;
364 	unit->q2trig=0;
365 
366 	//amortisation
367 	unit->m_amortisationstate=142; //off
368 
369 	//dyn prog initialise playing field
370 	float * lastscore= unit->m_lastscore;
371 	float * lastcandtempo= unit->m_lastcandidatetempo;
372 	float * lastcandphase= unit->m_lastcandidatephase;
373 
374 	for(j=0;j<10;++j) {
375 
376 		lastcandtempo[j]=1.5+j*0.15; //even spread
377 
378 		for (i=0;i<4;++i) {
379 			lastcandphase[4*j+i]=i*0.25; //even spread
380 			lastscore[4*j+i]=0;
381 
382 		}
383 	}
384 
385 
386 
387 	unit->m_scorenorm= 1.0;
388 
389 	//int storesize= FFTSTORESIZE; //24*FFTSTOREMEM;
390 //
391 //	unit->m_fftstore = (float*)RTAlloc(unit->mWorld, storesize * sizeof(float));
392 //
393 //	float * fftstore= unit->m_fftstore;
394 //
395 //	//zero initialise
396 //	for(j=0;j<storesize;++j) fftstore[j]=0;
397 //
398 //	unit->m_fftstorepos=FFTSTOREMEM-1;
399 //
400 	unit->m_bassmax=1.0;
401 	//unit->m_chordmax=1.0;
402 
403 	unit->m_prevphase=0.0;
404 	unit->m_prevtempo=2;
405 	unit->m_consistency=0.0;
406 
407 
408 	//snare detection
409 	for (i=0;i<3;++i)
410 		unit->m_powerbuf[i] = (float*)RTAlloc(unit->mWorld, NOVER4 * sizeof(float));
411 
412 	//zero buffers
413 	for (i=0;i<3;++i)
414 		for (j=0;j<NOVER4;++j)
415 			unit->m_powerbuf[i][j]=0.0;
416 
417 	unit->m_powerbufcount=0;
418 
419 	unit->m_maxsnaresig=ZIN0(9); //*15.0; //15.0; //40.0; //from testing, taken as the fair value
420 	unit->m_lastsnaredetect=0;
421 
422 	unit->m_maxkicksig=ZIN0(8)*20000.0; //1.0
423 
424 	//blank out onsets
425 	for(j=0;j<LOUDNESSFRAMESSTORED;++j) {
426 		unit->m_onsets[j]=0;
427 	}
428 
429 }
430 
431 
432 
DrumTrack_Dtor(DrumTrack * unit)433 void DrumTrack_Dtor(DrumTrack *unit)
434 {
435 
436 	RTFree(unit->mWorld, unit->m_prepareFFTBuf);
437 	RTFree(unit->mWorld, unit->m_FFTBuf);
438 	//RTFree(unit->mWorld, unit->m_fftstore);
439 
440 	for (int i=0;i<3;++i)
441 		RTFree(unit->mWorld, unit->m_powerbuf[i]);
442 
443 	if(unit->m_scfft) {
444 		SCWorld_Allocator alloc(ft, unit->mWorld);
445 		scfft_destroy(unit->m_scfft, alloc);
446 	}
447 }
448 
449 
DrumTrack_next(DrumTrack * unit,int wrongNumSamples)450 void DrumTrack_next(DrumTrack *unit, int wrongNumSamples)
451 {
452 	//would normally be float,will be cast to int for Tristan's optimisation
453 	float *in = IN(0);
454 
455 	//updated at control rate
456 	unit->m_maxsnaresig=ZIN0(9); //*15.0; //15.0; //40.0; //from testing, taken as the fair value
457 	unit->m_maxkicksig=ZIN0(8)*20000.0; //1.0
458 
459 	//printf("%d \n",wrongNumSamples);
460 
461 	int numSamples = unit->mWorld->mFullRate.mBufLength;
462 
463 	//conditions in reverse order to avoid immediate spillover
464 
465 	//printf("state %d \n",unit->m_amortisationstate);
466 
467 	//final update phase decision
468 	if(unit->m_amortisationstate==140) {
469 
470 		//printf("finaldecision \n");
471 
472 		unit->m_amortisationstate=unit->m_amortisationstate+1; //141 is off, nothing to do
473 
474 		finaldecision(unit);
475 	}
476 
477 	//then path assessments, 40*40= 1600, do 40 each time for conceptual clarity
478 	if((unit->m_amortisationstate>99) && (unit->m_amortisationstate<140)) {
479 
480 		//printf("do40thpath %d \n",unit->m_amortisationstate);
481 
482 		if(unit->m_amortisationstate==100) {
483 
484 			//maybe
485 			//	if((1.0/unit->m_bestscores[0])>0.00001) {
486 			if((1.0/unit->m_bestscores[0])<unit->m_scorenorm) {
487 				unit->m_scorenorm= 1.0/unit->m_bestscores[0];
488 
489 				//printf("%f \n",unit->m_scorenorm);
490 				 }
491 			//else
492 			//	unit->m_scorenorm= 1.0;
493 
494 			//set weakest candidate(s) to be the patten phase, tempo
495 
496 			//dangerous
497 			//unit->m_bestscores[9]=unit->m_patternscore;
498 			unit->m_bestscores[9]=unit->m_bestscores[0];
499 
500 		unit->m_besttemposcores[9]= unit->m_patterntempo;
501 		unit->m_bestphasescores[36]= unit->m_patternphase;
502 
503 
504 		}
505 
506 		do40thpath(unit, unit->m_amortisationstate-100);
507 		unit->m_amortisationstate=unit->m_amortisationstate+1;
508 
509 	}
510 
511 	//calculation spread out in time
512 	if(unit->m_amortisationstate<100) {
513 
514 		//printf("do100thscore %d \n",unit->m_amortisationstate);
515 
516 		do100thscoring(unit,unit->m_amortisationstate);
517 
518 		unit->m_amortisationstate=unit->m_amortisationstate+1;
519 
520 	}
521 
522 	preparefft(unit, in, numSamples);
523 
524 	//test if impulse to output
525 
526 	unit->m_phase+=unit->m_phaseperblock;
527 
528 	//if not locked, update output phase from model phase, else keep a separate output phase
529 
530 	float lock= ZIN0(1);
531 
532 	//printf("lock %f \n",lock);
533 
534 	if(lock<0.5) {
535 
536 	unit->m_outputphase= unit->m_phase;
537 	unit->m_outputtempo= unit->m_currtempo;
538 	unit->m_outputphaseperblock= unit->m_phaseperblock;
539 	} else {
540 	unit->m_outputphase+=unit->m_outputphaseperblock;
541 	}
542 
543 	if (unit->m_phase >= 1.f) {unit->m_phase-= 1.f;}
544 
545 	//0 is beat, 1 is quaver, 2 is semiquaver, 3 is actual current tempo in bps
546 	//so no audio accuracy with beats, just asap, may as well be control rate
547 	ZOUT0(0)=0.0;
548 	ZOUT0(1)=0.0;
549 	ZOUT0(2)=0.0;
550 	ZOUT0(3)=unit->m_outputtempo; //*0.016666667;
551 
552 	//output beat
553 	if (unit->m_outputphase >= 1.f) {
554 
555 		//printf("beat \n");
556 
557 		unit->m_outputphase -= 1.f;
558 		ZOUT0(0)=1.0;
559 		ZOUT0(1)=1.0;
560 		ZOUT0(2)=1.0;
561 		unit->halftrig=0;
562 		unit->q1trig=0;
563 		unit->q2trig=0;
564 	}
565 
566 	if (unit->m_outputphase>=0.5 && unit->halftrig==0) {
567 		ZOUT0(1)=1.0;
568 		ZOUT0(2)=1.0;
569 		unit->halftrig=1;
570 	}
571 
572 	if (unit->m_outputphase>=0.25 && unit->q1trig==0) {
573 		ZOUT0(2)=1.0;
574 		unit->q1trig=1;
575 	}
576 
577 	if (unit->m_outputphase>=0.75 && unit->q2trig==0) {
578 		ZOUT0(2)=1.0;
579 		unit->q2trig=1;
580 	}
581 
582 	//for (int i=0; i<numSamples; ++i) {
583 	//		*++output = 0.0;
584 	//	}
585 	//
586 
587 
588 }
589 
590 
591 //Tristan recommends copying ints rather than floats- I say negligible compared to other algorithm costs for the moment
592 // TO TREAT, check, update, probably replace entirely with pre allocated buffer based scheme?
preparefft(DrumTrack * unit,float * in,int n)593 void preparefft(DrumTrack *unit, float* in, int n) {
594 
595 	int i, index = 0, cpt = n, maxindex;
596 
597 	int bufpos= unit->m_bufWritePos;
598 
599 	float * preparefftbuf=unit->m_prepareFFTBuf;
600 	float * fftbuf= unit->m_FFTBuf;
601 
602 	// Copy input samples into prepare buffer
603 	while ((bufpos < N) && (cpt > 0)) {
604 		preparefftbuf[bufpos] = in[index];
605 		bufpos++;
606 		index++;
607 		cpt--;
608 	}
609 
610 	// When Buffer is full...
611 	if (bufpos >= N) {
612 
613 		// Make a copy of prepared buffer into FFT buffer for computation
614 		for (i=0; i<N; i++)
615 			fftbuf[i] = preparefftbuf[i];
616 
617 		// Save overlapping samples back into buffer- no danger since no indices overwritten
618 		for (i=0; i<OVERLAP; i++)
619 			preparefftbuf[i] = preparefftbuf[OVERLAPINDEX+i];
620 
621 		maxindex = n - index + OVERLAPINDEX;
622 
623 		//blockSize less than N-OVERLAPINDEX so no problem
624 		// Copy the rest of incoming samples into prepareFFTBuffer
625 		for (i=OVERLAPINDEX; i<maxindex; i++) {
626 			preparefftbuf[i] = in[index];
627 			index++;
628 		}
629 
630 		bufpos = maxindex;
631 
632 		//FFT buffer ready- calculate away!
633 		unit->m_frame= unit->m_frame+1;
634 		dofft(unit);
635 	}
636 
637 
638 	unit->m_bufWritePos= bufpos;
639 	//printf("%d \n",bufpos);
640 
641 }
642 
643 
644 
645 //calculation function once FFT data ready
dofft(DrumTrack * unit)646 void dofft(DrumTrack *unit) {
647 
648 	int i;
649 
650 	float * fftbuf= unit->m_FFTBuf;
651 
652 	for (i=0; i<N; ++i)
653 		fftbuf[i] *= hanning[i];
654 
655 	scfft_dofft(unit->m_scfft);
656 
657 	float val1, val2;
658 	// Squared Absolute so get power
659 	for (i=2; i<N; i+=2) {
660 		val1 = fftbuf[i];
661 		val2 = fftbuf[i+1];
662 		//i>>1 is i/2
663 		fftbuf[i>>1] = (val1*val1)+(val2*val2);
664 	}
665 
666 	//calculate loudness first, increments loudnesscounter needed in checkforonsets
667 	calculateloudness(unit);
668 
669 	//for snare and kick detection
670 	///keeping a record of last three fftbufs
671 	//update last three powers in required bands
672 	unit->m_powerbufcount=(unit->m_powerbufcount+1)%3;
673 
674 	float * storebuf= unit->m_powerbuf[unit->m_powerbufcount];
675 
676 	//only stores lower bands under 11kHz
677 	for (i=0;i<NOVER4;++i)
678 		storebuf[i]=fftbuf[i];
679 
680 	//zero out now, not two ago like before
681 	int onsetframe= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
682 	unit->m_onsets[onsetframe]=0;  //zero out old values
683 
684 	//high detections
685 	//gotodetectioninband(unit,unit->m_gotobands[1]);
686 
687 	//low detections second so these onsets always overpower the hgh onsets
688 	//gotodetectioninband(unit,unit->m_gotobands[0]);
689 
690 	//snare detections (not overwritable by kicks)
691 	snaredetection(unit);
692 	kickdetection(unit);
693 
694 	//avoid snare overwrite, trust snare detector
695 
696 	//	//check for any twos in last ten, checking ten either side
697 	//	int basepos= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED-2)%LOUDNESSFRAMESSTORED;
698 	//
699 	//	//if any kicks near recent snares, zero the snares
700 	//	for (j=0;j<5;++j) {
701 	//	 int pos=(basepos+LOUDNESSFRAMESSTORED-j)%LOUDNESSFRAMESSTORED;
702 	//
703 	//	 if(unit->m_onsets[pos]==1) {
704 	//		for (i=0;i<5;++i) { //checking 5 previous frames from current position, will gradually test 5 either side
705 	//		 int pos2=(basepos+LOUDNESSFRAMESSTORED-i)%LOUDNESSFRAMESSTORED;
706 	//
707 	//		if(unit->m_onsets[pos2]==2) {
708 	//		unit->m_onsets[pos]=0;
709 	//		//break //could break because know no 2 can come till 10 after a 2 onset, but safer to leave alone
710 	//		}
711 	//
712 	//		}
713 	//
714 	//	 }
715 	//
716 	//	}
717 
718 	//int onsetval= unit->m_onsets[(unit->m_loudnesscounter+LOUDNESSFRAMESSTORED-2)%LOUDNESSFRAMESSTORED];
719 	//if(onsetval) printf("onset %d \n",onsetval);
720 
721 
722 	if (unit->m_frame%SKIP==0) {
723 
724 		//printf("amortisation time \n");
725 
726 		//amortisation- 8 control periods in a frame
727 		//have 2000 calcs to do, split over 100 control periods = 6400 samples, ie one tempo per control period
728 
729 		unit->m_amortisationstate=0;
730 
731 		//fix time reference for calculations, so it doesn't update during the amortisation
732 		unit->m_storeloudnesscounter= unit->m_loudnesscounter;
733 
734 		//unit->m_fftstoreposhold= unit->m_fftstorepos;
735 
736 		unit->m_currphase=unit->m_phase;
737 
738 		//reset scoring
739 		//float * scores=  unit->m_scores;
740 		float * bestscores= unit->m_bestscores;
741 		//float * besttemposcores=unit->m_besttemposcores;
742 		//	float * bestphasescores=unit->m_bestphasescores;
743 		//
744 		for (i=0; i<10; ++i) {
745 
746 			//no need to zero, gets written into during this process
747 			//for (j=0; j<ND; ++j)
748 			//scores[i][j]; //2000 possibles
749 
750 			bestscores[i]=-1000;
751 			//besttemposcores[i]=0.0;
752 			//	bestphasescores[i*4]=0.0;
753 			//	bestphasescores[i*4+1]=0.0;
754 			//	bestphasescores[i*4+2]=0.0;
755 			//	bestphasescores[i*4+3]=0.0;
756 			//	no need to reset these since will automatically get written over
757 		}
758 
759 		//assess pattern matches for scoring
760 		int match= findarchetype(unit,0.0); //don't know tempowinner yet
761 
762 		//if (match && (unit->m_patternscore>1.75)) {
763 //
764 //		printf("pattern phase %f pattern tempo %f \n",unit->m_patternphase,unit->m_patterntempo);
765 //
766 //		}
767 
768 
769 
770 		//float tempowinner,phasewinner;
771 		//
772 		//	tempoassess(unit,&tempowinner,&phasewinner);
773 		//
774 		//	//1.0-phasewinner because the phasenow should be (1.0-pw) to get to a beat at pw
775 		//	updatetempophase(unit, tempowinner,phasewinner);
776 		//
777 	}
778 
779 	//updatephase
780 
781 }
782 
783 
784 
785 //global
786 float scoretemp[ND];
787 
do100thscoring(DrumTrack * unit,int j)788 void do100thscoring(DrumTrack *unit,int j) {
789 	int i,k, baseframe, rounded, testframe;
790 	float tempo, Ti, starttime;
791 	float phase, beatpos;
792 	float beat, beatsum;
793 	float prior;
794 
795 
796 	//weight by prior if one exists
797 	prior= 1.0;
798 
799 	if (unit->m_prior) {prior= unit->m_prior[j];}
800 
801 	//printf("prior %f %d\n",prior,j);
802 
803 	baseframe=unit->m_storeloudnesscounter+LOUDNESSFRAMESSTORED;
804 	float * loudness= unit->m_loudness;
805 
806 	float best, secondbest;
807 	int bestindex, secondbestindex;
808 	//find best two phases
809 	best=-1000;
810 	bestindex=0;
811 	secondbest=-1000;
812 	secondbestindex=0;
813 
814 	//float * scores=  unit->m_scores;
815 
816 	//int groovetype=0;
817 
818 	//for(int groove=0;groove<1;++groove) {
819 
820 	tempo=TEMPOLOW+(j*TEMPOSTEP);
821 
822 	Ti= 60/tempo;   //could have precalculated these- OPTIMISE
823 
824 	starttime= 0.0-(5*Ti);
825 
826 
827 	//different phase options
828 	for (k=0; k<ND; ++k) {
829 
830 		phase=k*NDRECIP;
831 
832 		beatpos=starttime+(Ti*phase);
833 
834 		beatsum=0.0;
835 
836 		//8 subbeats
837 		for (i=0;i<8;++i) {
838 
839 			beat=((subbeats[i])*Ti)+beatpos;
840 
841 			//beat=((subbeats[groove][i])*Ti)+beatpos;
842 
843 			//get nearest frame position
844 
845 			rounded= (int)floor(beat*FRAMESR+ .5f);
846 
847 			//printf("error in rounding? beat %f rounded %d correction %d \n",beat, rounded,  (int)(beat*FRAMESR -.5f));
848 
849 			testframe=(baseframe+rounded)%LOUDNESSFRAMESSTORED;
850 
851 			beatsum+=(sbtemplate[i])*loudness[testframe];
852 
853 			//could do a local sum +-2 frames
854 
855 		//	float localsum=0.0;
856 //
857 //			for (int hh=0; hh<3; ++hh) {
858 //
859 //			int locale= (testframe-1+hh+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
860 //
861 //			localsum+=loudness[locale];
862 //			}
863 
864 			//beatsum+=(sbtemplate[i])*localsum*0.333;
865 
866 		}
867 
868 		beatsum=beatsum*prior;
869 		scoretemp[k]=beatsum;
870 		//what is best so far?
871 
872 		//for normalising
873 		if (beatsum>best) {
874 			secondbest=best;
875 			secondbestindex=bestindex;
876 			best=beatsum;
877 			bestindex=k;
878 			//groovetype=groove;
879 		} else if (beatsum>secondbest) {
880 			secondbest=beatsum;
881 			secondbestindex=k;
882 		}
883 
884 		//not sure this needs to be stored at all
885 		//scores[j*ND+k]=beatsum;
886 
887 	}
888 
889 
890 
891 
892 	//what is minimum you need to do to get into the best scoring table?
893 	float leastbest= unit->m_bestscores[9];
894 
895 	//update topten
896 	if (best>leastbest) {
897 
898 		float * bestscores= unit->m_bestscores;
899 		float * besttemposcores=unit->m_besttemposcores;
900 		float * bestphasescores=unit->m_bestphasescores;
901 		float * phasescores= unit->m_phasescores;
902 
903 		//where does it rate
904 		for (i=0; i<10; ++i) {
905 			if(best>bestscores[i]) break;
906 		}
907 
908 		//copy all below down one
909 		for (k=9; k>i; --k) {
910 			bestscores[k]=bestscores[k-1];
911 			besttemposcores[k]=besttemposcores[k-1];
912 
913 			for (int g=0; g<4; ++g) {
914 				bestphasescores[k*4+g]=bestphasescores[(k-1)*4+g];
915 				phasescores[k*4+g]=phasescores[(k-1)*4+g];
916 			}
917 		}
918 
919 		//insertion at i
920 		bestscores[i]=best;
921 		besttemposcores[i]=tempo*0.01666667; //j;
922 
923 		//actually stores phases
924 		bestphasescores[i*4]=bestindex*NDRECIP;
925 		bestphasescores[i*4+1]=secondbestindex*NDRECIP;
926 		bestphasescores[i*4+2]=((bestindex+NDOVER2)%ND)*NDRECIP; //pi out of phase option, may be doubled up safely I assume
927 		bestphasescores[i*4+3]=((secondbestindex+NDOVER2)%ND)*NDRECIP;
928 
929 		//this stores scores
930 		phasescores[i*4]= scoretemp[bestindex];
931 		phasescores[i*4+1]= scoretemp[secondbestindex];
932 		phasescores[i*4+2]= scoretemp[((bestindex+NDOVER2)%ND)];
933 		phasescores[i*4+3]= scoretemp[((secondbestindex+NDOVER2)%ND)];
934 
935 	}
936 
937 	}
938 
939 
940 
941 
942 
do40thpath(DrumTrack * unit,int i)943 void do40thpath(DrumTrack *unit,int i) {
944 
945 	int j;
946 
947 	//will make them constants, variables?
948 	float dynleak=ZIN0(2); //0.7; //0.5;
949 	float tempowt=ZIN0(3); //1.0; //1.0; //dyn tempo cost
950 	float phasewt=ZIN0(4); //2.0; //dyn phase cost
951 						//	float gamma=0.0; //1.0; //1.0 //consistent tempo cost
952 						//	float epsilon=0.0; //2.0; //2.0; //consistent phase cost
953 	float basswt=ZIN0(5); //1.0;
954 	float patternwt=ZIN0(6); //1.0 used to be chordwt;
955 
956 
957 	//printf("do40th test1 %d %d \n",unit->m_amortisationstate,i);
958 
959 	float * lastscore= unit->m_lastscore;
960 
961 	//maybe store float as cheaper on CPU?
962 	float * lastcandtempo= unit->m_lastcandidatetempo;
963 	float * lastcandphase= unit->m_lastcandidatephase;
964 
965 	//float * bestscores= unit->m_bestscores;
966 
967 	//or should have stored actual values?
968 	float tempocand= unit->m_besttemposcores[i/4];
969 	float phasecand=unit->m_bestphasescores[i];
970 
971 
972 	//test phasewinner against bass onsets
973 	float bassonsetson= phasematchesbassonsets(unit,phasecand,tempocand);
974 	//compare to antiphase
975 
976 	//printf("phase winner %f antiphase %f\n",phasewinner,fmod(phasewinner+0.5,1.0));
977 
978 	float antiphase= fmod(phasecand+0.5,1.0);
979 
980 	float bassonsetsoff= phasematchesbassonsets(unit,antiphase,tempocand);
981 
982 	if (bassonsetsoff<1) bassonsetsoff=1;
983 
984 	float bassratio= bassonsetson/bassonsetsoff;
985 
986 	//float chordratio= comparechordetect(unit,phasecand,tempocand);
987 
988 	float bassmax= unit->m_bassmax;
989 
990 	//gradual decay over time
991 	bassmax= 0.999*bassmax;
992 
993 	if (bassratio>bassmax) bassmax=bassratio;
994 
995 	unit->m_bassmax=bassmax;
996 
997 	//float chordmax= unit->m_chordmax;
998 	//
999 	////gradual decay over time
1000 	//chordmax= 0.999*chordmax;
1001 	//
1002 	//if (chordratio>chordmax) chordmax=chordratio;
1003 	//
1004 	//unit->m_chordmax=chordmax;
1005 
1006 	//bigger the bass/chord ratio, less the cost
1007 	float basscost= (basswt)*(1.0-(bassratio/bassmax));
1008 
1009 	//maximal cost if no evidence
1010 	float patterncost= 1.0; //(chordwt)*(1.0-(chordratio/chordmax));
1011 
1012 	if (unit->m_patternscore>1.75) {
1013 		//be more lenient because kick/snare detection is approximate
1014 		float patttempodiff=fabs(tempocand-unit->m_patterntempo);
1015 		if (patttempodiff>0.105) patttempodiff=1; else patttempodiff=0.0;
1016 
1017 		//phase cost of this phase replacing current phase of oscillator
1018 		float pattphaseerror= fabs(calcphasediff(unit->m_patternphase,phasecand,unit->m_patterntempo,tempocand));
1019 
1020 		//printf("pattern phase cost %f pattern tempo cost %f \n",pattphaseerror,patttempodiff);
1021 
1022 		//patterncost= patternwt*((0.0*patttempodiff) + (3*pattphaseerror));
1023 		patterncost= patternwt*((0.5*patttempodiff) + (0.5*3*pattphaseerror));
1024 	}
1025 
1026 
1027 	//values now
1028 	float tempo=unit->m_currtempo;
1029 	float phase=unit->m_currphase; //captured at beginning of amortisation, can't used unit->m_phase without correction as some time has passed due to amortisation
1030 
1031 	float prevtempo,prevphase;
1032 
1033 	//find lowest score
1034 
1035 	//score= previousscore*dynleak + score+ tempotransitioncost*alpha + epsilon*tempoconfrimationcost (from currtempo to this)
1036 	//beta*phasetransitioncost (path cost) + gamma*phaseconfirmationcost (from last phase to this)
1037 
1038 	float cost,mincost;
1039 
1040 	mincost=1000000;
1041 
1042 	//these two transitions are dyn prog independent so calculated outside this loop
1043 	//tempo transition costs- fixed if tempo transition above some constant (assume JND for tempo = 8% so 0.105bps at 1.5bps
1044 
1045 	float tempodiff=fabs(tempocand-tempo);
1046 	if (tempodiff>0.105) tempodiff=1; else tempodiff=0.0;
1047 
1048 	float tempowincost= 0.0; //gamma*tempodiff;
1049 
1050 	//phase cost of this phase replacing current phase of oscillator
1051 	float phaseerror= fabs(calcphasediff(phase,phasecand,tempo,tempocand));
1052 
1053 	float phasewincost = 0.0; //epsilon*phaseerror;
1054 
1055 	float tempotransitioncost, phasetransitioncost, oldscorecost, newscorecost;
1056 
1057 	//aim is to minimse cost, normed to 0-1 then inverted
1058 	//could have *0.01);//fixed norm to avoid bias from calc to calc//
1059 	newscorecost= 1.0-(unit->m_phasescores[i]*(unit->m_scorenorm)); //score normalised by best result //bestscores[j];
1060 
1061 	//through 40 previous candidates to this one
1062 	for(j=0;j<40;++j) {
1063 
1064 		prevtempo=lastcandtempo[j/4];
1065 		prevphase=lastcandphase[j];
1066 
1067 		oldscorecost= dynleak*lastscore[j]; //could pre multiply to avoid redoing in each function call, one optimisation too much maybe
1068 
1069 		//cost over changing hypotheses (no cost if consistent)
1070 		tempodiff=fabs(prevtempo-tempocand);
1071 		if(tempodiff>0.105) tempodiff=1; else tempodiff=0.0;
1072 
1073 		tempotransitioncost=tempowt*tempodiff;
1074 
1075 		//DrumTrack phase transition costs (my correction)
1076 		phaseerror= fabs(calcphasediff(prevphase,phasecand,prevtempo,tempocand));
1077 
1078 		phasetransitioncost=phasewt*3*phaseerror; //random 3!
1079 
1080 		cost = oldscorecost+newscorecost+phasetransitioncost+tempotransitioncost+phasewincost+tempowincost+basscost+patterncost;
1081 
1082 		//if(j==0)
1083 		//printf(" oldscorecost %f newscorecost %f phasetransitioncost %f tempotransitioncost %f phasewincost %f tempowincost %f cost %f \n", oldscorecost,newscorecost,phasetransitioncost,tempotransitioncost,phasewincost,tempowincost,cost);
1084 
1085 		//cost
1086 		if (cost<mincost)
1087 			mincost=cost;
1088 
1089 	}
1090 
1091 	//will store mincost in current score until finalisation
1092 	//bestscores[j]=mincost;
1093 
1094 	//will also be the min passed through as lastscore, works OK
1095 	unit->m_phasescores[i]=mincost;
1096 
1097 	//save cost to unit->m_cost[j]=cost for unit->m_phasescores;
1098 
1099 }
1100 
1101 //find next beat times with respect to old phase, tempo and new phase, tempo at this point
1102 
1103 //favours low tempi since phase representation is time independent!
calcphasediff(float prevphase,float phase,float prevtempo,float tempo)1104 float calcphasediff(float prevphase, float phase, float prevtempo, float tempo) {
1105 
1106 	float a,b,c,result;
1107 
1108 	float phasediff= TIMEELAPSED*prevtempo- prevphase; //used to be timediff= TIMEELAPSED-(prevphase/prevtempo); phasediff=timediff*prevtempo
1109 
1110 	//phase from old beat to next beat, see 12 OCT diagram
1111 	float phasetobeat= floor(phasediff)+1.0-phasediff;
1112 
1113 	//corrected for old tempo (currtempo) then rewritten in terms of the new tempowinner
1114 	//float requiredphase= (phasetobeat*tempo)/prevtempo;
1115 
1116 	float oldtimetobeat= phasetobeat/prevtempo;
1117 	float newtimetobeat= phase/tempo;
1118 
1119 	a=oldtimetobeat;
1120 	b=newtimetobeat;
1121 
1122 	//wlog
1123 	if(b<a) {c=b; b=a; a=c;  c=1/prevtempo;} else {c= 1/tempo;}
1124 
1125 	//closest between the two beat predictions
1126 	result= sc_min(b-a, a-(b-c));
1127 //
1128 //	printf("phase error %f \n",result);
1129 //
1130 //if correct within 50mS
1131 	//if (result<0.03) result=0.0;
1132 
1133 	return result;//sc_min(b-a, a-(b-c));
1134 }
1135 
1136 /*
1137 //favours low tempi since phase representation is time independent!
1138 float calcphasediff(float prevphase, float phase, float prevtempo, float tempo) {
1139 
1140 	float a,b;
1141 
1142 	float phasediff= TIMEELAPSED*prevtempo- prevphase; //used to be timediff= TIMEELAPSED-(prevphase/prevtempo); phasediff=timediff*prevtempo
1143 
1144 	//phase from old beat to next beat, see 12 OCT diagram
1145 	float phasetobeat= floor(phasediff)+1.0-phasediff;
1146 
1147 	//corrected for old tempo (currtempo) then rewritten in terms of the new tempowinner
1148 	float requiredphase= (phasetobeat*tempo)/prevtempo;
1149 
1150 	a=requiredphase;
1151 	b=phase;
1152 
1153 	if(b<a) b=b+1.0;
1154 
1155 	return sc_min(b-a, 1.0+a-b);
1156 
1157 }
1158 */
1159 
1160 //choose lowest score as winner-
1161 //only swap if sufficiently unambiguous lead?
finaldecision(DrumTrack * unit)1162 void finaldecision(DrumTrack *unit) {
1163 	int i,j;
1164 
1165 	float * lastscore= unit->m_lastscore;
1166 
1167 	//maybe store float as cheaper on CPU?
1168 	float * lastcandtempo= unit->m_lastcandidatetempo;
1169 	float * lastcandphase= unit->m_lastcandidatephase;
1170 
1171 	float * bestscores= unit->m_phasescores; //actually stored in this array, was bestscores before but bestscores used for holding 10 best tempi scores
1172 
1173 	//or should have stored actual values?
1174 	float * tempocand= unit->m_besttemposcores;
1175 	float * phasecand=unit->m_bestphasescores;
1176 
1177 	float score,min, secondmin;
1178 	int minindex,secondminindex;
1179 
1180 	minindex=0;
1181 	min=10000000;
1182 	secondmin=10000000;
1183 	secondminindex=0;
1184 
1185 	for (j=0;j<40;++j){
1186 
1187 		score=bestscores[j];
1188 
1189 		if(score<min) {
1190 			min=score;
1191 			minindex=j;
1192 		} else if((score<secondmin) && (score>min)) {
1193 			secondmin=score;
1194 			secondminindex=j;
1195 		}
1196 
1197 
1198 	}
1199 
1200 	//minindex is winner, update paths
1201 	float phasewinner=phasecand[minindex];
1202 	float tempowinner=tempocand[minindex/4];
1203 
1204 	//int match= findarchetype(unit,tempowinner); //don't use tempowinner yet
1205 //
1206 //	if (match && (unit->m_patternscore>1.75)) {
1207 //
1208 //	printf("phasewinner %f pattern phase %f tempowinner %f pattern tempo %f \n",phasewinner,unit->m_patternphase, tempowinner,unit->m_patterntempo);
1209 //
1210 //	phasewinner= unit->m_patternphase;
1211 //	tempowinner= unit->m_patterntempo;
1212 //
1213 //	}
1214 
1215 	//perhaps only allow a tempochange if these two are sufficiently different
1216 	//printf("best %f secondbest %f ratio %f \n",min,secondmin, min/secondmin);
1217 
1218 	//check consistency of estimate
1219 
1220 	//float tempodiff=fabs(tempocand-unit->m_prevtempo);
1221 	//if (tempodiff<0.105) tempodiff=1; else tempodiff=0.0;
1222 	//
1223 
1224 	//phase cost of last posited phase becoming new phase of oscillator
1225 	float phaseerror= fabs(calcphasediff(unit->m_prevphase,phasewinner,unit->m_prevtempo,tempowinner));
1226 
1227 	//phaseerror is in time, if less than 0.075 seconds?
1228 	//used to be 0.1
1229 	//if ((phaseerror<0.1) && ((min/secondmin)<0.995))
1230 	if (phaseerror<0.135) //0.14
1231 		++unit->m_consistency;
1232 	else
1233 		unit->m_consistency=0.0;
1234 
1235 	unit->m_prevphase=phasewinner;
1236 	unit->m_prevtempo=tempowinner;
1237 
1238 
1239 	//printf("phasewinner %f tempowinner %f \n",phasewinner, tempowinner);
1240 	//printf("minimum score %f consistency %f phaseerror %f\n",min,unit->m_consistency,phaseerror);
1241 
1242 
1243 	//could make the test value a parameter, or do -2 on score
1244 	//only swap when sufficient consistent, don't keep swapping if consistent!
1245 	//if( (unit->m_consistency>2.5) && (unit->m_consistency<3.5)) {
1246 	if( (unit->m_consistency>1.5) && (unit->m_consistency<2.5)) {
1247 	//if( (unit->m_consistency>0.5) && (unit->m_consistency<1.5)) {
1248 
1249 		//phase has moved on by some time since the calculation frame
1250 		////correction for recording happened during this!
1251 		//int framespassed= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED- unit->m_storeloudnesscounter)%LOUDNESSFRAMESSTORED;
1252 		//float phasepassed= framespassed*FRAMEPERIOD*tempowinner;
1253 
1254 		float timepassed= 0.2046259; //141*64/44100; //fixed by control period, amortisation and sampling rate
1255 		float phasepassed= timepassed*tempowinner;
1256 
1257 		//don't update phase if sufficiently similar
1258 		updatetempophase(unit, tempowinner,fmod(phasewinner+phasepassed,1.0)); //phasewinner
1259 
1260 		if(unit->m_debugmode==1)
1261 		printf("update phasewinner %f pattern phase %f tempowinner %f pattern tempo %f \n",phasewinner,unit->m_patternphase, tempowinner,unit->m_patterntempo);
1262 
1263 	}
1264 
1265 	int index;
1266 
1267 	//update previous scores with these
1268 	for(j=0;j<10;++j) {
1269 
1270 		lastcandtempo[j]=tempocand[j]; //even spread
1271 
1272 		for (i=0;i<4;++i) {
1273 			index=4*j+i;
1274 			lastcandphase[index]=phasecand[index]; //even spread
1275 			lastscore[index]=bestscores[index];
1276 		}
1277 	}
1278 
1279 }
1280 
1281 
1282 
1283 //used twice, once for phase, once for antiphase?
phasematchesbassonsets(DrumTrack * unit,float phase,float bps)1284 float phasematchesbassonsets(DrumTrack *unit, float phase, float bps) {
1285 	int i,j,baseframe, rounded, testframe;
1286 	float Ti, starttime, beatpos, beat;
1287 	//just testing at beat frame positions
1288 
1289 	baseframe=unit->m_storeloudnesscounter+LOUDNESSFRAMESSTORED;
1290 
1291 	Ti= 1/bps;   //could have precalculated these- OPTIMISE
1292 
1293 	////correction for recording happened during this!
1294 	//int framespassed= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED- unit->m_storeloudnesscounter)%LOUDNESSFRAMESSTORED;
1295 	//
1296 	//printf("gone by %d \n",framespassed);
1297 	//
1298 	starttime= 0.0-(5*Ti);
1299 
1300 	beatpos=starttime+(Ti*phase);
1301 
1302 	float beatsum=0;
1303 	//int found;
1304 	float avg;
1305 
1306 	float * bassonsets= unit->m_bassonsets;
1307 
1308 	//4 beats
1309 	for (i=0;i<4;++i) {
1310 
1311 		beat=(i*Ti)+beatpos;
1312 
1313 		rounded= (int)floor(beat*FRAMESR+ .5f);
1314 
1315 		//found=0;
1316 		avg=0.0;
1317 
1318 	//	//test within 3 either side
1319 //		for(j=0;j<9;++j) {
1320 //			testframe=(baseframe+rounded+j-4)%LOUDNESSFRAMESSTORED;
1321 //
1322 //			//could do weighted sum, peak in middle...
1323 //			avg=avg+bassonsets[testframe]; //if(bassonsets[testframe]==1) found=1;
1324 //		}
1325 //
1326 //		//testframe=(baseframe+rounded)%LOUDNESSFRAMESSTORED;
1327 //
1328 //		beatsum+=avg*0.11111; //bassonsets[testframe];
1329 //
1330 
1331 		//test within 3 either side
1332 		for(j=0;j<7;++j) {
1333 			testframe=(baseframe+rounded+j-3)%LOUDNESSFRAMESSTORED;
1334 
1335 			//could do weighted sum, peak in middle...
1336 			avg=avg+bassonsets[testframe]; //if(bassonsets[testframe]==1) found=1;
1337 		}
1338 
1339 		//testframe=(baseframe+rounded)%LOUDNESSFRAMESSTORED;
1340 
1341 		beatsum+=avg*0.1428571; //bassonsets[testframe];
1342 
1343 
1344 	}
1345 
1346 	return beatsum;
1347 }
1348 
1349 
1350 
1351 
1352 //only updates if sufficiently different
updatetempophase(DrumTrack * unit,float newtempo,float newphase)1353 void updatetempophase(DrumTrack *unit, float newtempo,float newphase) {
1354 
1355 	float phase,phasenow,a,b,ahead;
1356 
1357 	phase=unit->m_phase;
1358 
1359 	//test phase difference of new estimate from current phase of oscillator
1360 
1361 	a=1.0-newphase;
1362 	b=phase;
1363 
1364 	if(b<a) b=b+1.0;
1365 
1366 	b=sc_min(b-a, 1.0+a-b); //value from 0.0 to 0.5
1367 
1368 	//only update if greater than 50mS phase difference (adjusted for tempo)
1369 
1370 	//if (b>(0.05*newtempo)) {
1371 	//if (b>(0.025*newtempo)) { //improved CDR by 5%
1372 	if (b>(0.01*newtempo)) { //by 10% now, but 0.0 doesn't help
1373 		//pass in [] if no update
1374 		//if(newphase>=(-0.1))
1375 		phasenow=1.0-newphase;
1376 		//printf("phasechange %f\n",phasenow);
1377 		//printf("check b %f\n",b);
1378 
1379 	}
1380 	else
1381 		phasenow=phase;
1382 
1383 	a=phase;
1384 	b=phasenow;
1385 
1386 	if(b<a) b=1.0+b;
1387 
1388 	//phasenow up to 1.0 ahead, but by how much?
1389 	ahead= b-a;
1390 
1391 	if(ahead>0.5) //phasenow behind phase- drop phase back, ahead will be negative
1392 		ahead= ahead-1.0;
1393 
1394 
1395 	//both cases now adjust by ahead
1396 	//correction by up to a quarter cycle? No, correct by a maximum of x seconds, tempo dependent
1397 
1398 	//actually, correct by full amount as long as there is consistent evidence
1399 	//0.2 seconds in beats at current tempo
1400 	//maxcorrection=1.0; //min(0.1*temponow,1.0); %correct by no more than a beat
1401 	//ahead=sign(ahead)*(min(abs(ahead),maxcorrection));
1402 
1403 	//can't correct back earlier than current phase else may beat twice!
1404 	//must temporarily drop the rate
1405 	//phase=mod(max(phase+ahead,floor(phase)),1.0);
1406 
1407 	//no, just store last beat time and require greater than...
1408 	unit->m_phase=fmod(phase+ahead+1.0,1.0);
1409 
1410 	unit->m_currtempo=newtempo;
1411 
1412 	unit->m_phaseperblock= (unit->mWorld->mFullRate.mBufLength*newtempo)/(FS);
1413 
1414 }
1415 
1416 
1417 
1418 
1419 //also calc kick drum detector on bottom three bands
calculateloudness(DrumTrack * unit)1420 void calculateloudness(DrumTrack *unit) {
1421 
1422 	int j,k;
1423 
1424 	float * fftbuf= unit->m_FFTBuf;
1425 
1426 	float dfsum=0.0; //,lsum=0.0;
1427 	float bassonset=0;
1428 	float basssum=0.0;
1429 
1430 		//store powers for later chord detection step
1431 //	float * fftstore= unit->m_fftstore;
1432 //
1433 //	unit->m_fftstorepos=(unit->m_fftstorepos+1)%FFTSTOREMEM;
1434 //
1435 //	int basepos= 24*unit->m_fftstorepos;
1436 //	for(j=0;j<24;++j) {
1437 //		fftstore[basepos+j]=fftbuf[j+1];
1438 //	}
1439 //
1440 
1441 
1442 
1443 	for (k=0; k<40; ++k){
1444 
1445 		int bandstart=eqlbandbins[k];
1446 		//int bandend=eqlbandbins[k+1];
1447 		int bandsize= eqlbandsizes[k];
1448 
1449 		float bsum=0.0;
1450 
1451 		for (int h=0; h<bandsize;++h) {
1452 			bsum= bsum+fftbuf[h+bandstart];
1453 		}
1454 
1455 		//store recips of bandsizes?
1456 		bsum= bsum/bandsize;
1457 
1458 
1459 			float diff=bsum;
1460 		dfsum=dfsum+diff;
1461 				if (k<5) basssum=basssum+diff;
1462 
1463 	}
1464 
1465 
1466 	//increment first so this frame is unit->loudnesscounter
1467 	unit->m_loudnesscounter=(unit->m_loudnesscounter+1)%LOUDNESSFRAMESSTORED;
1468 
1469 		unit->m_loudness[unit->m_loudnesscounter]=dfsum; //dfsum*0.025; //divide by num of bands to get a dB answer
1470 													 //printf("loudness %f %f \n",unit->loudness[unit->loudnesscounter], lsum);
1471 
1472 bassonset= basssum; //90+(10*log10(basssum));
1473 
1474 unit->m_bassonsets[unit->m_loudnesscounter]=bassonset;
1475 
1476 }
1477 
1478 
1479 //snare limits= [34,177] (may try to reduce summands for CPU saving)
snaredetection(DrumTrack * unit)1480 void snaredetection(DrumTrack *unit){
1481 
1482 	float snaresig,highfreqave,lowfreqave,quantsum, power,temp;
1483 	int count,num;
1484 
1485 	//will also use these for indexing
1486 	int now=unit->m_powerbufcount;
1487 	int last, lastlast;
1488 	last=(2+now)%3; //avoid negative numbers in modulo- get back negatives!
1489 	lastlast=(1+now)%3;
1490 
1491 	float * nowbuf,*lastbuf,*lastlastbuf;
1492 	nowbuf=unit->m_powerbuf[now];
1493 	lastbuf=unit->m_powerbuf[last];
1494 	lastlastbuf=unit->m_powerbuf[lastlast];
1495 
1496     num=0;
1497     quantsum=0.0;
1498     count=0;
1499 
1500 	snaresig=1.0;
1501 
1502     for(int f=33; f<177;++f) {
1503 
1504         power=lastbuf[f];
1505 
1506         highfreqave = 0.25*(lastbuf[f+2]+lastlastbuf[f+1]+lastbuf[f+1]+nowbuf[f+1]);
1507         lowfreqave = 0.25*(lastbuf[f-2]+lastlastbuf[f-1]+lastbuf[f-1]+nowbuf[f-1]);
1508 
1509 		temp=sc_min(highfreqave,lowfreqave);
1510 
1511 		//0.25
1512         if(temp > (0.5*power)) {
1513             quantsum=quantsum+power;
1514             num=num+1;
1515         }
1516 
1517 		//printf("minave %f power %f quantsum %f \n",temp,power,quantsum);
1518 
1519         count=count+1;
1520 
1521         if(count==9) {
1522 			//0.125*(quantsum*0.11111111)
1523 			temp=0.0138889*quantsum;
1524 			temp=sc_min(temp,0.54);
1525             snaresig*=(1+temp);
1526             quantsum=0.0;
1527             count=0;
1528 		}
1529 
1530     }
1531 
1532     //snaresig(1,t)= prod(noisebands); %mean(noisebands); %num
1533 
1534 	//printf("snaresig %f \n",snaresig);
1535 
1536 	//can't allow max to get too high else detections suddenly cut out- 100 seems a fair value
1537 
1538 	//if(snaresig>(unit->m_maxsnaresig)) {
1539 //		//unit->m_maxsnaresig=snaresig;
1540 //
1541 //		printf("max found! %f \n",snaresig); //unit->m_maxsnaresig);
1542 //	}
1543 
1544 	//max vals up to 1.54**16 ie about 1000
1545 
1546 	snaresig=snaresig/(1000*unit->m_maxsnaresig);
1547 
1548 	//printf("postsnaresig %f \n",snaresig);
1549 
1550 	//should peak pick really!
1551 
1552 	//snare detection- don't allow another for a while? m_lastsnaredetect
1553 	if(snaresig>0.5) { //used to be 0.5, can add a user defined threshold
1554 
1555 		//stop in a row detections
1556 		if(unit->m_lastsnaredetect<(unit->m_frame-6)) {
1557 
1558 			if(unit->m_debugmode==2)
1559 			printf("snare found! %ld %ld \n", unit->m_lastsnaredetect, unit->m_frame);
1560 
1561 			//occured one frame ago, but do -2 to avoid kick overwrite on next cycle!
1562 			int onsetframe= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED-2)%LOUDNESSFRAMESSTORED;
1563 
1564 			unit->m_onsets[onsetframe]=2; //(-1);  //snare
1565 		}
1566 
1567 		unit->m_lastsnaredetect=unit->m_frame;
1568 
1569 	}
1570 
1571 }
1572 
1573 
1574 
1575 //uses Goto onset detection to with threshold to spot a kick
kickdetection(DrumTrack * unit)1576 void kickdetection(DrumTrack *unit){
1577 
1578 	float dsum;
1579 	float kicksig;
1580 
1581 	//will also use these for indexing
1582 	int now=unit->m_powerbufcount;
1583 	int last, lastlast;
1584 	last=(2+now)%3; //avoid negative numbers in modulo- get back negatives!
1585 	lastlast=(1+now)%3;
1586 
1587 	float * nowbuf,*lastbuf,*lastlastbuf;
1588 	nowbuf=unit->m_powerbuf[now];
1589 	lastbuf=unit->m_powerbuf[last];
1590 	lastlastbuf=unit->m_powerbuf[lastlast];
1591 
1592 	dsum=0.0;
1593 
1594 	for(int f=1; f<=3; ++f) {
1595 
1596 		float updownmax= sc_max(lastlastbuf[f-1],lastlastbuf[f+1]);
1597 		float prevpow= sc_max(lastlastbuf[f],updownmax);
1598 
1599 		float tempmin=sc_min(lastbuf[f],nowbuf[f]);
1600 
1601 		if(tempmin>prevpow) {
1602 
1603 			float temp=sc_max(lastbuf[f],nowbuf[f]);
1604 			dsum=dsum+temp;
1605 		}
1606 	}
1607 
1608 
1609 	kicksig=dsum/3;
1610 	//running max must be kept- just will do best so far for now...could become best within last x seconds
1611 	//updatemaxforband
1612 
1613 
1614 //	if(kicksig>(unit->m_maxkicksig)) {
1615 //		unit->m_maxkicksig=kicksig;
1616 //
1617 //		printf("max found! %f \n",unit->m_maxkicksig);
1618 //	}
1619 
1620 	kicksig=kicksig/(unit->m_maxkicksig);
1621 
1622 	//kick detection- don't allow another for a while? m_lastsnaredetect
1623 	if(kicksig>0.6) { //used to be 0.5, can add a user defined threshold
1624 
1625 		//stop in a row detections
1626 		if(unit->m_lastkickdetect<(unit->m_frame-6)) {
1627 
1628 			if(unit->m_debugmode==2)
1629 			printf("kick found! %ld %ld \n", unit->m_lastkickdetect, unit->m_frame);
1630 
1631 
1632 			//occured one frame ago, but do -2 to avoid kick overwrite on next cycle!
1633 			int onsetframe= (unit->m_loudnesscounter+LOUDNESSFRAMESSTORED-2)%LOUDNESSFRAMESSTORED;
1634 
1635 			unit->m_onsets[onsetframe]=1;  //kick- might do 1 kick, -1 snare
1636 		}
1637 
1638 		unit->m_lastkickdetect=unit->m_frame;
1639 
1640 	}
1641 
1642 }
1643 
1644 
1645 
1646 //one matching the tempowinner will score most (can over write even if an equal score)
1647 
1648 //impose tempowinner t choose selection spread? o/w could be missing second beat but have third and fourth
1649 
1650 //look for archetypal pattern in m_onsets
1651 //phase not important, want to just look at a fixed area in the past
findarchetype(DrumTrack * unit,float tempowinner)1652 int findarchetype(DrumTrack *unit, float tempowinner) {
1653 	int i,j,k,baseframe;
1654 	float starttime, lasttime;
1655 	int startframe, lastframe, nextonset;
1656 	//just testing at beat frame positions
1657 
1658 	baseframe=unit->m_storeloudnesscounter+LOUDNESSFRAMESSTORED;
1659 	int * onsets= unit->m_onsets;
1660 
1661 	//don't know periods, just going to find from search
1662 	starttime= 0.0-(5*MAXPERIOD); //0.0-(5*0.667); //one more eighth note than usual to calc pre beat
1663 
1664 	startframe=((int)(starttime*FRAMESR+ .5f) + baseframe)%LOUDNESSFRAMESSTORED;
1665 
1666 	//must have at least room for a fast 0.333*4 bar else no point checking
1667 	lasttime= -4*MINPERIOD; //-4*0.33;
1668 
1669 	//this is last start frame, last end frame is baseframe
1670 	lastframe= ((int)(lasttime*FRAMESR+ .5f) + baseframe)%LOUDNESSFRAMESSTORED;
1671 
1672 	nextonset=(startframe+LOUDNESSFRAMESSTORED-1)%LOUDNESSFRAMESSTORED;
1673 
1674 	//already made a list of onsets?
1675 	int numtolast=0;
1676 
1677 	if (lastframe<startframe)
1678 		numtolast= lastframe+LOUDNESSFRAMESSTORED-startframe;
1679 	else
1680 		numtolast= lastframe-startframe;
1681 
1682 	int numtonow=0;
1683 
1684 	if (baseframe<startframe)
1685 		numtonow= baseframe+LOUDNESSFRAMESSTORED-startframe;
1686 	else
1687 		numtonow= baseframe-startframe;
1688 
1689 	int pos;
1690 
1691 	int numonsets=0;
1692 	int numstarts=0;
1693 
1694 
1695 	//store them in an array (preallocate 50, maximum size)
1696 	//permanent array for this
1697 	//int onsetposition[50];
1698 	int * onsetposition= unit->m_onsetposition;
1699 
1700 	for (i=0;i<numtonow;++i) {
1701 
1702 		pos= (startframe+i+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
1703 
1704 		if(onsets[pos]!=0) {
1705 			if(i<numtolast) ++numstarts;
1706 
1707 			onsetposition[numonsets]=pos;
1708 
1709 			  ++numonsets;
1710 
1711 			if (numonsets==MAXONSETS) {printf("disaster? %d \n",numonsets); break;}
1712 		}
1713 	}
1714 
1715 	//if (numstarts>MAXONSETS) numstarts= MAXONSETS;
1716 	//printf("numonsets %d numstarts %d \n", numonsets,numstarts);
1717 
1718 
1719 	int bestindex=-1;
1720 	float bestscore=0.0;
1721 	int besttempo=0;
1722 
1723 	//float score;
1724 	//int tempo;
1725 
1726 
1727 
1728 	for (i=0; i<numstarts; ++i) {
1729 
1730 		int first=onsetposition[i];
1731 		int firstval= onsets[first];
1732 
1733 		for (j=i+1;j<numonsets; ++j) {
1734 			int second=onsetposition[j];
1735 
1736 			int diff, realdiff;
1737 
1738 			diff= (second+LOUDNESSFRAMESSTORED- first)%LOUDNESSFRAMESSTORED; //works for both cases second<first and first<=second
1739 			int test= (baseframe+LOUDNESSFRAMESSTORED- first)%LOUDNESSFRAMESSTORED;
1740 
1741 			//second IS second beat
1742 			if(test>(3*diff)) {
1743 
1744 			testpattern(unit,bestindex,bestscore,besttempo,first,diff,firstval);
1745 
1746 			}
1747 
1748 			////second is actually third beat
1749 
1750 			if(test>((3/2)*diff)) {
1751 
1752 			realdiff= (diff/2);
1753 
1754 			testpattern(unit,bestindex,bestscore,besttempo,first,realdiff,firstval);
1755 
1756 			}
1757 
1758 			//second is fourth, already all beats will fit within
1759 			realdiff= (diff/3);
1760 
1761 			testpattern(unit,bestindex,bestscore,besttempo,first,realdiff,firstval);
1762 
1763 		}
1764 
1765 	}
1766 
1767 	//tempo= FRAMESR/(float)tempo;
1768 
1769 	float actualtempo;
1770 
1771 	if (besttempo>0) {
1772 		actualtempo = FRAMESR/(float)besttempo;
1773 
1774 		int dist= (baseframe-bestindex+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
1775 
1776 		float phase= (dist%besttempo)/(float)besttempo;
1777 
1778 		unit->m_patternphase= 1.0-phase;
1779 		unit->m_patternscore=bestscore;
1780 		unit->m_patterntempo=actualtempo;
1781 
1782 		if(unit->m_debugmode==1)
1783 		printf("best match phase %f score %f tempo %f \n", unit->m_patternphase, unit->m_patternscore, unit->m_patterntempo);
1784 
1785 		return 1;
1786 	}
1787 
1788 	return 0; //no matches found
1789 }
1790 
1791 
testpattern(DrumTrack * unit,int & bestindex,float & bestscore,int & besttempo,int first,int diff,int firstval)1792 void testpattern(DrumTrack * unit, int &bestindex, float &bestscore, int &besttempo, int first, int diff, int firstval) {
1793 
1794 	int k;
1795 	float score;
1796 
1797 	//int * onsetposition= unit->m_onsetposition;
1798 	int * onsets= unit->m_onsets;
1799 
1800 	int second= (first+diff)%LOUDNESSFRAMESSTORED;
1801 
1802 	//first case- second is the second beat of the pattern
1803 	//min one beat 0.33*FRAMESR max three beats 0.66*FRAMESR  86.1328
1804 	int mindiff= MINDIFF; //28; //allowing for some error could be 25, usually 28
1805 	int maxdiff= MAXDIFF; //58;
1806 
1807 	//int test= (baseframe+LOUDNESSFRAMESSTORED- first)%LOUDNESSFRAMESSTORED;
1808 
1809 	//can exclude more cases knowing diff- 3*diff can't be greater than LOUDNESSFRAMESSTORED
1810 	//if(3*diff<LOUDNESSFRAMESSTORED) {
1811 
1812 	//spacing must be plausible
1813 	if(diff>=mindiff && diff<=maxdiff) {
1814 
1815 		int tempo= diff; //will convert later FRAMESR/(float)diff;
1816 		int secondval= onsets[second];
1817 
1818 		//spacing is diff for testing
1819 
1820 		int third=(second+diff)%LOUDNESSFRAMESSTORED;
1821 		int fourth=(third+diff)%LOUDNESSFRAMESSTORED;
1822 
1823 		//two tests for each case, each case determines a unique position of bestindex
1824 
1825 		int thirdval=0;
1826 		int fourthval=0;
1827 
1828 		int posindex,negindex;
1829 
1830 		//allowing for an error of up to 5 either side, successively overwrites with best option if non zero
1831 		for (k=4;k>=0;--k) {
1832 
1833 			negindex=(third-k+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
1834 
1835 			if(onsets[negindex])
1836 				thirdval=onsets[negindex];
1837 
1838 			posindex=(third+k)%LOUDNESSFRAMESSTORED;
1839 
1840 			if(onsets[posindex])
1841 				thirdval=onsets[posindex];
1842 
1843 		}
1844 
1845 		for (k=4;k>=0;--k) {
1846 
1847 			negindex=(fourth-k+LOUDNESSFRAMESSTORED)%LOUDNESSFRAMESSTORED;
1848 
1849 			if(onsets[negindex])
1850 				fourthval=onsets[negindex];
1851 
1852 			posindex=(fourth+k)%LOUDNESSFRAMESSTORED;
1853 
1854 			if(onsets[posindex])
1855 				fourthval=onsets[posindex];
1856 
1857 		}
1858 
1859 
1860 		if (firstval==2) //snare
1861 		{
1862 
1863 			//two possibilities
1864 
1865 			score = 1.0;
1866 
1867 			if(secondval==1) score+=0.5;
1868 			if(thirdval==2) score+=1.0;
1869 			if(fourthval==1) score+=1.0;
1870 
1871 			if(score>bestscore) {
1872 
1873 				bestindex=fourth; //first beat of bar!
1874 				bestscore=score;
1875 				besttempo=tempo;
1876 			}
1877 
1878 			score = 1.0;
1879 
1880 			if(secondval==1) score+=1.0;
1881 			if(thirdval==2) score+=1.0;
1882 			if(fourthval==1) score+=0.5;
1883 
1884 			if(score>bestscore) {
1885 
1886 				bestindex=second; //first beat of bar!
1887 				bestscore=score;
1888 				besttempo=tempo;
1889 			}
1890 
1891 
1892 		} else { //kick
1893 
1894 			score = 1.0;
1895 
1896 			if(secondval==2) score+=1.0;
1897 			if(thirdval==1) score+=0.5;
1898 			if(fourthval==2) score+=1.0;
1899 
1900 			if(score>bestscore) {
1901 
1902 				bestindex=first; //first beat of bar!
1903 				bestscore=score;
1904 				besttempo=tempo;
1905 			}
1906 
1907 
1908 			score = 0.5;
1909 
1910 			if(secondval==2) score+=1.0;
1911 			if(thirdval==1) score+=1.0;
1912 			if(fourthval==2) score+=1.0;
1913 
1914 			if(score>bestscore) {
1915 
1916 				bestindex=third; //first beat of bar!
1917 				bestscore=score;
1918 				besttempo=tempo;
1919 			}
1920 
1921 
1922 		}
1923 
1924 
1925 
1926 
1927 
1928 	}
1929 
1930 
1931 
1932 }
1933 
1934 
1935 
1936 
1937 
1938 
1939 
1940 
1941 
1942 
1943 
prepareHanningWindow()1944 void prepareHanningWindow(){
1945 	float ang;
1946 
1947 	ang=(1.0/N)*TWOPI;
1948 
1949 	for(int i=0;i<N;++i)
1950 		hanning[i]=0.5 - 0.5*cos(ang*i);
1951 
1952 }
1953 
1954 
PluginLoad(DrumTrack)1955 PluginLoad(DrumTrack) {
1956 
1957 	ft= inTable;
1958 
1959 	prepareHanningWindow();
1960 
1961 	DefineDtorCantAliasUnit(DrumTrack);
1962 }
1963 
1964 
1965 
1966 /*
1967 
1968 
1969 //used twice, once for phase, once for antiphase?
1970 float comparechordetect(DrumTrack *unit, float phase, float bps) {
1971 	int i,j,k,baseframe, rounded, testframe;
1972 	float Ti, starttime, beatpos, beat;
1973 	//just testing at beat frame positions
1974 
1975 	baseframe=unit->m_fftstoreposhold+FFTSTOREMEM;
1976 
1977 	Ti= 1/bps;   //could have precalculated these- OPTIMISE
1978 
1979 	int framesize= (int)floor(0.5*Ti/FRAMEPERIOD); //eighth note area
1980 
1981 	//%as goto ignore outer 1/5s, only take middle 3/5
1982 	int keep= (int)floor((0.6*framesize)+ .5f);
1983 	int onefifth= (int)floor((0.2*framesize)+ .5f);
1984 
1985 	starttime= 0.0-(5.5*Ti); //one more eighth note than usual to calc pre beat
1986 
1987 	beatpos=starttime+(Ti*phase);
1988 
1989 	float * fftstore= unit->m_fftstore;
1990 
1991 	//should allocate for each
1992 	float *chordhistogram= unit->m_chordhistogram;
1993 	float *chordhistogramprev= unit->m_chordhistogramprev;
1994 	float onsum=0.0;
1995 	float offsum=0.0;
1996 
1997 	//8 beats
1998 	for (i=0;i<9;++i) {
1999 
2000 		beat=(i*(Ti*0.5))+beatpos;
2001 
2002 
2003 		//ERROR if beat negative? Should be -.5f in rounding! No, floor goes moe negative
2004 		rounded= (int)floor(beat*FRAMESR+ .5f);
2005 
2006 		//printf("error in rounding? beat %f rounded %d correction %d \n",beat, rounded,  (int)(beat*FRAMESR -.5f));
2007 
2008 		testframe=baseframe+rounded+onefifth;
2009 
2010 		//calc new histogram
2011 		for (j=0;j<24;++j) {
2012 
2013 			float sum=0.0;
2014 
2015 			for(k=0;k<keep;++k) {
2016 
2017 				sum+= fftstore[((testframe+k)%FFTSTOREMEM)*24+j];
2018 			}
2019 
2020 
2021 			chordhistogram[j]=sum;
2022 		}
2023 
2024 		//peak pick
2025 		//for (j=1;j<23;++j) {
2026 		//
2027 		//if((chordhistogram[j-1]>chordhistogram[j]) || (chordhistogram[j]<chordhistogram[j+1]))
2028 		//chordhistogram[j]=0;
2029 		//
2030 		//}
2031 
2032 		//zero 0 and 23
2033 		chordhistogram[0]=0;
2034 		chordhistogram[23]=0;
2035 
2036 		//do difference to prev, sum of positives only
2037 		if(i>0) {
2038 
2039 			for (j=0;j<24;++j) {
2040 
2041 				float diff;
2042 
2043 				diff=chordhistogram[j]-chordhistogramprev[j];
2044 
2045 				//printf("%f \n",diff);
2046 
2047 				if(diff<0) diff=0;
2048 
2049 				if(i%2==1)
2050 					onsum+=diff; //bassonsets[testframe];
2051 				else
2052 					offsum+=diff;
2053 			}
2054 
2055 		}
2056 
2057 		//copy new into previous
2058 		for (j=1;j<23;++j)
2059 			chordhistogramprev[j]=chordhistogram[j];
2060 
2061 
2062 	}
2063 
2064 
2065 if (offsum<1) offsum=1;
2066 
2067 //printf("onsum %f offsum %f ratio %f\n",onsum, offsum, onsum/offsum);
2068 //
2069 
2070 return onsum/offsum;
2071 }
2072 
2073 
2074 */
2075 
2076