## ffmpeg / libavcodec / acelp_filters.c @ 8955a9d7

History | View | Annotate | Download (4.47 KB)

1 | a52000f2 | Vladimir Voroshilov | ```
/*
``` |
---|---|---|---|

2 | ```
* various filters for ACELP-based codecs
``` |
||

3 | ```
*
``` |
||

4 | ```
* Copyright (c) 2008 Vladimir Voroshilov
``` |
||

5 | ```
*
``` |
||

6 | ```
* This file is part of FFmpeg.
``` |
||

7 | ```
*
``` |
||

8 | ```
* FFmpeg is free software; you can redistribute it and/or
``` |
||

9 | ```
* modify it under the terms of the GNU Lesser General Public
``` |
||

10 | ```
* License as published by the Free Software Foundation; either
``` |
||

11 | ```
* version 2.1 of the License, or (at your option) any later version.
``` |
||

12 | ```
*
``` |
||

13 | ```
* FFmpeg is distributed in the hope that it will be useful,
``` |
||

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

15 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

16 | ```
* Lesser General Public License for more details.
``` |
||

17 | ```
*
``` |
||

18 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

19 | ```
* License along with FFmpeg; if not, write to the Free Software
``` |
||

20 | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |
||

21 | ```
*/
``` |
||

22 | |||

23 | #include <inttypes.h> |
||

24 | |||

25 | #include "avcodec.h" |
||

26 | #include "acelp_filters.h" |
||

27 | |||

28 | 51222d10 | Diego Biurrun | const int16_t ff_acelp_interp_filter[61] = { /* (0.15) */ |

29 | d347a046 | Vladimir Voroshilov | 29443, 28346, 25207, 20449, 14701, 8693, |

30 | 3143, -1352, -4402, -5865, -5850, -4673, |
||

31 | -2783, -672, 1211, 2536, 3130, 2991, |
||

32 | 2259, 1170, 0, -1001, -1652, -1868, |
||

33 | -1666, -1147, -464, 218, 756, 1060, |
||

34 | 1099, 904, 550, 135, -245, -514, |
||

35 | -634, -602, -451, -231, 0, 191, |
||

36 | 308, 340, 296, 198, 78, -36, |
||

37 | -120, -163, -165, -132, -79, -19, |
||

38 | 34, 73, 91, 89, 70, 38, |
||

39 | ```
0,
``` |
||

40 | }; |
||

41 | |||

42 | 51222d10 | Diego Biurrun | void ff_acelp_interpolate(int16_t* out, const int16_t* in, |

43 | const int16_t* filter_coeffs, int precision, |
||

44 | int frac_pos, int filter_length, int length) |
||

45 | d347a046 | Vladimir Voroshilov | { |

46 | ```
int n, i;
``` |
||

47 | |||

48 | 3b3a676a | Carl Eugen Hoyos | ```
assert(frac_pos >= 0 && frac_pos < precision);
``` |

49 | d347a046 | Vladimir Voroshilov | |

50 | 51222d10 | Diego Biurrun | for (n = 0; n < length; n++) { |

51 | d347a046 | Vladimir Voroshilov | int idx = 0; |

52 | int v = 0x4000; |
||

53 | |||

54 | 51222d10 | Diego Biurrun | for (i = 0; i < filter_length;) { |

55 | d347a046 | Vladimir Voroshilov | |

56 | ```
/* The reference G.729 and AMR fixed point code performs clipping after
``` |
||

57 | ```
each of the two following accumulations.
``` |
||

58 | ```
Since clipping affects only the synthetic OVERFLOW test without
``` |
||

59 | ```
causing an int type overflow, it was moved outside the loop. */
``` |
||

60 | |||

61 | ```
/* R(x):=ac_v[-k+x]
``` |
||

62 | ```
v += R(n-i)*ff_acelp_interp_filter(t+6i)
``` |
||

63 | ```
v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
``` |
||

64 | |||

65 | 2bbd3434 | Michael Niedermayer | v += in[n + i] * filter_coeffs[idx + frac_pos]; |

66 | d347a046 | Vladimir Voroshilov | idx += precision; |

67 | i++; |
||

68 | 2bbd3434 | Michael Niedermayer | v += in[n - i] * filter_coeffs[idx - frac_pos]; |

69 | d347a046 | Vladimir Voroshilov | } |

70 | 51222d10 | Diego Biurrun | if (av_clip_int16(v >> 15) != (v >> 15)) |

71 | 2ad0d96a | Michael Niedermayer | av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n"); |

72 | ```
out[n] = v >> 15;
``` |
||

73 | d347a046 | Vladimir Voroshilov | } |

74 | } |
||

75 | |||

76 | 504eee37 | Vitor Sessak | void ff_acelp_interpolatef(float *out, const float *in, |

77 | const float *filter_coeffs, int precision, |
||

78 | int frac_pos, int filter_length, int length) |
||

79 | { |
||

80 | ```
int n, i;
``` |
||

81 | |||

82 | for (n = 0; n < length; n++) { |
||

83 | int idx = 0; |
||

84 | float v = 0; |
||

85 | |||

86 | for (i = 0; i < filter_length;) { |
||

87 | v += in[n + i] * filter_coeffs[idx + frac_pos]; |
||

88 | idx += precision; |
||

89 | i++; |
||

90 | v += in[n - i] * filter_coeffs[idx - frac_pos]; |
||

91 | } |
||

92 | out[n] = v; |
||

93 | } |
||

94 | } |
||

95 | |||

96 | a52000f2 | Vladimir Voroshilov | |

97 | 51222d10 | Diego Biurrun | void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2], |

98 | const int16_t* in, int length) |
||

99 | a52000f2 | Vladimir Voroshilov | { |

100 | ```
int i;
``` |
||

101 | ```
int tmp;
``` |
||

102 | |||

103 | 51222d10 | Diego Biurrun | for (i = 0; i < length; i++) { |

104 | tmp = (hpf_f[0]* 15836LL) >> 13; |
||

105 | tmp += (hpf_f[1]* -7667LL) >> 13; |
||

106 | 1b8a36d7 | Vladimir Voroshilov | tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); |

107 | a52000f2 | Vladimir Voroshilov | |

108 | f5e177f8 | Vladimir Voroshilov | ```
/* With "+0x800" rounding, clipping is needed
``` |

109 | ```
for ALGTHM and SPEECH tests. */
``` |
||

110 | 1b8a36d7 | Vladimir Voroshilov | out[i] = av_clip_int16((tmp + 0x800) >> 12); |

111 | a52000f2 | Vladimir Voroshilov | |

112 | hpf_f[1] = hpf_f[0]; |
||

113 | ```
hpf_f[0] = tmp;
``` |
||

114 | } |
||

115 | } |
||

116 | bb937155 | Colin McQuillan | |

117 | 8955a9d7 | Ronald S. Bultje | void ff_acelp_apply_order_2_transfer_function(float *out, const float *in, |

118 | bb937155 | Colin McQuillan | const float zero_coeffs[2], |

119 | const float pole_coeffs[2], |
||

120 | float gain, float mem[2], int n) |
||

121 | { |
||

122 | ```
int i;
``` |
||

123 | ```
float tmp;
``` |
||

124 | |||

125 | for (i = 0; i < n; i++) { |
||

126 | 8955a9d7 | Ronald S. Bultje | tmp = gain * in[i] - pole_coeffs[0] * mem[0] - pole_coeffs[1] * mem[1]; |

127 | out[i] = tmp + zero_coeffs[0] * mem[0] + zero_coeffs[1] * mem[1]; |
||

128 | bb937155 | Colin McQuillan | |

129 | mem[1] = mem[0]; |
||

130 | ```
mem[0] = tmp;
``` |
||

131 | } |
||

132 | } |
||

133 | 504eee37 | Vitor Sessak | |

134 | void ff_tilt_compensation(float *mem, float tilt, float *samples, int size) |
||

135 | { |
||

136 | float new_tilt_mem = samples[size - 1]; |
||

137 | ```
int i;
``` |
||

138 | |||

139 | for (i = size - 1; i > 0; i--) |
||

140 | ```
samples[i] -= tilt * samples[i - 1];
``` |
||

141 | |||

142 | ```
samples[0] -= tilt * *mem;
``` |
||

143 | *mem = new_tilt_mem; |
||

144 | } |