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