1 /*
2     SuperCollider real time audio synthesis system
3     Copyright (c) 2002 James McCartney. All rights reserved.
4     http://www.audiosynth.com
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 */
20 /*
21 #include "SC_CoreAudio.h"
22 #include <stdarg.h>
23 #include "SC_Prototypes.h"
24 #include "SC_HiddenWorld.h"
25 #include "SC_WorldOptions.h"
26 #include <stdlib.h>
27 
28 #ifdef _WIN32
29 #include "SC_Win32Utils.h"
30 #else
31 #include <sys/time.h>
32 #endif
33 */
34 
35 // =====================================================================
36 // SC_TimeDLL
37 //
38 //   Delay-Locked-Loop after
39 //   Fons Adriaensen, "Using a DLL to filter time"
40 #ifndef M_PI
41 #    define M_PI 3.14159265358979323846
42 #endif
43 #define SC_TIME_DLL_BW 0.012
44 
45 class SC_TimeDLL {
46 public:
SC_TimeDLL()47     SC_TimeDLL(): m_b(0.), m_c(0.), m_t0(0.), m_t1(0.), m_e2(0.), m_np(0), m_ei(0.), m_ec(0) {}
48 
Reset(double sampleRate,uint32_t periodFrames,double bandWidth,double t)49     void Reset(double sampleRate, uint32_t periodFrames, double bandWidth, double t) {
50         // compute coefficients
51         m_np = periodFrames;
52         m_b = 2 * M_PI * bandWidth * m_np / sampleRate;
53         m_c = m_b * m_b / 2.;
54         // initialize filter
55         double tp = m_np / sampleRate;
56         m_e2 = tp;
57         m_t0 = t;
58         m_t1 = t + tp;
59         // initialize statistics
60         m_ei = 0.;
61         m_ec = 0;
62     }
63 
Update(double t)64     void Update(double t) {
65         // compute error
66         double e = m_e = t - m_t1;
67         // update filter
68         m_t0 = m_t1;
69         m_t1 += m_b * e + m_e2;
70         m_e2 += m_c * e;
71         // collect statistics
72         m_ei += e;
73         m_ec++;
74     }
75 
PeriodTime() const76     double PeriodTime() const { return m_t0; }
NextPeriodTime() const77     double NextPeriodTime() const { return m_t1; }
Period() const78     double Period() const { return m_t1 - m_t0; }
SampleRate() const79     double SampleRate() const { return m_np / Period(); }
Error() const80     double Error() const { return m_e; }
AvgError() const81     double AvgError() const { return m_ec > 0 ? m_ei / m_ec : 0; }
82 
83 private:
84     double m_b, m_c;
85     double m_t0, m_t1, m_e, m_e2;
86     int m_np;
87     double m_ei;
88     int m_ec;
89 };
90