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