aacpsy_mips.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright (c) 2012
  3. * MIPS Technologies, Inc., California.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
  14. * contributors may be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * Author: Bojan Zivkovic (bojan@mips.com)
  30. *
  31. * AAC encoder psychoacoustic model routines optimized
  32. * for MIPS floating-point architecture
  33. *
  34. * This file is part of FFmpeg.
  35. *
  36. * FFmpeg is free software; you can redistribute it and/or
  37. * modify it under the terms of the GNU Lesser General Public
  38. * License as published by the Free Software Foundation; either
  39. * version 2.1 of the License, or (at your option) any later version.
  40. *
  41. * FFmpeg is distributed in the hope that it will be useful,
  42. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  43. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  44. * Lesser General Public License for more details.
  45. *
  46. * You should have received a copy of the GNU Lesser General Public
  47. * License along with FFmpeg; if not, write to the Free Software
  48. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  49. */
  50. /**
  51. * @file
  52. * Reference: libavcodec/aacpsy.c
  53. */
  54. #ifndef AVCODEC_MIPS_AACPSY_MIPS_H
  55. #define AVCODEC_MIPS_AACPSY_MIPS_H
  56. #include "libavutil/mips/asmdefs.h"
  57. #if HAVE_INLINE_ASM && HAVE_MIPSFPU && ( PSY_LAME_FIR_LEN == 21 )
  58. #if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
  59. static void calc_thr_3gpp_mips(const FFPsyWindowInfo *wi, const int num_bands,
  60. AacPsyChannel *pch, const uint8_t *band_sizes,
  61. const float *coefs, const int cutoff)
  62. {
  63. int i, w, g;
  64. int start = 0, wstart = 0;
  65. for (w = 0; w < wi->num_windows*16; w += 16) {
  66. wstart = 0;
  67. for (g = 0; g < num_bands; g++) {
  68. AacPsyBand *band = &pch->band[w+g];
  69. float form_factor = 0.0f;
  70. float Temp;
  71. band->energy = 0.0f;
  72. if (wstart < cutoff) {
  73. for (i = 0; i < band_sizes[g]; i+=4) {
  74. float a, b, c, d;
  75. float ax, bx, cx, dx;
  76. float *cf = (float *)&coefs[start+i];
  77. __asm__ volatile (
  78. "lwc1 %[a], 0(%[cf]) \n\t"
  79. "lwc1 %[b], 4(%[cf]) \n\t"
  80. "lwc1 %[c], 8(%[cf]) \n\t"
  81. "lwc1 %[d], 12(%[cf]) \n\t"
  82. "abs.s %[a], %[a] \n\t"
  83. "abs.s %[b], %[b] \n\t"
  84. "abs.s %[c], %[c] \n\t"
  85. "abs.s %[d], %[d] \n\t"
  86. "sqrt.s %[ax], %[a] \n\t"
  87. "sqrt.s %[bx], %[b] \n\t"
  88. "sqrt.s %[cx], %[c] \n\t"
  89. "sqrt.s %[dx], %[d] \n\t"
  90. "madd.s %[e], %[e], %[a], %[a] \n\t"
  91. "madd.s %[e], %[e], %[b], %[b] \n\t"
  92. "madd.s %[e], %[e], %[c], %[c] \n\t"
  93. "madd.s %[e], %[e], %[d], %[d] \n\t"
  94. "add.s %[f], %[f], %[ax] \n\t"
  95. "add.s %[f], %[f], %[bx] \n\t"
  96. "add.s %[f], %[f], %[cx] \n\t"
  97. "add.s %[f], %[f], %[dx] \n\t"
  98. : [a]"=&f"(a), [b]"=&f"(b),
  99. [c]"=&f"(c), [d]"=&f"(d),
  100. [e]"+f"(band->energy), [f]"+f"(form_factor),
  101. [ax]"=&f"(ax), [bx]"=&f"(bx),
  102. [cx]"=&f"(cx), [dx]"=&f"(dx)
  103. : [cf]"r"(cf)
  104. : "memory"
  105. );
  106. }
  107. }
  108. Temp = sqrtf((float)band_sizes[g] / band->energy);
  109. band->thr = band->energy * 0.001258925f;
  110. band->nz_lines = form_factor * sqrtf(Temp);
  111. start += band_sizes[g];
  112. wstart += band_sizes[g];
  113. }
  114. }
  115. }
  116. static void psy_hp_filter_mips(const float *firbuf, float *hpfsmpl, const float * psy_fir_coeffs)
  117. {
  118. float sum1, sum2, sum3, sum4;
  119. float *fb = (float*)firbuf;
  120. float *fb_end = fb + AAC_BLOCK_SIZE_LONG;
  121. float *hp = hpfsmpl;
  122. float coeff0 = psy_fir_coeffs[1];
  123. float coeff1 = psy_fir_coeffs[3];
  124. float coeff2 = psy_fir_coeffs[5];
  125. float coeff3 = psy_fir_coeffs[7];
  126. float coeff4 = psy_fir_coeffs[9];
  127. float f1 = 32768.0;
  128. __asm__ volatile (
  129. ".set push \n\t"
  130. ".set noreorder \n\t"
  131. "1: \n\t"
  132. "lwc1 $f0, 40(%[fb]) \n\t"
  133. "lwc1 $f1, 4(%[fb]) \n\t"
  134. "lwc1 $f2, 80(%[fb]) \n\t"
  135. "lwc1 $f3, 44(%[fb]) \n\t"
  136. "lwc1 $f4, 8(%[fb]) \n\t"
  137. "madd.s %[sum1], $f0, $f1, %[coeff0] \n\t"
  138. "lwc1 $f5, 84(%[fb]) \n\t"
  139. "lwc1 $f6, 48(%[fb]) \n\t"
  140. "madd.s %[sum2], $f3, $f4, %[coeff0] \n\t"
  141. "lwc1 $f7, 12(%[fb]) \n\t"
  142. "madd.s %[sum1], %[sum1], $f2, %[coeff0] \n\t"
  143. "lwc1 $f8, 88(%[fb]) \n\t"
  144. "lwc1 $f9, 52(%[fb]) \n\t"
  145. "madd.s %[sum2], %[sum2], $f5, %[coeff0] \n\t"
  146. "madd.s %[sum3], $f6, $f7, %[coeff0] \n\t"
  147. "lwc1 $f10, 16(%[fb]) \n\t"
  148. "lwc1 $f11, 92(%[fb]) \n\t"
  149. "madd.s %[sum1], %[sum1], $f7, %[coeff1] \n\t"
  150. "lwc1 $f1, 72(%[fb]) \n\t"
  151. "madd.s %[sum3], %[sum3], $f8, %[coeff0] \n\t"
  152. "madd.s %[sum4], $f9, $f10, %[coeff0] \n\t"
  153. "madd.s %[sum2], %[sum2], $f10, %[coeff1] \n\t"
  154. "madd.s %[sum1], %[sum1], $f1, %[coeff1] \n\t"
  155. "lwc1 $f4, 76(%[fb]) \n\t"
  156. "lwc1 $f8, 20(%[fb]) \n\t"
  157. "madd.s %[sum4], %[sum4], $f11, %[coeff0] \n\t"
  158. "lwc1 $f11, 24(%[fb]) \n\t"
  159. "madd.s %[sum2], %[sum2], $f4, %[coeff1] \n\t"
  160. "madd.s %[sum1], %[sum1], $f8, %[coeff2] \n\t"
  161. "madd.s %[sum3], %[sum3], $f8, %[coeff1] \n\t"
  162. "madd.s %[sum4], %[sum4], $f11, %[coeff1] \n\t"
  163. "lwc1 $f7, 64(%[fb]) \n\t"
  164. "madd.s %[sum2], %[sum2], $f11, %[coeff2] \n\t"
  165. "lwc1 $f10, 68(%[fb]) \n\t"
  166. "madd.s %[sum3], %[sum3], $f2, %[coeff1] \n\t"
  167. "madd.s %[sum4], %[sum4], $f5, %[coeff1] \n\t"
  168. "madd.s %[sum1], %[sum1], $f7, %[coeff2] \n\t"
  169. "madd.s %[sum2], %[sum2], $f10, %[coeff2] \n\t"
  170. "lwc1 $f2, 28(%[fb]) \n\t"
  171. "lwc1 $f5, 32(%[fb]) \n\t"
  172. "lwc1 $f8, 56(%[fb]) \n\t"
  173. "lwc1 $f11, 60(%[fb]) \n\t"
  174. "madd.s %[sum3], %[sum3], $f2, %[coeff2] \n\t"
  175. "madd.s %[sum4], %[sum4], $f5, %[coeff2] \n\t"
  176. "madd.s %[sum1], %[sum1], $f2, %[coeff3] \n\t"
  177. "madd.s %[sum2], %[sum2], $f5, %[coeff3] \n\t"
  178. "madd.s %[sum3], %[sum3], $f1, %[coeff2] \n\t"
  179. "madd.s %[sum4], %[sum4], $f4, %[coeff2] \n\t"
  180. "madd.s %[sum1], %[sum1], $f8, %[coeff3] \n\t"
  181. "madd.s %[sum2], %[sum2], $f11, %[coeff3] \n\t"
  182. "lwc1 $f1, 36(%[fb]) \n\t"
  183. PTR_ADDIU "%[fb], %[fb], 16 \n\t"
  184. "madd.s %[sum4], %[sum4], $f0, %[coeff3] \n\t"
  185. "madd.s %[sum3], %[sum3], $f1, %[coeff3] \n\t"
  186. "madd.s %[sum1], %[sum1], $f1, %[coeff4] \n\t"
  187. "madd.s %[sum2], %[sum2], $f0, %[coeff4] \n\t"
  188. "madd.s %[sum4], %[sum4], $f10, %[coeff3] \n\t"
  189. "madd.s %[sum3], %[sum3], $f7, %[coeff3] \n\t"
  190. "madd.s %[sum1], %[sum1], $f6, %[coeff4] \n\t"
  191. "madd.s %[sum2], %[sum2], $f9, %[coeff4] \n\t"
  192. "madd.s %[sum4], %[sum4], $f6, %[coeff4] \n\t"
  193. "madd.s %[sum3], %[sum3], $f3, %[coeff4] \n\t"
  194. "mul.s %[sum1], %[sum1], %[f1] \n\t"
  195. "mul.s %[sum2], %[sum2], %[f1] \n\t"
  196. "madd.s %[sum4], %[sum4], $f11, %[coeff4] \n\t"
  197. "madd.s %[sum3], %[sum3], $f8, %[coeff4] \n\t"
  198. "swc1 %[sum1], 0(%[hp]) \n\t"
  199. "swc1 %[sum2], 4(%[hp]) \n\t"
  200. "mul.s %[sum4], %[sum4], %[f1] \n\t"
  201. "mul.s %[sum3], %[sum3], %[f1] \n\t"
  202. "swc1 %[sum4], 12(%[hp]) \n\t"
  203. "swc1 %[sum3], 8(%[hp]) \n\t"
  204. "bne %[fb], %[fb_end], 1b \n\t"
  205. PTR_ADDIU "%[hp], %[hp], 16 \n\t"
  206. ".set pop \n\t"
  207. : [sum1]"=&f"(sum1), [sum2]"=&f"(sum2),
  208. [sum3]"=&f"(sum3), [sum4]"=&f"(sum4),
  209. [fb]"+r"(fb), [hp]"+r"(hp)
  210. : [coeff0]"f"(coeff0), [coeff1]"f"(coeff1),
  211. [coeff2]"f"(coeff2), [coeff3]"f"(coeff3),
  212. [coeff4]"f"(coeff4), [fb_end]"r"(fb_end), [f1]"f"(f1)
  213. : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6",
  214. "$f7", "$f8", "$f9", "$f10", "$f11",
  215. "memory"
  216. );
  217. }
  218. #define calc_thr_3gpp calc_thr_3gpp_mips
  219. #define psy_hp_filter psy_hp_filter_mips
  220. #endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
  221. #endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
  222. #endif /* AVCODEC_MIPS_AACPSY_MIPS_H */