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 <stdio.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 #endif