00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __JackFilters__
00021 #define __JackFilters__
00022
00023 #include "jack.h"
00024 #include "JackAtomicState.h"
00025 #include <math.h>
00026 #include <stdlib.h>
00027
00028 namespace Jack
00029 {
00030
00031 #define MAX_SIZE 64
00032
00033 struct JackFilter
00034 {
00035
00036 jack_time_t fTable[MAX_SIZE];
00037
00038 JackFilter()
00039 {
00040 for (int i = 0; i < MAX_SIZE; i++)
00041 fTable[i] = 0;
00042 }
00043
00044 void AddValue(jack_time_t val)
00045 {
00046 memcpy(&fTable[1], &fTable[0], sizeof(jack_time_t) * (MAX_SIZE - 1));
00047 fTable[0] = val;
00048 }
00049
00050 jack_time_t GetVal()
00051 {
00052 jack_time_t mean = 0;
00053 for (int i = 0; i < MAX_SIZE; i++)
00054 mean += fTable[i];
00055 return mean / MAX_SIZE;
00056 }
00057 };
00058
00059 class JackDelayLockedLoop
00060 {
00061
00062 private:
00063
00064 jack_nframes_t fFrames;
00065 jack_time_t fCurrentWakeup;
00066 jack_time_t fCurrentCallback;
00067 jack_time_t fNextWakeUp;
00068 float fSecondOrderIntegrator;
00069 jack_nframes_t fBufferSize;
00070 jack_nframes_t fSampleRate;
00071 jack_time_t fPeriodUsecs;
00072 float fFilterCoefficient;
00073 bool fUpdating;
00074
00075 public:
00076
00077 JackDelayLockedLoop()
00078 {}
00079
00080 JackDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00081 {
00082 Init(buffer_size, sample_rate);
00083 }
00084
00085 void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00086 {
00087 fFrames = 0;
00088 fCurrentWakeup = 0;
00089 fCurrentCallback = 0;
00090 fNextWakeUp = 0;
00091 fFilterCoefficient = 0.01f;
00092 fSecondOrderIntegrator = 0.0f;
00093 fBufferSize = buffer_size;
00094 fSampleRate = sample_rate;
00095 fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize);
00096 }
00097
00098 void Init(jack_time_t callback_usecs)
00099 {
00100 fFrames = 0;
00101 fCurrentWakeup = 0;
00102 fSecondOrderIntegrator = 0.0f;
00103 fCurrentCallback = callback_usecs;
00104 fNextWakeUp = callback_usecs + fPeriodUsecs;
00105 }
00106
00107 void IncFrame(jack_time_t callback_usecs)
00108 {
00109 float delta = (int64_t)callback_usecs - (int64_t)fNextWakeUp;
00110 fCurrentWakeup = fNextWakeUp;
00111 fCurrentCallback = callback_usecs;
00112 fFrames += fBufferSize;
00113 fSecondOrderIntegrator += 0.5f * fFilterCoefficient * delta;
00114 fNextWakeUp = fCurrentWakeup + fPeriodUsecs + (int64_t) floorf((fFilterCoefficient * (delta + fSecondOrderIntegrator)));
00115 }
00116
00117 jack_nframes_t Time2Frames(jack_time_t time)
00118 {
00119 long delta = (long) rint(((double) ((long long)(time - fCurrentWakeup)) / ((long long)(fNextWakeUp - fCurrentWakeup))) * fBufferSize);
00120 return (delta < 0) ? ((fFrames > 0) ? fFrames : 1) : (fFrames + delta);
00121 }
00122
00123 jack_time_t Frames2Time(jack_nframes_t frames)
00124 {
00125 long delta = (long) rint(((double) ((long long)(frames - fFrames)) * ((long long)(fNextWakeUp - fCurrentWakeup))) / fBufferSize);
00126 return (delta < 0) ? ((fCurrentWakeup > 0) ? fCurrentWakeup : 1) : (fCurrentWakeup + delta);
00127 }
00128
00129 jack_nframes_t CurFrame()
00130 {
00131 return fFrames;
00132 }
00133
00134 jack_time_t CurTime()
00135 {
00136 return fCurrentWakeup;
00137 }
00138
00139 };
00140
00141 class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop>
00142 {
00143 public:
00144
00145 JackAtomicDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00146 {
00147 fState[0].Init(buffer_size, sample_rate);
00148 fState[1].Init(buffer_size, sample_rate);
00149 }
00150
00151 void Init(jack_time_t callback_usecs)
00152 {
00153 JackDelayLockedLoop* dll = WriteNextStateStart();
00154 dll->Init(callback_usecs);
00155 WriteNextStateStop();
00156 TrySwitchState();
00157 }
00158
00159 void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00160 {
00161 JackDelayLockedLoop* dll = WriteNextStateStart();
00162 dll->Init(buffer_size, sample_rate);
00163 WriteNextStateStop();
00164 TrySwitchState();
00165 }
00166
00167 void IncFrame(jack_time_t callback_usecs)
00168 {
00169 JackDelayLockedLoop* dll = WriteNextStateStart();
00170 dll->IncFrame(callback_usecs);
00171 WriteNextStateStop();
00172 TrySwitchState();
00173 }
00174
00175 jack_nframes_t Time2Frames(jack_time_t time)
00176 {
00177 UInt16 next_index = GetCurrentIndex();
00178 UInt16 cur_index;
00179 jack_nframes_t res;
00180
00181 do {
00182 cur_index = next_index;
00183 res = ReadCurrentState()->Time2Frames(time);
00184 next_index = GetCurrentIndex();
00185 } while (cur_index != next_index);
00186
00187 return res;
00188 }
00189
00190 jack_time_t Frames2Time(jack_nframes_t frames)
00191 {
00192 UInt16 next_index = GetCurrentIndex();
00193 UInt16 cur_index;
00194 jack_time_t res;
00195
00196 do {
00197 cur_index = next_index;
00198 res = ReadCurrentState()->Frames2Time(frames);
00199 next_index = GetCurrentIndex();
00200 } while (cur_index != next_index);
00201
00202 return res;
00203 }
00204 };
00205
00206
00207
00208
00209
00210 struct JackPIControler {
00211
00212 double resample_mean;
00213 double static_resample_factor;
00214
00215 double* offset_array;
00216 double* window_array;
00217 int offset_differential_index;
00218
00219 double offset_integral;
00220
00221 double catch_factor;
00222 double catch_factor2;
00223 double pclamp;
00224 double controlquant;
00225 int smooth_size;
00226
00227 double hann(double x)
00228 {
00229 return 0.5 * (1.0 - cos(2 * M_PI * x));
00230 }
00231
00232 JackPIControler(double resample_factor, int fir_size)
00233 {
00234 resample_mean = resample_factor;
00235 static_resample_factor = resample_factor;
00236 offset_array = new double[fir_size];
00237 window_array = new double[fir_size];
00238 offset_differential_index = 0;
00239 offset_integral = 0.0;
00240 smooth_size = fir_size;
00241
00242 for (int i = 0; i < fir_size; i++) {
00243 offset_array[i] = 0.0;
00244 window_array[i] = hann(double(i) / (double(fir_size) - 1.0));
00245 }
00246
00247
00248 catch_factor = 100000;
00249 catch_factor2 = 10000;
00250 pclamp = 15.0;
00251 controlquant = 10000.0;
00252 }
00253
00254 ~JackPIControler()
00255 {
00256 delete[] offset_array;
00257 delete[] window_array;
00258 }
00259
00260 void Init(double resample_factor)
00261 {
00262 resample_mean = resample_factor;
00263 static_resample_factor = resample_factor;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 double GetRatio(int error)
00306 {
00307 double smooth_offset = error;
00308
00309
00310 offset_integral += smooth_offset;
00311
00312
00313
00314
00315 return static_resample_factor - smooth_offset/catch_factor - offset_integral/catch_factor/catch_factor2;
00316 }
00317
00318 void OurOfBounds()
00319 {
00320 int i;
00321
00322
00323
00324 offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
00325
00326 for (i = 0; i < smooth_size; i++) {
00327 offset_array[i] = 0.0;
00328 }
00329 }
00330
00331 };
00332
00333 }
00334
00335 #endif