33 PROG_IIR_CFG_ALPHA_NUM = 2,
34 PROG_IIR_CFG_ALPHA_DEN = 3,
44#ifdef CONFIG_DAWN_OBJECT_HAS_NAME
45 const char *getClassNameStr()
const override
74 return CProgIIRFilter::cfgId(
false, 1, PROG_IIR_CFG_ALPHA_NUM);
79 return CProgIIRFilter::cfgId(
false, 1, PROG_IIR_CFG_ALPHA_DEN);
85 size_t &offset)
override
95 DAWNERR(
"iir: invalid alpha config size %u\n", item->
cfgid.
s.
size);
104 case PROG_IIR_CFG_ALPHA_NUM:
107 case PROG_IIR_CFG_ALPHA_DEN:
114 if (alphaDen == 0 || alphaNum > alphaDen)
116 DAWNERR(
"iir: invalid alpha %u/%u\n", alphaNum, alphaDen);
127 bool &initsample)
override
131#ifdef CONFIG_DAWN_DTYPE_INT8
134 handleSigned<int8_t>(output, data, ioData, outputData, initsample);
139#ifdef CONFIG_DAWN_DTYPE_UINT8
142 handleUnsigned<uint8_t>(output, data, ioData, outputData, initsample);
147#ifdef CONFIG_DAWN_DTYPE_INT16
150 handleSigned<int16_t>(output, data, ioData, outputData, initsample);
155#ifdef CONFIG_DAWN_DTYPE_UINT16
158 handleUnsigned<uint16_t>(output, data, ioData, outputData, initsample);
163#ifdef CONFIG_DAWN_DTYPE_INT32
166 handleSigned<int32_t>(output, data, ioData, outputData, initsample);
171#ifdef CONFIG_DAWN_DTYPE_UINT32
174 handleUnsigned<uint32_t>(output, data, ioData, outputData, initsample);
179#ifdef CONFIG_DAWN_DTYPE_B16
182 handleSigned<int32_t>(output, data, ioData, outputData, initsample);
187#ifdef CONFIG_DAWN_DTYPE_UB16
190 handleUnsigned<uint32_t>(output, data, ioData, outputData, initsample);
195#ifdef CONFIG_DAWN_DTYPE_FLOAT
198 handleFloat<float>(output, data, ioData, outputData, initsample);
203#ifdef CONFIG_DAWN_DTYPE_DOUBLE
206 handleFloat<double>(output, data, ioData, outputData, initsample);
213 DAWNERR(
"iir: unsupported dtype %d\n", data->
getDtype());
232 static int64_t scaleDelta(int64_t diff, uint32_t num, uint32_t den)
234 const bool negative = diff < 0;
235 const uint64_t magnitude =
236 negative ?
static_cast<uint64_t
>(-diff) : static_cast<uint64_t>(diff);
237 const uint64_t quotient = magnitude / den;
238 const uint64_t remainder = magnitude % den;
239 const uint64_t scaled = quotient *
static_cast<uint64_t
>(num) +
240 (remainder *
static_cast<uint64_t
>(num)) /
static_cast<uint64_t
>(den);
242 return negative ? -
static_cast<int64_t
>(scaled) : static_cast<int64_t>(scaled);
246 static T clampSigned(int64_t value)
248 const int64_t min =
static_cast<int64_t
>(std::numeric_limits<T>::lowest());
249 const int64_t max =
static_cast<int64_t
>(std::numeric_limits<T>::max());
253 return std::numeric_limits<T>::lowest();
258 return std::numeric_limits<T>::max();
261 return static_cast<T
>(value);
265 static T clampUnsigned(int64_t value)
267 const int64_t max =
static_cast<int64_t
>(std::numeric_limits<T>::max());
276 return std::numeric_limits<T>::max();
279 return static_cast<T
>(value);
283 void handleSigned(CIOCommon *output,
286 io_ddata_t *outputData,
291 handleInitSample(output, data, ioData, outputData, initsample);
295 std::memcpy(ioData->getDataPtr(), data->getDataPtr(), ioData->getDataSize());
297 for (
size_t i = 0; i < ioData->getItems(); i++)
299 const int64_t x = ioData->get<T>(i);
300 int64_t y = outputData->get<T>(i);
301 const int64_t diff = x - y;
302 y += scaleDelta(diff, alphaNum, alphaDen);
303 outputData->get<T>(i) = clampSigned<T>(y);
306 output->setData(*outputData);
310 void handleUnsigned(CIOCommon *output,
313 io_ddata_t *outputData,
318 handleInitSample(output, data, ioData, outputData, initsample);
322 std::memcpy(ioData->getDataPtr(), data->getDataPtr(), ioData->getDataSize());
324 for (
size_t i = 0; i < ioData->getItems(); i++)
326 const int64_t x = ioData->get<T>(i);
327 int64_t y = outputData->get<T>(i);
328 const int64_t diff = x - y;
329 y += scaleDelta(diff, alphaNum, alphaDen);
330 outputData->get<T>(i) = clampUnsigned<T>(y);
333 output->setData(*outputData);
337 void handleFloat(CIOCommon *output,
340 io_ddata_t *outputData,
345 handleInitSample(output, data, ioData, outputData, initsample);
349 std::memcpy(ioData->getDataPtr(), data->getDataPtr(), ioData->getDataSize());
351 const T alpha =
static_cast<T
>(alphaNum) /
static_cast<T
>(alphaDen);
353 for (
size_t i = 0; i < ioData->getItems(); i++)
355 const T x = ioData->get<T>(i);
356 T y = outputData->get<T>(i);
357 y += (x - y) * alpha;
358 outputData->get<T>(i) = y;
361 output->setData(*outputData);