blob: 7145579efb6731574b226bb8a3f8d7b9a4c01933 [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.
Thomas Tsou7e4e5362013-10-30 21:18:55 -040016 */
17
18#include <malloc.h>
19#include <string.h>
20#include "convert.h"
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
Tom Tsou99cf9302015-11-09 20:05:04 +000026void neon_convert_ps_si16_4n(short *, const float *, const float *, int);
27void neon_convert_si16_ps_4n(float *, const short *, int);
Thomas Tsou7e4e5362013-10-30 21:18:55 -040028
Pau Espin Pedrol4a25d6b2018-01-11 17:55:03 +010029void convert_init(void) {
30}
31
Thomas Tsou7e4e5362013-10-30 21:18:55 -040032/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000033static void neon_convert_si16_ps(float *out,
34 const short *in,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040035 int len)
36{
37 int start = len / 4 * 4;
38
39 neon_convert_si16_ps_4n(out, in, len >> 2);
40
41 for (int i = 0; i < len % 4; i++)
42 out[start + i] = (float) in[start + i];
43}
44
45/* 4*N 16-bit signed integer conversion with remainder */
Tom Tsou99cf9302015-11-09 20:05:04 +000046static void neon_convert_ps_si16(short *out,
47 const float *in,
48 const float *scale,
Thomas Tsou7e4e5362013-10-30 21:18:55 -040049 int len)
50{
51 int start = len / 4 * 4;
52
53 neon_convert_ps_si16_4n(out, in, scale, len >> 2);
54
55 for (int i = 0; i < len % 4; i++)
56 out[start + i] = (short) (in[start + i] * (*scale));
57}
Thomas Tsou7e4e5362013-10-30 21:18:55 -040058
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}