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