comparison transform/BeatDetectionFunctionTransform.cpp @ 0:da6937383da8

initial import
author Chris Cannam
date Tue, 10 Jan 2006 16:33:16 +0000
parents
children d86891498eef
comparison
equal deleted inserted replaced
-1:000000000000 0:da6937383da8
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 A waveform viewer and audio annotation editor.
5 Chris Cannam, Queen Mary University of London, 2005
6
7 This is experimental software. Not for distribution.
8 */
9
10 #include "BeatDetectionFunctionTransform.h"
11
12 #include "model/DenseTimeValueModel.h"
13 #include "model/SparseTimeValueModel.h"
14
15 #include <iostream>
16 #include "dsp/onsets/DetectionFunction.h"
17 #include "dsp/tempotracking/TempoTrack.h"
18
19
20 BeatDetectionFunctionTransform::BeatDetectionFunctionTransform(Model *inputModel) :
21 Transform(inputModel)
22 {
23 m_output = new SparseTimeValueModel(inputModel->getSampleRate(), 1,
24 0.0, 0.0, false);
25 }
26
27 BeatDetectionFunctionTransform::~BeatDetectionFunctionTransform()
28 {
29 // parent does it all
30 }
31
32 TransformName
33 BeatDetectionFunctionTransform::getName()
34 {
35 return tr("Beat Detection Function");
36 }
37
38 void
39 BeatDetectionFunctionTransform::run()
40 {
41 SparseTimeValueModel *output = getOutput();
42 DenseTimeValueModel *input = getInput();
43 if (!input) {
44 std::cerr << "BeatDetectionFunctionTransform::run: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl;
45 return;
46 }
47
48 DFConfig config;
49
50 config.DFType = DF_COMPLEXSD;
51
52 // Step resolution for the detection function in seconds
53 config.stepSecs = 0.01161;
54
55 // Step resolution for the detection function in samples
56 config.stepSize = (unsigned int)floor((double)input->getSampleRate() *
57 config.stepSecs );
58
59 config.frameLength = 2 * config.stepSize;
60
61 unsigned int stepSize = config.stepSize;
62 unsigned int frameLength = config.frameLength;
63
64 output->setResolution(stepSize);
65
66 //Tempo Tracking Configuration Parameters
67 TTParams ttparams;
68
69 // Low Pass filter coefficients for detection function smoothing
70 double* aCoeffs = new double[3];
71 double* bCoeffs = new double[3];
72
73 aCoeffs[ 0 ] = 1;
74 aCoeffs[ 1 ] = -0.5949;
75 aCoeffs[ 2 ] = 0.2348;
76 bCoeffs[ 0 ] = 0.1600;
77 bCoeffs[ 1 ] = 0.3200;
78 bCoeffs[ 2 ] = 0.1600;
79
80 ttparams.winLength = 512;
81 ttparams.lagLength = 128;
82 ttparams.LPOrd = 2;
83 ttparams.LPACoeffs = aCoeffs;
84 ttparams.LPBCoeffs = bCoeffs;
85 ttparams.alpha = 9;
86 ttparams.WinT.post = 8;
87 ttparams.WinT.pre = 7;
88
89 ////////////////////////////////////////////////////////////
90 // DetectionFunction
91 ////////////////////////////////////////////////////////////
92 // Instantiate and configure detection function object
93
94 DetectionFunction df(config);
95
96 size_t origin = input->getStartFrame();
97 size_t frameCount = input->getEndFrame() - origin;
98 size_t blocks = (frameCount / stepSize);
99 if (blocks * stepSize < frameCount) ++blocks;
100
101 double *buffer = new double[frameLength];
102
103 // DF output with causal extension
104 unsigned int clen = blocks + ttparams.winLength;
105 double *dfOutput = new double[clen];
106
107 std::cerr << "Running beat detection function at step size " << stepSize << "..." << std::endl;
108
109 for (size_t i = 0; i < clen; ++i) {
110
111 // std::cerr << "block " << i << "/" << clen << std::endl;
112 // std::cerr << ".";
113
114 if (i < blocks) {
115 size_t got = input->getValues(-1, //!!! needs to come from parent layer -- which is not supposed to be in scope at this point
116 origin + i * stepSize,
117 origin + i * stepSize + frameLength,
118 buffer);
119 while (got < frameLength) buffer[got++] = 0.0;
120 dfOutput[i] = df.process(buffer);
121 } else {
122 dfOutput[i] = 0.0;
123 }
124
125 output->addPoint(SparseTimeValueModel::Point
126 (i * stepSize, dfOutput[i],
127 QString("%1").arg(dfOutput[i])));
128 // m_w->m_bdf->setCompletion(i * 99 / clen);
129 output->setCompletion(i * 99 / clen);
130
131 if (m_deleting) {
132 delete [] buffer;
133 delete [] dfOutput;
134 delete [] aCoeffs;
135 delete [] bCoeffs;
136 return;
137 }
138 }
139
140 output->setCompletion(100);
141 }
142
143 DenseTimeValueModel *
144 BeatDetectionFunctionTransform::getInput()
145 {
146 return dynamic_cast<DenseTimeValueModel *>(getInputModel());
147 }
148
149 SparseTimeValueModel *
150 BeatDetectionFunctionTransform::getOutput()
151 {
152 return static_cast<SparseTimeValueModel *>(getOutputModel());
153 }
154