ref: 7e6e33818acc4623d440ed1d6371760cf84d6ad3
dir: /src/sox.h/
/* * libSoX Library Public Interface * * Copyright 1999-2007 Chris Bagwell and SoX Contributors. * * This source code is freely redistributable and may be used for * any purpose. This copyright notice must be maintained. * Chris Bagwell And SoX Contributors are not responsible for * the consequences of using this software. */ #ifndef SOX_H #define SOX_H #include <stddef.h> /* Ensure NULL etc. are available throughout SoX */ #include <stdio.h> #include <stdlib.h> #include <limits.h> #include "soxstdint.h" /* Avoid warnings about unused parameters. */ #ifdef __GNUC__ #define UNUSED __attribute__ ((unused)) #else #define UNUSED #endif /* The following is the API version of libSoX. It is not meant * to follow the version number of SoX but it has historically. * Please do not count on these numbers being in sync. * The following is at 14.0.1 */ #define SOX_LIB_VERSION_CODE 0x0e0100 #define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) const char *sox_version(void); /* Returns version number */ #define SOX_SUCCESS 0 #define SOX_EOF (-1) /* End Of File or other error */ /* libSoX specific error codes. The rest directly map from errno. */ #define SOX_EHDR 2000 /* Invalid Audio Header */ #define SOX_EFMT 2001 /* Unsupported data format */ #define SOX_ERATE 2002 /* Unsupported rate for format */ #define SOX_ENOMEM 2003 /* Can't alloc memory */ #define SOX_EPERM 2004 /* Operation not permitted */ #define SOX_ENOTSUP 2005 /* Operation not supported */ #define SOX_EINVAL 2006 /* Invalid argument */ #define SOX_EFFMT 2007 /* Unsupported file format */ /* Boolean type, assignment (but not necessarily binary) compatible with * C++ bool */ typedef enum {sox_false, sox_true} sox_bool; typedef int32_t int24_t; /* But beware of the extra byte. */ typedef uint32_t uint24_t; /* ditto */ #define SOX_INT_MIN(bits) (1 <<((bits)-1)) #define SOX_INT_MAX(bits) (-1U>>(33-(bits))) #define SOX_UINT_MAX(bits) (SOX_INT_MIN(bits)|SOX_INT_MAX(bits)) #define SOX_INT8_MAX SOX_INT_MAX(8) #define SOX_INT16_MAX SOX_INT_MAX(16) #define SOX_INT24_MAX SOX_INT_MAX(24) #define SOX_INT32_MAX SOX_INT_MAX(32) #define SOX_INT64_MAX 0x7fffffffffffffffLL /* Not in use yet */ typedef int32_t sox_sample_t; /* Minimum and maximum values a sample can hold. */ #define SOX_SAMPLE_PRECISION 32 #define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32) #define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32) /* Conversions: Linear PCM <--> sox_sample_t * * I/O I/O sox_sample_t Clips? I/O sox_sample_t Clips? * Format Minimum Minimum I O Maximum Maximum I O * ------ --------- ------------ -- -- -------- ------------ -- -- * Float -1 -1.00000000047 y y 1 1 y n * Int8 -128 -128 n n 127 127.9999999 n y * Int16 -32768 -32768 n n 32767 32767.99998 n y * Int24 -8388608 -8388608 n n 8388607 8388607.996 n y * Int32 -2147483648 -2147483648 n n 2147483647 2147483647 n n * * Conversions are as accurate as possible (with rounding). * * Rounding: halves toward +inf, all others to nearest integer. * * Clips? shows whether on not there is the possibility of a conversion * clipping to the minimum or maximum value when inputing from or outputing * to a given type. * * Unsigned integers are converted to and from signed integers by flipping * the upper-most bit then treating them as signed integers. */ /* Temporary variables to prevent multiple evaluation of macro arguments: */ static sox_sample_t sox_macro_temp_sample UNUSED; static double sox_macro_temp_double UNUSED; #define SOX_SAMPLE_NEG SOX_INT_MIN(32) #define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \ (uint##bits##_t)( \ sox_macro_temp_sample=(d), \ sox_macro_temp_sample>(sox_sample_t)(SOX_SAMPLE_MAX-(1U<<(31-bits)))? \ ++(clips),SOX_UINT_MAX(bits): \ ((uint32_t)(sox_macro_temp_sample^SOX_SAMPLE_NEG)+(1U<<(31-bits)))>>(32-bits)) #define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \ (int##bits##_t)(SOX_SAMPLE_TO_UNSIGNED(bits,d,clips)^SOX_INT_MIN(bits)) #define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits)) #define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG) #define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d) #define SOX_SIGNED_8BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(8,d) #define SOX_UNSIGNED_16BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(16,d) #define SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(16,d) #define SOX_UNSIGNED_24BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(24,d) #define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d) #define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG) #define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d) #define SOX_FLOAT_32BIT_TO_SAMPLE SOX_FLOAT_64BIT_TO_SAMPLE #define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_macro_temp_double=(d),sox_macro_temp_double<-1?++(clips),(-SOX_SAMPLE_MAX):sox_macro_temp_double>1?++(clips),SOX_SAMPLE_MAX:(sox_sample_t)((uint32_t)((double)(sox_macro_temp_double)*SOX_SAMPLE_MAX+(SOX_SAMPLE_MAX+.5))-SOX_SAMPLE_MAX)) #define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips) #define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips) #define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips) #define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips) #define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips) #define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips) #define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (uint32_t)((d)^SOX_SAMPLE_NEG) #define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (int32_t)(d) #define SOX_SAMPLE_TO_FLOAT_32BIT SOX_SAMPLE_TO_FLOAT_64BIT #define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) (sox_macro_temp_sample=(d),sox_macro_temp_sample==SOX_SAMPLE_MIN?++(clips),-1.0:((double)(sox_macro_temp_sample)*(1.0/SOX_SAMPLE_MAX))) /* MACRO to clip a data type that is greater then sox_sample_t to * sox_sample_t's limits and increment a counter if clipping occurs.. */ #define SOX_SAMPLE_CLIP_COUNT(samp, clips) \ do { \ if (samp > SOX_SAMPLE_MAX) \ { samp = SOX_SAMPLE_MAX; clips++; } \ else if (samp < SOX_SAMPLE_MIN) \ { samp = SOX_SAMPLE_MIN; clips++; } \ } while (0) /* Rvalue MACRO to round and clip a double to a sox_sample_t, * and increment a counter if clipping occurs. */ #define SOX_ROUND_CLIP_COUNT(d, clips) \ ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \ : (d) >= SOX_SAMPLE_MAX + 0.5? ++(clips), SOX_SAMPLE_MAX: (d) + 0.5) /* Rvalue MACRO to clip an integer to a given number of bits * and increment a counter if clipping occurs. */ #define SOX_INTEGER_CLIP_COUNT(bits,i,clips) ( \ (i) >(1 << ((bits)-1))- 1? ++(clips),(1 << ((bits)-1))- 1 : \ (i) <-1 << ((bits)-1) ? ++(clips),-1 << ((bits)-1) : (i)) #define SOX_16BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(16,i,clips) #define SOX_24BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(24,i,clips) #include <stddef.h> typedef size_t sox_size_t; #define SOX_SIZE_MAX (sox_size_t)(-1) typedef ptrdiff_t sox_ssize_t; typedef double sox_rate_t; typedef enum { SOX_ENCODING_UNKNOWN , SOX_ENCODING_SIGN2 , /* signed linear 2's comp: Mac */ SOX_ENCODING_UNSIGNED , /* unsigned linear: Sound Blaster */ SOX_ENCODING_FLOAT , /* floating point (binary format) */ SOX_ENCODING_FLOAT_TEXT, /* floating point (text format) */ SOX_ENCODING_FLAC , /* FLAC compression */ SOX_ENCODING_HCOM , /* */ SOX_ENCODING_LOSSLESS , /* Lossless above, lossy below */ SOX_ENCODING_ULAW , /* u-law signed logs: US telephony, SPARC */ SOX_ENCODING_ALAW , /* A-law signed logs: non-US telephony */ SOX_ENCODING_G721 , /* G.721 4-bit ADPCM */ SOX_ENCODING_G723 , /* G.723 3 or 5 bit ADPCM */ SOX_ENCODING_CL_ADPCM , /* Creative Labs 8 --> 2,3,4 bit Compressed PCM */ SOX_ENCODING_CL_ADPCM16, /* Creative Labs 16 --> 4 bit Compressed PCM */ SOX_ENCODING_MS_ADPCM , /* Microsoft Compressed PCM */ SOX_ENCODING_IMA_ADPCM , /* IMA Compressed PCM */ SOX_ENCODING_OKI_ADPCM , /* Dialogic/OKI Compressed PCM */ SOX_ENCODING_GSM , /* GSM 6.10 33byte frame lossy compression */ SOX_ENCODING_MP3 , /* MP3 compression */ SOX_ENCODING_VORBIS , /* Vorbis compression */ SOX_ENCODING_AMR_WB , /* AMR-WB compression */ SOX_ENCODING_AMR_NB , /* AMR-NB compression */ SOX_ENCODING_CVSD , /* */ SOX_ENCODING_LPC10 , /* */ SOX_ENCODINGS /* End of list marker */ } sox_encoding_t; typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t; typedef enum {SOX_OPTION_NO, SOX_OPTION_YES, SOX_OPTION_DEFAULT} sox_option_t; typedef struct { /* Signal parameters; 0 if unknown */ sox_rate_t rate; /* sampling rate */ unsigned channels; /* number of sound channels */ unsigned precision; /* in bits */ } sox_signalinfo_t; typedef struct { /* Encoding parameters */ sox_encoding_t encoding; /* format of sample numbers */ unsigned bits_per_sample; /* 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */ double compression; /* compression factor (where applicable) */ /* There is a delineation between these vars being tri-state and * effectively boolean. Logically the line falls between setting * them up (could be done in libSoX, or by the libSoX client) and * using them (in libSoX). libSoX's logic to set them up includes * knowledge of the machine default and the format default. (The * sox client logic adds to this a layer of overridability via user * options.) The physical delineation is in the somewhat * snappily-named libSoX function `set_endianness_if_not_already_set' * which is called at the right times (as files are openned) by the * libSoX core, not by the file handlers themselves. The file handlers * indicate to the libSoX core if they have a preference using * SOX_FILE_xxx flags. */ sox_option_t reverse_bytes; /* endiannesses... */ sox_option_t reverse_nibbles; sox_option_t reverse_bits; } sox_encodinginfo_t; /* Defaults for common hardware */ #define SOX_DEFAULT_CHANNELS 2 #define SOX_DEFAULT_RATE 48000 #define SOX_DEFAULT_PRECISION 16 #define SOX_DEFAULT_ENCODING SOX_ENCODING_SIGN2 /* Loop parameters */ typedef struct sox_loopinfo { sox_size_t start; /* first sample */ sox_size_t length; /* length */ unsigned int count; /* number of repeats, 0=forever */ unsigned char type; /* 0=no, 1=forward, 2=forward/back */ } sox_loopinfo_t; /* Instrument parameters */ /* vague attempt at generic information for sampler-specific info */ typedef struct sox_instrinfo { char MIDInote; /* for unity pitch playback */ char MIDIlow, MIDIhi;/* MIDI pitch-bend range */ char loopmode; /* semantics of loop data */ unsigned nloops; /* number of active loops (max SOX_MAX_NLOOPS) */ } sox_instrinfo_t; /* Loop modes, upper 4 bits mask the loop blass, lower 4 bits describe */ /* the loop behaviour, ie. single shot, bidirectional etc. */ #define SOX_LOOP_NONE 0 #define SOX_LOOP_8 32 /* 8 loops: don't know ?? */ #define SOX_LOOP_SUSTAIN_DECAY 64 /* AIFF style: one sustain & one decay loop */ /* * File buffer info. Holds info so that data can be read in blocks. */ typedef struct sox_fileinfo { char *buf; /* Pointer to data buffer */ size_t size; /* Size of buffer */ size_t count; /* Count read in to buffer */ size_t pos; /* Position in buffer */ } sox_fileinfo_t; /* * Handler structure for each format. */ typedef struct sox_format sox_format_t; typedef struct { unsigned sox_lib_version_code; /* Checked on load; must be 1st in struct*/ char const * description; char const * const * names; unsigned int flags; int (*startread)(sox_format_t * ft); sox_size_t (*read)(sox_format_t * ft, sox_sample_t *buf, sox_size_t len); int (*stopread)(sox_format_t * ft); int (*startwrite)(sox_format_t * ft); sox_size_t (*write)(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len); int (*stopwrite)(sox_format_t * ft); int (*seek)(sox_format_t * ft, sox_size_t offset); unsigned const * write_formats; sox_rate_t const * write_rates; } sox_format_handler_t; /* * Format information for input and output files. */ #define SOX_MAX_FILE_PRIVSIZE 1000 #define SOX_MAX_NLOOPS 8 typedef char * * comments_t; struct sox_format { /* Placing priv at the start of this structure ensures that it gets aligned * in memory in the optimal way for any structure to be cast over it. */ char priv[SOX_MAX_FILE_PRIVSIZE]; /* format's private data area */ sox_signalinfo_t signal; /* signal specifications */ sox_encodinginfo_t encoding; /* encoding specifications */ sox_instrinfo_t instr; /* instrument specification */ sox_loopinfo_t loops[SOX_MAX_NLOOPS];/* Looping specification */ sox_bool seekable; /* can seek on this file */ char mode; /* read or write mode */ sox_size_t length; /* samples * channels in file; 0 if unknown */ sox_size_t olength; /* samples * channels in file; 0 if unknown */ sox_size_t clips; /* increment if clipping occurs */ char *filename; /* file name */ char *filetype; /* type of file */ comments_t comments; /* comment strings */ FILE *fp; /* File stream pointer */ int sox_errno; /* Failure error codes */ char sox_errstr[256]; /* Extend Failure text */ off_t data_start; sox_format_handler_t handler; /* format struct for this file */ }; /* file flags field */ #define SOX_FILE_LOOPS 1 /* does file format support loops? */ #define SOX_FILE_INSTR 2 /* does file format support instrument specs? */ #define SOX_FILE_NOSTDIO 8 /* does not use stdio routines */ #define SOX_FILE_DEVICE 16 /* file is an audio device */ #define SOX_FILE_PHONY 32 /* phony file/device */ /* These two for use by the libSoX core or libSoX clients: */ #define SOX_FILE_ENDIAN 64 /* is file format endian? */ #define SOX_FILE_ENDBIG 128/* if so, is it big endian? */ /* These two for use by libSoX handlers: */ #define SOX_FILE_LIT_END (0 + 64) #define SOX_FILE_BIG_END (128 + 64) #define SOX_FILE_BIT_REV 0x0100 #define SOX_FILE_NIB_REV 0x0200 #define SOX_FILE_CHANS 0x1C00 #define SOX_FILE_MONO 0x0400 #define SOX_FILE_STEREO 0x0800 #define SOX_FILE_QUAD 0x1000 #define SOX_FILE_REWIND 0x2000 /* declared in misc.c */ extern const char * const sox_encodings_str[]; extern const char * const sox_encodings_short_str[]; int sox_format_init(void); sox_format_t * sox_open_read( char const * path, sox_signalinfo_t const * signal, sox_encodinginfo_t const * encoding, char const * filetype); sox_bool sox_format_supports_encoding( char const * path, char const * filetype, sox_encodinginfo_t const * encoding); sox_format_t * sox_open_write( sox_bool (*overwrite_permitted)(const char *filename), char const * path, sox_signalinfo_t const * signal, sox_encodinginfo_t const * encoding, char const * filetype, comments_t comments, sox_size_t length, sox_instrinfo_t const * instr, sox_loopinfo_t const * loops); sox_size_t sox_read(sox_format_t * ft, sox_sample_t *buf, sox_size_t len); sox_size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len); int sox_close(sox_format_t * ft); #define SOX_SEEK_SET 0 int sox_seek(sox_format_t * ft, sox_size_t offset, int whence); sox_format_handler_t const * sox_find_format(char const * name, sox_bool no_dev); int sox_gettype(sox_format_t *, sox_bool); void sox_format_quit(void); /* * Structures for effects. */ #define SOX_MAX_EFFECT_PRIVSIZE (2 * SOX_MAX_FILE_PRIVSIZE) #define SOX_EFF_CHAN 1 /* Effect can alter # of channels */ #define SOX_EFF_RATE 2 /* Effect can alter sample rate */ #define SOX_EFF_PREC 4 /* Effect can alter sample precision */ #define SOX_EFF_LENGTH 8 /* Effect can alter audio length */ #define SOX_EFF_MCHAN 16 /* Effect can handle multi-channel */ #define SOX_EFF_NULL 32 /* Effect does nothing */ #define SOX_EFF_DEPRECATED 64 /* Effect is living on borrowed time */ typedef struct sox_effect sox_effect_t; typedef struct sox_effects_globals sox_effects_globals_t; typedef struct { char const * name; char const * usage; unsigned int flags; int (*getopts)(sox_effect_t * effp, int argc, char *argv[]); int (*start)(sox_effect_t * effp); int (*flow)(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf, sox_size_t *isamp, sox_size_t *osamp); int (*drain)(sox_effect_t * effp, sox_sample_t *obuf, sox_size_t *osamp); int (*stop)(sox_effect_t * effp); int (*kill)(sox_effect_t * effp); } sox_effect_handler_t; struct sox_effect { /* Placing priv at the start of this structure ensures that it gets aligned * in memory in the optimal way for any structure to be cast over it. */ char priv[SOX_MAX_EFFECT_PRIVSIZE]; /* private area for effect */ sox_effects_globals_t * global_info; /* global parameters */ sox_signalinfo_t in_signal; sox_signalinfo_t out_signal; sox_encodinginfo_t const * in_encoding; sox_encodinginfo_t const * out_encoding; sox_effect_handler_t handler; sox_sample_t * obuf; /* output buffer */ sox_size_t obeg, oend; /* consumed, total length */ sox_size_t imin; /* minimum input buffer size */ sox_size_t clips; /* increment if clipping occurs */ sox_size_t flows; /* 1 if MCHAN, # chans otherwise */ sox_size_t flow; /* flow # */ }; sox_effect_handler_t const *sox_find_effect(char const * name); void sox_create_effect(sox_effect_t * effp, sox_effect_handler_t const *e); /* Effects chain */ int sox_effect_set_imin(sox_effect_t * effp, sox_size_t imin); struct sox_effects_chain; typedef struct sox_effects_chain sox_effects_chain_t; sox_effects_chain_t * sox_create_effects_chain( sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc); int sox_add_effect( sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out); int sox_flow_effects(sox_effects_chain_t *, int (* callback)(sox_bool all_done)); sox_size_t sox_effects_clips(sox_effects_chain_t *); sox_size_t sox_stop_effect(sox_effects_chain_t *, sox_size_t e); void sox_delete_effects(sox_effects_chain_t *); char const * sox_parsesamples(sox_rate_t rate, const char *str, sox_size_t *samples, int def); /* The following routines are unique to the trim effect. * sox_trim_get_start can be used to find what is the start * of the trim operation as specified by the user. * sox_trim_clear_start will reset what ever the user specified * back to 0. * These two can be used together to find out what the user * wants to trim and use a sox_seek() operation instead. After * sox_seek()'ing, you should set the trim option to 0. */ sox_size_t sox_trim_get_start(sox_effect_t * effp); void sox_trim_clear_start(sox_effect_t * effp); typedef int (* sox_playlist_callback_t)(void *, char *); sox_bool sox_is_playlist(char const * filename); int sox_parse_playlist(sox_playlist_callback_t callback, void * p, char const * const listname); #endif