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