comment tweaks from a second reading
[ardour.git] / libs / rubberband / src / PercussiveAudioCurve.cpp
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     Rubber Band
5     An audio time-stretching and pitch-shifting library.
6     Copyright 2007-2008 Chris Cannam.
7     
8     This program is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License as
10     published by the Free Software Foundation; either version 2 of the
11     License, or (at your option) any later version.  See the file
12     COPYING included with this distribution for more information.
13 */
14
15 #include "PercussiveAudioCurve.h"
16
17 #include "Profiler.h"
18
19 #include <cmath>
20
21
22 namespace RubberBand
23 {
24
25 PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) :
26     AudioCurve(sampleRate, windowSize)
27 {
28     m_prevMag = new float[m_windowSize/2 + 1];
29
30     for (size_t i = 0; i <= m_windowSize/2; ++i) {
31         m_prevMag[i] = 0.f;
32     }
33 }
34
35 PercussiveAudioCurve::~PercussiveAudioCurve()
36 {
37     delete[] m_prevMag;
38 }
39
40 void
41 PercussiveAudioCurve::reset()
42 {
43     for (size_t i = 0; i <= m_windowSize/2; ++i) {
44         m_prevMag[i] = 0;
45     }
46 }
47
48 void
49 PercussiveAudioCurve::setWindowSize(size_t newSize)
50 {
51     m_windowSize = newSize;
52
53     delete[] m_prevMag;
54     m_prevMag = new float[m_windowSize/2 + 1];
55
56     reset();
57 }
58
59 float
60 PercussiveAudioCurve::process(const float *R__ mag, size_t /*increment*/)
61 {
62     static float threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude
63     static float zeroThresh = powf(10.f, -8);
64
65     size_t count = 0;
66     size_t nonZeroCount = 0;
67
68     const int sz = m_windowSize / 2;
69
70     for (int n = 1; n <= sz; ++n) {
71         bool above = ((mag[n] / m_prevMag[n]) >= threshold);
72         if (above) ++count;
73         if (mag[n] > zeroThresh) ++nonZeroCount;
74     }
75
76     for (int n = 1; n <= sz; ++n) {
77         m_prevMag[n] = mag[n];
78     }
79
80     if (nonZeroCount == 0) return 0;
81     else return float(count) / float(nonZeroCount);
82 }
83
84 float
85 PercussiveAudioCurve::processDouble(const double *R__ mag, size_t /*increment*/)
86 {
87     Profiler profiler("PercussiveAudioCurve::process");
88
89     static double threshold = pow(10.0, 0.15); // 3dB rise in square of magnitude
90     static double zeroThresh = pow(10.0, -8);
91
92     size_t count = 0;
93     size_t nonZeroCount = 0;
94
95     const int sz = m_windowSize / 2;
96
97     for (int n = 1; n <= sz; ++n) {
98         bool above = ((mag[n] / m_prevMag[n]) >= threshold);
99         if (above) ++count;
100         if (mag[n] > zeroThresh) ++nonZeroCount;
101     }
102
103     for (int n = 1; n <= sz; ++n) {
104         m_prevMag[n] = mag[n];
105     }
106
107     if (nonZeroCount == 0) return 0;
108     else return float(count) / float(nonZeroCount);
109 }
110
111 }
112