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 } POST_PACKED_STRUCTURE;
00059
00060 class JackDelayLockedLoop
00061 {
00062
00063 private:
00064
00065 jack_nframes_t fFrames;
00066 jack_time_t fCurrentWakeup;
00067 jack_time_t fCurrentCallback;
00068 jack_time_t fNextWakeUp;
00069 float fSecondOrderIntegrator;
00070 jack_nframes_t fBufferSize;
00071 jack_nframes_t fSampleRate;
00072 jack_time_t fPeriodUsecs;
00073 float fFilterCoefficient;
00074 bool fUpdating;
00075
00076 public:
00077
00078 JackDelayLockedLoop()
00079 {}
00080
00081 JackDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00082 {
00083 Init(buffer_size, sample_rate);
00084 }
00085
00086 void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00087 {
00088 fFrames = 0;
00089 fCurrentWakeup = 0;
00090 fCurrentCallback = 0;
00091 fNextWakeUp = 0;
00092 fFilterCoefficient = 0.01f;
00093 fSecondOrderIntegrator = 0.0f;
00094 fBufferSize = buffer_size;
00095 fSampleRate = sample_rate;
00096 fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize);
00097 }
00098
00099 void Init(jack_time_t callback_usecs)
00100 {
00101 fFrames = 0;
00102 fCurrentWakeup = 0;
00103 fSecondOrderIntegrator = 0.0f;
00104 fCurrentCallback = callback_usecs;
00105 fNextWakeUp = callback_usecs + fPeriodUsecs;
00106 }
00107
00108 void IncFrame(jack_time_t callback_usecs)
00109 {
00110 float delta = (int64_t)callback_usecs - (int64_t)fNextWakeUp;
00111 fCurrentWakeup = fNextWakeUp;
00112 fCurrentCallback = callback_usecs;
00113 fFrames += fBufferSize;
00114 fSecondOrderIntegrator += 0.5f * fFilterCoefficient * delta;
00115 fNextWakeUp = fCurrentWakeup + fPeriodUsecs + (int64_t) floorf((fFilterCoefficient * (delta + fSecondOrderIntegrator)));
00116 }
00117
00118 jack_nframes_t Time2Frames(jack_time_t time)
00119 {
00120 long delta = (long) rint(((double) ((long long)(time - fCurrentWakeup)) / ((long long)(fNextWakeUp - fCurrentWakeup))) * fBufferSize);
00121 return (delta < 0) ? ((fFrames > 0) ? fFrames : 1) : (fFrames + delta);
00122 }
00123
00124 jack_time_t Frames2Time(jack_nframes_t frames)
00125 {
00126 long delta = (long) rint(((double) ((long long)(frames - fFrames)) * ((long long)(fNextWakeUp - fCurrentWakeup))) / fBufferSize);
00127 return (delta < 0) ? ((fCurrentWakeup > 0) ? fCurrentWakeup : 1) : (fCurrentWakeup + delta);
00128 }
00129
00130 jack_nframes_t CurFrame()
00131 {
00132 return fFrames;
00133 }
00134
00135 jack_time_t CurTime()
00136 {
00137 return fCurrentWakeup;
00138 }
00139
00140 } POST_PACKED_STRUCTURE;
00141
00142 class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop>
00143 {
00144 public:
00145
00146 JackAtomicDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00147 {
00148 fState[0].Init(buffer_size, sample_rate);
00149 fState[1].Init(buffer_size, sample_rate);
00150 }
00151
00152 void Init(jack_time_t callback_usecs)
00153 {
00154 JackDelayLockedLoop* dll = WriteNextStateStart();
00155 dll->Init(callback_usecs);
00156 WriteNextStateStop();
00157 TrySwitchState();
00158 }
00159
00160 void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate)
00161 {
00162 JackDelayLockedLoop* dll = WriteNextStateStart();
00163 dll->Init(buffer_size, sample_rate);
00164 WriteNextStateStop();
00165 TrySwitchState();
00166 }
00167
00168 void IncFrame(jack_time_t callback_usecs)
00169 {
00170 JackDelayLockedLoop* dll = WriteNextStateStart();
00171 dll->IncFrame(callback_usecs);
00172 WriteNextStateStop();
00173 TrySwitchState();
00174 }
00175
00176 jack_nframes_t Time2Frames(jack_time_t time)
00177 {
00178 UInt16 next_index = GetCurrentIndex();
00179 UInt16 cur_index;
00180 jack_nframes_t res;
00181
00182 do {
00183 cur_index = next_index;
00184 res = ReadCurrentState()->Time2Frames(time);
00185 next_index = GetCurrentIndex();
00186 } while (cur_index != next_index);
00187
00188 return res;
00189 }
00190
00191 jack_time_t Frames2Time(jack_nframes_t frames)
00192 {
00193 UInt16 next_index = GetCurrentIndex();
00194 UInt16 cur_index;
00195 jack_time_t res;
00196
00197 do {
00198 cur_index = next_index;
00199 res = ReadCurrentState()->Frames2Time(frames);
00200 next_index = GetCurrentIndex();
00201 } while (cur_index != next_index);
00202
00203 return res;
00204 }
00205 } POST_PACKED_STRUCTURE;
00206
00207
00208
00209
00210
00211 struct JackPIControler {
00212
00213 double resample_mean;
00214 double static_resample_factor;
00215
00216 double* offset_array;
00217 double* window_array;
00218 int offset_differential_index;
00219
00220 double offset_integral;
00221
00222 double catch_factor;
00223 double catch_factor2;
00224 double pclamp;
00225 double controlquant;
00226 int smooth_size;
00227
00228 double hann(double x)
00229 {
00230 return 0.5 * (1.0 - cos(2 * M_PI * x));
00231 }
00232
00233 JackPIControler(double resample_factor, int fir_size)
00234 {
00235 resample_mean = resample_factor;
00236 static_resample_factor = resample_factor;
00237 offset_array = new double[fir_size];
00238 window_array = new double[fir_size];
00239 offset_differential_index = 0;
00240 offset_integral = 0.0;
00241 smooth_size = fir_size;
00242
00243 for (int i = 0; i < fir_size; i++) {
00244 offset_array[i] = 0.0;
00245 window_array[i] = hann(double(i) / (double(fir_size) - 1.0));
00246 }
00247
00248
00249 catch_factor = 100000;
00250 catch_factor2 = 10000;
00251 pclamp = 15.0;
00252 controlquant = 10000.0;
00253 }
00254
00255 ~JackPIControler()
00256 {
00257 delete[] offset_array;
00258 delete[] window_array;
00259 }
00260
00261 void Init(double resample_factor)
00262 {
00263 resample_mean = resample_factor;
00264 static_resample_factor = resample_factor;
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