blob: 57796ea5d995eed1cecd85b4d163e1e204e7207b [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
Thomas Tsou7e4e5362013-10-30 21:18:55 -040031/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000032static void neon_convert_si16_ps(float *out,
33 const short *in,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040034 int len)
35{
36 int start = len / 4 * 4;
37
38 neon_convert_si16_ps_4n(out, in, len >> 2);
39
40 for (int i = 0; i < len % 4; i++)
41 out[start + i] = (float) in[start + i];
42}
43
44/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000045static void neon_convert_ps_si16(short *out,
46 const float *in,
47 const float *scale,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040048 int len)
49{
50 int start = len / 4 * 4;
51
52 neon_convert_ps_si16_4n(out, in, scale, len >> 2);
53
54 for (int i = 0; i < len % 4; i++)
55 out[start + i] = (short) (in[start + i] * (*scale));
56}
57#endif
58
Tom Tsou99cf9302015-11-09 20:05:04 +000059void convert_float_short(short *out, const float *in, float scale, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040060{
61#ifdef HAVE_NEON
62 float q[4] = { scale, scale, scale, scale };
63
64 if (len % 4)
65 neon_convert_ps_si16(out, in, q, len);
66 else
67 neon_convert_ps_si16_4n(out, in, q, len >> 2);
68#else
Philipp Maierfe976982017-03-16 14:50:25 +010069 base_convert_float_short(out, in, scale, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040070#endif
71}
72
Tom Tsou99cf9302015-11-09 20:05:04 +000073void convert_short_float(float *out, const short *in, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040074{
75#ifdef HAVE_NEON
76 if (len % 4)
77 neon_convert_si16_ps(out, in, len);
78 else
79 neon_convert_si16_ps_4n(out, in, len >> 2);
80#else
Philipp Maierfe976982017-03-16 14:50:25 +010081 base_convert_short_float(out, in, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040082#endif
83}