1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qsinewavevalidator_p.h"
5
6#include <QtCore/qmath.h>
7#include <QtCore/QDebug>
8
9QT_BEGIN_NAMESPACE
10
11QSineWaveValidator::QSineWaveValidator(float notchFrequency, float sampleRate)
12{
13 using namespace std;
14 float pi = static_cast<float>(M_PI);
15 float f0 = notchFrequency;
16 float Fs = sampleRate;
17 float Q = 1 / sqrt(x: 2.f); // higher Q gives narrow bandwidth, but requires a larger number of
18 // frames during the transient
19
20 // compare https://webaudio.github.io/Audio-EQ-Cookbook/Audio-EQ-Cookbook.txt
21 float w0 = 2 * pi * f0 / Fs;
22 float alpha = sin(x: w0) / (2 * Q);
23
24 b0 = 1;
25 b1 = -2 * cos(x: w0);
26 b2 = 1;
27 a0 = 1 + alpha;
28 a1 = -2 * cos(x: w0);
29 a2 = 1 - alpha;
30}
31
32void QSineWaveValidator::feedSample(float sample)
33{
34 if (pendingFramesBeforeAnalysis == framesBeforeAnalysis) {
35 x.fill(u: sample);
36 y.fill(u: b0 / a0 * sample);
37 }
38
39 x[2] = x[1];
40 x[1] = x[0];
41 x[0] = sample;
42
43 y[2] = y[1];
44 y[1] = y[0];
45 y[0] = (b0 / a0) * x[0] + (b1 / a0) * x[1] + (b2 / a0) * x[2] - (a1 / a0) * y[1]
46 - (a2 / a0) * y[2];
47
48 accumPeak = std::max(a: std::abs(x: sample), b: accumPeak);
49
50 if (pendingFramesBeforeAnalysis) {
51 pendingFramesBeforeAnalysis -= 1;
52 return;
53 }
54
55 accumNotchPeak = std::max(a: std::abs(x: y[0]), b: accumNotchPeak);
56}
57
58float QSineWaveValidator::notchPeak() const
59{
60 if (pendingFramesBeforeAnalysis)
61 qWarning() << "notchPeak during initial frames. Result will not be accurate";
62 return accumNotchPeak;
63}
64
65QT_END_NAMESPACE
66

source code of qtmultimedia/src/multimediatestlib/qsinewavevalidator.cpp