Skip to content

Commit 9ba6dce

Browse files
author
Mischa Spiegelmock
authored
Merge pull request #312 from projectM-visualizer/beatdetect_309
new BeatDetect implementation
2 parents 7ac5c7f + 5fd9bc1 commit 9ba6dce

File tree

4 files changed

+217
-180
lines changed

4 files changed

+217
-180
lines changed

src/libprojectM/PCM.cpp

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,15 @@ void PCM::_initPCM(int samples) {
7474
start=0;
7575

7676
//Allocate FFT workspace
77-
w= (double *)wipemalloc(maxsamples*sizeof(double));
78-
ip= (int *)wipemalloc(maxsamples*sizeof(int));
77+
// per rdft() documentation
78+
// length of ip >= 2+sqrt(n) and length of w == n/2
79+
#if FFT_LENGTH > 1024
80+
#error update this code
81+
#endif
82+
w = (double *)wipemalloc(FFT_LENGTH/2*sizeof(double));
83+
ip = (int *)wipemalloc(34 * sizeof(int));
7984
ip[0]=0;
8085

81-
8286
/** PCM data */
8387
// this->maxsamples = 2048;
8488
// this->numsamples = 0;
@@ -134,8 +138,8 @@ void PCM::addPCMfloat(const float *PCMdata, int samples)
134138
if (newsamples>maxsamples) newsamples=maxsamples;
135139
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
136140
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
137-
getPCM(vdataL,512,0,1,0,0);
138-
getPCM(vdataR,512,1,1,0,0);
141+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
142+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
139143
}
140144

141145

@@ -158,8 +162,8 @@ void PCM::addPCMfloat_2ch(const float *PCMdata, int samples)
158162
newsamples=maxsamples;
159163
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
160164
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
161-
getPCM(vdataL,512,0,1,0,0);
162-
getPCM(vdataR,512,1,1,0,0);
165+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
166+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
163167
}
164168

165169

@@ -178,8 +182,8 @@ void PCM::addPCM16Data(const short* pcm_data, short samples) {
178182
if (newsamples>maxsamples) newsamples=maxsamples;
179183
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
180184
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
181-
getPCM(vdataL,512,0,1,0,0);
182-
getPCM(vdataR,512,1,1,0,0);
185+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
186+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
183187
}
184188

185189

@@ -210,8 +214,8 @@ void PCM::addPCM16(short PCMdata[2][512])
210214

211215
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
212216
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
213-
getPCM(vdataL,512,0,1,0,0);
214-
getPCM(vdataR,512,1,1,0,0);
217+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
218+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
215219
}
216220

217221

@@ -243,8 +247,8 @@ void PCM::addPCM8( unsigned char PCMdata[2][1024])
243247
if (newsamples>maxsamples) newsamples=maxsamples;
244248
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
245249
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
246-
getPCM(vdataL,512,0,1,0,0);
247-
getPCM(vdataR,512,1,1,0,0);
250+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
251+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
248252
}
249253

250254
void PCM::addPCM8_512( const unsigned char PCMdata[2][512])
@@ -275,8 +279,8 @@ void PCM::addPCM8_512( const unsigned char PCMdata[2][512])
275279
if (newsamples>maxsamples) newsamples=maxsamples;
276280
numsamples = getPCMnew(pcmdataR,1,0,waveSmoothing,0,0);
277281
getPCMnew(pcmdataL,0,0,waveSmoothing,0,1);
278-
getPCM(vdataL,512,0,1,0,0);
279-
getPCM(vdataR,512,1,1,0,0);
282+
getPCM(vdataL,FFT_LENGTH,0,1,0,0);
283+
getPCM(vdataR,FFT_LENGTH,1,1,0,0);
280284
}
281285

282286

@@ -291,43 +295,57 @@ void PCM::addPCM8_512( const unsigned char PCMdata[2][512])
291295

292296
void PCM::getPCM(float *PCMdata, int samples, int channel, int freq, float smoothing, int derive)
293297
{
294-
int index;
295-
296-
index=start-1;
297-
298-
if (index<0) index=maxsamples+index;
298+
if (smoothing == 0)
299+
{
300+
for (int i = 0; i < samples; i++)
301+
{
302+
int index = start - 1 - i;
303+
if (index < 0)
304+
index = maxsamples + index;
305+
PCMdata[i] = PCMd[channel][index];
306+
}
307+
}
308+
else
309+
{
310+
int index=start-1;
299311

300-
PCMdata[0]=PCMd[channel][index];
312+
if (index<0)
313+
index=maxsamples+index;
301314

302-
for(int i=1;i<samples;i++)
303-
{
304-
index=start-1-i;
305-
if (index<0) index=maxsamples+index;
315+
PCMdata[0] = PCMd[channel][index];
306316

307-
PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
317+
for (int i = 1; i < samples; i++)
318+
{
319+
index = start - 1 - i;
320+
if (index < 0)
321+
index = maxsamples + index;
322+
PCMdata[i] = (1 - smoothing) * PCMd[channel][index] + smoothing * PCMdata[i - 1];
323+
}
308324
}
309325

310326
//return derivative of PCM data
311-
if(derive)
327+
if (derive)
312328
{
313329
for(int i=0;i<samples-1;i++)
314-
{
315-
PCMdata[i]=PCMdata[i]-PCMdata[i+1];
316-
}
330+
{
331+
PCMdata[i]=PCMdata[i]-PCMdata[i+1];
332+
}
317333
PCMdata[samples-1]=0;
318334
}
319335

320336
//return frequency data instead of PCM (perform FFT)
321337

322338
if (freq)
323-
324339
{
340+
// NOTE some presets set bSpectrum=1 and samples!=2^n, not sure what rdft() does with that
341+
assert(samples <= 1024);
342+
samples = std::min(1024,samples);
325343
double temppcm[1024];
326344
for (int i=0;i<samples;i++)
327-
{temppcm[i]=(double)PCMdata[i];}
345+
{temppcm[i]=(double)PCMdata[i];}
328346
rdft(samples, 1, temppcm, ip, w);
329347
for (int j=0;j<samples;j++)
330-
{PCMdata[j]=(float)temppcm[j];}
348+
{PCMdata[j]=(float)temppcm[j];}
331349
}
332350
}
333351

src/libprojectM/PCM.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131

3232
#include "dlldefs.h"
3333

34+
35+
// 1024 is more computationally intensive, but maybe better at detecting lower bass
36+
#define FFT_LENGTH 1024
37+
38+
3439
class
3540
#ifdef WIN32
3641
DLLEXPORT
@@ -52,8 +57,8 @@ PCM {
5257
float *pcmdataR; //holder for most recent pcm data
5358

5459
/** PCM data */
55-
float vdataL[512]; //holders for FFT data (spectrum)
56-
float vdataR[512];
60+
float vdataL[FFT_LENGTH]; //holders for FFT data (spectrum)
61+
float vdataR[FFT_LENGTH];
5762

5863
static int maxsamples;
5964
PCM();

0 commit comments

Comments
 (0)