root/drivers/misc/echo/fir.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. fir16_create
  2. fir16_flush
  3. fir16_free
  4. fir16
  5. fir32_create
  6. fir32_flush
  7. fir32_free
  8. fir32

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * SpanDSP - a series of DSP components for telephony
   4  *
   5  * fir.h - General telephony FIR routines
   6  *
   7  * Written by Steve Underwood <steveu@coppice.org>
   8  *
   9  * Copyright (C) 2002 Steve Underwood
  10  *
  11  * All rights reserved.
  12  */
  13 
  14 #if !defined(_FIR_H_)
  15 #define _FIR_H_
  16 
  17 /*
  18    Ideas for improvement:
  19 
  20    1/ Rewrite filter for dual MAC inner loop.  The issue here is handling
  21    history sample offsets that are 16 bit aligned - the dual MAC needs
  22    32 bit aligmnent.  There are some good examples in libbfdsp.
  23 
  24    2/ Use the hardware circular buffer facility tohalve memory usage.
  25 
  26    3/ Consider using internal memory.
  27 
  28    Using less memory might also improve speed as cache misses will be
  29    reduced. A drop in MIPs and memory approaching 50% should be
  30    possible.
  31 
  32    The foreground and background filters currenlty use a total of
  33    about 10 MIPs/ch as measured with speedtest.c on a 256 TAP echo
  34    can.
  35 */
  36 
  37 /*
  38  * 16 bit integer FIR descriptor. This defines the working state for a single
  39  * instance of an FIR filter using 16 bit integer coefficients.
  40  */
  41 struct fir16_state_t {
  42         int taps;
  43         int curr_pos;
  44         const int16_t *coeffs;
  45         int16_t *history;
  46 };
  47 
  48 /*
  49  * 32 bit integer FIR descriptor. This defines the working state for a single
  50  * instance of an FIR filter using 32 bit integer coefficients, and filtering
  51  * 16 bit integer data.
  52  */
  53 struct fir32_state_t {
  54         int taps;
  55         int curr_pos;
  56         const int32_t *coeffs;
  57         int16_t *history;
  58 };
  59 
  60 /*
  61  * Floating point FIR descriptor. This defines the working state for a single
  62  * instance of an FIR filter using floating point coefficients and data.
  63  */
  64 struct fir_float_state_t {
  65         int taps;
  66         int curr_pos;
  67         const float *coeffs;
  68         float *history;
  69 };
  70 
  71 static inline const int16_t *fir16_create(struct fir16_state_t *fir,
  72                                               const int16_t *coeffs, int taps)
  73 {
  74         fir->taps = taps;
  75         fir->curr_pos = taps - 1;
  76         fir->coeffs = coeffs;
  77         fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
  78         return fir->history;
  79 }
  80 
  81 static inline void fir16_flush(struct fir16_state_t *fir)
  82 {
  83         memset(fir->history, 0, fir->taps * sizeof(int16_t));
  84 }
  85 
  86 static inline void fir16_free(struct fir16_state_t *fir)
  87 {
  88         kfree(fir->history);
  89 }
  90 
  91 static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
  92 {
  93         int32_t y;
  94         int i;
  95         int offset1;
  96         int offset2;
  97 
  98         fir->history[fir->curr_pos] = sample;
  99 
 100         offset2 = fir->curr_pos;
 101         offset1 = fir->taps - offset2;
 102         y = 0;
 103         for (i = fir->taps - 1; i >= offset1; i--)
 104                 y += fir->coeffs[i] * fir->history[i - offset1];
 105         for (; i >= 0; i--)
 106                 y += fir->coeffs[i] * fir->history[i + offset2];
 107         if (fir->curr_pos <= 0)
 108                 fir->curr_pos = fir->taps;
 109         fir->curr_pos--;
 110         return (int16_t) (y >> 15);
 111 }
 112 
 113 static inline const int16_t *fir32_create(struct fir32_state_t *fir,
 114                                               const int32_t *coeffs, int taps)
 115 {
 116         fir->taps = taps;
 117         fir->curr_pos = taps - 1;
 118         fir->coeffs = coeffs;
 119         fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
 120         return fir->history;
 121 }
 122 
 123 static inline void fir32_flush(struct fir32_state_t *fir)
 124 {
 125         memset(fir->history, 0, fir->taps * sizeof(int16_t));
 126 }
 127 
 128 static inline void fir32_free(struct fir32_state_t *fir)
 129 {
 130         kfree(fir->history);
 131 }
 132 
 133 static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
 134 {
 135         int i;
 136         int32_t y;
 137         int offset1;
 138         int offset2;
 139 
 140         fir->history[fir->curr_pos] = sample;
 141         offset2 = fir->curr_pos;
 142         offset1 = fir->taps - offset2;
 143         y = 0;
 144         for (i = fir->taps - 1; i >= offset1; i--)
 145                 y += fir->coeffs[i] * fir->history[i - offset1];
 146         for (; i >= 0; i--)
 147                 y += fir->coeffs[i] * fir->history[i + offset2];
 148         if (fir->curr_pos <= 0)
 149                 fir->curr_pos = fir->taps;
 150         fir->curr_pos--;
 151         return (int16_t) (y >> 15);
 152 }
 153 
 154 #endif

/* [<][>][^][v][top][bottom][index][help] */