blob: c94a3d7cc359914fb7e327208e865d7af5c43386 [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
Pau Espin Pedrol4a25d6b2018-01-11 17:55:03 +010031void convert_init(void) {
32}
33
Thomas Tsou7e4e5362013-10-30 21:18:55 -040034/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000035static void neon_convert_si16_ps(float *out,
36 const short *in,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040037 int len)
38{
39 int start = len / 4 * 4;
40
41 neon_convert_si16_ps_4n(out, in, len >> 2);
42
43 for (int i = 0; i < len % 4; i++)
44 out[start + i] = (float) in[start + i];
45}
46
47/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000048static void neon_convert_ps_si16(short *out,
49 const float *in,
50 const float *scale,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040051 int len)
52{
53 int start = len / 4 * 4;
54
55 neon_convert_ps_si16_4n(out, in, scale, len >> 2);
56
57 for (int i = 0; i < len % 4; i++)
58 out[start + i] = (short) (in[start + i] * (*scale));
59}
Thomas Tsou7e4e5362013-10-30 21:18:55 -040060
Tom Tsou99cf9302015-11-09 20:05:04 +000061void convert_float_short(short *out, const float *in, float scale, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040062{
63#ifdef HAVE_NEON
64 float q[4] = { scale, scale, scale, scale };
65
66 if (len % 4)
67 neon_convert_ps_si16(out, in, q, len);
68 else
69 neon_convert_ps_si16_4n(out, in, q, len >> 2);
70#else
Philipp Maierfe976982017-03-16 14:50:25 +010071 base_convert_float_short(out, in, scale, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040072#endif
73}
74
Tom Tsou99cf9302015-11-09 20:05:04 +000075void convert_short_float(float *out, const short *in, int len)
Thomas Tsou7e4e5362013-10-30 21:18:55 -040076{
77#ifdef HAVE_NEON
78 if (len % 4)
79 neon_convert_si16_ps(out, in, len);
80 else
81 neon_convert_si16_ps_4n(out, in, len >> 2);
82#else
Philipp Maierfe976982017-03-16 14:50:25 +010083 base_convert_short_float(out, in, len);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040084#endif
85}