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_write3(sox_format_t * ft, unsigned u3);
187 int lsx_writeb(sox_format_t * ft, unsigned ub);
188 int lsx_writedf(sox_format_t * ft, double d);
189 int lsx_writedw(sox_format_t * ft, unsigned udw);
190 int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
191 int lsx_writef(sox_format_t * ft, double f);
192 int lsx_writew(sox_format_t * ft, unsigned uw);
193
194 int lsx_writesb(sox_format_t * ft, signed);
195 int lsx_writesw(sox_format_t * ft, signed);
196
197 int lsx_eof(sox_format_t * ft);
198 int lsx_error(sox_format_t * ft);
199 int lsx_flush(sox_format_t * ft);
200 int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
201 int lsx_unreadb(sox_format_t * ft, unsigned ub);
202 /* uint64_t lsx_filelength(sox_format_t * ft); Temporarily Moved to sox.h. */
203 off_t lsx_tell(sox_format_t * ft);
204 void lsx_clearerr(sox_format_t * ft);
205 void lsx_rewind(sox_format_t * ft);
206
207 int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
208
209 void lsx_fail_errno(sox_format_t *, int, const char *, ...)
210 #ifdef __GNUC__
211 __attribute__ ((format (printf, 3, 4)));
212 #else
213 ;
214 #endif
215
216 typedef struct sox_formats_globals { /* Global parameters (for formats) */
217 sox_globals_t * global_info;
218 } sox_formats_globals;
219
220
221
222 /*------------------------------ File Handlers -------------------------------*/
223
224 int lsx_check_read_params(sox_format_t * ft, unsigned channels,
225 sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
226 uint64_t num_samples, sox_bool check_length);
227 #define LSX_FORMAT_HANDLER(name) \
228 sox_format_handler_t const * lsx_##name##_format_fn(void); \
229 sox_format_handler_t const * lsx_##name##_format_fn(void)
230 #define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
231
232 /* Raw I/O */
233 int lsx_rawstartread(sox_format_t * ft);
234 size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
235 int lsx_rawstopread(sox_format_t * ft);
236 int lsx_rawstartwrite(sox_format_t * ft);
237 size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
238 int lsx_rawseek(sox_format_t * ft, uint64_t offset);
239 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);
240 #define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
241 #define lsx_rawstartwrite lsx_rawstartread
242 #define lsx_rawstopread NULL
243 #define lsx_rawstopwrite NULL
244
245 extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
246
247 char * lsx_cat_comments(sox_comments_t comments);
248
249 /*--------------------------------- Effects ----------------------------------*/
250
251 int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
252 sox_sample_t * obuf, size_t * isamp, size_t * osamp);
253 int lsx_usage(sox_effect_t * effp);
254 char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
255 #define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
256 #include "effects.h"
257 #undef EFFECT
258
259 #define NUMERIC_PARAMETER(name, min, max) { \
260 char * end_ptr; \
261 double d; \
262 if (argc == 0) break; \
263 d = strtod(*argv, &end_ptr); \
264 if (end_ptr != *argv) { \
265 if (d < min || d > max || *end_ptr != '\0') {\
266 lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
267 return lsx_usage(effp); \
268 } \
269 p->name = d; \
270 --argc, ++argv; \
271 } \
272 }
273
274 #define TEXTUAL_PARAMETER(name, enum_table) { \
275 lsx_enum_item const * e; \
276 if (argc == 0) break; \
277 e = lsx_find_enum_text(*argv, enum_table, 0); \
278 if (e != NULL) { \
279 p->name = e->value; \
280 --argc, ++argv; \
281 } \
282 }
283
284 #define GETOPT_LOCAL_NUMERIC(state, ch, name, min, max) case ch:{ \
285 char * end_ptr; \
286 double d = strtod(state.arg, &end_ptr); \
287 if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
288 lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
289 return lsx_usage(effp); \
290 } \
291 name = d; \
292 break; \
293 }
294 #define GETOPT_NUMERIC(state, ch, name, min, max) GETOPT_LOCAL_NUMERIC(state, ch, p->name, min, max)
295
296 int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
297
298 int lsx_effects_init(void);
299 int lsx_effects_quit(void);
300
301 /*--------------------------------- Dynamic Library ----------------------------------*/
302
303 #if defined(HAVE_WIN32_LTDL_H)
304 #include "win32-ltdl.h"
305 #define HAVE_LIBLTDL 1
306 typedef lt_dlhandle lsx_dlhandle;
307 #elif defined(HAVE_LIBLTDL)
308 #include <ltdl.h>
309 typedef lt_dlhandle lsx_dlhandle;
310 #else
311 struct lsx_dlhandle_tag;
312 typedef struct lsx_dlhandle_tag *lsx_dlhandle;
313 #endif
314
315 typedef void (*lsx_dlptr)(void);
316
317 typedef struct lsx_dlfunction_info
318 {
319 const char* name;
320 lsx_dlptr static_func;
321 lsx_dlptr stub_func;
322 } lsx_dlfunction_info;
323
324 int lsx_open_dllibrary(
325 int show_error_on_failure,
326 const char* library_description,
327 const char * const library_names[],
328 const lsx_dlfunction_info func_infos[],
329 lsx_dlptr selected_funcs[],
330 lsx_dlhandle* pdl);
331
332 void lsx_close_dllibrary(
333 lsx_dlhandle dl);
334
335 #define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
336
337 #define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
338 func_return (*func_ptr) func_args;
339
340 #define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
341 func_return func_name func_args;
342
343 /* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
344 variable, declares the corresponding function pointer variables and the
345 dlhandle variable. */
346 #define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
347 LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
348 lsx_dlhandle dlhandle
349
350 /* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
351 functions. */
352 #define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
353 LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
354
355 #define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
356 { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
357
358 #define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
359 (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
360
361 /* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
362 a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
363 the name of the dlhandle variable, the name of the structure that contains
364 the function pointer and dlhandle variables, and the name of the variable in
365 which the result of the lsx_open_dllibrary call should be stored. This will
366 call lsx_open_dllibrary and copy the resulting function pointers into the
367 structure members. If the library cannot be opened, show a failure message. */
368 #define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
369 LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
370
371 /* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
372 a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
373 the name of the dlhandle variable, the name of the structure that contains
374 the function pointer and dlhandle variables, and the name of the variable in
375 which the result of the lsx_open_dllibrary call should be stored. This will
376 call lsx_open_dllibrary and copy the resulting function pointers into the
377 structure members. If the library cannot be opened, show a report or a failure
378 message, depending on whether error_on_failure is non-zero. */
379 #define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
380 do { \
381 lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
382 LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
383 {NULL,NULL,NULL} }; \
384 int lsx_dlfunction_open_library_index = 0; \
385 lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
386 (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); \
387 LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
388 } while(0)
389
390 #define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
391 lsx_close_dllibrary((ptr_container)->dlhandle)
392
393 /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
394 expected to be available at link time. If not present, link will fail. */
395 #define LSX_DLENTRY_STATIC(f,x, ret, func, args) f(x, ret, func, args, func, NULL, func)
396
397 /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
398 not be available at link time (and if present, the link time version will
399 not be used). func will be loaded via dlsym. If this function is not
400 found in the shared library, the shared library will not be used. */
401 #define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
402
403 /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
404 be available at link time (and if present, the link time version will not
405 be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
406 if not found, the shared library will still be used if all of the
407 non-stub functions are found. If the function is not found via dlsym (or
408 if we are not loading any shared libraries), the stub will be used. This
409 assumes that the name of the stub function is the name of the function +
410 "_stub". */
411 #define LSX_DLENTRY_STUB(f,x, ret, func, args) f(x, ret, func, args, NULL, func##_stub, func)
412
413 /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
414 stub. Assumes that the name of the stub function is the name of the
415 function + "_stub". */
416 #define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
417
418 #endif
419