Unified · Split
| @@ -25,6 +25,7 @@ Newly deprecated features (to be removed in future): · 24 unmodified lines | ||
| 25 | 25 | Deprec- Feature [O(ption)] Removal |
| 26 | 26 | ated in [F(ormat)] [E(ffect)] Replacement due after |
| 27 | 27 | ------- ---------------------- ---------------------- ------- |
| 28 | + 14.3.0 E norm -b, norm -i gain -B, gain -en 14.3.0 + 1 year | |
| 28 | 29 | 14.3.0 F flac: libFLAC 1.1.2,3 libFLAC > 1.1.3 14.3.0 + 6 months |
| 29 | 30 | |
| 30 | 31 | Previously deprecated features (to be removed in future): |
| @@ -59,11 +60,18 @@ File formats: · 28 unmodified lines | ||
| 59 | 60 | o Fix [2404566] segfault when converting from MS ADPCM wav file. (robs) |
| 60 | 61 | o Fix slight FLAC seek inaccuracy e.g. when using `trim' effect. (robs) |
| 61 | 62 | |
| 63 | +Audio device drivers: | |
| 64 | + | |
| 65 | + o New native OpenBSD audio handler for play/recording. (Alexandre Ratchov) | |
| 66 | + o 24-bit support for ALSA handler. (robs) | |
| 67 | + o Warn if ALSA under/overrun. (robs) | |
| 68 | + | |
| 62 | 69 | Effects: |
| 63 | 70 | |
| 64 | 71 | o New `overdrive' effect. (robs) |
| 65 | 72 | o New `pluck' and `tpdf' types for `synth'. (robs) |
| 66 | 73 | o Can now set common parameters for multiple `synth' channels. (robs) |
| 74 | + o Richer gain/normalise options. (robs) | |
| 67 | 75 | o Fix [2487589] `dither' clipping detection & handling. (robs) |
| 68 | 76 | o Fix `repeat' sometimes stopping repeating too soon. (robs) |
| 69 | 77 | o Fix `repeat' sometimes repeating wrong audio segments. (robs) |
| @@ -75,14 +83,13 @@ Effects: · 5 unmodified lines | ||
| 75 | 83 | |
| 76 | 84 | Other new features: |
| 77 | 85 | |
| 78 | − o New native OpenBSD audio handler for play/recording. (Alexandre Ratchov) | |
| 79 | − o 24-bit support for ALSA handler. (robs) | |
| 80 | − o Warn if ALSA under/overrun. (robs) | |
| 86 | + o Added ability to create shared DLL's on cygwin (cbagwell) | |
| 87 | + o New `--guard' & `--norm' options; use temporary files to guard against | |
| 88 | + clipping for many, but not currently all, effects. (robs) | |
| 81 | 89 | o New `--ignore-length' option to ignore length in input file |
| 82 | 90 | header (for simple encodings); instead, read to end of file. (robs) |
| 83 | − o Added ability to create shared DLL's on cygwin (cbagwell) | |
| 84 | − o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs) | |
| 85 | 91 | o New `--temp DIRECTORY' option. (robs) |
| 92 | + o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs) | |
| 86 | 93 | o New bitrate, time in seconds, & total options for soxi. (robs) |
| 87 | 94 | |
| 88 | 95 | Other bug fixes: |
| @@ -1,5 +1,4 @@ | ||
| 1 | 1 | Makefile Makefile.in |
| 2 | −sox_sample_test | |
| 3 | 2 | example0 example1 example2 |
| 4 | 3 | soxconfig.h.in soxconfig.h soxstdint.h |
| 5 | 4 | .deps |
| @@ -254,7 +254,6 @@ static int startwrite(sox_format_t * ft) · 253 unmodified lines | ||
| 254 | 254 | static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t len) |
| 255 | 255 | { |
| 256 | 256 | priv_t * p = (priv_t * ) ft->priv; |
| 257 | − SOX_SAMPLE_LOCALS; | |
| 258 | 257 | |
| 259 | 258 | unsigned char datum; |
| 260 | 259 | size_t done = 0, i; |
| @@ -263,7 +262,7 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 2 unmodified lines | ||
| 263 | 262 | |
| 264 | 263 | while(done < len) { |
| 265 | 264 | for (i = 0; i < ft->signal.channels; i++) { |
| 266 | − datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips); | |
| 265 | + datum = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++); | |
| 267 | 266 | /* FIXME: Needs to pass ft struct and not FILE */ |
| 268 | 267 | putc(datum, p->ch[i]); |
| 269 | 268 | } |
| @@ -28,16 +28,16 @@ add_custom_command( · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | # Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /' |
| 30 | 30 | set(effects_srcs |
| 31 | − bend dither lowfir phaser stat | |
| 32 | − biquad earwax mcompand rate stretch | |
| 33 | − biquads echo mixer remix swap | |
| 34 | − chorus echos noiseprof repeat synth | |
| 35 | − compand fade noisered reverb tempo | |
| 36 | − compandt fft4g normalise reverse tremolo | |
| 31 | + bend dither loudness phaser stat | |
| 32 | + biquad earwax lowfir rate stretch | |
| 33 | + biquads echo mcompand remix swap | |
| 34 | + chorus echos mixer repeat synth | |
| 35 | + compand fade noiseprof reverb tempo | |
| 36 | + compandt fft4g noisered reverse tremolo | |
| 37 | 37 | contrast filter output silence trim |
| 38 | 38 | dcshift flanger overdrive skeleff vol |
| 39 | − delay input pad speed | |
| 40 | − dft_filter loudness pan splice | |
| 39 | + delay gain pad speed | |
| 40 | + dft_filter input pan splice | |
| 41 | 41 | ) |
| 42 | 42 | set(formats_srcs |
| 43 | 43 | 8svx dat ima-fmt s3-fmt u3-fmt |
| @@ -62,7 +62,6 @@ add_library(lib${PROJECT_NAME} · 18 unmodified lines | ||
| 62 | 62 | ) |
| 63 | 63 | add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c) |
| 64 | 64 | target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} lpc10 ${optional_libs}) |
| 65 | −add_executable(sox_sample_test sox_sample_test.c) | |
| 66 | 65 | add_executable(example0 example0.c) |
| 67 | 66 | target_link_libraries(example0 lib${PROJECT_NAME} lpc10 ${optional_libs}) |
| 68 | 67 | add_executable(example1 example1.c) |
| @@ -28,7 +28,7 @@ endif · 27 unmodified lines | ||
| 28 | 28 | ######################### |
| 29 | 29 | |
| 30 | 30 | bin_PROGRAMS = sox |
| 31 | −EXTRA_PROGRAMS = example0 example1 example2 sox_sample_test | |
| 31 | +EXTRA_PROGRAMS = example0 example1 example2 | |
| 32 | 32 | lib_LTLIBRARIES = libsox.la |
| 33 | 33 | include_HEADERS = sox.h |
| 34 | 34 | nodist_include_HEADERS = soxstdint.h |
| @@ -37,7 +37,6 @@ sox_LDADD = libsox.la · 2 unmodified lines | ||
| 37 | 37 | example0_SOURCES = example0.c |
| 38 | 38 | example1_SOURCES = example1.c |
| 39 | 39 | example2_SOURCES = example2.c |
| 40 | −sox_sample_test_SOURCES = sox_sample_test.c sox_sample_test.h | |
| 41 | 40 | |
| 42 | 41 | ############################################### |
| 43 | 42 | # libsox - Dynamic Libraries for File Formats # |
| @@ -274,7 +273,7 @@ libsox_la_SOURCES += \ · 230 unmodified lines | ||
| 274 | 273 | dither_fir.h dither_iir.h earwax.c echo.c echos.c effects.c effects.h \ |
| 275 | 274 | effects_i.c fade.c fft4g.c fft4g.h fifo.h filter.c flanger.c input.c \ |
| 276 | 275 | ladspa.c loudness.c mcompand.c mcompand_xover.h mixer.c noiseprof.c \ |
| 277 | − noisered.c noisered.h normalise.c output.c pad.c pan.c phaser.c \ | |
| 276 | + noisered.c noisered.h gain.c output.c pad.c pan.c phaser.c \ | |
| 278 | 277 | rate.c rate_filters.h rate_half_fir.h \ |
| 279 | 278 | rate_poly_fir0.h rate_poly_fir.h remix.c repeat.c reverb.c \ |
| 280 | 279 | reverse.c silence.c skeleff.c speed.c splice.c stat.c swap.c stretch.c \ |
| @@ -400,7 +399,7 @@ EXTRA_DIST = monkey.au monkey.wav \ · 119 unmodified lines | ||
| 400 | 399 | CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake \ |
| 401 | 400 | tests.sh testall.sh tests.bat testall.bat test-comments |
| 402 | 401 | |
| 403 | −all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) | |
| 402 | +all: sox$(EXEEXT) play rec soxi example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) | |
| 404 | 403 | |
| 405 | 404 | play rec: sox$(EXEEXT) |
| 406 | 405 | if test "$(PLAYRECLINKS)" = "yes"; then \ |
| @@ -430,7 +429,6 @@ uninstall-hook: · 23 unmodified lines | ||
| 430 | 429 | |
| 431 | 430 | clean-local: |
| 432 | 431 | $(RM) play rec soxi |
| 433 | − $(RM) sox_sample_test$(EXEEXT) | |
| 434 | 432 | $(RM) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) |
| 435 | 433 | |
| 436 | 434 | distclean-local: |
| @@ -251,8 +251,7 @@ size_t lsx_adpcm_write(sox_format_t * ft, adpcm_io_t * state, const sox_sample_t · 250 unmodified lines | ||
| 251 | 251 | short word; |
| 252 | 252 | |
| 253 | 253 | while (count < length) { |
| 254 | − SOX_SAMPLE_LOCALS; | |
| 255 | − word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++, ft->clips); | |
| 254 | + word = SOX_SAMPLE_TO_SIGNED_16BIT(*buffer++); | |
| 256 | 255 | |
| 257 | 256 | byte <<= 4; |
| 258 | 257 | byte |= lsx_adpcm_encode(word, &state->encoder) & 0x0F; |
| @@ -187,45 +187,44 @@ static size_t write_(sox_format_t * ft, sox_sample_t const * buf, size_t len) · 186 unmodified lines | ||
| 187 | 187 | priv_t * p = (priv_t *)ft->priv; |
| 188 | 188 | size_t done, i, n; |
| 189 | 189 | snd_pcm_sframes_t actual; |
| 190 | − SOX_SAMPLE_LOCALS; | |
| 191 | 190 | |
| 192 | 191 | for (done = 0; done < len; done += n) { |
| 193 | 192 | i = n = min(len - done, p->buf_len); |
| 194 | 193 | switch (p->format) { |
| 195 | 194 | case SND_PCM_FORMAT_S8: { |
| 196 | 195 | int8_t * buf1 = (int8_t *)p->buf; |
| 197 | − while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++, ft->clips); | |
| 196 | + while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_8BIT(*buf++); | |
| 198 | 197 | break; |
| 199 | 198 | } |
| 200 | 199 | case SND_PCM_FORMAT_U8: { |
| 201 | 200 | uint8_t * buf1 = (uint8_t *)p->buf; |
| 202 | − while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips); | |
| 201 | + while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++); | |
| 203 | 202 | break; |
| 204 | 203 | } |
| 205 | 204 | case SND_PCM_FORMAT_S16: { |
| 206 | 205 | int16_t * buf1 = (int16_t *)p->buf; |
| 207 | 206 | if (ft->encoding.reverse_bytes) while (i--) |
| 208 | − *buf1++ = lsx_swapw(SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips)); | |
| 207 | + *buf1++ = lsx_swapw(SOX_SAMPLE_TO_SIGNED_16BIT(*buf++)); | |
| 209 | 208 | else |
| 210 | − while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips); | |
| 209 | + while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++); | |
| 211 | 210 | break; |
| 212 | 211 | } |
| 213 | 212 | case SND_PCM_FORMAT_U16: { |
| 214 | 213 | uint16_t * buf1 = (uint16_t *)p->buf; |
| 215 | 214 | if (ft->encoding.reverse_bytes) while (i--) |
| 216 | − *buf1++ = lsx_swapw(SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips)); | |
| 215 | + *buf1++ = lsx_swapw(SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++)); | |
| 217 | 216 | else |
| 218 | − while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips); | |
| 217 | + while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++); | |
| 219 | 218 | break; |
| 220 | 219 | } |
| 221 | 220 | case SND_PCM_FORMAT_S24: { |
| 222 | 221 | int24_t * buf1 = (int24_t *)p->buf; |
| 223 | − while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++, ft->clips); | |
| 222 | + while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_24BIT(*buf++); | |
| 224 | 223 | break; |
| 225 | 224 | } |
| 226 | 225 | case SND_PCM_FORMAT_U24: { |
| 227 | 226 | uint24_t * buf1 = (uint24_t *)p->buf; |
| 228 | − while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++, ft->clips); | |
| 227 | + while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_24BIT(*buf++); | |
| 229 | 228 | break; |
| 230 | 229 | } |
| 231 | 230 | } |
| @@ -117,8 +117,7 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, size_t · 116 unmodified lines | ||
| 117 | 117 | size_t done; |
| 118 | 118 | |
| 119 | 119 | for (done = 0; done < len; ++done) { |
| 120 | − SOX_SAMPLE_LOCALS; | |
| 121 | − p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips); | |
| 120 | + p->pcm[p->pcm_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++); | |
| 122 | 121 | if (p->pcm_index == AMR_FRAME) { |
| 123 | 122 | p->pcm_index = 0; |
| 124 | 123 | if (!encode_1_frame(ft)) |
| @@ -74,12 +74,11 @@ static int startwrite(sox_format_t * ft) · 73 unmodified lines | ||
| 74 | 74 | return SOX_SUCCESS; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | −static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap, size_t * clips) | |
| 77 | +static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, size_t len, sox_bool swap) | |
| 78 | 78 | { |
| 79 | 79 | while (len--) |
| 80 | 80 | { |
| 81 | − SOX_SAMPLE_LOCALS; | |
| 82 | − uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++, *clips); | |
| 81 | + uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++); | |
| 83 | 82 | if (swap) |
| 84 | 83 | datum = lsx_swapw(datum); |
| 85 | 84 | *(uint16_t *)buf1 = datum; |
| @@ -97,8 +96,7 @@ static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t le · 11 unmodified lines | ||
| 97 | 96 | |
| 98 | 97 | aobuf_size = (ft->encoding.bits_per_sample >> 3) * len; |
| 99 | 98 | |
| 100 | − sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes, | |
| 101 | − &(ft->clips)); | |
| 99 | + sox_sw_write_buf(ao->buf, buf, len, ft->encoding.reverse_bytes); | |
| 102 | 100 | if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0) |
| 103 | 101 | return 0; |
| 104 | 102 | |
| @@ -40,7 +40,8 @@ · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate); |
| 42 | 42 | p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate); |
| 43 | − if (p->filter_type == filter_BPF_SPK_N) | |
| 44 | − p->b0 = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)); | |
| 45 | − else | |
| 46 | − p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2); | |
| 43 | + p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2); | |
| 44 | + if (p->filter_type == filter_BPF_SPK_N) { | |
| 45 | + mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0; | |
| 46 | + p->b0 *= mult; | |
| 47 | + } | |
| @@ -154,7 +154,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 153 unmodified lines | ||
| 154 | 154 | ++p->in_pos; |
| 155 | 155 | |
| 156 | 156 | /* As long as we have not yet collected enough data just read in */ |
| 157 | − p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips); | |
| 157 | + p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i]); | |
| 158 | 158 | obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE( |
| 159 | 159 | p->gOutFIFO[p->gRover - inFifoLatency], effp->clips); |
| 160 | 160 | p->gRover++; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #ifndef biquad_included |
| 19 | 19 | #define biquad_included |
| 20 | 20 | |
| 21 | +#define LSX_EFF_ALIAS | |
| 21 | 22 | #include "sox_i.h" |
| 22 | 23 | |
| 23 | 24 | typedef enum { |
| @@ -74,7 +75,4 @@ int lsx_biquad_start(sox_effect_t * effp); · 50 unmodified lines | ||
| 74 | 75 | int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf, |
| 75 | 76 | size_t *isamp, size_t *osamp); |
| 76 | 77 | |
| 77 | −#undef lsx_fail | |
| 78 | −#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail | |
| 79 | − | |
| 80 | 78 | #endif |
| @@ -164,7 +164,7 @@ static int start(sox_effect_t * effp) · 163 unmodified lines | ||
| 164 | 164 | priv_t * p = (priv_t *)effp->priv; |
| 165 | 165 | double w0 = 2 * M_PI * p->fc / effp->in_signal.rate; |
| 166 | 166 | double A = exp(p->gain / 40 * log(10.)); |
| 167 | − double alpha = 0; | |
| 167 | + double alpha = 0, mult = dB_to_linear(max(p->gain, 0)); | |
| 168 | 168 | |
| 169 | 169 | if (w0 > M_PI) { |
| 170 | 170 | lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)"); |
| @@ -362,8 +362,11 @@ static int start(sox_effect_t * effp) · 191 unmodified lines | ||
| 362 | 362 | {double g = dB_to_linear(19.9 - linear_to_dB( |
| 363 | 363 | (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2))); |
| 364 | 364 | p->b0 *= g; p->b1 *= g; p->b2 *= g;} |
| 365 | + mult = dB_to_linear(19.9); | |
| 365 | 366 | break; |
| 366 | 367 | } |
| 368 | + if (effp->in_signal.mult) | |
| 369 | + *effp->in_signal.mult /= mult; | |
| 367 | 370 | return lsx_biquad_start(effp); |
| 368 | 371 | } |
| 369 | 372 | |
| @@ -333,7 +333,7 @@ static int sox_chorus_stop(sox_effect_t * effp) · 332 unmodified lines | ||
| 333 | 333 | static sox_effect_handler_t sox_chorus_effect = { |
| 334 | 334 | "chorus", |
| 335 | 335 | "gain-in gain-out delay decay speed depth [ -s | -t ]", |
| 336 | − SOX_EFF_LENGTH, | |
| 336 | + SOX_EFF_LENGTH | SOX_EFF_GAIN, | |
| 337 | 337 | sox_chorus_getopts, |
| 338 | 338 | sox_chorus_start, |
| 339 | 339 | sox_chorus_flow, |
| @@ -275,7 +275,7 @@ static int kill(sox_effect_t * effp) · 274 unmodified lines | ||
| 275 | 275 | sox_effect_handler_t const * sox_compand_effect_fn(void) |
| 276 | 276 | { |
| 277 | 277 | static sox_effect_handler_t handler = { |
| 278 | − "compand", compand_usage, SOX_EFF_MCHAN, | |
| 278 | + "compand", compand_usage, SOX_EFF_MCHAN | SOX_EFF_GAIN, | |
| 279 | 279 | getopts, start, flow, drain, stop, kill, sizeof(priv_t) |
| 280 | 280 | }; |
| 281 | 281 | return &handler; |
| @@ -285,7 +285,7 @@ static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t ns · 284 unmodified lines | ||
| 285 | 285 | p = &ac->buffer[ac->buf_offset]; |
| 286 | 286 | |
| 287 | 287 | while (samp_left--) |
| 288 | − *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++, ft->clips); | |
| 288 | + *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++); | |
| 289 | 289 | |
| 290 | 290 | ac->buf_offset += len; |
| 291 | 291 | |
| @@ -104,14 +104,14 @@ static size_t sox_datread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp) · 103 unmodified lines | ||
| 104 | 104 | /* Read a complete set of channels */ |
| 105 | 105 | sscanf(inpstr," %*s%n", &inpPtr); |
| 106 | 106 | for (i=0; i<ft->signal.channels; i++) { |
| 107 | + SOX_SAMPLE_LOCALS; | |
| 107 | 108 | retc = sscanf(&inpstr[inpPtr]," %lg%n", &sampval, &inpPtrInc); |
| 108 | 109 | inpPtr += inpPtrInc; |
| 109 | 110 | if (retc != 1) { |
| 110 | 111 | lsx_fail_errno(ft,SOX_EOF,"Unable to read sample."); |
| 111 | 112 | return 0; |
| 112 | 113 | } |
| 113 | − sampval *= SOX_SAMPLE_MAX; | |
| 114 | − *buf++ = SOX_ROUND_CLIP_COUNT(sampval, ft->clips); | |
| 114 | + *buf++ = SOX_FLOAT_64BIT_TO_SAMPLE(sampval, ft->clips); | |
| 115 | 115 | done++; |
| 116 | 116 | } |
| 117 | 117 | } |
| @@ -135,8 +135,7 @@ static size_t sox_datwrite(sox_format_t * ft, const sox_sample_t *buf, size_t ns · 17 unmodified lines | ||
| 135 | 135 | sprintf(s," %15.8g ",dat->timevalue); |
| 136 | 136 | lsx_writes(ft, s); |
| 137 | 137 | for (i=0; i<ft->signal.channels; i++) { |
| 138 | − SOX_SAMPLE_LOCALS; | |
| 139 | − sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++, ft->clips); | |
| 138 | + sampval = SOX_SAMPLE_TO_FLOAT_64BIT(*buf++); | |
| 140 | 139 | sprintf(s," %15.8g", sampval); |
| 141 | 140 | lsx_writes(ft, s); |
| 142 | 141 | done++; |
| @@ -173,7 +173,7 @@ static sox_effect_handler_t sox_dcshift_effect = { · 172 unmodified lines | ||
| 173 | 173 | "shift [ limitergain ]\n" |
| 174 | 174 | " The peak limiter has a gain much less than 1.0 (ie 0.05 or 0.02) which is only\n" |
| 175 | 175 | " used on peaks to prevent clipping. (default is no limiter)", |
| 176 | − SOX_EFF_MCHAN, | |
| 176 | + SOX_EFF_MCHAN | SOX_EFF_GAIN, | |
| 177 | 177 | sox_dcshift_getopts, |
| 178 | 178 | sox_dcshift_start, |
| 179 | 179 | sox_dcshift_flow, |
| @@ -79,7 +79,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 78 unmodified lines | ||
| 79 | 79 | p->samples_in += (int)*isamp; |
| 80 | 80 | |
| 81 | 81 | for (i = *isamp; i; --i) |
| 82 | − *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips); | |
| 82 | + *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++); | |
| 83 | 83 | filter(p); |
| 84 | 84 | } |
| 85 | 85 | else *isamp = 0; |
| @@ -122,7 +122,7 @@ static int stop(sox_effect_t * effp) · 36 unmodified lines | ||
| 122 | 122 | sox_effect_handler_t const * sox_dft_filter_effect_fn(void) |
| 123 | 123 | { |
| 124 | 124 | static sox_effect_handler_t handler = { |
| 125 | − NULL, NULL, 0, NULL, start, flow, drain, stop, NULL, 0 | |
| 125 | + NULL, NULL, SOX_EFF_GAIN, NULL, start, flow, drain, stop, NULL, 0 | |
| 126 | 126 | }; |
| 127 | 127 | return &handler; |
| 128 | 128 | } |
| @@ -24,10 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <assert.h> |
| 25 | 25 | |
| 26 | 26 | #define PREC effp->out_signal.precision |
| 27 | −#define SOX_ROUND_PREC_CLIP_COUNT(d, clips) \ | |
| 28 | − ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \ | |
| 29 | − : (d) >= SOX_SAMPLE_MAX - (1 << (31-PREC)) + 0.5? \ | |
| 30 | − ++(clips), SOX_SAMPLE_MAX - (1 << (31-PREC)): (d) + 0.5) | |
| 31 | 27 | |
| 32 | 28 | typedef enum {Pdf_rectangular, Pdf_triangular, Pdf_gaussian} pdf_type_t; |
| 33 | 29 | static lsx_enum_item const pdf_types[] = { |
| @@ -134,12 +130,12 @@ static const filter_t filters[] = { · 100 unmodified lines | ||
| 134 | 130 | {48000, iir, 4, 21.0, ges48, Shape_gesemann}, |
| 135 | 131 | {44100, iir, 4, 21.2, ges44, Shape_gesemann}, |
| 136 | 132 | {48000, fir, 16, 28.8, shi48, Shape_shibata}, |
| 137 | − {44100, fir, 20, 32.5, shi44, Shape_shibata}, | |
| 133 | + {44100, fir, 20, 32.6, shi44, Shape_shibata}, | |
| 138 | 134 | {37800, fir, 16, 22.7, shi38, Shape_shibata}, |
| 139 | 135 | {32000, fir, 16, 15.7, shi32, Shape_shibata}, |
| 140 | 136 | {22050, fir, 15, 9.0, shi22, Shape_shibata}, |
| 141 | 137 | {48000, fir, 16, 23.5, shl48, Shape_low_shibata}, |
| 142 | − {44100, fir, 15, 23.0, shl44, Shape_low_shibata}, | |
| 138 | + {44100, fir, 15, 23.1, shl44, Shape_low_shibata}, | |
| 143 | 139 | {44100, fir, 20, 37.5, shh44, Shape_high_shibata}, |
| 144 | 140 | { 0, fir, 0, 0.0, NULL, Shape_none}, |
| 145 | 141 | }; |
| @@ -154,6 +150,7 @@ typedef struct { · 8 unmodified lines | ||
| 154 | 150 | double previous_outputs[MAX_N * 2]; |
| 155 | 151 | size_t pos; |
| 156 | 152 | double const * coefs; |
| 153 | + sox_sample_t offset; | |
| 157 | 154 | int (*flow)(sox_effect_t *, const sox_sample_t *, sox_sample_t *, size_t *, size_t *); |
| 158 | 155 | } priv_t; |
| 159 | 156 | |
| @@ -189,7 +186,7 @@ static int flow_no_shape(sox_effect_t * effp, const sox_sample_t * ibuf, · 29 unmodified lines | ||
| 189 | 186 | size_t len = *isamp = *osamp = min(*isamp, *osamp); |
| 190 | 187 | |
| 191 | 188 | while (len--) { |
| 192 | − double d = *ibuf++ + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1); | |
| 189 | + double d = *ibuf++ + p->offset + floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1); | |
| 193 | 190 | SOX_SAMPLE_CLIP_COUNT(d, effp->clips); |
| 194 | 191 | *obuf++ = d; |
| 195 | 192 | } |
| @@ -227,36 +224,39 @@ static int start(sox_effect_t * effp) · 31 unmodified lines | ||
| 227 | 224 | if (PREC > 24) |
| 228 | 225 | return SOX_EFF_NULL; /* Dithering not needed at this resolution */ |
| 229 | 226 | |
| 230 | − if (!p->filter_name) | |
| 231 | − p->flow = flow_no_shape; | |
| 232 | − else { | |
| 227 | + p->flow = flow_no_shape; | |
| 228 | + if (p->filter_name) { | |
| 233 | 229 | filter_t const * f; |
| 234 | 230 | |
| 235 | 231 | for (f = filters; f->len && (f->name != p->filter_name || fabs(effp->in_signal.rate - f->rate) / f->rate > .05); ++f); |
| 236 | 232 | if (!f->len) { |
| 237 | − lsx_fail("no `%s' filter is available for rate %g", lsx_find_enum_value(p->filter_name, filter_names)->text, effp->in_signal.rate); | |
| 238 | − return SOX_EOF; | |
| 233 | + lsx_warn("no `%s' filter is available for rate %g", lsx_find_enum_value(p->filter_name, filter_names)->text, effp->in_signal.rate); | |
| 239 | 234 | } |
| 240 | − assert(f->len <= MAX_N); | |
| 241 | − if (f->type == fir) switch(f->len) { | |
| 242 | − case 5: p->flow = flow_fir_5 ; break; | |
| 243 | − case 9: p->flow = flow_fir_9 ; break; | |
| 244 | − case 15: p->flow = flow_fir_15; break; | |
| 245 | − case 16: p->flow = flow_fir_16; break; | |
| 246 | − case 20: p->flow = flow_fir_20; break; | |
| 247 | − default: assert(sox_false); | |
| 248 | − } else switch(f->len) { | |
| 249 | − case 4: p->flow = flow_iir_4 ; break; | |
| 250 | − default: assert(sox_false); | |
| 235 | + else { | |
| 236 | + assert(f->len <= MAX_N); | |
| 237 | + if (f->type == fir) switch(f->len) { | |
| 238 | + case 5: p->flow = flow_fir_5 ; break; | |
| 239 | + case 9: p->flow = flow_fir_9 ; break; | |
| 240 | + case 15: p->flow = flow_fir_15; break; | |
| 241 | + case 16: p->flow = flow_fir_16; break; | |
| 242 | + case 20: p->flow = flow_fir_20; break; | |
| 243 | + default: assert(sox_false); | |
| 244 | + } else switch(f->len) { | |
| 245 | + case 4: p->flow = flow_iir_4 ; break; | |
| 246 | + default: assert(sox_false); | |
| 247 | + } | |
| 248 | + p->coefs = f->coefs; | |
| 249 | + mult = dB_to_linear(f->gain); | |
| 251 | 250 | } |
| 252 | − p->coefs = f->coefs; | |
| 253 | − mult = dB_to_linear(f->gain); | |
| 254 | 251 | } |
| 255 | 252 | p->am1 = p->depth / (1 << PREC); |
| 256 | 253 | p->am0 = (p->pdf == Pdf_triangular) * p->am1; |
| 254 | + if (effp->out_encoding->half_bit && PREC < 32) | |
| 255 | + p->offset = 1 << (31 - PREC); | |
| 257 | 256 | |
| 258 | 257 | if (effp->flow == 0 && effp->in_signal.mult) |
| 259 | − *effp->in_signal.mult *= 1 - (p->am0 + p->am1) * mult; | |
| 258 | + *effp->in_signal.mult *= | |
| 259 | + 1 - (p->offset * (1./SOX_SAMPLE_MAX) + p->am0 + p->am1) * mult; | |
| 260 | 260 | |
| 261 | 261 | lsx_debug("pdf=%s filter=%s depth=%g", lsx_find_enum_value(p->pdf, pdf_types)->text, lsx_find_enum_value(p->filter_name, filter_names)->text, p->depth); |
| 262 | 262 | return SOX_SUCCESS; |
| @@ -7,12 +7,12 @@ static int NAME(sox_effect_t * effp, const sox_sample_t * ibuf, · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | while (len--) { |
| 9 | 9 | double r = floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1); |
| 10 | − double error, d = *ibuf++; | |
| 10 | + double error, d = *ibuf++ + p->offset; | |
| 11 | 11 | int j = 0; |
| 12 | 12 | CONVOLVE |
| 13 | 13 | assert(j == N); |
| 14 | − *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips); | |
| 15 | − error = ((*obuf++ + (1 << (31-PREC))) & (-1 << (32-PREC))) - d; | |
| 14 | + *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips); | |
| 15 | + error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d; | |
| 16 | 16 | p->pos = p->pos? p->pos - 1 : p->pos - 1 + N; |
| 17 | 17 | p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error; |
| 18 | 18 | } |
| @@ -12,9 +12,9 @@ static int NAME(sox_effect_t * effp, const sox_sample_t * ibuf, · 11 unmodified lines | ||
| 12 | 12 | int j = 0; |
| 13 | 13 | CONVOLVE |
| 14 | 14 | assert(j == N); |
| 15 | − d = *ibuf++ - output; | |
| 16 | − *obuf = SOX_ROUND_PREC_CLIP_COUNT(d + r, effp->clips); | |
| 17 | − error = ((*obuf++ + (1 << (31-PREC))) & (-1 << (32-PREC))) - d; | |
| 15 | + d = *ibuf++ + p->offset - output; | |
| 16 | + *obuf = SOX_ROUND_CLIP_COUNT(d + r, effp->clips); | |
| 17 | + error = (*obuf++ & (-1 << (32-PREC))) + (1 << (31-PREC)) - d; | |
| 18 | 18 | p->pos = p->pos? p->pos - 1 : p->pos - 1 + N; |
| 19 | 19 | p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error; |
| 20 | 20 | p->previous_outputs[p->pos + N] = p->previous_outputs[p->pos] = output; |
| @@ -62,6 +62,8 @@ static int start(sox_effect_t * effp) · 61 unmodified lines | ||
| 62 | 62 | return SOX_EOF; |
| 63 | 63 | } |
| 64 | 64 | memset(p->tap, 0, NUMTAPS * sizeof(*p->tap)); /* zero tap memory */ |
| 65 | + if (effp->in_signal.mult) | |
| 66 | + *effp->in_signal.mult *= dB_to_linear(-4.4); | |
| 65 | 67 | return SOX_SUCCESS; |
| 66 | 68 | } |
| 67 | 69 | |
| @@ -248,7 +248,7 @@ static int sox_echo_stop(sox_effect_t * effp) · 247 unmodified lines | ||
| 248 | 248 | static sox_effect_handler_t sox_echo_effect = { |
| 249 | 249 | "echo", |
| 250 | 250 | "gain-in gain-out delay decay [ delay decay ... ]", |
| 251 | − SOX_EFF_LENGTH, | |
| 251 | + SOX_EFF_LENGTH | SOX_EFF_GAIN, | |
| 252 | 252 | sox_echo_getopts, |
| 253 | 253 | sox_echo_start, |
| 254 | 254 | sox_echo_flow, |
| @@ -260,7 +260,7 @@ static int sox_echos_stop(sox_effect_t * effp) · 259 unmodified lines | ||
| 260 | 260 | static sox_effect_handler_t sox_echos_effect = { |
| 261 | 261 | "echos", |
| 262 | 262 | "gain-in gain-out delay decay [ delay decay ... ]", |
| 263 | − SOX_EFF_LENGTH, | |
| 263 | + SOX_EFF_LENGTH | SOX_EFF_GAIN, | |
| 264 | 264 | sox_echos_getopts, |
| 265 | 265 | sox_echos_start, |
| 266 | 266 | sox_echos_flow, |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | +#define LSX_EFF_ALIAS | |
| 18 | 19 | #include "sox_i.h" |
| 19 | 20 | #include "getopt.h" |
| 20 | 21 | #include <assert.h> |
| @@ -23,12 +24,6 @@ · 2 unmodified lines | ||
| 23 | 24 | #include <strings.h> |
| 24 | 25 | #endif |
| 25 | 26 | |
| 26 | − | |
| 27 | −#undef lsx_fail | |
| 28 | −#undef lsx_report | |
| 29 | −#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail | |
| 30 | −#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report | |
| 31 | − | |
| 32 | 27 | #define DEBUG_EFFECTS_CHAIN 0 |
| 33 | 28 | |
| 34 | 29 | /* FIXME: Not thread safe using globals */ |
| @@ -99,7 +94,7 @@ int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[]) · 64 unmodified lines | ||
| 99 | 94 | /* Effects chain: */ |
| 100 | 95 | |
| 101 | 96 | sox_effects_chain_t * sox_create_effects_chain( |
| 102 | − sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc) | |
| 97 | + sox_encodinginfo_t const * in_enc, sox_encodinginfo_t * out_enc) | |
| 103 | 98 | { |
| 104 | 99 | sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t)); |
| 105 | 100 | result->global_info = sox_effects_globals; |
| @@ -150,6 +145,8 @@ int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signali · 44 unmodified lines | ||
| 150 | 145 | effp->out_signal.rate = in->rate; |
| 151 | 146 | if (!(effp->handler.flags & SOX_EFF_PREC)) |
| 152 | 147 | effp->out_signal.precision = in->precision; |
| 148 | + if (!(effp->handler.flags & SOX_EFF_GAIN)) | |
| 149 | + effp->out_signal.mult = in->mult; | |
| 153 | 150 | |
| 154 | 151 | effp->flows = |
| 155 | 152 | (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels; |
| @@ -167,6 +164,8 @@ int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signali · 11 unmodified lines | ||
| 167 | 164 | free(eff0.priv); |
| 168 | 165 | return SOX_EOF; |
| 169 | 166 | } |
| 167 | + if (in->mult) | |
| 168 | + lsx_debug("mult=%g", *in->mult); | |
| 170 | 169 | |
| 171 | 170 | *in = effp->out_signal; |
| 172 | 171 | |
| @@ -18,12 +18,10 @@ · 17 unmodified lines | ||
| 18 | 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#define LSX_EFF_ALIAS | |
| 21 | 22 | #include "sox_i.h" |
| 22 | 23 | #include <string.h> |
| 23 | 24 | |
| 24 | −#undef lsx_fail | |
| 25 | −#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail | |
| 26 | − | |
| 27 | 25 | int lsx_usage(sox_effect_t * effp) |
| 28 | 26 | { |
| 29 | 27 | if (effp->handler.usage) |
| @@ -82,15 +82,14 @@ int main(int argc, char * argv[]) · 81 unmodified lines | ||
| 82 | 82 | /* Read in and process blocks of audio for the selected period or until EOF: */ |
| 83 | 83 | for (blocks = 0; sox_read(in, buf, block_size) == block_size && blocks * block_period < period; ++blocks) { |
| 84 | 84 | double left = 0, right = 0; |
| 85 | − size_t i, clips = 0; | |
| 85 | + size_t i; | |
| 86 | 86 | static const char line[] = "==================================="; |
| 87 | 87 | int l, r; |
| 88 | 88 | |
| 89 | 89 | for (i = 0; i < block_size; ++i) { |
| 90 | − SOX_SAMPLE_LOCALS; | |
| 91 | 90 | /* convert the sample from SoX's internal format to a `double' for |
| 92 | 91 | * processing in this application: */ |
| 93 | − double sample = SOX_SAMPLE_TO_FLOAT_64BIT(buf[i], clips); | |
| 92 | + double sample = SOX_SAMPLE_TO_FLOAT_64BIT(buf[i]); | |
| 94 | 93 | |
| 95 | 94 | /* The samples for each channel are interleaved; in this example |
| 96 | 95 | * we allow only stereo audio, so the left channel audio can be found in |
| @@ -406,9 +406,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 405 unmodified lines | ||
| 406 | 406 | do { |
| 407 | 407 | /* If output frame is not full, copy data into it */ |
| 408 | 408 | if (ffmpeg->samples_index < ffmpeg->audio_input_frame_size) { |
| 409 | − SOX_SAMPLE_LOCALS; | |
| 410 | 409 | for (; nread < len && ffmpeg->samples_index < ffmpeg->audio_input_frame_size; nread++) |
| 411 | − ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread], ft->clips); | |
| 410 | + ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread]); | |
| 412 | 411 | } |
| 413 | 412 | |
| 414 | 413 | /* If output frame full or no more data to read, write it out */ |
| @@ -441,22 +441,21 @@ static size_t write_samples(sox_format_t * const ft, sox_sample_t const * const · 440 unmodified lines | ||
| 441 | 441 | unsigned i; |
| 442 | 442 | |
| 443 | 443 | for (i = 0; i < len; ++i) { |
| 444 | − SOX_SAMPLE_LOCALS; | |
| 445 | − long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips); | |
| 444 | + long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]); | |
| 446 | 445 | p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample); |
| 447 | 446 | switch (p->bits_per_sample) { |
| 448 | 447 | case 8: p->decoded_samples[i] = |
| 449 | − SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips); | |
| 448 | + SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i]); | |
| 450 | 449 | break; |
| 451 | 450 | case 16: p->decoded_samples[i] = |
| 452 | − SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips); | |
| 451 | + SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i]); | |
| 453 | 452 | break; |
| 454 | 453 | case 24: p->decoded_samples[i] = /* sign extension: */ |
| 455 | − SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8; | |
| 454 | + SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i]) << 8; | |
| 456 | 455 | p->decoded_samples[i] >>= 8; |
| 457 | 456 | break; |
| 458 | 457 | case 32: p->decoded_samples[i] = |
| 459 | − SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips); | |
| 458 | + SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]); | |
| 460 | 459 | break; |
| 461 | 460 | } |
| 462 | 461 | } |
| @@ -428,6 +428,7 @@ sox_format_t * sox_open_read( · 427 unmodified lines | ||
| 428 | 428 | if (magic) |
| 429 | 429 | filetype = magic_file(magic, path); |
| 430 | 430 | if (filetype && ( |
| 431 | + lsx_strends(filetype, "/unknown") || | |
| 431 | 432 | !strcmp(filetype, "application/octet-stream") || |
| 432 | 433 | !strncmp(filetype, "text/plain", (size_t)10) )) |
| 433 | 434 | filetype = NULL; |
| @@ -90,14 +90,6 @@ int lsx_check_read_params(sox_format_t * ft, unsigned channels, · 89 unmodified lines | ||
| 90 | 90 | return SOX_EOF; |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | −sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding) | |
| 94 | −{ | |
| 95 | − unsigned precision = encoding->encoding == SOX_ENCODING_FLOAT? | |
| 96 | − SOX_SAMPLE_PRECISION : sox_precision(encoding->encoding, encoding->bits_per_sample); | |
| 97 | − unsigned shift = SOX_SAMPLE_PRECISION - min(precision, SOX_SAMPLE_PRECISION); | |
| 98 | − return (SOX_SAMPLE_MAX >> shift) << shift; | |
| 99 | −} | |
| 100 | − | |
| 101 | 93 | /* Read in a buffer of data of length len bytes. |
| 102 | 94 | * Returns number of bytes read. |
| 103 | 95 | */ |
| @@ -0,0 +1,248 @@ | ||
| 1 | +/* libSoX effect: gain/norm/etc. (c) 2008-9 robs@users.sourceforge.net | |
| 2 | + * | |
| 3 | + * This library is free software; you can redistribute it and/or modify it | |
| 4 | + * under the terms of the GNU Lesser General Public License as published by | |
| 5 | + * the Free Software Foundation; either version 2.1 of the License, or (at | |
| 6 | + * your option) any later version. | |
| 7 | + * | |
| 8 | + * This library is distributed in the hope that it will be useful, but | |
| 9 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
| 11 | + * General Public License for more details. | |
| 12 | + * | |
| 13 | + * You should have received a copy of the GNU Lesser General Public License | |
| 14 | + * along with this library; if not, write to the Free Software Foundation, | |
| 15 | + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#define LSX_EFF_ALIAS | |
| 19 | +#include "sox_i.h" | |
| 20 | +#include <ctype.h> | |
| 21 | +#include <string.h> | |
| 22 | + | |
| 23 | +typedef struct { | |
| 24 | + sox_bool do_equalise, do_balance, do_balance_no_clip; | |
| 25 | + sox_bool do_restore, make_headroom, do_normalise, do_scan; | |
| 26 | + double fixed_gain; /* Valid only in channel 0 */ | |
| 27 | + | |
| 28 | + double mult; | |
| 29 | + double restore; | |
| 30 | + double rms; | |
| 31 | + off_t num_samples; | |
| 32 | + sox_sample_t min, max; | |
| 33 | + FILE * tmp_file; | |
| 34 | +} priv_t; | |
| 35 | + | |
| 36 | +static int create(sox_effect_t * effp, int argc, char * * argv) | |
| 37 | +{ | |
| 38 | + priv_t * p = (priv_t *)effp->priv; | |
| 39 | + char const * q; | |
| 40 | + for (--argc, ++argv; argc && **argv == '-' && !isdigit(argv[0][1]) && | |
| 41 | + argv[0][1] != '.'; --argc, ++argv) | |
| 42 | + for (q = &argv[0][1]; *q; ++q) switch (*q) { | |
| 43 | + case 'n': p->do_scan = p->do_normalise = sox_true; break; | |
| 44 | + case 'e': p->do_scan = p->do_equalise = sox_true; break; | |
| 45 | + case 'B': p->do_scan = p->do_balance = sox_true; break; | |
| 46 | + case 'b': p->do_scan = p->do_balance_no_clip = sox_true; break; | |
| 47 | + case 'r': p->do_scan = p->do_restore = sox_true; break; | |
| 48 | + case 'h': p->make_headroom = sox_true; break; | |
| 49 | + default: lsx_fail("invalid option `-%c'", *q); return lsx_usage(effp); | |
| 50 | + } | |
| 51 | + if ((p->do_equalise + p->do_balance + p->do_balance_no_clip + p->do_restore)/ sox_true > 1) { | |
| 52 | + lsx_fail("Only one of -e, -B, -b, -r may be given"); | |
| 53 | + return SOX_EOF; | |
| 54 | + } | |
| 55 | + if (p->do_normalise && p->do_restore) { | |
| 56 | + lsx_fail("Only one of -n, -r may be given"); | |
| 57 | + return SOX_EOF; | |
| 58 | + } | |
| 59 | + do {NUMERIC_PARAMETER(fixed_gain, -HUGE_VAL, HUGE_VAL)} while (0); | |
| 60 | + p->fixed_gain = dB_to_linear(p->fixed_gain); | |
| 61 | + return argc? lsx_usage(effp) : SOX_SUCCESS; | |
| 62 | +} | |
| 63 | + | |
| 64 | +static int start(sox_effect_t * effp) | |
| 65 | +{ | |
| 66 | + priv_t * p = (priv_t *)effp->priv; | |
| 67 | + | |
| 68 | + if (effp->flow == 0) { | |
| 69 | + if (p->do_restore) { | |
| 70 | + if (!effp->in_signal.mult || *effp->in_signal.mult >= 1) { | |
| 71 | + lsx_fail("can't restore level"); | |
| 72 | + return SOX_EOF; | |
| 73 | + } | |
| 74 | + p->restore = 1 / *effp->in_signal.mult; | |
| 75 | + } | |
| 76 | + effp->out_signal.mult = p->make_headroom? &p->fixed_gain : NULL; | |
| 77 | + if (!p->do_equalise && !p->do_balance && !p->do_balance_no_clip) | |
| 78 | + effp->flows = 1; | |
| 79 | + } | |
| 80 | + p->mult = p->max = p->min = 0; | |
| 81 | + if (p->do_scan) { | |
| 82 | + p->tmp_file = lsx_tmpfile(); | |
| 83 | + if (p->tmp_file == NULL) { | |
| 84 | + lsx_fail("can't create temporary file: %s", strerror(errno)); | |
| 85 | + return SOX_EOF; | |
| 86 | + } | |
| 87 | + } | |
| 88 | + return SOX_SUCCESS; | |
| 89 | +} | |
| 90 | + | |
| 91 | +static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, | |
| 92 | + sox_sample_t * obuf, size_t * isamp, size_t * osamp) | |
| 93 | +{ | |
| 94 | + priv_t * p = (priv_t *)effp->priv; | |
| 95 | + size_t len; | |
| 96 | + | |
| 97 | + if (p->do_scan) { | |
| 98 | + if (fwrite(ibuf, sizeof(*ibuf), *isamp, p->tmp_file) != *isamp) { | |
| 99 | + lsx_fail("error writing temporary file: %s", strerror(errno)); | |
| 100 | + return SOX_EOF; | |
| 101 | + } | |
| 102 | + if (p->do_balance && !p->do_normalise) | |
| 103 | + for (len = *isamp; len; --len, ++ibuf) { | |
| 104 | + double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf); | |
| 105 | + p->rms += sqr(d); | |
| 106 | + ++p->num_samples; | |
| 107 | + } | |
| 108 | + else if (p->do_balance || p->do_balance_no_clip) | |
| 109 | + for (len = *isamp; len; --len, ++ibuf) { | |
| 110 | + double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf); | |
| 111 | + p->rms += sqr(d); | |
| 112 | + ++p->num_samples; | |
| 113 | + p->max = max(p->max, *ibuf); | |
| 114 | + p->min = min(p->min, *ibuf); | |
| 115 | + } | |
| 116 | + else for (len = *isamp; len; --len, ++ibuf) { | |
| 117 | + p->max = max(p->max, *ibuf); | |
| 118 | + p->min = min(p->min, *ibuf); | |
| 119 | + } | |
| 120 | + *osamp = 0; /* samples not output until drain */ | |
| 121 | + } | |
| 122 | + else { | |
| 123 | + double mult = ((priv_t *)(effp - effp->flow)->priv)->fixed_gain; | |
| 124 | + len = *isamp = *osamp = min(*isamp, *osamp); | |
| 125 | + for (; len; --len, ++ibuf) | |
| 126 | + *obuf++ = SOX_ROUND_CLIP_COUNT(*ibuf * mult, effp->clips); | |
| 127 | + } | |
| 128 | + return SOX_SUCCESS; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static void start_drain(sox_effect_t * effp) | |
| 132 | +{ | |
| 133 | + priv_t * p = (priv_t *)effp->priv; | |
| 134 | + double max = SOX_SAMPLE_MAX, max_peak = 0, max_rms = 0; | |
| 135 | + size_t i; | |
| 136 | + | |
| 137 | + if (p->do_balance || p->do_balance_no_clip) { | |
| 138 | + for (i = 0; i < effp->flows; ++i) { | |
| 139 | + priv_t * q = (priv_t *)(effp - effp->flow + i)->priv; | |
| 140 | + max_rms = max(max_rms, sqrt(q->rms / q->num_samples)); | |
| 141 | + rewind(q->tmp_file); | |
| 142 | + } | |
| 143 | + for (i = 0; i < effp->flows; ++i) { | |
| 144 | + priv_t * q = (priv_t *)(effp - effp->flow + i)->priv; | |
| 145 | + double this_rms = sqrt(q->rms / q->num_samples); | |
| 146 | + double this_peak = max(q->max / max, q->min / (double)SOX_SAMPLE_MIN); | |
| 147 | + q->mult = this_rms != 0? max_rms / this_rms : 1; | |
| 148 | + max_peak = max(max_peak, q->mult * this_peak); | |
| 149 | + q->mult *= p->fixed_gain; | |
| 150 | + } | |
| 151 | + if (p->do_normalise || (p->do_balance_no_clip && max_peak > 1)) | |
| 152 | + for (i = 0; i < effp->flows; ++i) { | |
| 153 | + priv_t * q = (priv_t *)(effp - effp->flow + i)->priv; | |
| 154 | + q->mult /= max_peak; | |
| 155 | + } | |
| 156 | + } else if (p->do_equalise && !p->do_normalise) { | |
| 157 | + for (i = 0; i < effp->flows; ++i) { | |
| 158 | + priv_t * q = (priv_t *)(effp - effp->flow + i)->priv; | |
| 159 | + double this_peak = max(q->max / max, q->min / (double)SOX_SAMPLE_MIN); | |
| 160 | + max_peak = max(max_peak, this_peak); | |
| 161 | + q->mult = p->fixed_gain / this_peak; | |
| 162 | + rewind(q->tmp_file); | |
| 163 | + } | |
| 164 | + for (i = 0; i < effp->flows; ++i) { | |
| 165 | + priv_t * q = (priv_t *)(effp - effp->flow + i)->priv; | |
| 166 | + q->mult *= max_peak; | |
| 167 | + } | |
| 168 | + } else { | |
| 169 | + p->mult = min(max / p->max, (double)SOX_SAMPLE_MIN / p->min); | |
| 170 | + if (p->do_restore) { | |
| 171 | + if (p->restore > p->mult) | |
| 172 | + lsx_debug("%.3gdB not restored", linear_to_dB(p->restore / p->mult)); | |
| 173 | + else p->mult = p->restore; | |
| 174 | + } | |
| 175 | + p->mult *= p->fixed_gain; | |
| 176 | + rewind(p->tmp_file); | |
| 177 | + } | |
| 178 | +} | |
| 179 | + | |
| 180 | +static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp) | |
| 181 | +{ | |
| 182 | + priv_t * p = (priv_t *)effp->priv; | |
| 183 | + size_t len; | |
| 184 | + int result = SOX_SUCCESS; | |
| 185 | + | |
| 186 | + if (p->do_scan) { | |
| 187 | + if (!p->mult) | |
| 188 | + start_drain(effp); | |
| 189 | + len = fread(obuf, sizeof(*obuf), *osamp, p->tmp_file); | |
| 190 | + if (len != *osamp && !feof(p->tmp_file)) { | |
| 191 | + lsx_fail("error reading temporary file: %s", strerror(errno)); | |
| 192 | + result = SOX_EOF; | |
| 193 | + } | |
| 194 | + if (p->mult > 1) for (*osamp = len; len; --len, ++obuf) | |
| 195 | + *obuf = SOX_ROUND_CLIP_COUNT(*obuf * p->mult, effp->clips); | |
| 196 | + else for (*osamp = len; len; --len, ++obuf) | |
| 197 | + *obuf = floor(*obuf * p->mult + .5); | |
| 198 | + } | |
| 199 | + else *osamp = 0; | |
| 200 | + return result; | |
| 201 | +} | |
| 202 | + | |
| 203 | +static int stop(sox_effect_t * effp) | |
| 204 | +{ | |
| 205 | + priv_t * p = (priv_t *)effp->priv; | |
| 206 | + if (p->do_scan) | |
| 207 | + fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */ | |
| 208 | + return SOX_SUCCESS; | |
| 209 | +} | |
| 210 | + | |
| 211 | +sox_effect_handler_t const * sox_gain_effect_fn(void) | |
| 212 | +{ | |
| 213 | + static sox_effect_handler_t handler = { | |
| 214 | + "gain", "[-e|-b|-B|-r] [-n] [-h] [gain-dB]", SOX_EFF_GAIN, | |
| 215 | + create, start, flow, drain, stop, NULL, sizeof(priv_t)}; | |
| 216 | + return &handler; | |
| 217 | +} | |
| 218 | + | |
| 219 | +/*------------------ emulation of the old `normalise' effect -----------------*/ | |
| 220 | + | |
| 221 | +static int norm_getopts(sox_effect_t * effp, int argc, char * * argv) | |
| 222 | +{ | |
| 223 | + char * argv2[3]; | |
| 224 | + int argc2 = 0; | |
| 225 | + | |
| 226 | + argv2[argc2++] = argv[0], --argc, ++argv; | |
| 227 | + if (argc && !strcmp(*argv, "-i")) | |
| 228 | + argv2[argc2++] = "-en", --argc, ++argv; | |
| 229 | + else if (argc && !strcmp(*argv, "-b")) | |
| 230 | + argv2[argc2++] = "-B", --argc, ++argv; | |
| 231 | + if (argc2 > 1) | |
| 232 | + lsx_warn("this use is deprecated; use `gain %s' instead", argv2[1]); | |
| 233 | + else argv2[argc2++] = "-n"; | |
| 234 | + if (argc) | |
| 235 | + argv2[argc2++] = *argv, --argc, ++argv; | |
| 236 | + return argc? lsx_usage(effp) : | |
| 237 | + sox_gain_effect_fn()->getopts(effp, argc2, argv2); | |
| 238 | +} | |
| 239 | + | |
| 240 | +sox_effect_handler_t const * sox_norm_effect_fn(void) | |
| 241 | +{ | |
| 242 | + static sox_effect_handler_t handler; | |
| 243 | + handler = *sox_gain_effect_fn(); | |
| 244 | + handler.name = "norm"; | |
| 245 | + handler.usage = "[level]"; | |
| 246 | + handler.getopts = norm_getopts; | |
| 247 | + return &handler; | |
| 248 | +} | |
| @@ -195,10 +195,9 @@ static size_t sox_gsmwrite(sox_format_t * ft, const sox_sample_t *buf, size_t sa · 194 unmodified lines | ||
| 195 | 195 | |
| 196 | 196 | while (done < samp) |
| 197 | 197 | { |
| 198 | − SOX_SAMPLE_LOCALS; | |
| 199 | 198 | while ((p->samplePtr < p->sampleTop) && (done < samp)) |
| 200 | 199 | *(p->samplePtr)++ = |
| 201 | − SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips); | |
| 200 | + SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]); | |
| 202 | 201 | |
| 203 | 202 | if (p->samplePtr == p->sampleTop) |
| 204 | 203 | { |
| @@ -277,9 +277,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 276 unmodified lines | ||
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 | for (i = 0; i < len; i++) { |
| 280 | − SOX_SAMPLE_LOCALS; | |
| 281 | 280 | datum = *buf++; |
| 282 | − p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum, ft->clips); | |
| 281 | + p->data[p->pos++] = SOX_SAMPLE_TO_UNSIGNED_8BIT(datum); | |
| 283 | 282 | } |
| 284 | 283 | |
| 285 | 284 | return len; |
| @@ -237,7 +237,7 @@ static int sox_ladspa_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sa · 236 unmodified lines | ||
| 237 | 237 | if (l_st->input_port != ULONG_MAX) { |
| 238 | 238 | /* Copy the input; FIXME: Assume LADSPA_Data == float! */ |
| 239 | 239 | for (i = 0; i < len; i++) |
| 240 | − buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips); | |
| 240 | + buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i]); | |
| 241 | 241 | |
| 242 | 242 | /* Connect the input port */ |
| 243 | 243 | l_st->desc->connect_port(l_st->handle, l_st->input_port, buf); |
| @@ -291,7 +291,7 @@ static int sox_ladspa_stop(sox_effect_t * effp) · 47 unmodified lines | ||
| 291 | 291 | static sox_effect_handler_t sox_ladspa_effect = { |
| 292 | 292 | "ladspa", |
| 293 | 293 | "MODULE [PLUGIN] [ARGUMENT...]", |
| 294 | − 0, | |
| 294 | + SOX_EFF_GAIN, | |
| 295 | 295 | sox_ladspa_getopts, |
| 296 | 296 | sox_ladspa_start, |
| 297 | 297 | sox_ladspa_flow, |
| @@ -179,8 +179,7 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 178 unmodified lines | ||
| 179 | 179 | |
| 180 | 180 | while (len > 0) { |
| 181 | 181 | while (len > 0 && lpc->samples < LPC10_SAMPLES_PER_FRAME) { |
| 182 | − SOX_SAMPLE_LOCALS; | |
| 183 | − lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++], ft->clips); | |
| 182 | + lpc->speech[lpc->samples++] = SOX_SAMPLE_TO_FLOAT_32BIT(buf[nwritten++]); | |
| 184 | 183 | len--; |
| 185 | 184 | } |
| 186 | 185 | |
| @@ -492,7 +492,7 @@ const sox_effect_handler_t *sox_mcompand_effect_fn(void) · 491 unmodified lines | ||
| 492 | 492 | " attack1,decay1[,attack2,decay2...]\n" |
| 493 | 493 | " in-dB1,out-dB1[,in-dB2,out-dB2...]\n" |
| 494 | 494 | " [ gain [ initial-volume [ delay ] ] ]", |
| 495 | − SOX_EFF_MCHAN, | |
| 495 | + SOX_EFF_MCHAN | SOX_EFF_GAIN, | |
| 496 | 496 | getopts, start, flow, drain, stop, kill, sizeof(priv_t) |
| 497 | 497 | }; |
| 498 | 498 | |
| @@ -485,6 +485,19 @@ static int start(sox_effect_t * effp) · 484 unmodified lines | ||
| 485 | 485 | } |
| 486 | 486 | } |
| 487 | 487 | |
| 488 | + if (effp->in_signal.mult) { | |
| 489 | + double max_sum = 0; | |
| 490 | + | |
| 491 | + for (j = 0; j < (int)effp->out_signal.channels; ++j) { | |
| 492 | + double sum = 0; | |
| 493 | + for (i = 0; i < (int)effp->in_signal.channels; ++i) | |
| 494 | + sum += fabs(mixer->sources[mixer->mix == MIX_CENTER? 0 : i][j]); | |
| 495 | + max_sum = max(max_sum, sum); | |
| 496 | + } | |
| 497 | + if (max_sum > 1) | |
| 498 | + *effp->in_signal.mult /= max_sum; | |
| 499 | + } | |
| 500 | + | |
| 488 | 501 | if (effp->in_signal.channels != effp->out_signal.channels) |
| 489 | 502 | return SOX_SUCCESS; |
| 490 | 503 | |
| @@ -406,7 +406,6 @@ static size_t sox_mp3write(sox_format_t * ft, const sox_sample_t *buf, size_t sa · 405 unmodified lines | ||
| 406 | 406 | int i,j; |
| 407 | 407 | ptrdiff_t done = 0; |
| 408 | 408 | size_t written; |
| 409 | − SOX_SAMPLE_LOCALS; | |
| 410 | 409 | |
| 411 | 410 | /* NOTE: This logic assumes that "short int" is 16-bits |
| 412 | 411 | * on all platforms. It happens to be for all that I know |
| @@ -435,15 +434,15 @@ static size_t sox_mp3write(sox_format_t * ft, const sox_sample_t *buf, size_t sa · 22 unmodified lines | ||
| 435 | 434 | j=0; |
| 436 | 435 | for (i=0; i<nsamples; i++) |
| 437 | 436 | { |
| 438 | − buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips); | |
| 439 | − buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips); | |
| 437 | + buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]); | |
| 438 | + buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]); | |
| 440 | 439 | } |
| 441 | 440 | } |
| 442 | 441 | else |
| 443 | 442 | { |
| 444 | 443 | j=0; |
| 445 | 444 | for (i=0; i<nsamples; i++) |
| 446 | − buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips); | |
| 445 | + buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++]); | |
| 447 | 446 | } |
| 448 | 447 | |
| 449 | 448 | mp3buffer_size = 1.25 * nsamples + 7200; |
| @@ -116,7 +116,7 @@ static int sox_noiseprof_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox · 115 unmodified lines | ||
| 116 | 116 | size_t *isamp, size_t *osamp) |
| 117 | 117 | { |
| 118 | 118 | priv_t * p = (priv_t *) effp->priv; |
| 119 | − size_t samp = min(*isamp, *osamp), dummy = 0; /* No need to clip count */ | |
| 119 | + size_t samp = min(*isamp, *osamp); | |
| 120 | 120 | size_t chans = effp->in_signal.channels; |
| 121 | 121 | size_t i, j, n = min(samp / chans, WINDOWSIZE - p->bufdata); |
| 122 | 122 | |
| @@ -125,11 +125,10 @@ static int sox_noiseprof_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox · 2 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | /* Collect data for every channel. */ |
| 127 | 127 | for (i = 0; i < chans; i ++) { |
| 128 | − SOX_SAMPLE_LOCALS; | |
| 129 | 128 | chandata_t * chan = &(p->chandata[i]); |
| 130 | 129 | for (j = 0; j < n; j ++) |
| 131 | 130 | chan->window[j + p->bufdata] = |
| 132 | − SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + j * chans], dummy); | |
| 131 | + SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + j * chans]); | |
| 133 | 132 | if (n + p->bufdata == WINDOWSIZE) |
| 134 | 133 | collect_data(chan); |
| 135 | 134 | } |
| @@ -208,7 +207,7 @@ static int sox_noiseprof_stop(sox_effect_t * effp) · 72 unmodified lines | ||
| 208 | 207 | static sox_effect_handler_t sox_noiseprof_effect = { |
| 209 | 208 | "noiseprof", |
| 210 | 209 | "[profile-file]", |
| 211 | − SOX_EFF_MCHAN, | |
| 210 | + SOX_EFF_MCHAN | SOX_EFF_MODIFY, | |
| 212 | 211 | sox_noiseprof_getopts, |
| 213 | 212 | sox_noiseprof_start, |
| 214 | 213 | sox_noiseprof_flow, |
| @@ -285,7 +285,6 @@ static int sox_noisered_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_ · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | /* Reduce noise on every channel. */ |
| 287 | 287 | for (i = 0; i < tracks; i ++) { |
| 288 | − SOX_SAMPLE_LOCALS; | |
| 289 | 288 | chandata_t* chan = &(data->chandata[i]); |
| 290 | 289 | size_t j; |
| 291 | 290 | |
| @@ -294,7 +293,7 @@ static int sox_noisered_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_ · 2 unmodified lines | ||
| 294 | 293 | |
| 295 | 294 | for (j = 0; j < ncopy; j ++) |
| 296 | 295 | chan->window[oldbuf + j] = |
| 297 | − SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j], effp->clips); | |
| 296 | + SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i + tracks * j]); | |
| 298 | 297 | |
| 299 | 298 | if (!whole_window) |
| 300 | 299 | continue; |
| @@ -1,127 +0,0 @@ | ||
| 1 | −/* libSoX effect: Normalise (c) 2008 robs@users.sourceforge.net | |
| 2 | − * | |
| 3 | − * This library is free software; you can redistribute it and/or modify it | |
| 4 | − * under the terms of the GNU Lesser General Public License as published by | |
| 5 | − * the Free Software Foundation; either version 2.1 of the License, or (at | |
| 6 | − * your option) any later version. | |
| 7 | − * | |
| 8 | − * This library is distributed in the hope that it will be useful, but | |
| 9 | − * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
| 11 | − * General Public License for more details. | |
| 12 | − * | |
| 13 | − * You should have received a copy of the GNU Lesser General Public License | |
| 14 | − * along with this library; if not, write to the Free Software Foundation, | |
| 15 | − * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 16 | − */ | |
| 17 | − | |
| 18 | −#include "sox_i.h" | |
| 19 | −#include <string.h> | |
| 20 | − | |
| 21 | −typedef struct { | |
| 22 | − sox_bool individual, balance; | |
| 23 | − double norm0; /* Multiplier to take to 0dB FSD */ | |
| 24 | − double level; /* Multiplier to take to 'level' */ | |
| 25 | − double rms; | |
| 26 | − off_t num_samples; | |
| 27 | − sox_sample_t min, max; | |
| 28 | − FILE * tmp_file; | |
| 29 | −} priv_t; | |
| 30 | − | |
| 31 | −static int create(sox_effect_t * effp, int argc, char * * argv) | |
| 32 | −{ | |
| 33 | − priv_t * p = (priv_t *)effp->priv; | |
| 34 | − --argc, ++argv; | |
| 35 | − if (argc && !strcmp(*argv, "-i")) p->individual = sox_true, ++argv, --argc; | |
| 36 | − if (argc && !strcmp(*argv, "-b")) p->balance = sox_true, ++argv, --argc; | |
| 37 | − do {NUMERIC_PARAMETER(level, -100, 0)} while (0); | |
| 38 | − p->level = dB_to_linear(p->level); | |
| 39 | − return argc? lsx_usage(effp) : SOX_SUCCESS; | |
| 40 | −} | |
| 41 | − | |
| 42 | −static int start(sox_effect_t * effp) | |
| 43 | −{ | |
| 44 | − priv_t * p = (priv_t *)effp->priv; | |
| 45 | − if (!(p->individual || p->balance)) | |
| 46 | − effp->flows = 1; | |
| 47 | − p->norm0 = p->max = p->min = 0; | |
| 48 | − p->tmp_file = lsx_tmpfile(); | |
| 49 | − if (p->tmp_file == NULL) { | |
| 50 | − lsx_fail("can't create temporary file: %s", strerror(errno)); | |
| 51 | − return SOX_EOF; | |
| 52 | − } | |
| 53 | − return SOX_SUCCESS; | |
| 54 | −} | |
| 55 | − | |
| 56 | −static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, | |
| 57 | − sox_sample_t * obuf, size_t * isamp, size_t * osamp) | |
| 58 | −{ | |
| 59 | − priv_t * p = (priv_t *)effp->priv; | |
| 60 | − size_t len; | |
| 61 | − | |
| 62 | − if (fwrite(ibuf, sizeof(*ibuf), *isamp, p->tmp_file) != *isamp) { | |
| 63 | − lsx_fail("error writing temporary file: %s", strerror(errno)); | |
| 64 | − return SOX_EOF; | |
| 65 | − } | |
| 66 | − if (p->balance) for (len = *isamp; len; --len, ++ibuf) { | |
| 67 | − SOX_SAMPLE_LOCALS; | |
| 68 | − size_t dummy = 0; | |
| 69 | − double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf, dummy); | |
| 70 | − p->rms += sqr(d); | |
| 71 | − ++p->num_samples; | |
| 72 | − } | |
| 73 | − else for (len = *isamp; len; --len, ++ibuf) { | |
| 74 | − p->max = max(p->max, *ibuf); | |
| 75 | − p->min = min(p->min, *ibuf); | |
| 76 | − } | |
| 77 | − (void)obuf, *osamp = 0; /* samples not output until drain */ | |
| 78 | − return SOX_SUCCESS; | |
| 79 | −} | |
| 80 | − | |
| 81 | −static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp) | |
| 82 | −{ | |
| 83 | − priv_t * p = (priv_t *)effp->priv; | |
| 84 | − size_t len, i; | |
| 85 | − int result = SOX_SUCCESS; | |
| 86 | − | |
| 87 | − if (!p->norm0) { | |
| 88 | − if (p->balance) { | |
| 89 | − double max_rms = 0, this_rms = sqrt(p->rms / p->num_samples); | |
| 90 | − sox_effect_t * effects = effp - effp->flow; | |
| 91 | − for (i = 0; i < effp->flows; ++i) { | |
| 92 | − priv_t * q = (priv_t *)(effects + i)->priv; | |
| 93 | − max_rms = max(max_rms, sqrt(q->rms / q->num_samples)); | |
| 94 | − } | |
| 95 | − p->norm0 = p->level * (this_rms != 0? max_rms / this_rms : 1); | |
| 96 | − } | |
| 97 | − else { | |
| 98 | − double max = lsx_sample_max(effp->out_encoding); | |
| 99 | − p->norm0 = p->level * min(max / p->max, (double)SOX_SAMPLE_MIN / p->min); | |
| 100 | − } | |
| 101 | − rewind(p->tmp_file); | |
| 102 | − } | |
| 103 | − len = fread(obuf, sizeof(*obuf), *osamp, p->tmp_file); | |
| 104 | − if (len != *osamp && !feof(p->tmp_file)) { | |
| 105 | − lsx_fail("error reading temporary file: %s", strerror(errno)); | |
| 106 | − result = SOX_EOF; | |
| 107 | − } | |
| 108 | − if (p->balance) for (*osamp = len; len; --len, ++obuf) | |
| 109 | − *obuf = SOX_ROUND_CLIP_COUNT(*obuf * p->norm0, effp->clips); | |
| 110 | − else for (*osamp = len; len; --len, ++obuf) | |
| 111 | − *obuf = floor(*obuf * p->norm0 + .5); | |
| 112 | − return result; | |
| 113 | −} | |
| 114 | − | |
| 115 | −static int stop(sox_effect_t * effp) | |
| 116 | −{ | |
| 117 | − priv_t * p = (priv_t *)effp->priv; | |
| 118 | − fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */ | |
| 119 | − return SOX_SUCCESS; | |
| 120 | −} | |
| 121 | − | |
| 122 | −sox_effect_handler_t const * sox_norm_effect_fn(void) | |
| 123 | −{ | |
| 124 | − static sox_effect_handler_t handler = {"norm", "[-i|-b] [level]", 0, | |
| 125 | − create, start, flow, drain, stop, NULL, sizeof(priv_t)}; | |
| 126 | − return &handler; | |
| 127 | −} | |
| @@ -52,7 +52,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 51 unmodified lines | ||
| 52 | 52 | size_t dummy = 0, len = *isamp = *osamp = min(*isamp, *osamp); |
| 53 | 53 | while (len--) { |
| 54 | 54 | SOX_SAMPLE_LOCALS; |
| 55 | − double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, dummy), d0 = d; | |
| 55 | + double d = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++), d0 = d; | |
| 56 | 56 | d *= p->gain; |
| 57 | 57 | d += p->colour; |
| 58 | 58 | d = d < -1? -2./3 : d > 1? 2./3 : d - d * d * d * (1./3); |
| @@ -66,6 +66,6 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 7 unmodified lines | ||
| 66 | 66 | sox_effect_handler_t const * sox_overdrive_effect_fn(void) |
| 67 | 67 | { |
| 68 | 68 | static sox_effect_handler_t handler = {"overdrive", "[gain [colour]]", |
| 69 | − 0, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)}; | |
| 69 | + SOX_EFF_GAIN, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)}; | |
| 70 | 70 | return &handler; |
| 71 | 71 | } |
| @@ -139,7 +139,7 @@ sox_effect_handler_t const * sox_phaser_effect_fn(void) · 138 unmodified lines | ||
| 139 | 139 | { |
| 140 | 140 | static sox_effect_handler_t handler = { |
| 141 | 141 | "phaser", "gain-in gain-out delay decay speed [ -s | -t ]", |
| 142 | − SOX_EFF_LENGTH, getopts, start, flow, NULL, stop, NULL, sizeof(priv_t) | |
| 142 | + SOX_EFF_LENGTH | SOX_EFF_GAIN, getopts, start, flow, NULL, stop, NULL, sizeof(priv_t) | |
| 143 | 143 | }; |
| 144 | 144 | return &handler; |
| 145 | 145 | } |
| @@ -494,7 +494,7 @@ static int start(sox_effect_t * effp) · 493 unmodified lines | ||
| 494 | 494 | if (effp->in_signal.rate == out_rate) |
| 495 | 495 | return SOX_EFF_NULL; |
| 496 | 496 | |
| 497 | − if (effp->flow == 0 && effp->in_signal.mult) | |
| 497 | + if (effp->in_signal.mult) | |
| 498 | 498 | *effp->in_signal.mult *= .705; /* 1/(2/sinc(pi/3)-1); see De Soras 4.1.2 */ |
| 499 | 499 | |
| 500 | 500 | effp->out_signal.channels = effp->in_signal.channels; |
| @@ -516,7 +516,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 15 unmodified lines | ||
| 516 | 516 | |
| 517 | 517 | if (*isamp && odone < *osamp) { |
| 518 | 518 | sample_t * t = rate_input(&p->rate, NULL, *isamp); |
| 519 | − for (i = *isamp; i; --i) *t++ = FROM_SOX(*ibuf++, effp->clips); | |
| 519 | + for (i = *isamp; i; --i) *t++ = FROM_SOX(*ibuf++); | |
| 520 | 520 | rate_process(&p->rate); |
| 521 | 521 | } |
| 522 | 522 | else *isamp = 0; |
| @@ -14,8 +14,8 @@ typedef uint16_t uint14_t; · 13 unmodified lines | ||
| 14 | 14 | typedef uint16_t uint13_t; |
| 15 | 15 | #define SOX_ULAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_ulaw2linear16(d),clips) |
| 16 | 16 | #define SOX_ALAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_alaw2linear16(d),clips) |
| 17 | −#define SOX_SAMPLE_TO_ULAW_BYTE(d,c) sox_14linear2ulaw(SOX_SAMPLE_TO_UNSIGNED(14,d,c) - 0x2000) | |
| 18 | −#define SOX_SAMPLE_TO_ALAW_BYTE(d,c) sox_13linear2alaw(SOX_SAMPLE_TO_UNSIGNED(13,d,c) - 0x1000) | |
| 17 | +#define SOX_SAMPLE_TO_ULAW_BYTE(d) sox_14linear2ulaw(SOX_SAMPLE_TO_UNSIGNED(14,d) - 0x2000) | |
| 18 | +#define SOX_SAMPLE_TO_ALAW_BYTE(d) sox_13linear2alaw(SOX_SAMPLE_TO_UNSIGNED(13,d) - 0x1000) | |
| 19 | 19 | |
| 20 | 20 | int lsx_rawseek(sox_format_t * ft, uint64_t offset) |
| 21 | 21 | { |
| @@ -95,11 +95,10 @@ READ_SAMPLES_FUNC(df, sizeof(double), su, double, double, SOX_FLOAT_64BIT_TO_SAM · 73 unmodified lines | ||
| 95 | 95 | static size_t sox_write_ ## sign ## type ## _samples( \ |
| 96 | 96 | sox_format_t * ft, sox_sample_t const * buf, size_t len) \ |
| 97 | 97 | { \ |
| 98 | − SOX_SAMPLE_LOCALS; \ | |
| 99 | 98 | size_t n, nwritten; \ |
| 100 | 99 | ctype *data = lsx_malloc(sizeof(ctype) * len); \ |
| 101 | 100 | for (n = 0; n < len; n++) \ |
| 102 | − data[n] = cast(buf[n], ft->clips); \ | |
| 101 | + data[n] = cast(buf[n]); \ | |
| 103 | 102 | nwritten = lsx_write_ ## type ## _buf(ft, (uctype *)data, len); \ |
| 104 | 103 | free(data); \ |
| 105 | 104 | return nwritten; \ |
| @@ -95,6 +95,19 @@ static int parse(sox_effect_t * effp, char * * argv, unsigned channels) · 94 unmodified lines | ||
| 95 | 95 | p->out_specs[i].in_specs[j].multiplier = (p->mode == automatic || (p->mode == semi && !mul_spec)) ? mult : 1; |
| 96 | 96 | } |
| 97 | 97 | effp->out_signal.channels = p->num_out_channels; |
| 98 | + | |
| 99 | + if (effp->in_signal.mult) { | |
| 100 | + double max_sum = 0; | |
| 101 | + | |
| 102 | + for (j = 0; j < effp->out_signal.channels; j++) { | |
| 103 | + double sum = 0; | |
| 104 | + for (i = 0; i < p->out_specs[j].num_in_channels; i++) | |
| 105 | + sum += fabs(p->out_specs[j].in_specs[i].multiplier); | |
| 106 | + max_sum = max(max_sum, sum); | |
| 107 | + } | |
| 108 | + if (max_sum > 1) | |
| 109 | + *effp->in_signal.mult /= max_sum; | |
| 110 | + } | |
| 98 | 111 | return SOX_SUCCESS; |
| 99 | 112 | } |
| 100 | 113 | |
| @@ -212,6 +212,9 @@ static int start(sox_effect_t * effp) · 211 unmodified lines | ||
| 212 | 212 | &p->chan[i].reverb, effp->in_signal.rate, p->wet_gain_dB, p->room_scale, |
| 213 | 213 | p->reverberance, p->hf_damping, p->pre_delay_ms, p->stereo_depth, |
| 214 | 214 | effp->global_info->global_info->bufsiz / p->ochannels, p->chan[i].wet); |
| 215 | + | |
| 216 | + if (effp->in_signal.mult) | |
| 217 | + *effp->in_signal.mult /= !p->wet_only + 2 * dB_to_linear(max(0,p->wet_gain_dB)); | |
| 215 | 218 | return SOX_SUCCESS; |
| 216 | 219 | } |
| 217 | 220 | |
| @@ -226,7 +229,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 8 unmodified lines | ||
| 226 | 229 | for (c = 0; c < p->ichannels; ++c) |
| 227 | 230 | p->chan[c].dry = fifo_write(&p->chan[c].reverb.input_fifo, len, 0); |
| 228 | 231 | for (i = 0; i < len; ++i) for (c = 0; c < p->ichannels; ++c) |
| 229 | − p->chan[c].dry[i] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips); | |
| 232 | + p->chan[c].dry[i] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++); | |
| 230 | 233 | for (c = 0; c < p->ichannels; ++c) |
| 231 | 234 | reverb_process(&p->chan[c].reverb, len); |
| 232 | 235 | if (p->ichannels == 2) for (i = 0; i < len; ++i) for (w = 0; w < 2; ++w) { |
| @@ -275,27 +275,25 @@ static int aboveThreshold(sox_effect_t * effp, sox_sample_t value, double thresh · 274 unmodified lines | ||
| 275 | 275 | { |
| 276 | 276 | double ratio; |
| 277 | 277 | int rc; |
| 278 | − sox_sample_t dummy_clipped_count = 0; | |
| 279 | 278 | |
| 280 | 279 | /* When scaling low bit data, noise values got scaled way up */ |
| 281 | 280 | /* Only consider the original bits when looking for silence */ |
| 282 | 281 | switch(effp->in_signal.precision) |
| 283 | 282 | { |
| 284 | − SOX_SAMPLE_LOCALS; | |
| 285 | 283 | case 8: |
| 286 | − value = SOX_SAMPLE_TO_SIGNED_8BIT(value, dummy_clipped_count); | |
| 284 | + value = SOX_SAMPLE_TO_SIGNED_8BIT(value); | |
| 287 | 285 | ratio = (double)abs(value) / (double)SOX_INT8_MAX; |
| 288 | 286 | break; |
| 289 | 287 | case 16: |
| 290 | − value = SOX_SAMPLE_TO_SIGNED_16BIT(value, dummy_clipped_count); | |
| 288 | + value = SOX_SAMPLE_TO_SIGNED_16BIT(value); | |
| 291 | 289 | ratio = (double)abs(value) / (double)SOX_INT16_MAX; |
| 292 | 290 | break; |
| 293 | 291 | case 24: |
| 294 | − value = SOX_SAMPLE_TO_SIGNED_24BIT(value, dummy_clipped_count); | |
| 292 | + value = SOX_SAMPLE_TO_SIGNED_24BIT(value); | |
| 295 | 293 | ratio = (double)abs(value) / (double)SOX_INT24_MAX; |
| 296 | 294 | break; |
| 297 | 295 | case 32: |
| 298 | − value = SOX_SAMPLE_TO_SIGNED_32BIT(value,); | |
| 296 | + value = SOX_SAMPLE_TO_SIGNED_32BIT(value); | |
| 299 | 297 | ratio = (double)abs(value) / (double)SOX_INT32_MAX; |
| 300 | 298 | break; |
| 301 | 299 | default: |
| @@ -159,9 +159,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 158 unmodified lines | ||
| 159 | 159 | switch (ft->encoding.bits_per_sample) { |
| 160 | 160 | case 8: |
| 161 | 161 | switch (ft->encoding.encoding) { |
| 162 | − SOX_SAMPLE_LOCALS; | |
| 163 | 162 | case SOX_ENCODING_UNSIGNED: |
| 164 | − while (done < len && lsx_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips)) == SOX_SUCCESS) | |
| 163 | + while (done < len && lsx_writeb(ft, SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++)) == SOX_SUCCESS) | |
| 165 | 164 | ++done; |
| 166 | 165 | break; |
| 167 | 166 | default: |
| @@ -368,8 +368,7 @@ static size_t sox_smpwrite(sox_format_t * ft, const sox_sample_t *buf, size_t le · 367 unmodified lines | ||
| 368 | 368 | size_t done = 0; |
| 369 | 369 | |
| 370 | 370 | while(done < len) { |
| 371 | − SOX_SAMPLE_LOCALS; | |
| 372 | − datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips); | |
| 371 | + datum = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++); | |
| 373 | 372 | lsx_writew(ft, (uint16_t)datum); |
| 374 | 373 | smp->NoOfSamps++; |
| 375 | 374 | done++; |
| @@ -1,9 +1,9 @@ | ||
| 1 | 1 | /* SoX - The Swiss Army Knife of Audio Manipulation. |
| 2 | 2 | * |
| 3 | − * This is the main function for the command line sox program. | |
| 3 | + * This is the main function for the SoX command line programs. | |
| 4 | 4 | * |
| 5 | + * Copyright 1998-2009 Chris Bagwell and SoX contributors | |
| 5 | 6 | * Copyright 1991 Lance Norskog And Sundry Contributors |
| 6 | − * Copyright 1998-2008 Chris Bagwell and SoX contributors | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | 9 | * under the terms of the GNU General Public License as published by the |
| @@ -133,6 +133,7 @@ typedef struct { · 123 unmodified lines | ||
| 133 | 133 | sox_signalinfo_t signal; |
| 134 | 134 | sox_encodinginfo_t encoding; |
| 135 | 135 | double volume; |
| 136 | + sox_sample_t offset; | |
| 136 | 137 | double replay_gain; |
| 137 | 138 | sox_oob_t oob; |
| 138 | 139 | sox_bool no_glob; |
| @@ -197,8 +198,7 @@ static sox_bool single_threaded = sox_false; · 58 unmodified lines | ||
| 197 | 198 | static struct termios original_termios; |
| 198 | 199 | #endif |
| 199 | 200 | |
| 200 | −static sox_bool stdin_is_a_tty, is_player; | |
| 201 | − | |
| 201 | +static sox_bool stdin_is_a_tty, is_player, is_guarded, do_guarded_norm; | |
| 202 | 202 | |
| 203 | 203 | /* Cleanup atexit() function, hence always called. */ |
| 204 | 204 | static void cleanup(void) |
| @@ -214,7 +214,7 @@ static void cleanup(void) · 9 unmodified lines | ||
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | if (file_count) { |
| 217 | − if (ofile->ft) { | |
| 217 | + if (ofile->ft) { | |
| 218 | 218 | if (!success && ofile->ft->fp) { /* If we failed part way through */ |
| 219 | 219 | struct stat st; /* writing a normal file, remove it. */ |
| 220 | 220 | fstat(fileno(ofile->ft->fp), &st); |
| @@ -405,13 +405,14 @@ static void progress_to_next_input_file(file_t * f) · 184 unmodified lines | ||
| 405 | 405 | display_file_info(f->ft, f, sox_false); |
| 406 | 406 | if (f->volume == HUGE_VAL) |
| 407 | 407 | f->volume = 1; |
| 408 | + if (f->encoding.half_bit && f->ft->signal.precision < 32) | |
| 409 | + f->offset = 1 << (31 - f->ft->signal.precision); | |
| 408 | 410 | if (f->replay_gain != HUGE_VAL) |
| 409 | 411 | f->volume *= pow(10.0, f->replay_gain / 20); |
| 410 | 412 | f->ft->sox_errno = errno = 0; |
| 411 | 413 | } |
| 412 | 414 | |
| 413 | 415 | /* Read up to max `wide' samples. A wide sample contains one sample per channel |
| 414 | − printf("effect %d obeg = %d oend = %d\n", e, effects_chain->effects[e]->obeg, effects_chain->effects[e]->oend); | |
| 415 | 416 | * from the input audio. */ |
| 416 | 417 | static size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, size_t max) |
| 417 | 418 | { |
| @@ -427,11 +428,12 @@ static void balance_input(sox_sample_t * buf, size_t ws, file_t * f) · 9 unmodified lines | ||
| 427 | 428 | { |
| 428 | 429 | size_t s = ws * f->ft->signal.channels; |
| 429 | 430 | |
| 430 | − if (f->volume != 1) | |
| 431 | − while (s--) { | |
| 432 | − double d = f->volume * *buf; | |
| 433 | − *buf++ = SOX_ROUND_CLIP_COUNT(d, f->volume_clips); | |
| 434 | − } | |
| 431 | + if (f->volume == 1 && f->offset !=0 ) while (s--) | |
| 432 | + *buf++ -= f->offset; | |
| 433 | + else if (f->volume != 1 || f->offset !=0 ) while (s--) { | |
| 434 | + double d = f->volume * (*buf - f->offset); | |
| 435 | + *buf++ = SOX_ROUND_CLIP_COUNT(d, f->volume_clips); | |
| 436 | + } | |
| 435 | 437 | } |
| 436 | 438 | |
| 437 | 439 | /* The input combiner: contains one sample buffer per input file, but only |
| @@ -557,12 +559,24 @@ static sox_effect_handler_t const * input_combiner_effect_fn(void) · 119 unmodified lines | ||
| 557 | 559 | return &handler; |
| 558 | 560 | } |
| 559 | 561 | |
| 562 | +static int ostart(sox_effect_t *effp) | |
| 563 | +{ | |
| 564 | + (void)effp; | |
| 565 | + if (effp->out_encoding->half_bit && effp->out_signal.precision < 32) | |
| 566 | + ofile->offset = 1 << (31 - ofile->ft->signal.precision); | |
| 567 | + return SOX_SUCCESS; | |
| 568 | +} | |
| 569 | + | |
| 560 | 570 | static int output_flow(sox_effect_t *effp, sox_sample_t const * ibuf, |
| 561 | 571 | sox_sample_t * obuf, size_t * isamp, size_t * osamp) |
| 562 | 572 | { |
| 573 | + sox_sample_t const * buf; | |
| 563 | 574 | size_t len; |
| 564 | 575 | |
| 565 | 576 | (void)effp, (void)obuf; |
| 577 | + if (ofile->offset != 0 ) for (buf = ibuf, len = *isamp; len; --len, ++buf) | |
| 578 | + *(sox_sample_t *)buf = *buf >= SOX_SAMPLE_MAX - ofile->offset? | |
| 579 | + SOX_SAMPLE_MAX : *buf + ofile->offset; | |
| 566 | 580 | if (show_progress) for (len = 0; len < *isamp; len += effp->in_signal.channels) { |
| 567 | 581 | omax[0] = max(omax[0], ibuf[len]); |
| 568 | 582 | omin[0] = min(omin[0], ibuf[len]); |
| @@ -591,26 +605,49 @@ static int output_flow(sox_effect_t *effp, sox_sample_t const * ibuf, · 22 unmodified lines | ||
| 591 | 605 | static sox_effect_handler_t const * output_effect_fn(void) |
| 592 | 606 | { |
| 593 | 607 | static sox_effect_handler_t handler = { |
| 594 | − "output", 0, SOX_EFF_MCHAN, NULL, NULL, output_flow, NULL, NULL, NULL, 0 | |
| 608 | + "output", 0, SOX_EFF_MCHAN, NULL, ostart, output_flow, NULL, NULL, NULL, 0 | |
| 595 | 609 | }; |
| 596 | 610 | return &handler; |
| 597 | 611 | } |
| 598 | 612 | |
| 599 | −static void add_effect(sox_effects_chain_t *chain, char const *name, | |
| 600 | − int argc, char *argv[], sox_signalinfo_t *signal) | |
| 613 | +static void auto_effect(sox_effects_chain_t *, char const *, int, char **, | |
| 614 | + sox_signalinfo_t *, int *); | |
| 615 | + | |
| 616 | +static int add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, | |
| 617 | + sox_signalinfo_t * in, sox_signalinfo_t const * out, int * guard) { | |
| 618 | + int no_guard = -1; | |
| 619 | + switch (*guard) { | |
| 620 | + case 0: if (!(effp->handler.flags & SOX_EFF_GAIN)) { | |
| 621 | + char * arg = "-h"; | |
| 622 | + auto_effect(chain, "gain", 1, &arg, in, &no_guard); | |
| 623 | + ++*guard; | |
| 624 | + } | |
| 625 | + break; | |
| 626 | + case 1: if (effp->handler.flags & SOX_EFF_GAIN) { | |
| 627 | + char * arg = "-r"; | |
| 628 | + auto_effect(chain, "gain", 1, &arg, in, &no_guard); | |
| 629 | + --*guard; | |
| 630 | + } | |
| 631 | + break; | |
| 632 | + case 2: if (!(effp->handler.flags & SOX_EFF_MODIFY)) { | |
| 633 | + lsx_fail("effects that modify audio must not follow dither"); | |
| 634 | + exit(1); | |
| 635 | + } | |
| 636 | + } | |
| 637 | + return sox_add_effect(chain, effp, in, out); | |
| 638 | +} | |
| 639 | + | |
| 640 | +static void auto_effect(sox_effects_chain_t *chain, char const *name, int argc, | |
| 641 | + char *argv[], sox_signalinfo_t *signal, int * guard) | |
| 601 | 642 | { |
| 602 | 643 | sox_effect_t * effp; |
| 603 | 644 | |
| 604 | 645 | effp = sox_create_effect(sox_find_effect(name)); /* Should always succeed. */ |
| 605 | 646 | |
| 606 | − if (effp->handler.flags & SOX_EFF_DEPRECATED) | |
| 607 | − lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative", | |
| 608 | − effp->handler.name); | |
| 609 | − | |
| 610 | 647 | if (sox_effect_options(effp, argc, argv) == SOX_EOF) |
| 611 | 648 | exit(1); /* The failing effect should have displayed an error message */ |
| 612 | − | |
| 613 | − if (sox_add_effect(chain, effp, signal, &ofile->ft->signal) != SOX_SUCCESS) | |
| 649 | + | |
| 650 | + if (add_effect(chain, effp, signal, &ofile->ft->signal, guard) != SOX_SUCCESS) | |
| 614 | 651 | exit(2); /* The effects chain should have displayed an error message */ |
| 615 | 652 | } |
| 616 | 653 | |
| @@ -621,7 +658,7 @@ static void init_eff_chains(void) · 4 unmodified lines | ||
| 621 | 658 | nuser_effects[0] = 0; |
| 622 | 659 | } /* init_eff_chains */ |
| 623 | 660 | |
| 624 | −/* add_eff_chain() - NOTE: this only adds memory for one | |
| 661 | +/* add_eff_chain() - NOTE: this only adds memory for one | |
| 625 | 662 | * additional effects chain beyond value of eff_chain_count. It |
| 626 | 663 | * does not unconditionally increase size of effects chain. |
| 627 | 664 | */ |
| @@ -639,9 +676,9 @@ static void delete_eff_chains(void) · 11 unmodified lines | ||
| 639 | 676 | unsigned j; |
| 640 | 677 | int i, k; |
| 641 | 678 | |
| 642 | − for (i = 0; i < eff_chain_count; i++) | |
| 679 | + for (i = 0; i < eff_chain_count; i++) | |
| 643 | 680 | { |
| 644 | − for (j = 0; j < nuser_effects[i]; j++) | |
| 681 | + for (j = 0; j < nuser_effects[i]; j++) | |
| 645 | 682 | { |
| 646 | 683 | if (user_effargs[i][j].name) |
| 647 | 684 | free(user_effargs[i][j].name); |
| @@ -665,7 +702,7 @@ static void delete_eff_chains(void) · 17 unmodified lines | ||
| 665 | 702 | |
| 666 | 703 | static sox_bool is_pseudo_effect(char *s) |
| 667 | 704 | { |
| 668 | − if (strcmp("newfile", s) == 0 || | |
| 705 | + if (strcmp("newfile", s) == 0 || | |
| 669 | 706 | strcmp("restart", s) == 0 || |
| 670 | 707 | strcmp(":", s) == 0) |
| 671 | 708 | return sox_true; |
| @@ -700,7 +737,7 @@ static void parse_effects(int argc, char **argv) · 28 unmodified lines | ||
| 700 | 737 | optind++; |
| 701 | 738 | continue; |
| 702 | 739 | } |
| 703 | − | |
| 740 | + | |
| 704 | 741 | if (strcmp(argv[optind], "newfile") == 0) |
| 705 | 742 | { |
| 706 | 743 | /* Start a new effect chain for newfile if user doesn't |
| @@ -739,7 +776,7 @@ static void parse_effects(int argc, char **argv) · 32 unmodified lines | ||
| 739 | 776 | |
| 740 | 777 | optind += j; /* Skip past the effect arguments */ |
| 741 | 778 | nuser_effects[eff_chain_count]++; |
| 742 | − if (newline_mode) | |
| 779 | + if (newline_mode) | |
| 743 | 780 | { |
| 744 | 781 | output_method = sox_multiple; |
| 745 | 782 | eff_chain_count++; |
| @@ -865,9 +902,9 @@ static void read_user_effects(char *filename) · 119 unmodified lines | ||
| 865 | 902 | /* Creates users effects and passes in user specified options. |
| 866 | 903 | * This is done without putting anything into the effects chain |
| 867 | 904 | * because an effect may set the effp->in_format and we may want |
| 868 | − * to copy that back into the input/combiner before opening and | |
| 869 | − * inserting it. | |
| 870 | − * Similarly, we may want to use effp->out_format to override the | |
| 905 | + * to copy that back into the input/combiner before opening and | |
| 906 | + * inserting it. | |
| 907 | + * Similarly, we may want to use effp->out_format to override the | |
| 871 | 908 | * default values of output file before we open it. |
| 872 | 909 | * To keep things simple, we create all user effects. Later, when |
| 873 | 910 | * we add them, some may already be in the chain and we will need to free |
| @@ -882,11 +919,11 @@ static void create_user_effects(void) · 8 unmodified lines | ||
| 882 | 919 | effp = sox_create_effect(sox_find_effect(user_effargs[current_eff_chain][i].name)); |
| 883 | 920 | |
| 884 | 921 | if (effp->handler.flags & SOX_EFF_DEPRECATED) |
| 885 | − lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative", | |
| 922 | + lsx_warn("effect `%s' is deprecated; see sox(1) for an alternative", | |
| 886 | 923 | effp->handler.name); |
| 887 | 924 | |
| 888 | 925 | /* The failing effect should have displayed an error message */ |
| 889 | − if (sox_effect_options(effp, user_effargs[current_eff_chain][i].argc, | |
| 926 | + if (sox_effect_options(effp, user_effargs[current_eff_chain][i].argc, | |
| 890 | 927 | user_effargs[current_eff_chain][i].argv) == SOX_EOF) |
| 891 | 928 | exit(1); |
| 892 | 929 | |
| @@ -905,38 +942,50 @@ static void create_user_effects(void) · 12 unmodified lines | ||
| 905 | 942 | static void add_effects(sox_effects_chain_t *chain) |
| 906 | 943 | { |
| 907 | 944 | sox_signalinfo_t signal = combiner_signal; |
| 945 | + int guard = is_guarded - 1; | |
| 908 | 946 | unsigned i; |
| 909 | 947 | sox_effect_t * effp; |
| 910 | 948 | char * rate_arg = |
| 911 | 949 | is_player ? (rate_arg = getenv("PLAY_RATE_ARG")) ? rate_arg : "-l" : NULL; |
| 912 | 950 | |
| 913 | 951 | /* 1st `effect' in the chain is the input combiner_signal. |
| 914 | − * add it only if its not there from a previous run. | |
| 915 | − */ | |
| 916 | − if (chain->length == 0) | |
| 917 | − { | |
| 952 | + * add it only if its not there from a previous run. */ | |
| 953 | + if (chain->length == 0) { | |
| 918 | 954 | effp = sox_create_effect(input_combiner_effect_fn()); |
| 919 | 955 | sox_add_effect(chain, effp, &signal, &ofile->ft->signal); |
| 920 | 956 | } |
| 921 | 957 | |
| 922 | − /* Add auto effects if appropriate; add user specified effects */ | |
| 923 | − for (i = 0; i < nuser_effects[current_eff_chain]; i++) { | |
| 924 | − /* Effects chain should have displayed an error message */ | |
| 925 | − if (sox_add_effect(chain, user_efftab[i], | |
| 926 | − &signal, &ofile->ft->signal) != SOX_SUCCESS) | |
| 927 | − exit(2); | |
| 928 | − } | |
| 958 | + /* Add user specified effects; stop before `dither' */ | |
| 959 | + for (i = 0; i < nuser_effects[current_eff_chain] && | |
| 960 | + strcmp(user_efftab[i]->handler.name, "dither"); i++) | |
| 961 | + if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal, | |
| 962 | + &guard) != SOX_SUCCESS) | |
| 963 | + exit(2); /* Effects chain should have displayed an error message */ | |
| 929 | 964 | |
| 930 | 965 | /* Add auto effects if still needed at this point */ |
| 966 | + if (signal.channels < ofile->ft->signal.channels && | |
| 967 | + signal.rate != ofile->ft->signal.rate) | |
| 968 | + auto_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal, &guard); | |
| 969 | + if (signal.channels != ofile->ft->signal.channels) | |
| 970 | + auto_effect(chain, "mixer", 0, NULL, &signal, &guard); | |
| 931 | 971 | if (signal.rate != ofile->ft->signal.rate) |
| 932 | − { | |
| 933 | − add_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal); /* Must be up-sampling */ | |
| 972 | + auto_effect(chain, "rate", rate_arg != NULL, &rate_arg, &signal, &guard); | |
| 973 | + | |
| 974 | + if (is_guarded && (do_guarded_norm || !(signal.mult && *signal.mult == 1))) { | |
| 975 | + char * arg = do_guarded_norm? "-nh" : guard? "-rh" : "-h"; | |
| 976 | + int no_guard = -1; | |
| 977 | + auto_effect(chain, "gain", 1, &arg, &signal, &no_guard); | |
| 978 | + guard = 1; | |
| 934 | 979 | } |
| 935 | − if (signal.channels != ofile->ft->signal.channels) | |
| 936 | − { | |
| 937 | − add_effect(chain, "mixer", 0, NULL, &signal); /* Must be increasing channels */ | |
| 980 | + | |
| 981 | + /* Add user specified effects from `dither' onwards */ | |
| 982 | + for (; i < nuser_effects[current_eff_chain]; i++, guard = 2) { | |
| 983 | + if (add_effect(chain, user_efftab[i], &signal, &ofile->ft->signal, | |
| 984 | + &guard) != SOX_SUCCESS) | |
| 985 | + exit(2); /* Effects chain should have displayed an error message */ | |
| 986 | + chain->out_enc->half_bit = sox_false; | |
| 938 | 987 | } |
| 939 | − | |
| 988 | + | |
| 940 | 989 | if (!save_output_eff) |
| 941 | 990 | { |
| 942 | 991 | /* Last `effect' in the chain is the output file */ |
| @@ -981,15 +1030,15 @@ static int advance_eff_chain(void) · 38 unmodified lines | ||
| 981 | 1030 | /* Effect chain stopped so advance to next effect chain but |
| 982 | 1031 | * quite if no more chains exist. |
| 983 | 1032 | */ |
| 984 | − else if (++current_eff_chain >= eff_chain_count) | |
| 1033 | + else if (++current_eff_chain >= eff_chain_count) | |
| 985 | 1034 | return SOX_EOF; |
| 986 | 1035 | |
| 987 | − while (nuser_effects[current_eff_chain] == 1 && | |
| 1036 | + while (nuser_effects[current_eff_chain] == 1 && | |
| 988 | 1037 | is_pseudo_effect(user_effargs[current_eff_chain][0].name)) |
| 989 | 1038 | { |
| 990 | 1039 | if (strcmp("newfile", user_effargs[current_eff_chain][0].name) == 0) |
| 991 | 1040 | { |
| 992 | − if (++current_eff_chain >= eff_chain_count) | |
| 1041 | + if (++current_eff_chain >= eff_chain_count) | |
| 993 | 1042 | return SOX_EOF; |
| 994 | 1043 | reuse_output = sox_false; |
| 995 | 1044 | } |
| @@ -1167,7 +1216,7 @@ static int update_status(sox_bool all_done) · 171 unmodified lines | ||
| 1167 | 1216 | int ch = getchar(); |
| 1168 | 1217 | |
| 1169 | 1218 | #ifdef INTERACTIVE |
| 1170 | − if (files[current_input]->ft->handler.seek && | |
| 1219 | + if (files[current_input]->ft->handler.seek && | |
| 1171 | 1220 | files[current_input]->ft->seekable) |
| 1172 | 1221 | { |
| 1173 | 1222 | if (ch == '>') |
| @@ -1408,7 +1457,7 @@ static void calculate_combiner_signal_parameters(void) · 234 unmodified lines | ||
| 1408 | 1457 | */ |
| 1409 | 1458 | for (i = 0; i < input_count; i++) { |
| 1410 | 1459 | unsigned j; |
| 1411 | − for (j =0; j < nuser_effects[current_eff_chain] && | |
| 1460 | + for (j =0; j < nuser_effects[current_eff_chain] && | |
| 1412 | 1461 | !files[i]->ft->signal.channels; ++j) |
| 1413 | 1462 | files[i]->ft->signal.channels = user_efftab[j]->in_signal.channels; |
| 1414 | 1463 | /* For historical reasons, default to one channel if not specified. */ |
| @@ -1520,7 +1569,7 @@ static void set_combiner_and_output_encoding_parameters(void) · 105 unmodified lines | ||
| 1520 | 1569 | /* Determine the output file encoding attributes; set from user options |
| 1521 | 1570 | * if given: */ |
| 1522 | 1571 | ofile->encoding = ofile_encoding_options; |
| 1523 | − | |
| 1572 | + | |
| 1524 | 1573 | /* Get unspecified output file encoding attributes from the input file and |
| 1525 | 1574 | * set the output file to the resultant encoding if this is supported by the |
| 1526 | 1575 | * output file type; if not, the output file handler should select an |
| @@ -1548,7 +1597,7 @@ static int process(void) · 21 unmodified lines | ||
| 1548 | 1597 | open_output_file(); |
| 1549 | 1598 | |
| 1550 | 1599 | if (!effects_chain) |
| 1551 | − effects_chain = sox_create_effects_chain(&combiner_encoding, | |
| 1600 | + effects_chain = sox_create_effects_chain(&combiner_encoding, | |
| 1552 | 1601 | &ofile->ft->encoding); |
| 1553 | 1602 | add_effects(effects_chain); |
| 1554 | 1603 | |
| @@ -1564,7 +1613,7 @@ static int process(void) · 9 unmodified lines | ||
| 1564 | 1613 | * effect chains. |
| 1565 | 1614 | * For case #2, something else must decide when to stop processing. |
| 1566 | 1615 | */ |
| 1567 | − if ((input_eof && current_input < input_count) || | |
| 1616 | + if ((input_eof && current_input < input_count) || | |
| 1568 | 1617 | (!output_eof && current_eff_chain < eff_chain_count)) |
| 1569 | 1618 | flow_status = SOX_SUCCESS; |
| 1570 | 1619 | |
| @@ -1691,6 +1740,7 @@ static void usage(char const * message) · 120 unmodified lines | ||
| 1691 | 1740 | "--combine concatenate Concatenate multiple input files (default for sox, rec)", |
| 1692 | 1741 | "--combine sequence Sequence multiple input files (default for play)", |
| 1693 | 1742 | "--effects-file FILENAME File containing effects and options", |
| 1743 | +"-G, --guard Use temporary files to guard against clipping", | |
| 1694 | 1744 | "-h, --help Display version number and usage information", |
| 1695 | 1745 | "--help-effect NAME Show usage of effect NAME, or NAME=all for all", |
| 1696 | 1746 | "--help-format NAME Show info on format NAME, or NAME=all for all", |
| @@ -1698,6 +1748,7 @@ static void usage(char const * message) · 1 unmodified line | ||
| 1698 | 1748 | "--interactive Prompt to overwrite output file", |
| 1699 | 1749 | "-m, --combine mix Mix multiple input files (instead of concatenating)", |
| 1700 | 1750 | "-M, --combine merge Merge multiple input files (instead of concatenating)", |
| 1751 | +"--norm Guard (see --guard) & normalise", | |
| 1701 | 1752 | "--plot gnuplot|octave Generate script to plot response of filter effect", |
| 1702 | 1753 | "-q, --no-show-progress Run in quiet mode; opposite of -S", |
| 1703 | 1754 | "--replay-gain track|album|off Default: off (sox, rec), track (play)", |
| @@ -1728,6 +1779,7 @@ static void usage(char const * message) · 24 unmodified lines | ||
| 1728 | 1779 | "-X|--reverse-bits Encoded bit-order", |
| 1729 | 1780 | "--endian little|big|swap Encoded byte-order; swap means opposite to default", |
| 1730 | 1781 | "-L/-B/-x Short options for the above", |
| 1782 | +"-0 PCM encoding is 0 biased (offset by half a bit)", | |
| 1731 | 1783 | "-c|--channels CHANNELS Number of channels of audio data; e.g. 2 = stereo", |
| 1732 | 1784 | "-r|--rate RATE Sample rate of audio", |
| 1733 | 1785 | "-C|--compression FACTOR Compression factor for output format", |
| @@ -1885,7 +1937,7 @@ static void read_comment_file(sox_comments_t * comments, char const * const file · 151 unmodified lines | ||
| 1885 | 1937 | free(text); |
| 1886 | 1938 | } |
| 1887 | 1939 | |
| 1888 | −static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:LMNRSTUV::X12348"; | |
| 1940 | +static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:GLMNRSTUV::X012348"; | |
| 1889 | 1941 | |
| 1890 | 1942 | static struct option long_options[] = |
| 1891 | 1943 | { |
| @@ -1908,6 +1960,7 @@ static struct option long_options[] = · 16 unmodified lines | ||
| 1908 | 1960 | {"temp" , required_argument, NULL, 0}, |
| 1909 | 1961 | {"single-threaded" , no_argument, NULL, 0}, |
| 1910 | 1962 | {"ignore-length" , no_argument, NULL, 0}, |
| 1963 | + {"norm" , no_argument, NULL, 0}, | |
| 1911 | 1964 | |
| 1912 | 1965 | {"bits" , required_argument, NULL, 'b'}, |
| 1913 | 1966 | {"channels" , required_argument, NULL, 'c'}, |
| @@ -1924,6 +1977,7 @@ static struct option long_options[] = · 10 unmodified lines | ||
| 1924 | 1977 | {"show-progress" , no_argument, NULL, 'S'}, |
| 1925 | 1978 | {"type" , required_argument, NULL, 't'}, |
| 1926 | 1979 | {"volume" , required_argument, NULL, 'v'}, |
| 1980 | + {"guard" , no_argument, NULL, 'G'}, | |
| 1927 | 1981 | |
| 1928 | 1982 | {NULL, 0, NULL, 0} |
| 1929 | 1983 | }; |
| @@ -2056,57 +2110,25 @@ static char parse_gopts_and_fopts(file_t * f, int argc, char **argv) · 126 unmodified lines | ||
| 2056 | 2110 | sox_globals.input_bufsiz = i; |
| 2057 | 2111 | break; |
| 2058 | 2112 | |
| 2059 | − case 7: | |
| 2060 | − interactive = sox_true; | |
| 2061 | − break; | |
| 2062 | − | |
| 2063 | − case 8: | |
| 2064 | − usage_effect(optarg); | |
| 2065 | − break; | |
| 2066 | − | |
| 2067 | − case 9: | |
| 2068 | − usage_format(optarg); | |
| 2069 | − break; | |
| 2070 | − | |
| 2071 | − case 10: | |
| 2072 | − f->no_glob = sox_true; | |
| 2073 | − break; | |
| 2074 | − | |
| 2113 | + case 7: interactive = sox_true; break; | |
| 2114 | + case 8: usage_effect(optarg); break; | |
| 2115 | + case 9: usage_format(optarg); break; | |
| 2116 | + case 10: f->no_glob = sox_true; break; | |
| 2075 | 2117 | case 11: |
| 2076 | 2118 | sox_effects_globals.plot = enum_option(option_index, plot_methods); |
| 2077 | 2119 | break; |
| 2078 | − | |
| 2079 | − case 12: | |
| 2080 | − replay_gain_mode = enum_option(option_index, rg_modes); | |
| 2081 | − break; | |
| 2082 | − | |
| 2083 | − case 13: | |
| 2084 | − display_SoX_version(stdout); | |
| 2085 | − exit(0); | |
| 2086 | − break; | |
| 2087 | − | |
| 2088 | − case 14: | |
| 2089 | − break; | |
| 2090 | − | |
| 2091 | − case 15: | |
| 2092 | − effects_filename = strdup(optarg); | |
| 2093 | − break; | |
| 2094 | − | |
| 2095 | − case 16: | |
| 2096 | − sox_globals.tmp_path = strdup(optarg); | |
| 2097 | − break; | |
| 2098 | − | |
| 2099 | − case 17: | |
| 2100 | − single_threaded = sox_true; | |
| 2101 | − break; | |
| 2102 | − | |
| 2103 | − case 18: | |
| 2104 | − f->signal.length = SOX_IGNORE_LENGTH; | |
| 2105 | − break; | |
| 2106 | − | |
| 2120 | + case 12: replay_gain_mode = enum_option(option_index, rg_modes); break; | |
| 2121 | + case 13: display_SoX_version(stdout); exit(0); break; | |
| 2122 | + case 14: break; | |
| 2123 | + case 15: effects_filename = strdup(optarg); break; | |
| 2124 | + case 16: sox_globals.tmp_path = strdup(optarg); break; | |
| 2125 | + case 17: single_threaded = sox_true; break; | |
| 2126 | + case 18: f->signal.length = SOX_IGNORE_LENGTH; break; | |
| 2127 | + case 19: do_guarded_norm = is_guarded = sox_true; break; | |
| 2107 | 2128 | } |
| 2108 | 2129 | break; |
| 2109 | 2130 | |
| 2131 | + case 'G': is_guarded = sox_true; break; | |
| 2110 | 2132 | case 'm': combine_method = sox_mix; break; |
| 2111 | 2133 | case 'M': combine_method = sox_merge; break; |
| 2112 | 2134 | case 'T': combine_method = sox_multiply; break; |
| @@ -2119,7 +2141,7 @@ static char parse_gopts_and_fopts(file_t * f, int argc, char **argv) · 6 unmodified lines | ||
| 2119 | 2141 | return c; |
| 2120 | 2142 | break; |
| 2121 | 2143 | |
| 2122 | − case 'h': | |
| 2144 | + case 'h': | |
| 2123 | 2145 | usage(NULL); |
| 2124 | 2146 | break; |
| 2125 | 2147 | |
| @@ -2144,6 +2166,8 @@ static char parse_gopts_and_fopts(file_t * f, int argc, char **argv) · 18 unmodified lines | ||
| 2144 | 2166 | break; |
| 2145 | 2167 | } |
| 2146 | 2168 | |
| 2169 | + case '0': f->encoding.half_bit = sox_true; break; | |
| 2170 | + | |
| 2147 | 2171 | case 'v': |
| 2148 | 2172 | if (sscanf(optarg, "%lf %c", &f->volume, &dummy) != 1) { |
| 2149 | 2173 | lsx_fail("Volume value `%s' is not a number", optarg); |
| @@ -2444,7 +2468,7 @@ static int soxi(int argc, char * const * argv) · 294 unmodified lines | ||
| 2444 | 2468 | } |
| 2445 | 2469 | sox_globals.verbosity = (unsigned)i; |
| 2446 | 2470 | } |
| 2447 | − } | |
| 2471 | + } | |
| 2448 | 2472 | else if (opt == 'T') |
| 2449 | 2473 | do_total = sox_true; |
| 2450 | 2474 | else type = 1 + (strchr(opts, opt) - opts); |
| @@ -2512,12 +2536,6 @@ static sox_bool cmp_comment_text(char const * c1, char const * c2) · 61 unmodified lines | ||
| 2512 | 2536 | return c1 && c2 && !strcasecmp(c1, c2); |
| 2513 | 2537 | } |
| 2514 | 2538 | |
| 2515 | −static int strends(char const * str, char const * end) | |
| 2516 | −{ | |
| 2517 | − size_t str_len = strlen(str), end_len = strlen(end); | |
| 2518 | − return str_len >= end_len && !strcmp(str + str_len - end_len, end); | |
| 2519 | −} | |
| 2520 | − | |
| 2521 | 2539 | #ifdef __CYGWIN__ |
| 2522 | 2540 | static char * check_dir(char * name) |
| 2523 | 2541 | { |
| @@ -2534,11 +2552,11 @@ int main(int argc, char **argv) · 10 unmodified lines | ||
| 2534 | 2552 | myname = argv[0]; |
| 2535 | 2553 | sox_globals.output_message_handler = output_message; |
| 2536 | 2554 | |
| 2537 | − if (strends(myname, "play")) | |
| 2555 | + if (lsx_strends(myname, "play")) | |
| 2538 | 2556 | sox_mode = sox_play; |
| 2539 | − else if (strends(myname, "rec")) | |
| 2557 | + else if (lsx_strends(myname, "rec")) | |
| 2540 | 2558 | sox_mode = sox_rec; |
| 2541 | − else if (strends(myname, "soxi")) | |
| 2559 | + else if (lsx_strends(myname, "soxi")) | |
| 2542 | 2560 | sox_mode = sox_soxi; |
| 2543 | 2561 | |
| 2544 | 2562 | if (sox_init() != SOX_SUCCESS) |
| @@ -2686,7 +2704,7 @@ int main(int argc, char **argv) · 141 unmodified lines | ||
| 2686 | 2704 | } |
| 2687 | 2705 | |
| 2688 | 2706 | /* Not the best way for users to do this; now deprecated in favour of soxi. */ |
| 2689 | − if (!show_progress && !nuser_effects[current_eff_chain] && | |
| 2707 | + if (!show_progress && !nuser_effects[current_eff_chain] && | |
| 2690 | 2708 | ofile->filetype && !strcmp(ofile->filetype, "null")) { |
| 2691 | 2709 | for (i = 0; i < input_count; i++) |
| 2692 | 2710 | report_file_info(files[i]); |
| @@ -2703,7 +2721,7 @@ int main(int argc, char **argv) · 10 unmodified lines | ||
| 2703 | 2721 | |
| 2704 | 2722 | /* If user specified an effects filename then use that file |
| 2705 | 2723 | * to load user effects. Free any previously specified options |
| 2706 | − * from the command line. | |
| 2724 | + * from the command line. | |
| 2707 | 2725 | */ |
| 2708 | 2726 | if (effects_filename) |
| 2709 | 2727 | { |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* libSoX Library Public Interface |
| 2 | 2 | * |
| 3 | − * Copyright 1999-2008 Chris Bagwell and SoX Contributors. | |
| 3 | + * Copyright 1999-2009 Chris Bagwell and SoX Contributors. | |
| 4 | 4 | * |
| 5 | 5 | * This source code is freely redistributable and may be used for |
| 6 | 6 | * any purpose. This copyright notice must be maintained. |
| @@ -12,6 +12,7 @@ · 5 unmodified lines | ||
| 12 | 12 | #define SOX_H |
| 13 | 13 | |
| 14 | 14 | #include <limits.h> |
| 15 | +#include <math.h> | |
| 15 | 16 | #include <stdarg.h> |
| 16 | 17 | #include <stddef.h> /* Ensure NULL etc. are available throughout SoX */ |
| 17 | 18 | #include <stdio.h> |
| @@ -75,40 +76,32 @@ typedef int32_t sox_sample_t; · 57 unmodified lines | ||
| 75 | 76 | |
| 76 | 77 | /* Conversions: Linear PCM <--> sox_sample_t |
| 77 | 78 | * |
| 78 | − * I/O I/O sox_sample_t Clips? I/O sox_sample_t Clips? | |
| 79 | − * Format Minimum Minimum I O Maximum Maximum I O | |
| 80 | − * ------ --------- ------------ -- -- -------- ------------ -- -- | |
| 81 | − * Float -1 -1.00000000047 y y 1 1 y n | |
| 82 | − * Int8 -128 -128 n n 127 127.9999999 n y | |
| 83 | − * Int16 -32768 -32768 n n 32767 32767.99998 n y | |
| 84 | − * Int24 -8388608 -8388608 n n 8388607 8388607.996 n y | |
| 85 | − * Int32 -2147483648 -2147483648 n n 2147483647 2147483647 n n | |
| 79 | + * I/O I/O sox_sample_t I/O sox_sample_t | |
| 80 | + * Format Minimum Minimum Maximum Maximum | |
| 81 | + * ------ --------- ------------ -------- ------------ | |
| 82 | + * Float -1 -1 1 1 - 5e-10 | |
| 83 | + * Int8 -128 -127.5 127 127.4999999 | |
| 84 | + * Int16 -32768 -32767.5 32767 32767.49998 | |
| 85 | + * Int24 -8388608 -8388607.5 8388607 8388607.496 | |
| 86 | + * Int32 -2147483648 -2147483648 2147483647 2147483647 | |
| 86 | 87 | * |
| 87 | 88 | * Conversions are as accurate as possible (with rounding). |
| 88 | 89 | * |
| 89 | 90 | * Rounding: halves toward +inf, all others to nearest integer. |
| 90 | 91 | * |
| 91 | − * Clips? shows whether on not there is the possibility of a conversion | |
| 92 | − * clipping to the minimum or maximum value when inputing from or outputing | |
| 93 | − * to a given type. | |
| 92 | + * The only possibility of clipping on conversion is when inputting Float. | |
| 94 | 93 | * |
| 95 | 94 | * Unsigned integers are converted to and from signed integers by flipping |
| 96 | 95 | * the upper-most bit then treating them as signed integers. |
| 97 | 96 | */ |
| 98 | 97 | |
| 99 | −#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample UNUSED; \ | |
| 100 | − double sox_macro_temp_double UNUSED | |
| 98 | +#define SOX_SAMPLE_LOCALS double sox_macro_temp_double UNUSED | |
| 101 | 99 | |
| 102 | 100 | #define SOX_SAMPLE_NEG SOX_INT_MIN(32) |
| 103 | −#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \ | |
| 104 | − (uint##bits##_t)( \ | |
| 105 | − sox_macro_temp_sample=(d), \ | |
| 106 | − sox_macro_temp_sample>(sox_sample_t)(SOX_SAMPLE_MAX-(1U<<(31-bits)))? \ | |
| 107 | − ++(clips),SOX_UINT_MAX(bits): \ | |
| 108 | − ((uint32_t)(sox_macro_temp_sample^SOX_SAMPLE_NEG)+(1U<<(31-bits)))>>(32-bits)) | |
| 109 | −#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \ | |
| 110 | − (int##bits##_t)(SOX_SAMPLE_TO_UNSIGNED(bits,d,clips)^SOX_INT_MIN(bits)) | |
| 111 | −#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits)) | |
| 101 | +#define SOX_SAMPLE_TO_UNSIGNED(bits,d) \ | |
| 102 | + (uint##bits##_t)(((uint32_t)((d)^SOX_SAMPLE_NEG))>>(32-bits)) | |
| 103 | +#define SOX_SAMPLE_TO_SIGNED(bits,d) (int##bits##_t)(((uint32_t)(d))>>(32-bits)) | |
| 104 | +#define SOX_SIGNED_TO_SAMPLE(bits,d)(((sox_sample_t)(d)<<(32-bits))+(1<<(31-bits))) | |
| 112 | 105 | #define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG) |
| 113 | 106 | |
| 114 | 107 | #define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d) |
| @@ -120,17 +113,17 @@ typedef int32_t sox_sample_t; · 5 unmodified lines | ||
| 120 | 113 | #define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG) |
| 121 | 114 | #define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d) |
| 122 | 115 | #define SOX_FLOAT_32BIT_TO_SAMPLE SOX_FLOAT_64BIT_TO_SAMPLE |
| 123 | −#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)) | |
| 124 | −#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips) | |
| 125 | −#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips) | |
| 126 | −#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips) | |
| 127 | −#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips) | |
| 128 | −#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips) | |
| 129 | −#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips) | |
| 130 | −#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (uint32_t)((d)^SOX_SAMPLE_NEG) | |
| 131 | −#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (int32_t)(d) | |
| 116 | +#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.)+.5,sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.5?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:(sox_sample_t)floor(sox_macro_temp_double)) | |
| 117 | +#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d) SOX_SAMPLE_TO_UNSIGNED(8,d) | |
| 118 | +#define SOX_SAMPLE_TO_SIGNED_8BIT(d) SOX_SAMPLE_TO_SIGNED(8,d) | |
| 119 | +#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d) SOX_SAMPLE_TO_UNSIGNED(16,d) | |
| 120 | +#define SOX_SAMPLE_TO_SIGNED_16BIT(d) SOX_SAMPLE_TO_SIGNED(16,d) | |
| 121 | +#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d) SOX_SAMPLE_TO_UNSIGNED(24,d) | |
| 122 | +#define SOX_SAMPLE_TO_SIGNED_24BIT(d) SOX_SAMPLE_TO_SIGNED(24,d) | |
| 123 | +#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d) (uint32_t)((d)^SOX_SAMPLE_NEG) | |
| 124 | +#define SOX_SAMPLE_TO_SIGNED_32BIT(d) (int32_t)(d) | |
| 132 | 125 | #define SOX_SAMPLE_TO_FLOAT_32BIT SOX_SAMPLE_TO_FLOAT_64BIT |
| 133 | −#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))) | |
| 126 | +#define SOX_SAMPLE_TO_FLOAT_64BIT(d) ((d)*(1./(SOX_SAMPLE_MAX+1.))) | |
| 134 | 127 | |
| 135 | 128 | |
| 136 | 129 | |
| @@ -250,6 +243,7 @@ typedef enum {SOX_OPTION_NO, SOX_OPTION_YES, SOX_OPTION_DEFAULT} sox_option_t; · 113 unmodified lines | ||
| 250 | 243 | typedef struct { /* Encoding parameters */ |
| 251 | 244 | sox_encoding_t encoding; /* format of sample numbers */ |
| 252 | 245 | unsigned bits_per_sample; /* 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */ |
| 246 | + sox_bool half_bit; | |
| 253 | 247 | double compression; /* compression factor (where applicable) */ |
| 254 | 248 | |
| 255 | 249 | /* If these 3 variables are set to DEFAULT, then, during |
| @@ -452,6 +446,8 @@ sox_format_handler_t const * sox_find_format(char const * name, sox_bool no_dev) · 196 unmodified lines | ||
| 452 | 446 | #define SOX_EFF_MCHAN 16 /* Effect can handle multi-channel */ |
| 453 | 447 | #define SOX_EFF_NULL 32 /* Effect does nothing */ |
| 454 | 448 | #define SOX_EFF_DEPRECATED 64 /* Effect is living on borrowed time */ |
| 449 | +#define SOX_EFF_GAIN 128 /* Effect does not support gain -r */ | |
| 450 | +#define SOX_EFF_MODIFY 256 /* Effect does not modify samples */ | |
| 455 | 451 | |
| 456 | 452 | typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t; |
| 457 | 453 | typedef struct sox_effect sox_effect_t; |
| @@ -508,11 +504,11 @@ struct sox_effects_chain { · 50 unmodified lines | ||
| 508 | 504 | sox_sample_t **ibufc, **obufc; /* Channel interleave buffers */ |
| 509 | 505 | sox_effects_globals_t global_info; |
| 510 | 506 | sox_encodinginfo_t const * in_enc; |
| 511 | − sox_encodinginfo_t const * out_enc; | |
| 507 | + sox_encodinginfo_t * out_enc; | |
| 512 | 508 | }; |
| 513 | 509 | typedef struct sox_effects_chain sox_effects_chain_t; |
| 514 | 510 | sox_effects_chain_t * sox_create_effects_chain( |
| 515 | − sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc); | |
| 511 | + sox_encodinginfo_t const * in_enc, sox_encodinginfo_t * out_enc); | |
| 516 | 512 | void sox_delete_effects_chain(sox_effects_chain_t *ecp); |
| 517 | 513 | int sox_add_effect( sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out); |
| 518 | 514 | int sox_flow_effects(sox_effects_chain_t *, int (* callback)(sox_bool all_done)); |
| @@ -565,6 +561,7 @@ typedef struct {char const *text; unsigned value;} lsx_enum_item; · 46 unmodified lines | ||
| 565 | 561 | lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * lsx_enum_items); |
| 566 | 562 | lsx_enum_item const * lsx_find_enum_value(unsigned value, lsx_enum_item const * lsx_enum_items); |
| 567 | 563 | int lsx_enum_option(int c, lsx_enum_item const * items); |
| 564 | +sox_bool lsx_strends(char const * str, char const * end); | |
| 568 | 565 | char const * lsx_find_file_extension(char const * pathname); |
| 569 | 566 | char const * lsx_sigfigs3(size_t number); |
| 570 | 567 | char const * lsx_sigfigs3p(double percentage); |
| @@ -19,6 +19,17 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #include <errno.h> |
| 21 | 21 | |
| 22 | +#if defined(LSX_EFF_ALIAS) | |
| 23 | +#undef lsx_debug | |
| 24 | +#undef lsx_fail | |
| 25 | +#undef lsx_report | |
| 26 | +#undef lsx_warn | |
| 27 | +#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug | |
| 28 | +#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail | |
| 29 | +#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report | |
| 30 | +#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn | |
| 31 | +#endif | |
| 32 | + | |
| 22 | 33 | #define RANQD1 ranqd1(sox_globals.ranqd1) |
| 23 | 34 | #define DRANQD1 dranqd1(sox_globals.ranqd1) |
| 24 | 35 | |
| @@ -213,7 +224,6 @@ typedef struct sox_formats_globals { /* Global parameters (for formats) */ · 188 unmodified lines | ||
| 213 | 224 | int lsx_check_read_params(sox_format_t * ft, unsigned channels, |
| 214 | 225 | sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample, |
| 215 | 226 | off_t num_samples, sox_bool check_length); |
| 216 | −sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding); | |
| 217 | 227 | #define SOX_FORMAT_HANDLER(name) \ |
| 218 | 228 | sox_format_handler_t const * sox_##name##_format_fn(void); \ |
| 219 | 229 | sox_format_handler_t const * sox_##name##_format_fn(void) |
| @@ -1,18 +0,0 @@ | ||
| 1 | −/* libSoX test code copyright (c) 2006 robs@users.sourceforge.net | |
| 2 | − * | |
| 3 | − * This program is free software; you can redistribute it and/or modify it | |
| 4 | − * under the terms of the GNU General Public License as published by the | |
| 5 | − * Free Software Foundation; either version 2 of the License, or (at your | |
| 6 | − * option) any later version. | |
| 7 | − * | |
| 8 | − * This program is distributed in the hope that it will be useful, but | |
| 9 | − * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
| 11 | − * Public License for more details. | |
| 12 | − * | |
| 13 | − * You should have received a copy of the GNU General Public License along | |
| 14 | − * with this program; if not, write to the Free Software Foundation, Inc., | |
| 15 | − * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 16 | − */ | |
| 17 | − | |
| 18 | −#include "sox_sample_test.h" | |
| @@ -1,207 +0,0 @@ | ||
| 1 | −/* libSoX test code copyright (c) 2006 robs@users.sourceforge.net | |
| 2 | − * | |
| 3 | − * This program is free software; you can redistribute it and/or modify it | |
| 4 | − * under the terms of the GNU General Public License as published by the | |
| 5 | − * Free Software Foundation; either version 2 of the License, or (at your | |
| 6 | − * option) any later version. | |
| 7 | − * | |
| 8 | − * This program is distributed in the hope that it will be useful, but | |
| 9 | − * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
| 11 | − * Public License for more details. | |
| 12 | − * | |
| 13 | − * You should have received a copy of the GNU General Public License along | |
| 14 | − * with this program; if not, write to the Free Software Foundation, Inc., | |
| 15 | − * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 16 | − */ | |
| 17 | − | |
| 18 | −#define DEBUG | |
| 19 | −#include <assert.h> | |
| 20 | −#include "sox.h" | |
| 21 | − | |
| 22 | −#define TEST_UINT(bits) \ | |
| 23 | − uint##bits = 0; \ | |
| 24 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 25 | − assert(sample == SOX_SAMPLE_MIN); \ | |
| 26 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 27 | − assert(uint##bits == 0 && clips == 0); \ | |
| 28 | − \ | |
| 29 | − uint##bits = 1; \ | |
| 30 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 31 | − assert(sample > SOX_SAMPLE_MIN && sample < 0); \ | |
| 32 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 33 | − assert(uint##bits == 1 && clips == 0); \ | |
| 34 | − \ | |
| 35 | − uint##bits = SOX_INT_MAX(bits); \ | |
| 36 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 37 | − assert(sample * SOX_INT_MAX(bits) == SOX_UNSIGNED_TO_SAMPLE(bits,1)); \ | |
| 38 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 39 | − assert(uint##bits == SOX_INT_MAX(bits) && clips == 0); \ | |
| 40 | − \ | |
| 41 | − sample =SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2; \ | |
| 42 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 43 | − assert(uint##bits == 1 && clips == 0); \ | |
| 44 | − \ | |
| 45 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2-1; \ | |
| 46 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 47 | − assert(uint##bits == 0 && clips == 0); \ | |
| 48 | − \ | |
| 49 | − uint##bits = (0^SOX_INT_MIN(bits)); \ | |
| 50 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 51 | − assert(sample == 0); \ | |
| 52 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 53 | − assert(uint##bits == (0^SOX_INT_MIN(bits)) && clips == 0); \ | |
| 54 | − \ | |
| 55 | − uint##bits = ((0^SOX_INT_MIN(bits))+1); \ | |
| 56 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 57 | − assert(sample > 0 && sample < SOX_SAMPLE_MAX); \ | |
| 58 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 59 | − assert(uint##bits == ((0^SOX_INT_MIN(bits))+1) && clips == 0); \ | |
| 60 | − \ | |
| 61 | − uint##bits = SOX_UINT_MAX(bits); \ | |
| 62 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,uint##bits); \ | |
| 63 | − assert(sample == SOX_INT_MAX(bits) * SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))); \ | |
| 64 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 65 | − assert(uint##bits == SOX_UINT_MAX(bits) && clips == 0); \ | |
| 66 | − \ | |
| 67 | − sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2-1; \ | |
| 68 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 69 | − assert(uint##bits == SOX_UINT_MAX(bits) && clips == 0); \ | |
| 70 | − \ | |
| 71 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2; \ | |
| 72 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 73 | − assert(uint##bits == SOX_UINT_MAX(bits) && --clips == 0); \ | |
| 74 | − \ | |
| 75 | − sample = SOX_SAMPLE_MAX; \ | |
| 76 | − uint##bits = SOX_SAMPLE_TO_UNSIGNED(bits,sample, clips); \ | |
| 77 | − assert(uint##bits == SOX_UINT_MAX(bits) && --clips == 0); \ | |
| 78 | − | |
| 79 | −#define TEST_SINT(bits) \ | |
| 80 | − int##bits = SOX_INT_MIN(bits); \ | |
| 81 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 82 | − assert(sample == SOX_SAMPLE_MIN); \ | |
| 83 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 84 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 85 | − \ | |
| 86 | − int##bits = SOX_INT_MIN(bits)+1; \ | |
| 87 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 88 | − assert(sample > SOX_SAMPLE_MIN && sample < 0); \ | |
| 89 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 90 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 91 | − \ | |
| 92 | − int##bits = SOX_UINT_MAX(bits) /* i.e. -1 */; \ | |
| 93 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 94 | − assert(sample * SOX_INT_MAX(bits) == SOX_SIGNED_TO_SAMPLE(bits,SOX_INT_MIN(bits)+1)); \ | |
| 95 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 96 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 97 | − \ | |
| 98 | − int##bits = SOX_INT_MIN(bits)+1; \ | |
| 99 | − sample =SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2; \ | |
| 100 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 101 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 102 | − \ | |
| 103 | − int##bits = SOX_INT_MIN(bits); \ | |
| 104 | − sample = SOX_UNSIGNED_TO_SAMPLE(bits,1)+SOX_UNSIGNED_TO_SAMPLE(bits,SOX_INT_MAX(bits))/2-1; \ | |
| 105 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 106 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 107 | − \ | |
| 108 | − int##bits = 0; \ | |
| 109 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 110 | − assert(sample == 0); \ | |
| 111 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 112 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 113 | − \ | |
| 114 | − int##bits = 1; \ | |
| 115 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 116 | − assert(sample > 0 && sample < SOX_SAMPLE_MAX); \ | |
| 117 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 118 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 119 | − \ | |
| 120 | − int##bits = SOX_INT_MAX(bits); \ | |
| 121 | − sample = SOX_SIGNED_TO_SAMPLE(bits,int##bits); \ | |
| 122 | − assert(sample == SOX_INT_MAX(bits) * SOX_SIGNED_TO_SAMPLE(bits,1)); \ | |
| 123 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 124 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 125 | − \ | |
| 126 | − sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2-1; \ | |
| 127 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 128 | − assert(int##bits##_2 == int##bits && clips == 0); \ | |
| 129 | − \ | |
| 130 | − sample =SOX_UNSIGNED_TO_SAMPLE(bits,SOX_UINT_MAX(bits))+SOX_UNSIGNED_TO_SAMPLE(bits,((0^SOX_INT_MIN(bits))+1))/2; \ | |
| 131 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 132 | − assert(int##bits##_2 == int##bits && --clips == 0); \ | |
| 133 | − \ | |
| 134 | − sample = SOX_SAMPLE_MAX; \ | |
| 135 | − int##bits##_2 = SOX_SAMPLE_TO_SIGNED(bits,sample, clips); \ | |
| 136 | − assert(int##bits##_2 == int##bits && --clips == 0); | |
| 137 | − | |
| 138 | −#if defined __GNUC__ | |
| 139 | − #pragma GCC system_header | |
| 140 | −#elif defined __SUNPRO_CC | |
| 141 | − #pragma disable_warn | |
| 142 | −#elif defined _MSC_VER | |
| 143 | − #pragma warning(push, 1) | |
| 144 | −#endif | |
| 145 | − | |
| 146 | −#define epsilon 1e-16 | |
| 147 | − | |
| 148 | −int main() | |
| 149 | −{ | |
| 150 | − int8_t int8; | |
| 151 | − int16_t int16; | |
| 152 | − int24_t int24; | |
| 153 | − | |
| 154 | − uint8_t uint8; | |
| 155 | − uint16_t uint16; | |
| 156 | − uint24_t uint24; | |
| 157 | − | |
| 158 | − int8_t int8_2; | |
| 159 | − int16_t int16_2; | |
| 160 | − int24_t int24_2; | |
| 161 | − | |
| 162 | − sox_sample_t sample; | |
| 163 | − size_t clips = 0; | |
| 164 | − | |
| 165 | − double d; | |
| 166 | − SOX_SAMPLE_LOCALS; | |
| 167 | − | |
| 168 | − TEST_UINT(8) | |
| 169 | − TEST_UINT(16) | |
| 170 | − TEST_UINT(24) | |
| 171 | − | |
| 172 | − TEST_SINT(8) | |
| 173 | − TEST_SINT(16) | |
| 174 | − TEST_SINT(24) | |
| 175 | − | |
| 176 | − d = -1.0000000001; | |
| 177 | − sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips); | |
| 178 | − assert(sample == -SOX_SAMPLE_MAX && --clips == 0); | |
| 179 | − | |
| 180 | − d = -1; | |
| 181 | − sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips); | |
| 182 | − assert(sample == -SOX_SAMPLE_MAX && clips == 0); | |
| 183 | − d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips); | |
| 184 | − assert(fabs(d + 1) < epsilon && clips == 0); | |
| 185 | − | |
| 186 | − --sample; | |
| 187 | − d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips); | |
| 188 | − assert(fabs(d + 1) < epsilon && --clips == 0); | |
| 189 | − | |
| 190 | − d = 1; | |
| 191 | − sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips); | |
| 192 | − assert(sample == SOX_SAMPLE_MAX && clips == 0); | |
| 193 | − d = SOX_SAMPLE_TO_FLOAT_64BIT(sample,clips); | |
| 194 | − assert(fabs(d - 1) < epsilon && clips == 0); | |
| 195 | − | |
| 196 | − d = 1.0000000001; | |
| 197 | − sample = SOX_FLOAT_64BIT_TO_SAMPLE(d, clips); | |
| 198 | − assert(sample == SOX_SAMPLE_MAX && --clips == 0); | |
| 199 | − | |
| 200 | − return 0; | |
| 201 | −} | |
| 202 | − | |
| 203 | −#if defined __SUNPRO_CC | |
| 204 | − #pragma enable_warn | |
| 205 | −#elif defined _MSC_VER | |
| 206 | − #pragma warning(pop) | |
| 207 | −#endif | |
| @@ -186,21 +186,20 @@ static int flow(sox_effect_t * effp, · 185 unmodified lines | ||
| 186 | 186 | size_t * isamp, size_t * osamp) |
| 187 | 187 | { |
| 188 | 188 | priv_t * p = (priv_t *)effp->priv; |
| 189 | − size_t len = min(*isamp, *osamp), dummy = 0; /* No need to clip count */ | |
| 189 | + size_t len = min(*isamp, *osamp); | |
| 190 | 190 | int i; |
| 191 | 191 | |
| 192 | 192 | memcpy(obuf, ibuf, len * sizeof(*obuf)); /* Pass on audio unaffected */ |
| 193 | 193 | *isamp = *osamp = len; |
| 194 | 194 | |
| 195 | 195 | while (sox_true) { |
| 196 | − SOX_SAMPLE_LOCALS; | |
| 197 | 196 | if (p->read == p->step_size) { |
| 198 | 197 | memmove(p->buf, p->buf + p->step_size, |
| 199 | 198 | (p->dft_size - p->step_size) * sizeof(*p->buf)); |
| 200 | 199 | p->read = 0; |
| 201 | 200 | } |
| 202 | 201 | for (; len && p->read < p->step_size; --len, ++p->read, --p->end) |
| 203 | − p->buf[p->dft_size - p->step_size + p->read] = FROM_SOX(*ibuf++, dummy); | |
| 202 | + p->buf[p->dft_size - p->step_size + p->read] = FROM_SOX(*ibuf++); | |
| 204 | 203 | if (p->read != p->step_size) |
| 205 | 204 | break; |
| 206 | 205 | |
| @@ -494,7 +493,7 @@ static int stop(sox_effect_t * effp) · 287 unmodified lines | ||
| 494 | 493 | sox_effect_handler_t const * sox_spectrogram_effect_fn(void) |
| 495 | 494 | { |
| 496 | 495 | static sox_effect_handler_t handler = { |
| 497 | − "spectrogram", 0, 0, getopts, start, flow, drain, stop, 0, sizeof(priv_t)}; | |
| 496 | + "spectrogram", 0, SOX_EFF_MODIFY, getopts, start, flow, drain, stop, 0, sizeof(priv_t)}; | |
| 498 | 497 | static char const * lines[] = { |
| 499 | 498 | "[options]", |
| 500 | 499 | "\t-x num\tX-axis pixels/second, default 100", |
| @@ -185,7 +185,7 @@ buffering: · 184 unmodified lines | ||
| 185 | 185 | break; |
| 186 | 186 | } |
| 187 | 187 | for (c = 0; c < effp->in_signal.channels; ++c) |
| 188 | − p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips); | |
| 188 | + p->buffer[p->buffer_pos++] = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++); | |
| 189 | 189 | } |
| 190 | 190 | break; |
| 191 | 191 | } |
| @@ -141,8 +141,7 @@ static int sox_stat_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_samp · 140 unmodified lines | ||
| 141 | 141 | |
| 142 | 142 | if (stat->fft) { |
| 143 | 143 | for (x = 0; x < len; x++) { |
| 144 | − SOX_SAMPLE_LOCALS; | |
| 145 | − stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x], effp->clips); | |
| 144 | + stat->re_in[stat->fft_offset++] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[x]); | |
| 146 | 145 | |
| 147 | 146 | if (stat->fft_offset >= stat->fft_size) { |
| 148 | 147 | stat->fft_offset = 0; |
| @@ -321,7 +320,7 @@ static int sox_stat_stop(sox_effect_t * effp) · 172 unmodified lines | ||
| 321 | 320 | static sox_effect_handler_t sox_stat_effect = { |
| 322 | 321 | "stat", |
| 323 | 322 | "[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]", |
| 324 | − SOX_EFF_MCHAN, | |
| 323 | + SOX_EFF_MCHAN | SOX_EFF_MODIFY, | |
| 325 | 324 | sox_stat_getopts, |
| 326 | 325 | sox_stat_start, |
| 327 | 326 | sox_stat_flow, |
| @@ -168,7 +168,6 @@ typedef struct { · 167 unmodified lines | ||
| 168 | 168 | char * length_str; |
| 169 | 169 | channel_t * getopts_channels; |
| 170 | 170 | size_t getopts_nchannels; |
| 171 | − sox_sample_t max; | |
| 172 | 171 | size_t samples_done; |
| 173 | 172 | size_t samples_to_do; |
| 174 | 173 | channel_t * channels; |
| @@ -378,7 +377,6 @@ static int start(sox_effect_t * effp) · 203 unmodified lines | ||
| 378 | 377 | priv_t * synth = (priv_t *) effp->priv; |
| 379 | 378 | size_t i, j; |
| 380 | 379 | |
| 381 | − synth->max = lsx_sample_max(effp->out_encoding); | |
| 382 | 380 | synth->samples_done = 0; |
| 383 | 381 | |
| 384 | 382 | if (synth->length_str) |
| @@ -438,9 +436,6 @@ static int start(sox_effect_t * effp) · 53 unmodified lines | ||
| 438 | 436 | return SOX_SUCCESS; |
| 439 | 437 | } |
| 440 | 438 | |
| 441 | − | |
| 442 | − | |
| 443 | −#define sign(d) ((d) < 0? -1. : 1.) | |
| 444 | 439 | #define elapsed_time_s synth->samples_done / effp->in_signal.rate |
| 445 | 440 | |
| 446 | 441 | static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, sox_sample_t * obuf, |
| @@ -607,11 +602,12 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, sox_sample_t * o · 160 unmodified lines | ||
| 607 | 602 | synth_out = synth_out * (1 - fabs(chan->offset)) + chan->offset; |
| 608 | 603 | |
| 609 | 604 | switch (chan->combine) { |
| 610 | − case synth_create: *obuf++ = synth_out * synth->max; break; | |
| 611 | − case synth_mix : *obuf++ = (synth_out * synth->max + synth_input) * 0.5; break; | |
| 612 | − case synth_amod : *obuf++ = (synth_out + 1) * synth_input * 0.5; break; | |
| 613 | − case synth_fmod : *obuf++ = synth_out * synth_input; break; | |
| 605 | + case synth_create: synth_out *= SOX_SAMPLE_MAX; break; | |
| 606 | + case synth_mix : synth_out = (synth_out * SOX_SAMPLE_MAX + synth_input) * 0.5; break; | |
| 607 | + case synth_amod : synth_out = (synth_out + 1) * synth_input * 0.5; break; | |
| 608 | + case synth_fmod : synth_out *= synth_input; break; | |
| 614 | 609 | } |
| 610 | + *obuf++ = floor(synth_out + .5); | |
| 615 | 611 | } |
| 616 | 612 | if (++synth->samples_done == synth->samples_to_do) |
| 617 | 613 | result = SOX_EOF; |
| @@ -649,7 +645,7 @@ const sox_effect_handler_t *sox_synth_effect_fn(void) · 31 unmodified lines | ||
| 649 | 645 | { |
| 650 | 646 | static sox_effect_handler_t handler = { |
| 651 | 647 | "synth", "[len] {type [combine] [[%]freq[k][:|+|/|-[%]freq2[k]] [off [ph [p1 [p2 [p3]]]]]]}", |
| 652 | − SOX_EFF_MCHAN | SOX_EFF_PREC |SOX_EFF_LENGTH, | |
| 648 | + SOX_EFF_MCHAN | SOX_EFF_PREC |SOX_EFF_LENGTH | SOX_EFF_GAIN, | |
| 653 | 649 | getopts, start, flow, 0, stop, kill, sizeof(priv_t) |
| 654 | 650 | }; |
| 655 | 651 | return &handler; |
| @@ -272,7 +272,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 271 unmodified lines | ||
| 272 | 272 | if (*isamp && odone < *osamp) { |
| 273 | 273 | float * t = tempo_input(p->tempo, NULL, *isamp / effp->in_signal.channels); |
| 274 | 274 | for (i = *isamp; i; --i) |
| 275 | − *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips); | |
| 275 | + *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++); | |
| 276 | 276 | tempo_process(p->tempo); |
| 277 | 277 | } |
| 278 | 278 | else *isamp = 0; |
| @@ -200,8 +200,6 @@ skip_check () { · 199 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | # Run tests |
| 202 | 202 | |
| 203 | −${builddir}/sox_sample_test || exit 1 | |
| 204 | − | |
| 205 | 203 | skip_check caf flac mat4 mat5 paf w64 wv |
| 206 | 204 | |
| 207 | 205 | vectors=0 |
| @@ -172,7 +172,7 @@ void sox_trim_clear_start(sox_effect_t * effp) · 171 unmodified lines | ||
| 172 | 172 | const sox_effect_handler_t *sox_trim_effect_fn(void) |
| 173 | 173 | { |
| 174 | 174 | static sox_effect_handler_t handler = { |
| 175 | − "trim", "start [length]", SOX_EFF_MCHAN|SOX_EFF_LENGTH, | |
| 175 | + "trim", "start [length]", SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_MODIFY, | |
| 176 | 176 | sox_trim_getopts, sox_trim_start, sox_trim_flow, |
| 177 | 177 | NULL, NULL, kill, sizeof(priv_t) |
| 178 | 178 | }; |
| @@ -37,6 +37,12 @@ int strncasecmp(char const * s1, char const * s2, size_t n) · 36 unmodified lines | ||
| 37 | 37 | } |
| 38 | 38 | #endif |
| 39 | 39 | |
| 40 | +sox_bool lsx_strends(char const * str, char const * end) | |
| 41 | +{ | |
| 42 | + size_t str_len = strlen(str), end_len = strlen(end); | |
| 43 | + return str_len >= end_len && !strcmp(str + str_len - end_len, end); | |
| 44 | +} | |
| 45 | + | |
| 40 | 46 | char const * lsx_find_file_extension(char const * pathname) |
| 41 | 47 | { |
| 42 | 48 | /* First, chop off any path portions of filename. This |
| @@ -31,14 +31,22 @@ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #ifdef _MSC_VER |
| 33 | 33 | #define __STDC__ 1 |
| 34 | −#define S_IFMT _S_IFMT | |
| 35 | −#define S_IFREG _S_IFREG | |
| 36 | 34 | #define O_BINARY _O_BINARY |
| 35 | +#define O_CREAT _O_CREAT | |
| 36 | +#define O_RDWR _O_RDWR | |
| 37 | +#define O_TRUNC _O_TRUNC | |
| 38 | +#define S_IFMT _S_IFMT | |
| 39 | +#define S_IFREG _S_IFREG | |
| 40 | +#define S_IREAD _S_IREAD | |
| 41 | +#define S_IWRITE _S_IWRITE | |
| 42 | +#define fdopen _fdopen | |
| 37 | 43 | #define fstat _fstat |
| 38 | 44 | #define ftime _ftime |
| 39 | 45 | #define inline __inline |
| 40 | 46 | #define isatty _isatty |
| 47 | +#define mktemp _mktemp | |
| 41 | 48 | #define off_t _off_t |
| 49 | +#define open _open | |
| 42 | 50 | #define popen _popen |
| 43 | 51 | #define stat _stat |
| 44 | 52 | #define strdup _strdup |
| @@ -92,6 +100,8 @@ · 47 unmodified lines | ||
| 92 | 100 | #define M_SQRT2 sqrt(2.) |
| 93 | 101 | #endif |
| 94 | 102 | |
| 103 | +#define sign(x) ((x) < 0? -1 : 1) | |
| 104 | + | |
| 95 | 105 | /* Numerical Recipes in C, p. 284 */ |
| 96 | 106 | #define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */ |
| 97 | 107 | #define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */ |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -347,14 +347,13 @@ static size_t read_samples(sox_format_t * ft, sox_sample_t * buf, · 346 unmodified lines | ||
| 347 | 347 | /* Read the data in the file */ |
| 348 | 348 | if (v->size <= 4) { |
| 349 | 349 | if (!v->adpcm.setup.sign) { |
| 350 | − SOX_SAMPLE_LOCALS; | |
| 351 | 350 | if (lsx_readb(ft, &uc) == SOX_EOF) { |
| 352 | 351 | lsx_warn("VOC input: short file"); |
| 353 | 352 | v->block_remaining = 0; |
| 354 | 353 | return done; |
| 355 | 354 | } |
| 356 | 355 | *buf = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,); |
| 357 | − lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf, ft->clips)); | |
| 356 | + lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf)); | |
| 358 | 357 | ++buf; |
| 359 | 358 | --v->block_remaining; |
| 360 | 359 | ++done; |
| @@ -490,12 +489,11 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, · 129 unmodified lines | ||
| 490 | 489 | } |
| 491 | 490 | v->samples += len; |
| 492 | 491 | while (done < len) { |
| 493 | − SOX_SAMPLE_LOCALS; | |
| 494 | 492 | if (ft->encoding.bits_per_sample == 8) { |
| 495 | − uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++, ft->clips); | |
| 493 | + uc = SOX_SAMPLE_TO_UNSIGNED_8BIT(*buf++); | |
| 496 | 494 | lsx_writeb(ft, uc); |
| 497 | 495 | } else { |
| 498 | − sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips); | |
| 496 | + sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++); | |
| 499 | 497 | lsx_writesw(ft, sw); |
| 500 | 498 | } |
| 501 | 499 | done++; |
| @@ -178,28 +178,7 @@ static int stop(sox_effect_t * effp) · 177 unmodified lines | ||
| 178 | 178 | sox_effect_handler_t const * sox_vol_effect_fn(void) |
| 179 | 179 | { |
| 180 | 180 | static sox_effect_handler_t handler = { |
| 181 | − "vol", vol_usage, SOX_EFF_MCHAN, getopts, start, flow, 0, stop, 0, sizeof(priv_t) | |
| 181 | + "vol", vol_usage, SOX_EFF_MCHAN | SOX_EFF_GAIN, getopts, start, flow, 0, stop, 0, sizeof(priv_t) | |
| 182 | 182 | }; |
| 183 | 183 | return &handler; |
| 184 | 184 | } |
| 185 | − | |
| 186 | −static int gain_getopts(sox_effect_t * effp, int argc, char * * argv) | |
| 187 | −{ | |
| 188 | − char * args[] = {0, 0, "dB"}; | |
| 189 | − | |
| 190 | − if (argc != 2) | |
| 191 | − return lsx_usage(effp); | |
| 192 | − args[0] = argv[0]; | |
| 193 | − args[1] = argv[1]; | |
| 194 | − return sox_vol_effect_fn()->getopts(effp, (int)array_length(args), args); | |
| 195 | −} | |
| 196 | − | |
| 197 | −sox_effect_handler_t const * sox_gain_effect_fn(void) | |
| 198 | −{ | |
| 199 | − static sox_effect_handler_t handler; | |
| 200 | − handler = *sox_vol_effect_fn(); | |
| 201 | − handler.name = "gain"; | |
| 202 | − handler.usage = "dB-gain"; | |
| 203 | − handler.getopts = gain_getopts; | |
| 204 | − return &handler; | |
| 205 | −} | |
| @@ -331,10 +331,9 @@ static size_t wavgsmwrite(sox_format_t * ft, const sox_sample_t *buf, size_t len · 330 unmodified lines | ||
| 331 | 331 | ft->sox_errno = SOX_SUCCESS; |
| 332 | 332 | |
| 333 | 333 | while (done < len) { |
| 334 | − SOX_SAMPLE_LOCALS; | |
| 335 | 334 | while ((wav->gsmindex < 160*2) && (done < len)) |
| 336 | 335 | wav->gsmsample[(wav->gsmindex)++] = |
| 337 | − SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips); | |
| 336 | + SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]); | |
| 338 | 337 | |
| 339 | 338 | if (wav->gsmindex < 160*2) |
| 340 | 339 | break; |
| @@ -120,14 +120,13 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, size_t · 119 unmodified lines | ||
| 120 | 120 | int result; |
| 121 | 121 | |
| 122 | 122 | for (i = 0; i < len; ++i) switch (ft->encoding.bits_per_sample) { |
| 123 | − SOX_SAMPLE_LOCALS; | |
| 124 | − case 8: obuf[i] = SOX_SAMPLE_TO_SIGNED_8BIT(buf[i], ft->clips); break; | |
| 125 | − case 16: obuf[i] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[i], ft->clips); break; | |
| 126 | − case 24: obuf[i] = SOX_SAMPLE_TO_SIGNED_24BIT(buf[i], ft->clips) << 8; | |
| 123 | + case 8: obuf[i] = SOX_SAMPLE_TO_SIGNED_8BIT(buf[i]); break; | |
| 124 | + case 16: obuf[i] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[i]); break; | |
| 125 | + case 24: obuf[i] = SOX_SAMPLE_TO_SIGNED_24BIT(buf[i]) << 8; | |
| 127 | 126 | obuf[i] >>= 8; break; |
| 128 | 127 | case 32: obuf[i] = ft->encoding.encoding == SOX_ENCODING_WAVPACKF? |
| 129 | − SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i], ft->clips) : | |
| 130 | − SOX_SAMPLE_TO_SIGNED_32BIT(buf[i], ft->clips); | |
| 128 | + SOX_SAMPLE_TO_SIGNED_24BIT(*(float *)&buf[i]) : | |
| 129 | + SOX_SAMPLE_TO_SIGNED_32BIT(buf[i]); | |
| 131 | 130 | break; |
| 132 | 131 | } |
| 133 | 132 | result = WavpackPackSamples(p->codec, obuf, (uint32_t) len / ft->signal.channels); |