blob: ace1b6f8c35f255daa7b37ab149f75946ae5dd09 [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 *
Pau Espin Pedrol21d03d32019-07-22 12:05:52 +02005 * SPDX-License-Identifier: LGPL-2.1+
6 *
Thomas Tsou7e4e5362013-10-30 21:18:55 -04007 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <malloc.h>
23#include <string.h>
24#include "convert.h"
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
Tom Tsou99cf9302015-11-09 20:05:04 +000030void neon_convert_ps_si16_4n(short *, const float *, const float *, int);
31void neon_convert_si16_ps_4n(float *, const short *, int);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040032
Pau Espin Pedrol4a25d6b2018-01-11 17:55:03 +010033void convert_init(void) {
34}
35
Thomas Tsou7e4e5362013-10-30 21:18:55 -040036/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000037static void neon_convert_si16_ps(float *out,
38 const short *in,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040039 int len)
40{
41 int start = len / 4 * 4;
42
43 neon_convert_si16_ps_4n(out, in, len >> 2);
44
45 for (int i = 0; i < len % 4; i++)
46 out[start + i] = (float) in[start + i];
47}
48
49/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000050static void neon_convert_ps_si16(short *out,
51 const float *in,
52 const float *scale,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040053 int len)
54{
55 int start = len / 4 * 4;
56
57 neon_convert_ps_si16_4n(out, in, scale, len >> 2);
58
59 for (int i = 0; i < len % 4; i++)
60 out[start + i] = (short) (in[start + i] * (*scale));
61}
Thomas Tsou7e4e5362013-10-30 21:18:55 -040062
Tom Tsou99cf9302015-11-09 20:05:04 +000063void convert_float_short(short *out, const float *in, float scale, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040064{
65#ifdef HAVE_NEON
66 float q[4] = { scale, scale, scale, scale };
67
68 if (len % 4)
69 neon_convert_ps_si16(out, in, q, len);
70 else
71 neon_convert_ps_si16_4n(out, in, q, len >> 2);
72#else
Philipp Maierfe976982017-03-16 14:50:25 +010073 base_convert_float_short(out, in, scale, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040074#endif
75}
76
Tom Tsou99cf9302015-11-09 20:05:04 +000077void convert_short_float(float *out, const short *in, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040078{
79#ifdef HAVE_NEON
80 if (len % 4)
81 neon_convert_si16_ps(out, in, len);
82 else
83 neon_convert_si16_ps_4n(out, in, len >> 2);
84#else
Philipp Maierfe976982017-03-16 14:50:25 +010085 base_convert_short_float(out, in, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040086#endif
87}