re-fix #ifdef cond for lrint()
[fdkaac.git] / src / lpcm.c
CommitLineData
48e2f01c 1/*
2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
4 */
5#if HAVE_CONFIG_H
6# include "config.h"
7#endif
8#if HAVE_STDINT_H
9# include <stdint.h>
10#endif
11#include <stdlib.h>
12#include <math.h>
13#include "lpcm.h"
14#include "m4af_endian.h"
15
5ccbfaa7 16#if defined(_MSC_VER) && _MSC_VER < 1800
48e2f01c 17# ifdef _M_IX86
18inline int lrint(double x)
19{
20 int n;
21 _asm {
22 fld x
23 fistp n
24 }
25 return n;
26}
27# else
28# include <emmintrin.h>
29inline int lrint(double x)
30{
31 return _mm_cvtsd_si32(_mm_load_sd(&x));
32}
33# endif
34#endif
35
01993d67 36static
6da14aae 37inline double pcm_clip(double n, double min_value, double max_value)
48e2f01c 38{
39 if (n < min_value)
40 return min_value;
41 else if (n > max_value)
42 return max_value;
43 return n;
44}
01993d67 45static
48e2f01c 46inline float pcm_i2f(int32_t n)
47{
48 union {
49 int32_t ivalue;
50 float fvalue;
51 } u;
52 u.ivalue = n;
53 return u.fvalue;
54}
01993d67 55static
48e2f01c 56inline double pcm_i2d(int64_t n)
57{
58 union {
59 int64_t ivalue;
60 double fvalue;
61 } u;
62 u.ivalue = n;
63 return u.fvalue;
64}
01993d67 65static
48e2f01c 66inline int16_t pcm_quantize_s32(int32_t n)
67{
68 n = ((n >> 15) + 1) >> 1;
69 return (n == 0x8000) ? 0x7fff : n;
70}
01993d67 71static
48e2f01c 72inline int16_t pcm_quantize_f64(double v)
73{
6da14aae 74 return (int16_t)lrint(pcm_clip(v * 32768.0, -32768.0, 32767.0));
48e2f01c 75}
01993d67 76static
48e2f01c 77inline int16_t pcm_s8_to_s16(int8_t n)
78{
79 return n << 8;
80}
01993d67 81static
48e2f01c 82inline int16_t pcm_u8_to_s16(uint8_t n)
83{
84 return (n << 8) ^ 0x8000;
85}
01993d67 86static
48e2f01c 87inline int16_t pcm_s16le_to_s16(int16_t n)
88{
89 return m4af_ltoh16(n);
90}
01993d67 91static
48e2f01c 92inline int16_t pcm_s16be_to_s16(int16_t n)
93{
94 return m4af_btoh16(n);
95}
01993d67 96static
48e2f01c 97inline int16_t pcm_u16le_to_s16(uint16_t n)
98{
99 return m4af_ltoh16(n) ^ 0x8000;
100}
01993d67 101static
48e2f01c 102inline int16_t pcm_u16be_to_s16(uint16_t n)
103{
104 return m4af_btoh16(n) ^ 0x8000;
105}
01993d67 106static
48e2f01c 107inline int32_t pcm_s24le_to_s32(uint8_t *p)
108{
109 return p[0]<<8 | p[1]<<16 | p[2]<<24;
110}
01993d67 111static
48e2f01c 112inline int32_t pcm_s24be_to_s32(uint8_t *p)
113{
114 return p[0]<<24 | p[1]<<16 | p[2]<<8;
115}
01993d67 116static
48e2f01c 117inline int32_t pcm_u24le_to_s32(uint8_t *p)
118{
119 return pcm_s24le_to_s32(p) ^ 0x80000000;
120}
01993d67 121static
48e2f01c 122inline int32_t pcm_u24be_to_s32(uint8_t *p)
123{
124 return pcm_s24be_to_s32(p) ^ 0x80000000;
125}
01993d67 126static
48e2f01c 127inline int16_t pcm_s24le_to_s16(uint8_t *p)
128{
129 return pcm_quantize_s32(pcm_s24le_to_s32(p));
130}
01993d67 131static
48e2f01c 132inline int16_t pcm_s24be_to_s16(uint8_t *p)
133{
134 return pcm_quantize_s32(pcm_s24be_to_s32(p));
135}
01993d67 136static
48e2f01c 137inline int16_t pcm_u24le_to_s16(uint8_t *p)
138{
139 return pcm_quantize_s32(pcm_u24le_to_s32(p));
140}
01993d67 141static
48e2f01c 142inline int16_t pcm_u24be_to_s16(uint8_t *p)
143{
144 return pcm_quantize_s32(pcm_u24be_to_s32(p));
145}
01993d67 146static
48e2f01c 147inline int16_t pcm_s32le_to_s16(int32_t n)
148{
149 return pcm_quantize_s32(m4af_ltoh32(n));
150}
01993d67 151static
48e2f01c 152inline int16_t pcm_s32be_to_s16(int32_t n)
153{
154 return pcm_quantize_s32(m4af_btoh32(n));
155}
01993d67 156static
48e2f01c 157inline int16_t pcm_u32le_to_s16(int32_t n)
158{
159 return pcm_quantize_s32(m4af_ltoh32(n) ^ 0x80000000);
160}
01993d67 161static
48e2f01c 162inline int16_t pcm_u32be_to_s16(int32_t n)
163{
164 return pcm_quantize_s32(m4af_btoh32(n) ^ 0x80000000);
165}
158dc13c 166static
48e2f01c 167inline int16_t pcm_f32le_to_s16(int32_t n)
168{
169 return pcm_quantize_f64(pcm_i2f(m4af_ltoh32(n)));
170}
01993d67 171static
48e2f01c 172inline int16_t pcm_f32be_to_s16(int32_t n)
173{
174 return pcm_quantize_f64(pcm_i2f(m4af_btoh32(n)));
175}
01993d67 176static
48e2f01c 177inline int16_t pcm_f64le_to_s16(int64_t n)
178{
179 return pcm_quantize_f64(pcm_i2d(m4af_ltoh64(n)));
180}
01993d67 181static
48e2f01c 182inline int16_t pcm_f64be_to_s16(int64_t n)
183{
184 return pcm_quantize_f64(pcm_i2d(m4af_btoh64(n)));
185}
186
187int pcm_convert_to_native_sint16(const pcm_sample_description_t *format,
188 const void *input, uint32_t nframes,
e8e9f79e 189 int16_t *result)
48e2f01c 190{
191#define CONVERT(type, conv) \
192 do { \
193 unsigned i; \
194 type *ip = (type *)input; \
195 for (i = 0; i < count; ++i) { \
e8e9f79e 196 result[i] = conv(ip[i]); \
48e2f01c 197 } \
198 } while(0)
199
200#define CONVERT_BYTES(conv) \
201 do { \
202 unsigned i, bytes_per_channel; \
203 uint8_t *ip = (uint8_t *)input; \
204 bytes_per_channel = PCM_BYTES_PER_CHANNEL(format); \
205 for (i = 0; i < count; ++i) { \
e8e9f79e 206 result[i] = conv(ip); \
48e2f01c 207 ip += bytes_per_channel; \
208 } \
209 } while(0)
210
211 uint32_t count = nframes * format->channels_per_frame;
212 if (!count)
213 return 0;
48e2f01c 214 switch (PCM_BYTES_PER_CHANNEL(format) | format->sample_type<<4) {
215 case 1 | PCM_TYPE_SINT<<4:
216 CONVERT(int8_t, pcm_s8_to_s16); break;
217 case 1 | PCM_TYPE_UINT<<4:
218 CONVERT(uint8_t, pcm_u8_to_s16); break;
219 case 2 | PCM_TYPE_SINT<<4:
220 CONVERT(int16_t, pcm_s16le_to_s16); break;
221 case 2 | PCM_TYPE_UINT<<4:
222 CONVERT(uint16_t, pcm_u16le_to_s16); break;
223 case 2 | PCM_TYPE_SINT_BE<<4:
224 CONVERT(int16_t, pcm_s16be_to_s16); break;
225 case 2 | PCM_TYPE_UINT_BE<<4:
226 CONVERT(int16_t, pcm_u16be_to_s16); break;
227 case 3 | PCM_TYPE_SINT<<4:
228 CONVERT_BYTES(pcm_s24le_to_s16); break;
229 case 3 | PCM_TYPE_UINT<<4:
230 CONVERT_BYTES(pcm_u24le_to_s16); break;
231 case 3 | PCM_TYPE_SINT_BE<<4:
232 CONVERT_BYTES(pcm_s24be_to_s16); break;
233 case 3 | PCM_TYPE_UINT_BE<<4:
234 CONVERT_BYTES(pcm_u24be_to_s16); break;
235 case 4 | PCM_TYPE_SINT<<4:
236 CONVERT(int32_t, pcm_s32le_to_s16); break;
237 case 4 | PCM_TYPE_UINT<<4:
238 CONVERT(uint32_t, pcm_u32le_to_s16); break;
239 case 4 | PCM_TYPE_FLOAT<<4:
240 CONVERT(int32_t, pcm_f32le_to_s16); break;
241 case 4 | PCM_TYPE_SINT_BE<<4:
242 CONVERT(int32_t, pcm_s32be_to_s16); break;
243 case 4 | PCM_TYPE_UINT_BE<<4:
244 CONVERT(uint32_t, pcm_u32be_to_s16); break;
245 case 4 | PCM_TYPE_FLOAT_BE<<4:
246 CONVERT(int32_t, pcm_f32be_to_s16); break;
247 case 8 | PCM_TYPE_FLOAT<<4:
248 CONVERT(int64_t, pcm_f64le_to_s16); break;
249 case 8 | PCM_TYPE_FLOAT_BE<<4:
250 CONVERT(int64_t, pcm_f64be_to_s16); break;
251 default:
252 return -1;
253 }
254 return 0;
255}
This page took 0.025448 seconds and 4 git commands to generate.