• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (c) 2002-2021, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
4 **
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
7 */
8 
9 #ifndef COMMON_H_INCLUDED
10 #define COMMON_H_INCLUDED
11 
12 #include <stdint.h>
13 #ifdef HAVE_STDBOOL_H
14 #include <stdbool.h>
15 #endif
16 
17 #if defined(__x86_64__) || defined(_M_X64)
18 #   define HAVE_SSE2_INTRINSICS
19 #elif defined(ENABLE_SSE2_LRINT) && (defined(_M_IX86) || defined(__i386__))
20 #   if defined(_MSC_VER)
21 #       define HAVE_SSE2_INTRINSICS
22 #   elif defined(__clang__)
23 #       ifdef __SSE2__
24 #           define HAVE_SSE2_INTRINSICS
25 #       elif (__has_attribute(target))
26 #           define HAVE_SSE2_INTRINSICS
27 #           define USE_TARGET_ATTRIBUTE
28 #       endif
29 #   elif defined(__GNUC__)
30 #       ifdef __SSE2__
31 #           define HAVE_SSE2_INTRINSICS
32 #       elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
33 #           define HAVE_SSE2_INTRINSICS
34 #           define USE_TARGET_ATTRIBUTE
35 #       endif
36 #   endif
37 #endif
38 
39 #ifdef HAVE_SSE2_INTRINSICS
40 #ifdef HAVE_IMMINTRIN_H
41 #include <immintrin.h>
42 #else
43 #include <emmintrin.h>
44 #endif
45 #endif /* HAVE_SSE2_INTRINSICS */
46 
47 #include <math.h>
48 
49 #ifdef HAVE_VISIBILITY
50   #define LIBSAMPLERATE_DLL_PRIVATE __attribute__ ((visibility ("hidden")))
51 #elif defined (__APPLE__)
52   #define LIBSAMPLERATE_DLL_PRIVATE __private_extern__
53 #else
54   #define LIBSAMPLERATE_DLL_PRIVATE
55 #endif
56 
57 #define	SRC_MAX_RATIO			256
58 #define	SRC_MAX_RATIO_STR		"256"
59 
60 #define	SRC_MIN_RATIO_DIFF		(1e-20)
61 
62 #ifndef MAX
63 #define	MAX(a,b)	(((a) > (b)) ? (a) : (b))
64 #endif
65 
66 #ifndef MIN
67 #define	MIN(a,b)	(((a) < (b)) ? (a) : (b))
68 #endif
69 
70 #define	ARRAY_LEN(x)			((int) (sizeof (x) / sizeof ((x) [0])))
71 #define OFFSETOF(type,member)	((int) (&((type*) 0)->member))
72 
73 #define	MAKE_MAGIC(a,b,c,d,e,f)	((a) + ((b) << 4) + ((c) << 8) + ((d) << 12) + ((e) << 16) + ((f) << 20))
74 
75 /*
76 ** Inspiration : http://sourcefrog.net/weblog/software/languages/C/unused.html
77 */
78 #ifdef UNUSED
79 #elif defined (__GNUC__)
80 #	define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
81 #elif defined (__LCLINT__)
82 #	define UNUSED(x) /*@unused@*/ x
83 #else
84 #	define UNUSED(x) x
85 #endif
86 
87 #ifdef __GNUC__
88 #	define WARN_UNUSED	__attribute__ ((warn_unused_result))
89 #else
90 #	define WARN_UNUSED
91 #endif
92 
93 #include "samplerate.h"
94 
95 enum
96 {	SRC_FALSE	= 0,
97 	SRC_TRUE	= 1,
98 } ;
99 
100 enum SRC_MODE
101 {
102 	SRC_MODE_PROCESS	= 0,
103 	SRC_MODE_CALLBACK	= 1
104 } ;
105 
106 typedef enum SRC_ERROR
107 {
108 	SRC_ERR_NO_ERROR = 0,
109 
110 	SRC_ERR_MALLOC_FAILED,
111 	SRC_ERR_BAD_STATE,
112 	SRC_ERR_BAD_DATA,
113 	SRC_ERR_BAD_DATA_PTR,
114 	SRC_ERR_NO_PRIVATE,
115 	SRC_ERR_BAD_SRC_RATIO,
116 	SRC_ERR_BAD_PROC_PTR,
117 	SRC_ERR_SHIFT_BITS,
118 	SRC_ERR_FILTER_LEN,
119 	SRC_ERR_BAD_CONVERTER,
120 	SRC_ERR_BAD_CHANNEL_COUNT,
121 	SRC_ERR_SINC_BAD_BUFFER_LEN,
122 	SRC_ERR_SIZE_INCOMPATIBILITY,
123 	SRC_ERR_BAD_PRIV_PTR,
124 	SRC_ERR_BAD_SINC_STATE,
125 	SRC_ERR_DATA_OVERLAP,
126 	SRC_ERR_BAD_CALLBACK,
127 	SRC_ERR_BAD_MODE,
128 	SRC_ERR_NULL_CALLBACK,
129 	SRC_ERR_NO_VARIABLE_RATIO,
130 	SRC_ERR_SINC_PREPARE_DATA_BAD_LEN,
131 	SRC_ERR_BAD_INTERNAL_STATE,
132 
133 	/* This must be the last error number. */
134 	SRC_ERR_MAX_ERROR
135 } SRC_ERROR ;
136 
137 typedef struct SRC_STATE_VT_tag
138 {
139 	/* Varispeed process function. */
140 	SRC_ERROR		(*vari_process) (SRC_STATE *state, SRC_DATA *data) ;
141 
142 	/* Constant speed process function. */
143 	SRC_ERROR		(*const_process) (SRC_STATE *state, SRC_DATA *data) ;
144 
145 	/* State reset. */
146 	void			(*reset) (SRC_STATE *state) ;
147 
148 	/* State clone. */
149 	SRC_STATE		*(*copy) (SRC_STATE *state) ;
150 
151 	/* State close. */
152 	void			(*close) (SRC_STATE *state) ;
153 } SRC_STATE_VT ;
154 
155 struct SRC_STATE_tag
156 {
157 	SRC_STATE_VT *vt ;
158 
159 	double	last_ratio, last_position ;
160 
161 	SRC_ERROR	error ;
162 	int		channels ;
163 
164 	/* SRC_MODE_PROCESS or SRC_MODE_CALLBACK */
165 	enum SRC_MODE	mode ;
166 
167 	/* Data specific to SRC_MODE_CALLBACK. */
168 	src_callback_t	callback_func ;
169 	void			*user_callback_data ;
170 	long			saved_frames ;
171 	const float		*saved_data ;
172 
173 	/* Pointer to data to converter specific data. */
174 	void	*private_data ;
175 } ;
176 
177 /* In src_sinc.c */
178 const char* sinc_get_name (int src_enum) ;
179 const char* sinc_get_description (int src_enum) ;
180 
181 SRC_STATE *sinc_state_new (int converter_type, int channels, SRC_ERROR *error) ;
182 
183 /* In src_linear.c */
184 const char* linear_get_name (int src_enum) ;
185 const char* linear_get_description (int src_enum) ;
186 
187 SRC_STATE *linear_state_new (int channels, SRC_ERROR *error) ;
188 
189 /* In src_zoh.c */
190 const char* zoh_get_name (int src_enum) ;
191 const char* zoh_get_description (int src_enum) ;
192 
193 SRC_STATE *zoh_state_new (int channels, SRC_ERROR *error) ;
194 
195 /*----------------------------------------------------------
196 ** SIMD optimized math functions.
197 */
198 
199 #ifdef HAVE_SSE2_INTRINSICS
200 static inline int
201 #ifdef USE_TARGET_ATTRIBUTE
202 __attribute__((target("sse2")))
203 #endif
psf_lrintf(float x)204 psf_lrintf (float x)
205 {
206 	return _mm_cvtss_si32 (_mm_load_ss (&x)) ;
207 }
208 static inline int
209 #ifdef USE_TARGET_ATTRIBUTE
210 __attribute__((target("sse2")))
211 #endif
psf_lrint(double x)212 psf_lrint (double x)
213 {
214 	return _mm_cvtsd_si32 (_mm_load_sd (&x)) ;
215 }
216 
217 #else
218 
psf_lrintf(float x)219 static inline int psf_lrintf (float x)
220 {
221 	return lrintf (x) ;
222 } /* psf_lrintf */
223 
psf_lrint(double x)224 static inline int psf_lrint (double x)
225 {
226 	return lrint (x) ;
227 } /* psf_lrint */
228 #endif
229 
230 /*----------------------------------------------------------
231 **	Common static inline functions.
232 */
233 
234 static inline double
fmod_one(double x)235 fmod_one (double x)
236 {	double res ;
237 
238 	res = x - psf_lrint (x) ;
239 	if (res < 0.0)
240 		return res + 1.0 ;
241 
242 	return res ;
243 } /* fmod_one */
244 
245 static inline int
is_bad_src_ratio(double ratio)246 is_bad_src_ratio (double ratio)
247 {	return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
248 } /* is_bad_src_ratio */
249 
250 
251 #endif	/* COMMON_H_INCLUDED */
252 
253