blob: e489d224e9ab93c742b4c425e778a60fc492dad8 [file] [log] [blame]
Thomas Tsou7e4e5362013-10-30 21:18:55 -04001/*
2 * NEON type conversions
3 * Copyright (C) 2012, 2013 Thomas Tsou <tom@tsou.cc>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <malloc.h>
21#include <string.h>
22#include "convert.h"
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
Tom Tsou99cf9302015-11-09 20:05:04 +000028void neon_convert_ps_si16_4n(short *, const float *, const float *, int);
29void neon_convert_si16_ps_4n(float *, const short *, int);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040030
31#ifndef HAVE_NEON
Tom Tsou99cf9302015-11-09 20:05:04 +000032static void convert_si16_ps(float *out, const short *in, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040033{
34 for (int i = 0; i < len; i++)
35 out[i] = in[i];
36}
37
Tom Tsou99cf9302015-11-09 20:05:04 +000038static void convert_ps_si16(short *out, const float *in, float scale, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040039{
40 for (int i = 0; i < len; i++)
41 out[i] = in[i] * scale;
42}
43#else
44/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000045static void neon_convert_si16_ps(float *out,
46 const short *in,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040047 int len)
48{
49 int start = len / 4 * 4;
50
51 neon_convert_si16_ps_4n(out, in, len >> 2);
52
53 for (int i = 0; i < len % 4; i++)
54 out[start + i] = (float) in[start + i];
55}
56
57/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000058static void neon_convert_ps_si16(short *out,
59 const float *in,
60 const float *scale,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040061 int len)
62{
63 int start = len / 4 * 4;
64
65 neon_convert_ps_si16_4n(out, in, scale, len >> 2);
66
67 for (int i = 0; i < len % 4; i++)
68 out[start + i] = (short) (in[start + i] * (*scale));
69}
70#endif
71
Tom Tsou99cf9302015-11-09 20:05:04 +000072void convert_float_short(short *out, const float *in, float scale, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040073{
74#ifdef HAVE_NEON
75 float q[4] = { scale, scale, scale, scale };
76
77 if (len % 4)
78 neon_convert_ps_si16(out, in, q, len);
79 else
80 neon_convert_ps_si16_4n(out, in, q, len >> 2);
81#else
82 convert_ps_si16(out, in, scale, len);
83#endif
84}
85
Tom Tsou99cf9302015-11-09 20:05:04 +000086void convert_short_float(float *out, const short *in, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040087{
88#ifdef HAVE_NEON
89 if (len % 4)
90 neon_convert_si16_ps(out, in, len);
91 else
92 neon_convert_si16_ps_4n(out, in, len >> 2);
93#else
94 convert_si16_ps(out, in, len);
95#endif
96}