MPD: pcm/Neon.hxx Source File

MPD 0.20.15

Neon.hxx
Go to the documentation of this file.
1 /*
2 * Copyright 2003-2017 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef MPD_PCM_NEON_HXX
21 #define MPD_PCM_NEON_HXX
22
23 #include "Traits.hxx"
24
25 #include <arm_neon.h>
26
34 #define neon_x4_u(func, result, vector) do { \
35 result.val[0] = func(vector.val[0]); \
36 result.val[1] = func(vector.val[1]); \
37 result.val[2] = func(vector.val[2]); \
38 result.val[3] = func(vector.val[3]); \
39 } while (0)
40
48 #define neon_x4_b(func, result, vector, ...) do { \
49 result.val[0] = func(vector.val[0], __VA_ARGS__); \
50 result.val[1] = func(vector.val[1], __VA_ARGS__); \
51 result.val[2] = func(vector.val[2], __VA_ARGS__); \
52 result.val[3] = func(vector.val[3], __VA_ARGS__); \
53 } while (0)
54
58 struct NeonFloatTo16 {
59 static constexpr SampleFormat src_format = SampleFormat::FLOAT;
60 static constexpr SampleFormat dst_format = SampleFormat::S16;
61 typedef SampleTraits<src_format> SrcTraits;
62 typedef SampleTraits<dst_format> DstTraits;
63
64 typedef typename SrcTraits::value_type SV;
65 typedef typename DstTraits::value_type DV;
66
67 static constexpr size_t BLOCK_SIZE = 16;
68
69 void Convert(int16_t *dst, const float *src, const size_t n) const {
70 for (unsigned i = 0; i < n / BLOCK_SIZE;
71 ++i, src += BLOCK_SIZE, dst += BLOCK_SIZE) {
72 /* load 16 float samples into 4 quad
73 registers */
74 float32x4x4_t value = vld4q_f32(src);
75
76 /* convert to 32 bit integer */
77 int32x4x4_t ivalue;
78 neon_x4_b(vcvtq_n_s32_f32, ivalue, value,
79 30);
80
81 /* convert to 16 bit integer with saturation
82 and rounding */
83 int16x4x4_t nvalue;
84 neon_x4_b(vqrshrn_n_s32, nvalue, ivalue,
85 30 - DstTraits::BITS + 1);
86
87 /* store result */
88 vst4_s16(dst, nvalue);
89 }
90 }
91 };
92
93 #endif
SampleFormat::S16
NeonFloatTo16
Convert floating point samples to 16 bit signed integer using ARM NEON.
Definition: Neon.hxx:58
SampleTraits
This template describes the specified SampleFormat.
Definition: PcmUtils.hxx:30
Traits.hxx
NeonFloatTo16::SV
SrcTraits::value_type SV
Definition: Neon.hxx:64
NeonFloatTo16::Convert
void Convert(int16_t *dst, const float *src, const size_t n) const
Definition: Neon.hxx:69
NeonFloatTo16::BLOCK_SIZE
static constexpr size_t BLOCK_SIZE
Definition: Neon.hxx:67
neon_x4_b
#define neon_x4_b(func, result, vector,...)
Call a NEON intrinsic for each element in the vector.
Definition: Neon.hxx:48
NeonFloatTo16::dst_format
static constexpr SampleFormat dst_format
Definition: Neon.hxx:60
SampleFormat
SampleFormat
Definition: SampleFormat.hxx:33
NeonFloatTo16::DstTraits
SampleTraits< dst_format > DstTraits
Definition: Neon.hxx:62
NeonFloatTo16::DV
DstTraits::value_type DV
Definition: Neon.hxx:65
SampleFormat::FLOAT
32 bit floating point samples in the host&#39;s format.
NeonFloatTo16::src_format
static constexpr SampleFormat src_format
Definition: Neon.hxx:59
NeonFloatTo16::SrcTraits
SampleTraits< src_format > SrcTraits
Definition: Neon.hxx:61