1 /* libSoX Internal header
2 *
3 * This file is meant for libSoX internal use only
4 *
5 * Copyright 2001-2012 Chris Bagwell and SoX Contributors
6 *
7 * This source code is freely redistributable and may be used for
8 * any purpose. This copyright notice must be maintained.
9 * Chris Bagwell And SoX Contributors are not responsible for
10 * the consequences of using this software.
11 */
12
13 #ifndef SOX_I_H
14 #define SOX_I_H
15
16 #include "soxomp.h" /* Note: soxomp.h includes soxconfig.h */
17 #include "sox.h"
18
19 #if defined HAVE_FMEMOPEN
20 #define _GNU_SOURCE
21 #endif
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include "util.h"
28
29 #if defined(LSX_EFF_ALIAS)
30 #undef lsx_debug
31 #undef lsx_fail
32 #undef lsx_report
33 #undef lsx_warn
34 #define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug_impl
35 #define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail_impl
36 #define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report_impl
37 #define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn_impl
38 #endif
39
40 #define RANQD1 ranqd1(sox_globals.ranqd1)
41 #define DRANQD1 dranqd1(sox_globals.ranqd1)
42
43 typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
44 typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
45 lsx_enum_item const * lsx_get_wave_enum(void);
46
47 /* Define fseeko and ftello for platforms lacking them */
48 #ifndef HAVE_FSEEKO
49 #define fseeko fseek
50 #define ftello ftell
51 #endif
52
53 #ifdef _FILE_OFFSET_BITS
54 assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
55 #endif
56
57 FILE * lsx_tmpfile(void);
58
59 void lsx_debug_more_impl(char const * fmt, ...) LSX_PRINTF12;
60 void lsx_debug_most_impl(char const * fmt, ...) LSX_PRINTF12;
61
62 #define lsx_debug_more sox_get_globals()->subsystem=__FILE__,lsx_debug_more_impl
63 #define lsx_debug_most sox_get_globals()->subsystem=__FILE__,lsx_debug_most_impl
64
65 /* Digitise one cycle of a wave and store it as
66 * a table of samples of a specified data-type.
67 */
68 void lsx_generate_wave_table(
69 lsx_wave_t wave_type,
70 sox_data_t data_type,
71 void * table, /* Really of type indicated by data_type. */
72 size_t table_size, /* Number of points on the x-axis. */
73 double min, /* Minimum value on the y-axis. (e.g. -1) */
74 double max, /* Maximum value on the y-axis. (e.g. +1) */
75 double phase); /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
76 char const * lsx_parsesamples(sox_rate_t rate, const char *str, uint64_t *samples, int def);
77 char const * lsx_parseposition(sox_rate_t rate, const char *str, uint64_t *samples, uint64_t latest, uint64_t end, int def);
78 int lsx_parse_note(char const * text, char * * end_ptr);
79 double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
80 #define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
81 FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename, sox_bool text_mode);
82
83 void lsx_prepare_spline3(double const * x, double const * y, int n,
84 double start_1d, double end_1d, double * y_2d);
85 double lsx_spline3(double const * x, double const * y, double const * y_2d,
86 int n, double x1);
87
88 double lsx_bessel_I_0(double x);
89 int lsx_set_dft_length(int num_taps);
90 void init_fft_cache(void);
91 void clear_fft_cache(void);
92 #define lsx_is_power_of_2(x) !(x < 2 || (x & (x - 1)))
93 void lsx_safe_rdft(int len, int type, double * d);
94 void lsx_safe_cdft(int len, int type, double * d);
95 void lsx_power_spectrum(int n, double const * in, double * out);
96 void lsx_power_spectrum_f(int n, float const * in, float * out);
97 void lsx_apply_hann_f(float h[], const int num_points);
98 void lsx_apply_hann(double h[], const int num_points);
99 void lsx_apply_hamming(double h[], const int num_points);
100 void lsx_apply_bartlett(double h[], const int num_points);
101 void lsx_apply_blackman(double h[], const int num_points, double alpha);
102 void lsx_apply_blackman_nutall(double h[], const int num_points);
103 double lsx_kaiser_beta(double att, double tr_bw);
104 void lsx_apply_kaiser(double h[], const int num_points, double beta);
105 void lsx_apply_dolph(double h[], const int num_points, double att);
106 double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
107 double scale, sox_bool dc_norm);
108 void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
109 double * lsx_design_lpf(
110 double Fp, /* End of pass-band */
111 double Fs, /* Start of stop-band */
112 double Fn, /* Nyquist freq; e.g. 0.5, 1, PI; < 0: dummy run */
113 double att, /* Stop-band attenuation in dB */
114 int * num_taps, /* 0: value will be estimated */
115 int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
116 double beta); /* <0: value will be estimated */
117 void lsx_fir_to_phase(double * * h, int * len,
118 int * post_len, double phase0);
119 void lsx_plot_fir(double * h, int num_points, sox_rate_t rate, sox_plot_t type, char const * title, double y1, double y2);
120 void lsx_save_samples(sox_sample_t * const dest, double const * const src,
121 size_t const n, sox_uint64_t * const clips);
122 void lsx_load_samples(double * const dest, sox_sample_t const * const src,
123 size_t const n);
124
125 #ifdef HAVE_BYTESWAP_H
126 #include <byteswap.h>
127 #define lsx_swapw(x) bswap_16(x)
128 #define lsx_swapdw(x) bswap_32(x)
129 #elif defined(_MSC_VER)
130 #define lsx_swapw(x) _byteswap_ushort(x)
131 #define lsx_swapdw(x) _byteswap_ulong(x)
132 #else
133 #define lsx_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
134 #define lsx_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
135 #endif
136
137
138
139 /*------------------------ Implemented in libsoxio.c -------------------------*/
140
141 /* Read and write basic data types from "ft" stream. */
142 size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len);
143 int lsx_skipbytes(sox_format_t * ft, size_t n);
144 int lsx_padbytes(sox_format_t * ft, size_t n);
145 size_t lsx_writebuf(sox_format_t * ft, void const *buf, size_t len);
146 int lsx_reads(sox_format_t * ft, char *c, size_t len);
147 int lsx_writes(sox_format_t * ft, char const * c);
148 void lsx_set_signal_defaults(sox_format_t * ft);
149 #define lsx_writechars(ft, chars, len) (lsx_writebuf(ft, chars, len) == len? SOX_SUCCESS : SOX_EOF)
150
151 size_t lsx_read_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
152 size_t lsx_read_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
153 size_t lsx_read_df_buf(sox_format_t * ft, double *buf, size_t len);
154 size_t lsx_read_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
155 size_t lsx_read_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
156 size_t lsx_read_f_buf(sox_format_t * ft, float *buf, size_t len);
157 size_t lsx_read_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
158
159 size_t lsx_write_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
160 size_t lsx_write_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
161 size_t lsx_write_df_buf(sox_format_t * ft, double *buf, size_t len);
162 size_t lsx_write_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
163 size_t lsx_write_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
164 size_t lsx_write_f_buf(sox_format_t * ft, float *buf, size_t len);
165 size_t lsx_write_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
166
167 int lsx_read3(sox_format_t * ft, sox_uint24_t * u3);
168 int lsx_readb(sox_format_t * ft, uint8_t * ub);
169 int lsx_readchars(sox_format_t * ft, char * chars, size_t len);
170 int lsx_readdf(sox_format_t * ft, double * d);
171 int lsx_readdw(sox_format_t * ft, uint32_t * udw);
172 int lsx_readqw(sox_format_t * ft, uint64_t * udw);
173 int lsx_readf(sox_format_t * ft, float * f);
174 int lsx_readw(sox_format_t * ft, uint16_t * uw);
175
176 #if 1 /* FIXME: use defines */
lsx_readsb(sox_format_t * ft,int8_t * sb)177 UNUSED static int lsx_readsb(sox_format_t * ft, int8_t * sb)
178 {return lsx_readb(ft, (uint8_t *)sb);}
lsx_readsw(sox_format_t * ft,int16_t * sw)179 UNUSED static int lsx_readsw(sox_format_t * ft, int16_t * sw)
180 {return lsx_readw(ft, (uint16_t *)sw);}
181 #else
182 #define lsx_readsb(ft, sb) lsx_readb(ft, (uint8_t *)sb)
183 #define lsx_readsw(ft, sw) lsx_readb(ft, (uint16_t *)sw)
184 #endif
185
186 int lsx_read_fields(sox_format_t *ft, uint32_t *len, const char *spec, ...);
187
188 int lsx_write3(sox_format_t * ft, unsigned u3);
189 int lsx_writeb(sox_format_t * ft, unsigned ub);
190 int lsx_writedf(sox_format_t * ft, double d);
191 int lsx_writedw(sox_format_t * ft, unsigned udw);
192 int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
193 int lsx_writef(sox_format_t * ft, double f);
194 int lsx_writew(sox_format_t * ft, unsigned uw);
195
196 int lsx_writesb(sox_format_t * ft, signed);
197 int lsx_writesw(sox_format_t * ft, signed);
198
199 int lsx_eof(sox_format_t * ft);
200 int lsx_error(sox_format_t * ft);
201 int lsx_flush(sox_format_t * ft);
202 int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
203 int lsx_unreadb(sox_format_t * ft, unsigned ub);
204 /* uint64_t lsx_filelength(sox_format_t * ft); Temporarily Moved to sox.h. */
205 off_t lsx_tell(sox_format_t * ft);
206 void lsx_clearerr(sox_format_t * ft);
207 void lsx_rewind(sox_format_t * ft);
208
209 int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
210
211 void lsx_fail_errno(sox_format_t *, int, const char *, ...)
212 #ifdef __GNUC__
213 __attribute__ ((format (printf, 3, 4)));
214 #else
215 ;
216 #endif
217
218 typedef struct sox_formats_globals { /* Global parameters (for formats) */
219 sox_globals_t * global_info;
220 } sox_formats_globals;
221
222
223
224 /*------------------------------ File Handlers -------------------------------*/
225
226 int lsx_check_read_params(sox_format_t * ft, unsigned channels,
227 sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
228 uint64_t num_samples, sox_bool check_length);
229 #define LSX_FORMAT_HANDLER(name) \
230 sox_format_handler_t const * lsx_##name##_format_fn(void); \
231 sox_format_handler_t const * lsx_##name##_format_fn(void)
232 #define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
233
234 /* Raw I/O */
235 int lsx_rawstartread(sox_format_t * ft);
236 size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
237 int lsx_rawstopread(sox_format_t * ft);
238 int lsx_rawstartwrite(sox_format_t * ft);
239 size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
240 int lsx_rawseek(sox_format_t * ft, uint64_t offset);
241 int lsx_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned bits_per_sample);
242 #define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
243 #define lsx_rawstartwrite lsx_rawstartread
244 #define lsx_rawstopread NULL
245 #define lsx_rawstopwrite NULL
246
247 extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
248
249 char * lsx_cat_comments(sox_comments_t comments);
250
251 /*--------------------------------- Effects ----------------------------------*/
252
253 int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
254 sox_sample_t * obuf, size_t * isamp, size_t * osamp);
255 int lsx_usage(sox_effect_t * effp);
256 char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
257 #define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
258 #include "effects.h"
259 #undef EFFECT
260
261 #define NUMERIC_PARAMETER(name, min, max) { \
262 char * end_ptr; \
263 double d; \
264 if (argc == 0) break; \
265 d = strtod(*argv, &end_ptr); \
266 if (end_ptr != *argv) { \
267 if (d < min || d > max || *end_ptr != '\0') {\
268 lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
269 return lsx_usage(effp); \
270 } \
271 p->name = d; \
272 --argc, ++argv; \
273 } \
274 }
275
276 #define TEXTUAL_PARAMETER(name, enum_table) { \
277 lsx_enum_item const * e; \
278 if (argc == 0) break; \
279 e = lsx_find_enum_text(*argv, enum_table, 0); \
280 if (e != NULL) { \
281 p->name = e->value; \
282 --argc, ++argv; \
283 } \
284 }
285
286 #define GETOPT_LOCAL_NUMERIC(state, ch, name, min, max) case ch:{ \
287 char * end_ptr; \
288 double d = strtod(state.arg, &end_ptr); \
289 if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
290 lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
291 return lsx_usage(effp); \
292 } \
293 name = d; \
294 break; \
295 }
296 #define GETOPT_NUMERIC(state, ch, name, min, max) GETOPT_LOCAL_NUMERIC(state, ch, p->name, min, max)
297
298 int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
299
300 int lsx_effects_init(void);
301 int lsx_effects_quit(void);
302
303 /*--------------------------------- Dynamic Library ----------------------------------*/
304
305 #if defined(HAVE_LIBLTDL)
306 #include <ltdl.h>
307 typedef lt_dlhandle lsx_dlhandle;
308 #else
309 struct lsx_dlhandle_tag;
310 typedef struct lsx_dlhandle_tag *lsx_dlhandle;
311 #endif
312
313 typedef void (*lsx_dlptr)(void);
314
315 typedef struct lsx_dlfunction_info
316 {
317 const char* name;
318 lsx_dlptr static_func;
319 lsx_dlptr stub_func;
320 } lsx_dlfunction_info;
321
322 int lsx_open_dllibrary(
323 int show_error_on_failure,
324 const char* library_description,
325 const char * const library_names[],
326 const lsx_dlfunction_info func_infos[],
327 lsx_dlptr selected_funcs[],
328 lsx_dlhandle* pdl);
329
330 void lsx_close_dllibrary(
331 lsx_dlhandle dl);
332
333 #define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
334
335 #define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
336 func_return (*func_ptr) func_args;
337
338 #define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
339 func_return func_name func_args;
340
341 /* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
342 variable, declares the corresponding function pointer variables and the
343 dlhandle variable. */
344 #define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
345 LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
346 lsx_dlhandle dlhandle
347
348 /* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
349 functions. */
350 #define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
351 LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
352
353 #define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
354 { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
355
356 #define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
357 (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
358
359 /* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
360 a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
361 the name of the dlhandle variable, the name of the structure that contains
362 the function pointer and dlhandle variables, and the name of the variable in
363 which the result of the lsx_open_dllibrary call should be stored. This will
364 call lsx_open_dllibrary and copy the resulting function pointers into the
365 structure members. If the library cannot be opened, show a failure message. */
366 #define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
367 LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
368
369 /* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
370 a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
371 the name of the dlhandle variable, the name of the structure that contains
372 the function pointer and dlhandle variables, and the name of the variable in
373 which the result of the lsx_open_dllibrary call should be stored. This will
374 call lsx_open_dllibrary and copy the resulting function pointers into the
375 structure members. If the library cannot be opened, show a report or a failure
376 message, depending on whether error_on_failure is non-zero. */
377 #define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
378 do { \
379 lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
380 LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
381 {NULL,NULL,NULL} }; \
382 int lsx_dlfunction_open_library_index = 0; \
383 lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
384 (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
385 LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
386 } while(0)
387
388 #define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
389 lsx_close_dllibrary((ptr_container)->dlhandle)
390
391 /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
392 expected to be available at link time. If not present, link will fail. */
393 #define LSX_DLENTRY_STATIC(f,x, ret, func, args) f(x, ret, func, args, func, NULL, func)
394
395 /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
396 not be available at link time (and if present, the link time version will
397 not be used). func will be loaded via dlsym. If this function is not
398 found in the shared library, the shared library will not be used. */
399 #define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
400
401 /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
402 be available at link time (and if present, the link time version will not
403 be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
404 if not found, the shared library will still be used if all of the
405 non-stub functions are found. If the function is not found via dlsym (or
406 if we are not loading any shared libraries), the stub will be used. This
407 assumes that the name of the stub function is the name of the function +
408 "_stub". */
409 #define LSX_DLENTRY_STUB(f,x, ret, func, args) f(x, ret, func, args, NULL, func##_stub, func)
410
411 /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
412 stub. Assumes that the name of the stub function is the name of the
413 function + "_stub". */
414 #define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
415
416 #endif
417