# root/trunk/libffado/src/libutil/DelayLockedLoop.cpp

Revision 864, 5.9 kB (checked in by ppalmers, 15 years ago) |
---|

Line | |
---|---|

1 | /* |

2 | * Copyright (C) 2005-2008 by Pieter Palmers |

3 | * |

4 | * This file is part of FFADO |

5 | * FFADO = Free Firewire (pro-)audio drivers for linux |

6 | * |

7 | * FFADO is based upon FreeBoB. |

8 | * |

9 | * This program is free software: you can redistribute it and/or modify |

10 | * it under the terms of the GNU General Public License as published by |

11 | * the Free Software Foundation, either version 2 of the License, or |

12 | * (at your option) version 3 of the License. |

13 | * |

14 | * This program is distributed in the hope that it will be useful, |

15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |

16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |

17 | * GNU General Public License for more details. |

18 | * |

19 | * You should have received a copy of the GNU General Public License |

20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |

21 | * |

22 | */ |

23 | |

24 | #include "DelayLockedLoop.h" |

25 | |

26 | namespace Util { |

27 | |

28 | /** |

29 | * Creates a new Delay Locked Loop with a predefined order and |

30 | * a predefined set of coefficients. |

31 | * |

32 | * Make sure coeffs is a float array containing order+1 coefficients. |

33 | * |

34 | * @pre order > 0 |

35 | * @param order order of the DLL |

36 | * @param coeffs coefficients to use |

37 | */ |

38 | DelayLockedLoop::DelayLockedLoop(unsigned int order, float *coeffs) |

39 | { |

40 | unsigned int i; |

41 | |

42 | m_order=order; |

43 | if (m_order==0) m_order=1; |

44 | |

45 | m_coeffs=new float[order]; |

46 | m_nodes=new float[order]; |

47 | |

48 | for (i=0;i<order;i++) { |

49 | m_coeffs[i]=coeffs[i]; |

50 | m_nodes[i]=0.0; |

51 | } |

52 | |

53 | } |

54 | |

55 | /** |

56 | * Creates a new Delay Locked Loop with a predefined order. |

57 | * All coefficients are set to 0. |

58 | * |

59 | * @pre order > 0 |

60 | * @param order order of the DLL |

61 | */ |

62 | DelayLockedLoop::DelayLockedLoop(unsigned int order) |

63 | { |

64 | unsigned int i; |

65 | |

66 | m_order=order; |

67 | if (m_order==0) m_order=1; |

68 | |

69 | m_coeffs=new float[order]; |

70 | m_nodes=new float[order]; |

71 | |

72 | for (i=0;i<order;i++) { |

73 | m_coeffs[i]=0.0; |

74 | m_nodes[i]=0.0; |

75 | } |

76 | } |

77 | |

78 | /** |

79 | * Creates a new first order Delay Locked Loop. |

80 | * The coefficient is set to 0. |

81 | * |

82 | */ |

83 | DelayLockedLoop::DelayLockedLoop() { |

84 | m_order=1; |

85 | |

86 | m_coeffs=new float[1]; |

87 | m_coeffs[0]=0.0; |

88 | |

89 | m_nodes=new float[1]; |

90 | m_nodes[0]=0.0; |

91 | } |

92 | |

93 | DelayLockedLoop::~DelayLockedLoop() { |

94 | if(m_coeffs) delete[] m_coeffs; |

95 | if(m_nodes) delete[] m_nodes; |

96 | |

97 | } |

98 | |

99 | /** |

100 | * Returns the coefficient with index i |

101 | * |

102 | * i should be smaller than the DLL order |

103 | * |

104 | * @param i index of the coefficient |

105 | * @return value of the coefficient |

106 | */ |

107 | float |

108 | DelayLockedLoop::getCoefficient(unsigned int i) { |

109 | |

110 | if (i<m_order) { |

111 | return m_coeffs[i]; |

112 | } else { |

113 | return 0.0; |

114 | } |

115 | } |

116 | /** |

117 | * Sets the value of the coefficient with index i |

118 | * |

119 | * i should be smaller than the DLL order |

120 | * |

121 | * @param i index of the coefficient |

122 | * @param c value of the coefficient |

123 | */ |

124 | void |

125 | DelayLockedLoop::setCoefficient(unsigned int i, float c) { |

126 | |

127 | if (i<m_order) { |

128 | m_coeffs[i]=c; |

129 | } |

130 | } |

131 | |

132 | /** |

133 | * Sets the value of the integrator output with index i. |

134 | * This allows to set the inital values |

135 | * |

136 | * i should be smaller than the DLL order |

137 | * |

138 | * |

139 | * @param i index of the integrator |

140 | * @param c value of the integrator output |

141 | */ |

142 | void |

143 | DelayLockedLoop::setIntegrator(unsigned int i, float c) { |

144 | |

145 | if (i<m_order) { |

146 | m_nodes[i]=c; |

147 | } |

148 | } |

149 | |

150 | /** |

151 | * Clears the internal state of the DLL, |

152 | * meaning that it will set all internal nodes to 0.0 |

153 | */ |

154 | void |

155 | DelayLockedLoop::reset() { |

156 | |

157 | unsigned int i; |

158 | for (i=0;i<m_order;i++) { |

159 | m_nodes[i]=0.0; |

160 | } |

161 | |

162 | } |

163 | |

164 | /** |

165 | * Returns the order of the DLL |

166 | * @return DLL order |

167 | */ |

168 | unsigned int |

169 | DelayLockedLoop::getOrder() { |

170 | return m_order; |

171 | } |

172 | |

173 | /** |

174 | * Set the order of the DLL |

175 | * with setting of new coefficients |

176 | * |

177 | * Make sure coeffs is a float array containing 'order' coefficients. |

178 | * |

179 | * resets the DLL before changing the order |

180 | * |

181 | * @pre order > 0 |

182 | * @param order new order for the DLL |

183 | * @param coeffs coefficients to use |

184 | */ |

185 | void |

186 | DelayLockedLoop::setOrder(unsigned int order, float* coeffs) { |

187 | unsigned int i; |

188 | |

189 | reset(); |

190 | |

191 | m_order=order; |

192 | if (m_order==0) m_order=1; |

193 | |

194 | if(m_coeffs) delete[] m_coeffs; |

195 | m_coeffs=new float[order]; |

196 | |

197 | if(m_nodes) delete[] m_nodes; |

198 | m_nodes=new float[order]; |

199 | |

200 | for (i=0;i<order;i++) { |

201 | m_coeffs[i]=coeffs[i]; |

202 | m_nodes[i]=0.0; |

203 | } |

204 | |

205 | } |

206 | |

207 | /** |

208 | * Set the order of the DLL, |

209 | * the coefficients are set to 0 |

210 | * |

211 | * resets the DLL before changing the order |

212 | * |

213 | * @pre order > 0 |

214 | * @param order new order for the DLL |

215 | */ |

216 | void |

217 | DelayLockedLoop::setOrder(unsigned int order) { |

218 | unsigned int i; |

219 | |

220 | reset(); |

221 | |

222 | m_order=order; |

223 | |

224 | if (m_order==0) m_order=1; |

225 | |

226 | if(m_coeffs) delete[] m_coeffs; |

227 | m_coeffs=new float[order]; |

228 | |

229 | if(m_nodes) delete[] m_nodes; |

230 | m_nodes=new float[order]; |

231 | |

232 | for (i=0;i<order;i++) { |

233 | m_coeffs[i]=0.0; |

234 | m_nodes[i]=0.0; |

235 | } |

236 | |

237 | } |

238 | |

239 | /** |

240 | * Put a new value in the loop, updating all internal nodes and |

241 | * the output value. |

242 | * |

243 | * @param v new value |

244 | */ |

245 | void |

246 | DelayLockedLoop::put(float v) { |

247 | |

248 | // we write the calculation out |

249 | // to make use of pipeline-ing and out of order execution |

250 | // except for very high order loops, then we do it looped |

251 | |

252 | // error = newval - output |

253 | m_error=v-m_nodes[0]; |

254 | |

255 | // update the output value |

256 | m_nodes[0]+=m_error*m_coeffs[0]; |

257 | |

258 | if(m_order==1) return; // we are done |

259 | |

260 | // add the output of the second integrator |

261 | m_nodes[0]+=m_nodes[1]; |

262 | |

263 | // update the second integrator |

264 | m_nodes[1]+=m_error*m_coeffs[1]; |

265 | |

266 | if(m_order==2) return; // we are done |

267 | |

268 | // if the order is even higher, we are using a loop |

269 | unsigned int i; |

270 | for (i=2; i < m_order;i++) { |

271 | // add the i-th integrator value |

272 | m_nodes[i-1] += m_nodes[i]; |

273 | |

274 | // update the i-th integrator |

275 | m_nodes[i] = m_coeffs[i] * m_error; |

276 | } |

277 | |

278 | return; |

279 | } |

280 | |

281 | /** |

282 | * Get the output value of the DLL |

283 | * |

284 | * @return current output value |

285 | */ |

286 | float |

287 | DelayLockedLoop::get() { |

288 | return m_nodes[0]; |

289 | } |

290 | |

291 | /** |

292 | * Get the current error signal value |

293 | * |

294 | * @return current error signal value |

295 | */ |

296 | float |

297 | DelayLockedLoop::getError() { |

298 | return m_error; |

299 | } |

300 | |

301 | } // end of namespace FFADOUtil |

**Note:**See TracBrowser for help on using the browser.