Commit f3512603 authored by ale's avatar ale

add a stream-based analyzer interface

parent c8c182e3
......@@ -35,7 +35,96 @@ using std::cout;
using std::cerr;
using std::endl;
typedef uint16_t sample_t;
#define STATE_PREFILL 0
#define STATE_RUN 1
StreamAnalyzer::StreamAnalyzer()
: hanwin(WINDOWSIZE),
state(STATE_PREFILL),
frames(0),
buf_pos(0),
outdata(NUMFREQS)
{}
void StreamAnalyzer::process(char *data, int n) {
char *buf_head = (char *)(indata + OVERLAP);
while (n > 0) {
int sz = sizeof(sample_t) * READSIZE - buf_pos;
if (n < sz)
sz = n;
memcpy(buf_head + buf_pos, data, sz);
n -= sz;
data += sz;
buf_pos += sz;
if (buf_pos == sizeof(sample_t) * READSIZE) {
buf_pos = 0;
process_buffer();
}
}
}
void StreamAnalyzer::process_buffer() {
switch(state) {
case STATE_PREFILL:
state = STATE_RUN;
break;
case STATE_RUN:
process_buffer_internal();
}
// shift the read data
memmove(indata, indata + READSIZE, OVERLAP * sizeof(sample_t));
}
void StreamAnalyzer::process_buffer_internal() {
if (++frames > MAXFRAMES)
return;
// calculate MFCCs:
for (int i = 0; i < WINDOWSIZE; ++i)
pcmfft.input()[i] = (double)indata[i];
// window the data
hanwin.apply(pcmfft.input(), WINDOWSIZE);
// fft to get the spectrum
pcmfft.execute();
// calculate the power spectrum
for (int i = 0; i < NUMFREQS; ++i)
outdata[i] = pow(pcmfft.output()[i][0], 2) +
pow(pcmfft.output()[i][1], 2);
// apply mel filter bank
vector<double> melfreqs;
mfbank.apply(outdata, melfreqs);
beatkeeper.process(melfreqs);
// compute log energy
for (int i = 0; i < NUMMEL; ++i)
melfreqs[i] = log(melfreqs[i]);
// another fft to get the MFCCs
specfft.apply(melfreqs);
// discard the first mfcc
float cepstrum[NUMCEPSTR];
for (int i = 1; i <= NUMCEPSTR; ++i)
cepstrum[i - 1] = specfft.output()[i][0];
mfcckeeper.process(cepstrum);
}
Features *StreamAnalyzer::get_result() {
if (frames < 100)
return NULL;
mfcckeeper.finalize();
beatkeeper.finalize();
return new Features(mfcckeeper.get_result(), beatkeeper.get_result());
}
// Calculate acoustic stats for a song and write them to the database.
Features *Analyzer::analyze(int infd)
......
......@@ -57,4 +57,31 @@ protected:
HanningWindow hanwin;
};
typedef uint16_t sample_t;
class StreamAnalyzer
{
public:
StreamAnalyzer();
void process(char *data, int n);
Features *get_result();
protected:
void process_buffer();
void process_buffer_internal();
FFTWisdom wisdom;
FFTProvider<WINDOWSIZE> pcmfft;
FFTProvider<NUMMEL> specfft;
MelFilterBank mfbank;
HanningWindow hanwin;
int state;
size_t frames;
int buf_pos;
sample_t indata[WINDOWSIZE];
vector<double> outdata;
MFCCKeeper mfcckeeper;
BeatManager beatkeeper;
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment