History

--guard, & associated changes

robs committed 17 years ago

Commit 1f70a301 parent bd403cd74 files · +628 −719Browse files

Unified · Split

74 files
  1. ChangeLog +12 −5
  2. src/.cvsignore +0 −1
  3. src/8svx.c +1 −2
  4. src/CMakeLists.txt +8 −9
  5. src/Makefile.am +3 −5
  6. src/adpcms.c +1 −2
  7. src/alsa.c +8 −9
  8. src/amr.h +1 −2
  9. src/ao.c +3 −5
  10. src/band.h +5 −4
  11. src/bend.c +1 −1
  12. src/biquad.h +1 −3
  13. src/biquads.c +4 −1
  14. src/chorus.c +1 −1
  15. src/compand.c +1 −1
  16. src/coreaudio.c +1 −1
  17. src/dat.c +3 −4
  18. src/dcshift.c +1 −1
  19. src/dft_filter.c +2 −2
  20. src/dither.c +26 −26
  21. src/dither_fir.h +3 −3
  22. src/dither_iir.h +3 −3
  23. src/earwax.c +2 −0
  24. src/echo.c +1 −1
  25. src/echos.c +1 −1
  26. src/effects.c +6 −7
  27. src/effects_i.c +1 −3
  28. src/example2.c +2 −3
  29. src/ffmpeg.c +1 −2
  30. src/flac.c +5 −6
  31. src/formats.c +1 −0
  32. src/formats_i.c +0 −8
  33. src/gain.c +248 −0
  34. src/gsm.c +1 −2
  35. src/hcom.c +1 −2
  36. src/ladspa.c +2 −2
  37. src/lpc10.c +1 −2
  38. src/mcompand.c +1 −1
  39. src/mixer.c +13 −0
  40. src/mp3.c +3 −4
  41. src/noiseprof.c +3 −4
  42. src/noisered.c +1 −2
  43. src/normalise.c +0 −127
  44. src/overdrive.c +2 −2
  45. src/phaser.c +1 −1
  46. src/rate.c +2 −2
  47. src/raw.c +3 −4
  48. src/remix.c +13 −0
  49. src/reverb.c +4 −1
  50. src/silence.c +4 −6
  51. src/skelform.c +1 −2
  52. src/smp.c +1 −2
  53. src/sox.c +133 −115
  54. src/sox.h +32 −35
  55. src/sox_i.h +11 −1
  56. src/sox_sample_test.c +0 −18
  57. src/sox_sample_test.h +0 −207
  58. src/spectrogram.c +3 −4
  59. src/splice.c +1 −1
  60. src/stat.c +2 −3
  61. src/synth.c +6 −10
  62. src/tempo.c +1 −1
  63. src/tests.sh +0 −2
  64. src/trim.c +1 −1
  65. src/util.c +6 −0
  66. src/util.h +12 −2
  67. src/vectors/intermediate1_44100_-u_-1_wav_-N.s1 +0 −0
  68. src/vectors/intermediate1_44100_-u_-1_wav_-X.s1 +0 −0
  69. src/vectors/intermediate1_44100_-u_-1_wav_-X_-N.s1 +0 −0
  70. src/vectors/intermediate1_44100_-u_-1_wav_.s1 +0 −0
  71. src/voc.c +3 −5
  72. src/vol.c +1 −22
  73. src/wav.c +1 −2
  74. src/wavpack.c +5 −6
ChangeLog+12−5
@@ -25,6 +25,7 @@ Newly deprecated features (to be removed in future): · 24 unmodified lines
2525 Deprec- Feature [O(ption)] Removal
2626 ated in [F(ormat)] [E(ffect)] Replacement due after
2727 ------- ---------------------- ---------------------- -------
28+ 14.3.0 E norm -b, norm -i gain -B, gain -en 14.3.0 + 1 year
2829 14.3.0 F flac: libFLAC 1.1.2,3 libFLAC > 1.1.3 14.3.0 + 6 months
2930
3031 Previously deprecated features (to be removed in future):
@@ -59,11 +60,18 @@ File formats: · 28 unmodified lines
5960 o Fix [2404566] segfault when converting from MS ADPCM wav file. (robs)
6061 o Fix slight FLAC seek inaccuracy e.g. when using `trim' effect. (robs)
6162
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+
6269 Effects:
6370
6471 o New `overdrive' effect. (robs)
6572 o New `pluck' and `tpdf' types for `synth'. (robs)
6673 o Can now set common parameters for multiple `synth' channels. (robs)
74+ o Richer gain/normalise options. (robs)
6775 o Fix [2487589] `dither' clipping detection & handling. (robs)
6876 o Fix `repeat' sometimes stopping repeating too soon. (robs)
6977 o Fix `repeat' sometimes repeating wrong audio segments. (robs)
@@ -75,14 +83,13 @@ Effects: · 5 unmodified lines
7583
7684 Other new features:
7785
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)
8189 o New `--ignore-length' option to ignore length in input file
8290 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)
8591 o New `--temp DIRECTORY' option. (robs)
92+ o Grouped files, e.g. play -r 6k "*.vox" plays all at 6k. (robs)
8693 o New bitrate, time in seconds, & total options for soxi. (robs)
8794
8895 Other bug fixes:
src/.cvsignore+0−1
@@ -1,5 +1,4 @@
11 Makefile Makefile.in
2−sox_sample_test
32 example0 example1 example2
43 soxconfig.h.in soxconfig.h soxstdint.h
54 .deps
src/8svx.c+1−2
@@ -254,7 +254,6 @@ static int startwrite(sox_format_t * ft) · 253 unmodified lines
254254 static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t len)
255255 {
256256 priv_t * p = (priv_t * ) ft->priv;
257− SOX_SAMPLE_LOCALS;
258257
259258 unsigned char datum;
260259 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
263262
264263 while(done < len) {
265264 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++);
267266 /* FIXME: Needs to pass ft struct and not FILE */
268267 putc(datum, p->ch[i]);
269268 }
src/CMakeLists.txt+8−9
@@ -28,16 +28,16 @@ add_custom_command( · 27 unmodified lines
2828
2929 # Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/ /'
3030 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
3737 contrast filter output silence trim
3838 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
4141 )
4242 set(formats_srcs
4343 8svx dat ima-fmt s3-fmt u3-fmt
@@ -62,7 +62,6 @@ add_library(lib${PROJECT_NAME} · 18 unmodified lines
6262 )
6363 add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c)
6464 target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} lpc10 ${optional_libs})
65−add_executable(sox_sample_test sox_sample_test.c)
6665 add_executable(example0 example0.c)
6766 target_link_libraries(example0 lib${PROJECT_NAME} lpc10 ${optional_libs})
6867 add_executable(example1 example1.c)
src/Makefile.am+3−5
@@ -28,7 +28,7 @@ endif · 27 unmodified lines
2828 #########################
2929
3030 bin_PROGRAMS = sox
31−EXTRA_PROGRAMS = example0 example1 example2 sox_sample_test
31+EXTRA_PROGRAMS = example0 example1 example2
3232 lib_LTLIBRARIES = libsox.la
3333 include_HEADERS = sox.h
3434 nodist_include_HEADERS = soxstdint.h
@@ -37,7 +37,6 @@ sox_LDADD = libsox.la · 2 unmodified lines
3737 example0_SOURCES = example0.c
3838 example1_SOURCES = example1.c
3939 example2_SOURCES = example2.c
40−sox_sample_test_SOURCES = sox_sample_test.c sox_sample_test.h
4140
4241 ###############################################
4342 # libsox - Dynamic Libraries for File Formats #
@@ -274,7 +273,7 @@ libsox_la_SOURCES += \ · 230 unmodified lines
274273 dither_fir.h dither_iir.h earwax.c echo.c echos.c effects.c effects.h \
275274 effects_i.c fade.c fft4g.c fft4g.h fifo.h filter.c flanger.c input.c \
276275 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 \
278277 rate.c rate_filters.h rate_half_fir.h \
279278 rate_poly_fir0.h rate_poly_fir.h remix.c repeat.c reverb.c \
280279 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
400399 CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake \
401400 tests.sh testall.sh tests.bat testall.bat test-comments
402401
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)
404403
405404 play rec: sox$(EXEEXT)
406405 if test "$(PLAYRECLINKS)" = "yes"; then \
@@ -430,7 +429,6 @@ uninstall-hook: · 23 unmodified lines
430429
431430 clean-local:
432431 $(RM) play rec soxi
433− $(RM) sox_sample_test$(EXEEXT)
434432 $(RM) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT)
435433
436434 distclean-local:
src/adpcms.c+1−2
@@ -251,8 +251,7 @@ size_t lsx_adpcm_write(sox_format_t * ft, adpcm_io_t * state, const sox_sample_t · 250 unmodified lines
251251 short word;
252252
253253 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++);
256255
257256 byte <<= 4;
258257 byte |= lsx_adpcm_encode(word, &state->encoder) & 0x0F;
src/alsa.c+8−9
@@ -187,45 +187,44 @@ static size_t write_(sox_format_t * ft, sox_sample_t const * buf, size_t len) · 186 unmodified lines
187187 priv_t * p = (priv_t *)ft->priv;
188188 size_t done, i, n;
189189 snd_pcm_sframes_t actual;
190− SOX_SAMPLE_LOCALS;
191190
192191 for (done = 0; done < len; done += n) {
193192 i = n = min(len - done, p->buf_len);
194193 switch (p->format) {
195194 case SND_PCM_FORMAT_S8: {
196195 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++);
198197 break;
199198 }
200199 case SND_PCM_FORMAT_U8: {
201200 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++);
203202 break;
204203 }
205204 case SND_PCM_FORMAT_S16: {
206205 int16_t * buf1 = (int16_t *)p->buf;
207206 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++));
209208 else
210− while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
209+ while (i--) *buf1++ = SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
211210 break;
212211 }
213212 case SND_PCM_FORMAT_U16: {
214213 uint16_t * buf1 = (uint16_t *)p->buf;
215214 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++));
217216 else
218− while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++, ft->clips);
217+ while (i--) *buf1++ = SOX_SAMPLE_TO_UNSIGNED_16BIT(*buf++);
219218 break;
220219 }
221220 case SND_PCM_FORMAT_S24: {
222221 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++);
224223 break;
225224 }
226225 case SND_PCM_FORMAT_U24: {
227226 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++);
229228 break;
230229 }
231230 }
src/amr.h+1−2
@@ -117,8 +117,7 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, size_t · 116 unmodified lines
117117 size_t done;
118118
119119 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++);
122121 if (p->pcm_index == AMR_FRAME) {
123122 p->pcm_index = 0;
124123 if (!encode_1_frame(ft))
src/ao.c+3−5
@@ -74,12 +74,11 @@ static int startwrite(sox_format_t * ft) · 73 unmodified lines
7474 return SOX_SUCCESS;
7575 }
7676
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)
7878 {
7979 while (len--)
8080 {
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++);
8382 if (swap)
8483 datum = lsx_swapw(datum);
8584 *(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
9796
9897 aobuf_size = (ft->encoding.bits_per_sample >> 3) * len;
9998
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);
102100 if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0)
103101 return 0;
104102
src/band.h+5−4
@@ -40,7 +40,8 @@ · 39 unmodified lines
4040
4141 p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
4242 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+ }
src/bend.c+1−1
@@ -154,7 +154,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 153 unmodified lines
154154 ++p->in_pos;
155155
156156 /* 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]);
158158 obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(
159159 p->gOutFIFO[p->gRover - inFifoLatency], effp->clips);
160160 p->gRover++;
src/biquad.h+1−3
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #ifndef biquad_included
1919 #define biquad_included
2020
21+#define LSX_EFF_ALIAS
2122 #include "sox_i.h"
2223
2324 typedef enum {
@@ -74,7 +75,4 @@ int lsx_biquad_start(sox_effect_t * effp); · 50 unmodified lines
7475 int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
7576 size_t *isamp, size_t *osamp);
7677
77−#undef lsx_fail
78−#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
79−
8078 #endif
src/biquads.c+4−1
@@ -164,7 +164,7 @@ static int start(sox_effect_t * effp) · 163 unmodified lines
164164 priv_t * p = (priv_t *)effp->priv;
165165 double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
166166 double A = exp(p->gain / 40 * log(10.));
167− double alpha = 0;
167+ double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
168168
169169 if (w0 > M_PI) {
170170 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
362362 {double g = dB_to_linear(19.9 - linear_to_dB(
363363 (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2)));
364364 p->b0 *= g; p->b1 *= g; p->b2 *= g;}
365+ mult = dB_to_linear(19.9);
365366 break;
366367 }
368+ if (effp->in_signal.mult)
369+ *effp->in_signal.mult /= mult;
367370 return lsx_biquad_start(effp);
368371 }
369372
src/chorus.c+1−1
@@ -333,7 +333,7 @@ static int sox_chorus_stop(sox_effect_t * effp) · 332 unmodified lines
333333 static sox_effect_handler_t sox_chorus_effect = {
334334 "chorus",
335335 "gain-in gain-out delay decay speed depth [ -s | -t ]",
336− SOX_EFF_LENGTH,
336+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
337337 sox_chorus_getopts,
338338 sox_chorus_start,
339339 sox_chorus_flow,
src/compand.c+1−1
@@ -275,7 +275,7 @@ static int kill(sox_effect_t * effp) · 274 unmodified lines
275275 sox_effect_handler_t const * sox_compand_effect_fn(void)
276276 {
277277 static sox_effect_handler_t handler = {
278− "compand", compand_usage, SOX_EFF_MCHAN,
278+ "compand", compand_usage, SOX_EFF_MCHAN | SOX_EFF_GAIN,
279279 getopts, start, flow, drain, stop, kill, sizeof(priv_t)
280280 };
281281 return &handler;
src/coreaudio.c+1−1
@@ -285,7 +285,7 @@ static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t ns · 284 unmodified lines
285285 p = &ac->buffer[ac->buf_offset];
286286
287287 while (samp_left--)
288− *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++, ft->clips);
288+ *p++ = SOX_SAMPLE_TO_FLOAT_32BIT(*buf++);
289289
290290 ac->buf_offset += len;
291291
src/dat.c+3−4
@@ -104,14 +104,14 @@ static size_t sox_datread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp) · 103 unmodified lines
104104 /* Read a complete set of channels */
105105 sscanf(inpstr," %*s%n", &inpPtr);
106106 for (i=0; i<ft->signal.channels; i++) {
107+ SOX_SAMPLE_LOCALS;
107108 retc = sscanf(&inpstr[inpPtr]," %lg%n", &sampval, &inpPtrInc);
108109 inpPtr += inpPtrInc;
109110 if (retc != 1) {
110111 lsx_fail_errno(ft,SOX_EOF,"Unable to read sample.");
111112 return 0;
112113 }
113− sampval *= SOX_SAMPLE_MAX;
114− *buf++ = SOX_ROUND_CLIP_COUNT(sampval, ft->clips);
114+ *buf++ = SOX_FLOAT_64BIT_TO_SAMPLE(sampval, ft->clips);
115115 done++;
116116 }
117117 }
@@ -135,8 +135,7 @@ static size_t sox_datwrite(sox_format_t * ft, const sox_sample_t *buf, size_t ns · 17 unmodified lines
135135 sprintf(s," %15.8g ",dat->timevalue);
136136 lsx_writes(ft, s);
137137 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++);
140139 sprintf(s," %15.8g", sampval);
141140 lsx_writes(ft, s);
142141 done++;
src/dcshift.c+1−1
@@ -173,7 +173,7 @@ static sox_effect_handler_t sox_dcshift_effect = { · 172 unmodified lines
173173 "shift [ limitergain ]\n"
174174 " The peak limiter has a gain much less than 1.0 (ie 0.05 or 0.02) which is only\n"
175175 " used on peaks to prevent clipping. (default is no limiter)",
176− SOX_EFF_MCHAN,
176+ SOX_EFF_MCHAN | SOX_EFF_GAIN,
177177 sox_dcshift_getopts,
178178 sox_dcshift_start,
179179 sox_dcshift_flow,
src/dft_filter.c+2−2
@@ -79,7 +79,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 78 unmodified lines
7979 p->samples_in += (int)*isamp;
8080
8181 for (i = *isamp; i; --i)
82− *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
82+ *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++);
8383 filter(p);
8484 }
8585 else *isamp = 0;
@@ -122,7 +122,7 @@ static int stop(sox_effect_t * effp) · 36 unmodified lines
122122 sox_effect_handler_t const * sox_dft_filter_effect_fn(void)
123123 {
124124 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
126126 };
127127 return &handler;
128128 }
src/dither.c+26−26
@@ -24,10 +24,6 @@ · 23 unmodified lines
2424 #include <assert.h>
2525
2626 #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)
3127
3228 typedef enum {Pdf_rectangular, Pdf_triangular, Pdf_gaussian} pdf_type_t;
3329 static lsx_enum_item const pdf_types[] = {
@@ -134,12 +130,12 @@ static const filter_t filters[] = { · 100 unmodified lines
134130 {48000, iir, 4, 21.0, ges48, Shape_gesemann},
135131 {44100, iir, 4, 21.2, ges44, Shape_gesemann},
136132 {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},
138134 {37800, fir, 16, 22.7, shi38, Shape_shibata},
139135 {32000, fir, 16, 15.7, shi32, Shape_shibata},
140136 {22050, fir, 15, 9.0, shi22, Shape_shibata},
141137 {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},
143139 {44100, fir, 20, 37.5, shh44, Shape_high_shibata},
144140 { 0, fir, 0, 0.0, NULL, Shape_none},
145141 };
@@ -154,6 +150,7 @@ typedef struct { · 8 unmodified lines
154150 double previous_outputs[MAX_N * 2];
155151 size_t pos;
156152 double const * coefs;
153+ sox_sample_t offset;
157154 int (*flow)(sox_effect_t *, const sox_sample_t *, sox_sample_t *, size_t *, size_t *);
158155 } priv_t;
159156
@@ -189,7 +186,7 @@ static int flow_no_shape(sox_effect_t * effp, const sox_sample_t * ibuf, · 29 unmodified lines
189186 size_t len = *isamp = *osamp = min(*isamp, *osamp);
190187
191188 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);
193190 SOX_SAMPLE_CLIP_COUNT(d, effp->clips);
194191 *obuf++ = d;
195192 }
@@ -227,36 +224,39 @@ static int start(sox_effect_t * effp) · 31 unmodified lines
227224 if (PREC > 24)
228225 return SOX_EFF_NULL; /* Dithering not needed at this resolution */
229226
230− if (!p->filter_name)
231− p->flow = flow_no_shape;
232− else {
227+ p->flow = flow_no_shape;
228+ if (p->filter_name) {
233229 filter_t const * f;
234230
235231 for (f = filters; f->len && (f->name != p->filter_name || fabs(effp->in_signal.rate - f->rate) / f->rate > .05); ++f);
236232 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);
239234 }
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);
251250 }
252− p->coefs = f->coefs;
253− mult = dB_to_linear(f->gain);
254251 }
255252 p->am1 = p->depth / (1 << PREC);
256253 p->am0 = (p->pdf == Pdf_triangular) * p->am1;
254+ if (effp->out_encoding->half_bit && PREC < 32)
255+ p->offset = 1 << (31 - PREC);
257256
258257 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;
260260
261261 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);
262262 return SOX_SUCCESS;
src/dither_fir.h+3−3
@@ -7,12 +7,12 @@ static int NAME(sox_effect_t * effp, const sox_sample_t * ibuf, · 6 unmodified lines
77
88 while (len--) {
99 double r = floor(p->am0 * RANQD1) + floor(p->am1 * RANQD1);
10− double error, d = *ibuf++;
10+ double error, d = *ibuf++ + p->offset;
1111 int j = 0;
1212 CONVOLVE
1313 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;
1616 p->pos = p->pos? p->pos - 1 : p->pos - 1 + N;
1717 p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error;
1818 }
src/dither_iir.h+3−3
@@ -12,9 +12,9 @@ static int NAME(sox_effect_t * effp, const sox_sample_t * ibuf, · 11 unmodified lines
1212 int j = 0;
1313 CONVOLVE
1414 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;
1818 p->pos = p->pos? p->pos - 1 : p->pos - 1 + N;
1919 p->previous_errors[p->pos + N] = p->previous_errors[p->pos] = error;
2020 p->previous_outputs[p->pos + N] = p->previous_outputs[p->pos] = output;
src/earwax.c+2−0
@@ -62,6 +62,8 @@ static int start(sox_effect_t * effp) · 61 unmodified lines
6262 return SOX_EOF;
6363 }
6464 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);
6567 return SOX_SUCCESS;
6668 }
6769
src/echo.c+1−1
@@ -248,7 +248,7 @@ static int sox_echo_stop(sox_effect_t * effp) · 247 unmodified lines
248248 static sox_effect_handler_t sox_echo_effect = {
249249 "echo",
250250 "gain-in gain-out delay decay [ delay decay ... ]",
251− SOX_EFF_LENGTH,
251+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
252252 sox_echo_getopts,
253253 sox_echo_start,
254254 sox_echo_flow,
src/echos.c+1−1
@@ -260,7 +260,7 @@ static int sox_echos_stop(sox_effect_t * effp) · 259 unmodified lines
260260 static sox_effect_handler_t sox_echos_effect = {
261261 "echos",
262262 "gain-in gain-out delay decay [ delay decay ... ]",
263− SOX_EFF_LENGTH,
263+ SOX_EFF_LENGTH | SOX_EFF_GAIN,
264264 sox_echos_getopts,
265265 sox_echos_start,
266266 sox_echos_flow,
src/effects.c+6−7
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1616 */
1717
18+#define LSX_EFF_ALIAS
1819 #include "sox_i.h"
1920 #include "getopt.h"
2021 #include <assert.h>
@@ -23,12 +24,6 @@ · 2 unmodified lines
2324 #include <strings.h>
2425 #endif
2526
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−
3227 #define DEBUG_EFFECTS_CHAIN 0
3328
3429 /* 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
9994 /* Effects chain: */
10095
10196 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)
10398 {
10499 sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
105100 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
150145 effp->out_signal.rate = in->rate;
151146 if (!(effp->handler.flags & SOX_EFF_PREC))
152147 effp->out_signal.precision = in->precision;
148+ if (!(effp->handler.flags & SOX_EFF_GAIN))
149+ effp->out_signal.mult = in->mult;
153150
154151 effp->flows =
155152 (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
167164 free(eff0.priv);
168165 return SOX_EOF;
169166 }
167+ if (in->mult)
168+ lsx_debug("mult=%g", *in->mult);
170169
171170 *in = effp->out_signal;
172171
src/effects_i.c+1−3
@@ -18,12 +18,10 @@ · 17 unmodified lines
1818 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1919 */
2020
21+#define LSX_EFF_ALIAS
2122 #include "sox_i.h"
2223 #include <string.h>
2324
24−#undef lsx_fail
25−#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail
26−
2725 int lsx_usage(sox_effect_t * effp)
2826 {
2927 if (effp->handler.usage)
src/example2.c+2−3
@@ -82,15 +82,14 @@ int main(int argc, char * argv[]) · 81 unmodified lines
8282 /* Read in and process blocks of audio for the selected period or until EOF: */
8383 for (blocks = 0; sox_read(in, buf, block_size) == block_size && blocks * block_period < period; ++blocks) {
8484 double left = 0, right = 0;
85− size_t i, clips = 0;
85+ size_t i;
8686 static const char line[] = "===================================";
8787 int l, r;
8888
8989 for (i = 0; i < block_size; ++i) {
90− SOX_SAMPLE_LOCALS;
9190 /* convert the sample from SoX's internal format to a `double' for
9291 * 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]);
9493
9594 /* The samples for each channel are interleaved; in this example
9695 * we allow only stereo audio, so the left channel audio can be found in
src/ffmpeg.c+1−2
@@ -406,9 +406,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 405 unmodified lines
406406 do {
407407 /* If output frame is not full, copy data into it */
408408 if (ffmpeg->samples_index < ffmpeg->audio_input_frame_size) {
409− SOX_SAMPLE_LOCALS;
410409 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]);
412411 }
413412
414413 /* If output frame full or no more data to read, write it out */
src/flac.c+5−6
@@ -441,22 +441,21 @@ static size_t write_samples(sox_format_t * const ft, sox_sample_t const * const · 440 unmodified lines
441441 unsigned i;
442442
443443 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]);
446445 p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample);
447446 switch (p->bits_per_sample) {
448447 case 8: p->decoded_samples[i] =
449− SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
448+ SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i]);
450449 break;
451450 case 16: p->decoded_samples[i] =
452− SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
451+ SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i]);
453452 break;
454453 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;
456455 p->decoded_samples[i] >>= 8;
457456 break;
458457 case 32: p->decoded_samples[i] =
459− SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
458+ SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i]);
460459 break;
461460 }
462461 }
src/formats.c+1−0
@@ -428,6 +428,7 @@ sox_format_t * sox_open_read( · 427 unmodified lines
428428 if (magic)
429429 filetype = magic_file(magic, path);
430430 if (filetype && (
431+ lsx_strends(filetype, "/unknown") ||
431432 !strcmp(filetype, "application/octet-stream") ||
432433 !strncmp(filetype, "text/plain", (size_t)10) ))
433434 filetype = NULL;
src/formats_i.c+0−8
@@ -90,14 +90,6 @@ int lsx_check_read_params(sox_format_t * ft, unsigned channels, · 89 unmodified lines
9090 return SOX_EOF;
9191 }
9292
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−
10193 /* Read in a buffer of data of length len bytes.
10294 * Returns number of bytes read.
10395 */
src/gain.c+248−0
@@ -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+}
src/gsm.c+1−2
@@ -195,10 +195,9 @@ static size_t sox_gsmwrite(sox_format_t * ft, const sox_sample_t *buf, size_t sa · 194 unmodified lines
195195
196196 while (done < samp)
197197 {
198− SOX_SAMPLE_LOCALS;
199198 while ((p->samplePtr < p->sampleTop) && (done < samp))
200199 *(p->samplePtr)++ =
201− SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
200+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]);
202201
203202 if (p->samplePtr == p->sampleTop)
204203 {
src/hcom.c+1−2
@@ -277,9 +277,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 276 unmodified lines
277277 }
278278
279279 for (i = 0; i < len; i++) {
280− SOX_SAMPLE_LOCALS;
281280 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);
283282 }
284283
285284 return len;
src/ladspa.c+2−2
@@ -237,7 +237,7 @@ static int sox_ladspa_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sa · 236 unmodified lines
237237 if (l_st->input_port != ULONG_MAX) {
238238 /* Copy the input; FIXME: Assume LADSPA_Data == float! */
239239 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]);
241241
242242 /* Connect the input port */
243243 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
291291 static sox_effect_handler_t sox_ladspa_effect = {
292292 "ladspa",
293293 "MODULE [PLUGIN] [ARGUMENT...]",
294− 0,
294+ SOX_EFF_GAIN,
295295 sox_ladspa_getopts,
296296 sox_ladspa_start,
297297 sox_ladspa_flow,
src/lpc10.c+1−2
@@ -179,8 +179,7 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 178 unmodified lines
179179
180180 while (len > 0) {
181181 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++]);
184183 len--;
185184 }
186185
src/mcompand.c+1−1
@@ -492,7 +492,7 @@ const sox_effect_handler_t *sox_mcompand_effect_fn(void) · 491 unmodified lines
492492 " attack1,decay1[,attack2,decay2...]\n"
493493 " in-dB1,out-dB1[,in-dB2,out-dB2...]\n"
494494 " [ gain [ initial-volume [ delay ] ] ]",
495− SOX_EFF_MCHAN,
495+ SOX_EFF_MCHAN | SOX_EFF_GAIN,
496496 getopts, start, flow, drain, stop, kill, sizeof(priv_t)
497497 };
498498
src/mixer.c+13−0
@@ -485,6 +485,19 @@ static int start(sox_effect_t * effp) · 484 unmodified lines
485485 }
486486 }
487487
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+
488501 if (effp->in_signal.channels != effp->out_signal.channels)
489502 return SOX_SUCCESS;
490503
src/mp3.c+3−4
@@ -406,7 +406,6 @@ static size_t sox_mp3write(sox_format_t * ft, const sox_sample_t *buf, size_t sa · 405 unmodified lines
406406 int i,j;
407407 ptrdiff_t done = 0;
408408 size_t written;
409− SOX_SAMPLE_LOCALS;
410409
411410 /* NOTE: This logic assumes that "short int" is 16-bits
412411 * 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
435434 j=0;
436435 for (i=0; i<nsamples; i++)
437436 {
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++]);
440439 }
441440 }
442441 else
443442 {
444443 j=0;
445444 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++]);
447446 }
448447
449448 mp3buffer_size = 1.25 * nsamples + 7200;
src/noiseprof.c+3−4
@@ -116,7 +116,7 @@ static int sox_noiseprof_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox · 115 unmodified lines
116116 size_t *isamp, size_t *osamp)
117117 {
118118 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);
120120 size_t chans = effp->in_signal.channels;
121121 size_t i, j, n = min(samp / chans, WINDOWSIZE - p->bufdata);
122122
@@ -125,11 +125,10 @@ static int sox_noiseprof_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox · 2 unmodified lines
125125
126126 /* Collect data for every channel. */
127127 for (i = 0; i < chans; i ++) {
128− SOX_SAMPLE_LOCALS;
129128 chandata_t * chan = &(p->chandata[i]);
130129 for (j = 0; j < n; j ++)
131130 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]);
133132 if (n + p->bufdata == WINDOWSIZE)
134133 collect_data(chan);
135134 }
@@ -208,7 +207,7 @@ static int sox_noiseprof_stop(sox_effect_t * effp) · 72 unmodified lines
208207 static sox_effect_handler_t sox_noiseprof_effect = {
209208 "noiseprof",
210209 "[profile-file]",
211− SOX_EFF_MCHAN,
210+ SOX_EFF_MCHAN | SOX_EFF_MODIFY,
212211 sox_noiseprof_getopts,
213212 sox_noiseprof_start,
214213 sox_noiseprof_flow,
src/noisered.c+1−2
@@ -285,7 +285,6 @@ static int sox_noisered_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_ · 284 unmodified lines
285285
286286 /* Reduce noise on every channel. */
287287 for (i = 0; i < tracks; i ++) {
288− SOX_SAMPLE_LOCALS;
289288 chandata_t* chan = &(data->chandata[i]);
290289 size_t j;
291290
@@ -294,7 +293,7 @@ static int sox_noisered_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_ · 2 unmodified lines
294293
295294 for (j = 0; j < ncopy; j ++)
296295 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]);
298297
299298 if (!whole_window)
300299 continue;
src/normalise.c+0−127
@@ -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−}
src/overdrive.c+2−2
@@ -52,7 +52,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 51 unmodified lines
5252 size_t dummy = 0, len = *isamp = *osamp = min(*isamp, *osamp);
5353 while (len--) {
5454 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;
5656 d *= p->gain;
5757 d += p->colour;
5858 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
6666 sox_effect_handler_t const * sox_overdrive_effect_fn(void)
6767 {
6868 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)};
7070 return &handler;
7171 }
src/phaser.c+1−1
@@ -139,7 +139,7 @@ sox_effect_handler_t const * sox_phaser_effect_fn(void) · 138 unmodified lines
139139 {
140140 static sox_effect_handler_t handler = {
141141 "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)
143143 };
144144 return &handler;
145145 }
src/rate.c+2−2
@@ -494,7 +494,7 @@ static int start(sox_effect_t * effp) · 493 unmodified lines
494494 if (effp->in_signal.rate == out_rate)
495495 return SOX_EFF_NULL;
496496
497− if (effp->flow == 0 && effp->in_signal.mult)
497+ if (effp->in_signal.mult)
498498 *effp->in_signal.mult *= .705; /* 1/(2/sinc(pi/3)-1); see De Soras 4.1.2 */
499499
500500 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
516516
517517 if (*isamp && odone < *osamp) {
518518 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++);
520520 rate_process(&p->rate);
521521 }
522522 else *isamp = 0;
src/raw.c+3−4
@@ -14,8 +14,8 @@ typedef uint16_t uint14_t; · 13 unmodified lines
1414 typedef uint16_t uint13_t;
1515 #define SOX_ULAW_BYTE_TO_SAMPLE(d,clips) SOX_SIGNED_16BIT_TO_SAMPLE(sox_ulaw2linear16(d),clips)
1616 #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)
1919
2020 int lsx_rawseek(sox_format_t * ft, uint64_t offset)
2121 {
@@ -95,11 +95,10 @@ READ_SAMPLES_FUNC(df, sizeof(double), su, double, double, SOX_FLOAT_64BIT_TO_SAM · 73 unmodified lines
9595 static size_t sox_write_ ## sign ## type ## _samples( \
9696 sox_format_t * ft, sox_sample_t const * buf, size_t len) \
9797 { \
98− SOX_SAMPLE_LOCALS; \
9998 size_t n, nwritten; \
10099 ctype *data = lsx_malloc(sizeof(ctype) * len); \
101100 for (n = 0; n < len; n++) \
102− data[n] = cast(buf[n], ft->clips); \
101+ data[n] = cast(buf[n]); \
103102 nwritten = lsx_write_ ## type ## _buf(ft, (uctype *)data, len); \
104103 free(data); \
105104 return nwritten; \
src/remix.c+13−0
@@ -95,6 +95,19 @@ static int parse(sox_effect_t * effp, char * * argv, unsigned channels) · 94 unmodified lines
9595 p->out_specs[i].in_specs[j].multiplier = (p->mode == automatic || (p->mode == semi && !mul_spec)) ? mult : 1;
9696 }
9797 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+ }
98111 return SOX_SUCCESS;
99112 }
100113
src/reverb.c+4−1
@@ -212,6 +212,9 @@ static int start(sox_effect_t * effp) · 211 unmodified lines
212212 &p->chan[i].reverb, effp->in_signal.rate, p->wet_gain_dB, p->room_scale,
213213 p->reverberance, p->hf_damping, p->pre_delay_ms, p->stereo_depth,
214214 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));
215218 return SOX_SUCCESS;
216219 }
217220
@@ -226,7 +229,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 8 unmodified lines
226229 for (c = 0; c < p->ichannels; ++c)
227230 p->chan[c].dry = fifo_write(&p->chan[c].reverb.input_fifo, len, 0);
228231 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++);
230233 for (c = 0; c < p->ichannels; ++c)
231234 reverb_process(&p->chan[c].reverb, len);
232235 if (p->ichannels == 2) for (i = 0; i < len; ++i) for (w = 0; w < 2; ++w) {
src/silence.c+4−6
@@ -275,27 +275,25 @@ static int aboveThreshold(sox_effect_t * effp, sox_sample_t value, double thresh · 274 unmodified lines
275275 {
276276 double ratio;
277277 int rc;
278− sox_sample_t dummy_clipped_count = 0;
279278
280279 /* When scaling low bit data, noise values got scaled way up */
281280 /* Only consider the original bits when looking for silence */
282281 switch(effp->in_signal.precision)
283282 {
284− SOX_SAMPLE_LOCALS;
285283 case 8:
286− value = SOX_SAMPLE_TO_SIGNED_8BIT(value, dummy_clipped_count);
284+ value = SOX_SAMPLE_TO_SIGNED_8BIT(value);
287285 ratio = (double)abs(value) / (double)SOX_INT8_MAX;
288286 break;
289287 case 16:
290− value = SOX_SAMPLE_TO_SIGNED_16BIT(value, dummy_clipped_count);
288+ value = SOX_SAMPLE_TO_SIGNED_16BIT(value);
291289 ratio = (double)abs(value) / (double)SOX_INT16_MAX;
292290 break;
293291 case 24:
294− value = SOX_SAMPLE_TO_SIGNED_24BIT(value, dummy_clipped_count);
292+ value = SOX_SAMPLE_TO_SIGNED_24BIT(value);
295293 ratio = (double)abs(value) / (double)SOX_INT24_MAX;
296294 break;
297295 case 32:
298− value = SOX_SAMPLE_TO_SIGNED_32BIT(value,);
296+ value = SOX_SAMPLE_TO_SIGNED_32BIT(value);
299297 ratio = (double)abs(value) / (double)SOX_INT32_MAX;
300298 break;
301299 default:
src/skelform.c+1−2
@@ -159,9 +159,8 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t l · 158 unmodified lines
159159 switch (ft->encoding.bits_per_sample) {
160160 case 8:
161161 switch (ft->encoding.encoding) {
162− SOX_SAMPLE_LOCALS;
163162 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)
165164 ++done;
166165 break;
167166 default:
src/smp.c+1−2
@@ -368,8 +368,7 @@ static size_t sox_smpwrite(sox_format_t * ft, const sox_sample_t *buf, size_t le · 367 unmodified lines
368368 size_t done = 0;
369369
370370 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++);
373372 lsx_writew(ft, (uint16_t)datum);
374373 smp->NoOfSamps++;
375374 done++;
src/sox.c+133−115
@@ -1,9 +1,9 @@
11 /* SoX - The Swiss Army Knife of Audio Manipulation.
22 *
3− * This is the main function for the command line sox program.
3+ * This is the main function for the SoX command line programs.
44 *
5+ * Copyright 1998-2009 Chris Bagwell and SoX contributors
56 * Copyright 1991 Lance Norskog And Sundry Contributors
6− * Copyright 1998-2008 Chris Bagwell and SoX contributors
77 *
88 * This program is free software; you can redistribute it and/or modify it
99 * under the terms of the GNU General Public License as published by the
@@ -133,6 +133,7 @@ typedef struct { · 123 unmodified lines
133133 sox_signalinfo_t signal;
134134 sox_encodinginfo_t encoding;
135135 double volume;
136+ sox_sample_t offset;
136137 double replay_gain;
137138 sox_oob_t oob;
138139 sox_bool no_glob;
@@ -197,8 +198,7 @@ static sox_bool single_threaded = sox_false; · 58 unmodified lines
197198 static struct termios original_termios;
198199 #endif
199200
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;
202202
203203 /* Cleanup atexit() function, hence always called. */
204204 static void cleanup(void)
@@ -214,7 +214,7 @@ static void cleanup(void) · 9 unmodified lines
214214 }
215215
216216 if (file_count) {
217− if (ofile->ft) {
217+ if (ofile->ft) {
218218 if (!success && ofile->ft->fp) { /* If we failed part way through */
219219 struct stat st; /* writing a normal file, remove it. */
220220 fstat(fileno(ofile->ft->fp), &st);
@@ -405,13 +405,14 @@ static void progress_to_next_input_file(file_t * f) · 184 unmodified lines
405405 display_file_info(f->ft, f, sox_false);
406406 if (f->volume == HUGE_VAL)
407407 f->volume = 1;
408+ if (f->encoding.half_bit && f->ft->signal.precision < 32)
409+ f->offset = 1 << (31 - f->ft->signal.precision);
408410 if (f->replay_gain != HUGE_VAL)
409411 f->volume *= pow(10.0, f->replay_gain / 20);
410412 f->ft->sox_errno = errno = 0;
411413 }
412414
413415 /* 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);
415416 * from the input audio. */
416417 static size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, size_t max)
417418 {
@@ -427,11 +428,12 @@ static void balance_input(sox_sample_t * buf, size_t ws, file_t * f) · 9 unmodified lines
427428 {
428429 size_t s = ws * f->ft->signal.channels;
429430
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+ }
435437 }
436438
437439 /* 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
557559 return &handler;
558560 }
559561
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+
560570 static int output_flow(sox_effect_t *effp, sox_sample_t const * ibuf,
561571 sox_sample_t * obuf, size_t * isamp, size_t * osamp)
562572 {
573+ sox_sample_t const * buf;
563574 size_t len;
564575
565576 (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;
566580 if (show_progress) for (len = 0; len < *isamp; len += effp->in_signal.channels) {
567581 omax[0] = max(omax[0], ibuf[len]);
568582 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
591605 static sox_effect_handler_t const * output_effect_fn(void)
592606 {
593607 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
595609 };
596610 return &handler;
597611 }
598612
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)
601642 {
602643 sox_effect_t * effp;
603644
604645 effp = sox_create_effect(sox_find_effect(name)); /* Should always succeed. */
605646
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−
610647 if (sox_effect_options(effp, argc, argv) == SOX_EOF)
611648 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)
614651 exit(2); /* The effects chain should have displayed an error message */
615652 }
616653
@@ -621,7 +658,7 @@ static void init_eff_chains(void) · 4 unmodified lines
621658 nuser_effects[0] = 0;
622659 } /* init_eff_chains */
623660
624−/* add_eff_chain() - NOTE: this only adds memory for one
661+/* add_eff_chain() - NOTE: this only adds memory for one
625662 * additional effects chain beyond value of eff_chain_count. It
626663 * does not unconditionally increase size of effects chain.
627664 */
@@ -639,9 +676,9 @@ static void delete_eff_chains(void) · 11 unmodified lines
639676 unsigned j;
640677 int i, k;
641678
642− for (i = 0; i < eff_chain_count; i++)
679+ for (i = 0; i < eff_chain_count; i++)
643680 {
644− for (j = 0; j < nuser_effects[i]; j++)
681+ for (j = 0; j < nuser_effects[i]; j++)
645682 {
646683 if (user_effargs[i][j].name)
647684 free(user_effargs[i][j].name);
@@ -665,7 +702,7 @@ static void delete_eff_chains(void) · 17 unmodified lines
665702
666703 static sox_bool is_pseudo_effect(char *s)
667704 {
668− if (strcmp("newfile", s) == 0 ||
705+ if (strcmp("newfile", s) == 0 ||
669706 strcmp("restart", s) == 0 ||
670707 strcmp(":", s) == 0)
671708 return sox_true;
@@ -700,7 +737,7 @@ static void parse_effects(int argc, char **argv) · 28 unmodified lines
700737 optind++;
701738 continue;
702739 }
703−
740+
704741 if (strcmp(argv[optind], "newfile") == 0)
705742 {
706743 /* 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
739776
740777 optind += j; /* Skip past the effect arguments */
741778 nuser_effects[eff_chain_count]++;
742− if (newline_mode)
779+ if (newline_mode)
743780 {
744781 output_method = sox_multiple;
745782 eff_chain_count++;
@@ -865,9 +902,9 @@ static void read_user_effects(char *filename) · 119 unmodified lines
865902 /* Creates users effects and passes in user specified options.
866903 * This is done without putting anything into the effects chain
867904 * 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
871908 * default values of output file before we open it.
872909 * To keep things simple, we create all user effects. Later, when
873910 * 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
882919 effp = sox_create_effect(sox_find_effect(user_effargs[current_eff_chain][i].name));
883920
884921 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",
886923 effp->handler.name);
887924
888925 /* 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,
890927 user_effargs[current_eff_chain][i].argv) == SOX_EOF)
891928 exit(1);
892929
@@ -905,38 +942,50 @@ static void create_user_effects(void) · 12 unmodified lines
905942 static void add_effects(sox_effects_chain_t *chain)
906943 {
907944 sox_signalinfo_t signal = combiner_signal;
945+ int guard = is_guarded - 1;
908946 unsigned i;
909947 sox_effect_t * effp;
910948 char * rate_arg =
911949 is_player ? (rate_arg = getenv("PLAY_RATE_ARG")) ? rate_arg : "-l" : NULL;
912950
913951 /* 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) {
918954 effp = sox_create_effect(input_combiner_effect_fn());
919955 sox_add_effect(chain, effp, &signal, &ofile->ft->signal);
920956 }
921957
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 */
929964
930965 /* 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);
931971 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;
934979 }
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;
938987 }
939−
988+
940989 if (!save_output_eff)
941990 {
942991 /* Last `effect' in the chain is the output file */
@@ -981,15 +1030,15 @@ static int advance_eff_chain(void) · 38 unmodified lines
9811030 /* Effect chain stopped so advance to next effect chain but
9821031 * quite if no more chains exist.
9831032 */
984− else if (++current_eff_chain >= eff_chain_count)
1033+ else if (++current_eff_chain >= eff_chain_count)
9851034 return SOX_EOF;
9861035
987− while (nuser_effects[current_eff_chain] == 1 &&
1036+ while (nuser_effects[current_eff_chain] == 1 &&
9881037 is_pseudo_effect(user_effargs[current_eff_chain][0].name))
9891038 {
9901039 if (strcmp("newfile", user_effargs[current_eff_chain][0].name) == 0)
9911040 {
992− if (++current_eff_chain >= eff_chain_count)
1041+ if (++current_eff_chain >= eff_chain_count)
9931042 return SOX_EOF;
9941043 reuse_output = sox_false;
9951044 }
@@ -1167,7 +1216,7 @@ static int update_status(sox_bool all_done) · 171 unmodified lines
11671216 int ch = getchar();
11681217
11691218 #ifdef INTERACTIVE
1170− if (files[current_input]->ft->handler.seek &&
1219+ if (files[current_input]->ft->handler.seek &&
11711220 files[current_input]->ft->seekable)
11721221 {
11731222 if (ch == '>')
@@ -1408,7 +1457,7 @@ static void calculate_combiner_signal_parameters(void) · 234 unmodified lines
14081457 */
14091458 for (i = 0; i < input_count; i++) {
14101459 unsigned j;
1411− for (j =0; j < nuser_effects[current_eff_chain] &&
1460+ for (j =0; j < nuser_effects[current_eff_chain] &&
14121461 !files[i]->ft->signal.channels; ++j)
14131462 files[i]->ft->signal.channels = user_efftab[j]->in_signal.channels;
14141463 /* 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
15201569 /* Determine the output file encoding attributes; set from user options
15211570 * if given: */
15221571 ofile->encoding = ofile_encoding_options;
1523−
1572+
15241573 /* Get unspecified output file encoding attributes from the input file and
15251574 * set the output file to the resultant encoding if this is supported by the
15261575 * output file type; if not, the output file handler should select an
@@ -1548,7 +1597,7 @@ static int process(void) · 21 unmodified lines
15481597 open_output_file();
15491598
15501599 if (!effects_chain)
1551− effects_chain = sox_create_effects_chain(&combiner_encoding,
1600+ effects_chain = sox_create_effects_chain(&combiner_encoding,
15521601 &ofile->ft->encoding);
15531602 add_effects(effects_chain);
15541603
@@ -1564,7 +1613,7 @@ static int process(void) · 9 unmodified lines
15641613 * effect chains.
15651614 * For case #2, something else must decide when to stop processing.
15661615 */
1567− if ((input_eof && current_input < input_count) ||
1616+ if ((input_eof && current_input < input_count) ||
15681617 (!output_eof && current_eff_chain < eff_chain_count))
15691618 flow_status = SOX_SUCCESS;
15701619
@@ -1691,6 +1740,7 @@ static void usage(char const * message) · 120 unmodified lines
16911740 "--combine concatenate Concatenate multiple input files (default for sox, rec)",
16921741 "--combine sequence Sequence multiple input files (default for play)",
16931742 "--effects-file FILENAME File containing effects and options",
1743+"-G, --guard Use temporary files to guard against clipping",
16941744 "-h, --help Display version number and usage information",
16951745 "--help-effect NAME Show usage of effect NAME, or NAME=all for all",
16961746 "--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
16981748 "--interactive Prompt to overwrite output file",
16991749 "-m, --combine mix Mix multiple input files (instead of concatenating)",
17001750 "-M, --combine merge Merge multiple input files (instead of concatenating)",
1751+"--norm Guard (see --guard) & normalise",
17011752 "--plot gnuplot|octave Generate script to plot response of filter effect",
17021753 "-q, --no-show-progress Run in quiet mode; opposite of -S",
17031754 "--replay-gain track|album|off Default: off (sox, rec), track (play)",
@@ -1728,6 +1779,7 @@ static void usage(char const * message) · 24 unmodified lines
17281779 "-X|--reverse-bits Encoded bit-order",
17291780 "--endian little|big|swap Encoded byte-order; swap means opposite to default",
17301781 "-L/-B/-x Short options for the above",
1782+"-0 PCM encoding is 0 biased (offset by half a bit)",
17311783 "-c|--channels CHANNELS Number of channels of audio data; e.g. 2 = stereo",
17321784 "-r|--rate RATE Sample rate of audio",
17331785 "-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
18851937 free(text);
18861938 }
18871939
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";
18891941
18901942 static struct option long_options[] =
18911943 {
@@ -1908,6 +1960,7 @@ static struct option long_options[] = · 16 unmodified lines
19081960 {"temp" , required_argument, NULL, 0},
19091961 {"single-threaded" , no_argument, NULL, 0},
19101962 {"ignore-length" , no_argument, NULL, 0},
1963+ {"norm" , no_argument, NULL, 0},
19111964
19121965 {"bits" , required_argument, NULL, 'b'},
19131966 {"channels" , required_argument, NULL, 'c'},
@@ -1924,6 +1977,7 @@ static struct option long_options[] = · 10 unmodified lines
19241977 {"show-progress" , no_argument, NULL, 'S'},
19251978 {"type" , required_argument, NULL, 't'},
19261979 {"volume" , required_argument, NULL, 'v'},
1980+ {"guard" , no_argument, NULL, 'G'},
19271981
19281982 {NULL, 0, NULL, 0}
19291983 };
@@ -2056,57 +2110,25 @@ static char parse_gopts_and_fopts(file_t * f, int argc, char **argv) · 126 unmodified lines
20562110 sox_globals.input_bufsiz = i;
20572111 break;
20582112
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;
20752117 case 11:
20762118 sox_effects_globals.plot = enum_option(option_index, plot_methods);
20772119 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;
21072128 }
21082129 break;
21092130
2131+ case 'G': is_guarded = sox_true; break;
21102132 case 'm': combine_method = sox_mix; break;
21112133 case 'M': combine_method = sox_merge; break;
21122134 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
21192141 return c;
21202142 break;
21212143
2122− case 'h':
2144+ case 'h':
21232145 usage(NULL);
21242146 break;
21252147
@@ -2144,6 +2166,8 @@ static char parse_gopts_and_fopts(file_t * f, int argc, char **argv) · 18 unmodified lines
21442166 break;
21452167 }
21462168
2169+ case '0': f->encoding.half_bit = sox_true; break;
2170+
21472171 case 'v':
21482172 if (sscanf(optarg, "%lf %c", &f->volume, &dummy) != 1) {
21492173 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
24442468 }
24452469 sox_globals.verbosity = (unsigned)i;
24462470 }
2447− }
2471+ }
24482472 else if (opt == 'T')
24492473 do_total = sox_true;
24502474 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
25122536 return c1 && c2 && !strcasecmp(c1, c2);
25132537 }
25142538
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−
25212539 #ifdef __CYGWIN__
25222540 static char * check_dir(char * name)
25232541 {
@@ -2534,11 +2552,11 @@ int main(int argc, char **argv) · 10 unmodified lines
25342552 myname = argv[0];
25352553 sox_globals.output_message_handler = output_message;
25362554
2537− if (strends(myname, "play"))
2555+ if (lsx_strends(myname, "play"))
25382556 sox_mode = sox_play;
2539− else if (strends(myname, "rec"))
2557+ else if (lsx_strends(myname, "rec"))
25402558 sox_mode = sox_rec;
2541− else if (strends(myname, "soxi"))
2559+ else if (lsx_strends(myname, "soxi"))
25422560 sox_mode = sox_soxi;
25432561
25442562 if (sox_init() != SOX_SUCCESS)
@@ -2686,7 +2704,7 @@ int main(int argc, char **argv) · 141 unmodified lines
26862704 }
26872705
26882706 /* 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] &&
26902708 ofile->filetype && !strcmp(ofile->filetype, "null")) {
26912709 for (i = 0; i < input_count; i++)
26922710 report_file_info(files[i]);
@@ -2703,7 +2721,7 @@ int main(int argc, char **argv) · 10 unmodified lines
27032721
27042722 /* If user specified an effects filename then use that file
27052723 * to load user effects. Free any previously specified options
2706− * from the command line.
2724+ * from the command line.
27072725 */
27082726 if (effects_filename)
27092727 {
src/sox.h+32−35
@@ -1,6 +1,6 @@
11 /* libSoX Library Public Interface
22 *
3− * Copyright 1999-2008 Chris Bagwell and SoX Contributors.
3+ * Copyright 1999-2009 Chris Bagwell and SoX Contributors.
44 *
55 * This source code is freely redistributable and may be used for
66 * any purpose. This copyright notice must be maintained.
@@ -12,6 +12,7 @@ · 5 unmodified lines
1212 #define SOX_H
1313
1414 #include <limits.h>
15+#include <math.h>
1516 #include <stdarg.h>
1617 #include <stddef.h> /* Ensure NULL etc. are available throughout SoX */
1718 #include <stdio.h>
@@ -75,40 +76,32 @@ typedef int32_t sox_sample_t; · 57 unmodified lines
7576
7677 /* Conversions: Linear PCM <--> sox_sample_t
7778 *
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
8687 *
8788 * Conversions are as accurate as possible (with rounding).
8889 *
8990 * Rounding: halves toward +inf, all others to nearest integer.
9091 *
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.
9493 *
9594 * Unsigned integers are converted to and from signed integers by flipping
9695 * the upper-most bit then treating them as signed integers.
9796 */
9897
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
10199
102100 #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)))
112105 #define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
113106
114107 #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
120113 #define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
121114 #define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
122115 #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)
132125 #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.)))
134127
135128
136129
@@ -250,6 +243,7 @@ typedef enum {SOX_OPTION_NO, SOX_OPTION_YES, SOX_OPTION_DEFAULT} sox_option_t; · 113 unmodified lines
250243 typedef struct { /* Encoding parameters */
251244 sox_encoding_t encoding; /* format of sample numbers */
252245 unsigned bits_per_sample; /* 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
246+ sox_bool half_bit;
253247 double compression; /* compression factor (where applicable) */
254248
255249 /* 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
452446 #define SOX_EFF_MCHAN 16 /* Effect can handle multi-channel */
453447 #define SOX_EFF_NULL 32 /* Effect does nothing */
454448 #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 */
455451
456452 typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t;
457453 typedef struct sox_effect sox_effect_t;
@@ -508,11 +504,11 @@ struct sox_effects_chain { · 50 unmodified lines
508504 sox_sample_t **ibufc, **obufc; /* Channel interleave buffers */
509505 sox_effects_globals_t global_info;
510506 sox_encodinginfo_t const * in_enc;
511− sox_encodinginfo_t const * out_enc;
507+ sox_encodinginfo_t * out_enc;
512508 };
513509 typedef struct sox_effects_chain sox_effects_chain_t;
514510 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);
516512 void sox_delete_effects_chain(sox_effects_chain_t *ecp);
517513 int sox_add_effect( sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
518514 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
565561 lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * lsx_enum_items);
566562 lsx_enum_item const * lsx_find_enum_value(unsigned value, lsx_enum_item const * lsx_enum_items);
567563 int lsx_enum_option(int c, lsx_enum_item const * items);
564+sox_bool lsx_strends(char const * str, char const * end);
568565 char const * lsx_find_file_extension(char const * pathname);
569566 char const * lsx_sigfigs3(size_t number);
570567 char const * lsx_sigfigs3p(double percentage);
src/sox_i.h+11−1
@@ -19,6 +19,17 @@ · 18 unmodified lines
1919
2020 #include <errno.h>
2121
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+
2233 #define RANQD1 ranqd1(sox_globals.ranqd1)
2334 #define DRANQD1 dranqd1(sox_globals.ranqd1)
2435
@@ -213,7 +224,6 @@ typedef struct sox_formats_globals { /* Global parameters (for formats) */ · 188 unmodified lines
213224 int lsx_check_read_params(sox_format_t * ft, unsigned channels,
214225 sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
215226 off_t num_samples, sox_bool check_length);
216−sox_sample_t lsx_sample_max(sox_encodinginfo_t const * encoding);
217227 #define SOX_FORMAT_HANDLER(name) \
218228 sox_format_handler_t const * sox_##name##_format_fn(void); \
219229 sox_format_handler_t const * sox_##name##_format_fn(void)
src/sox_sample_test.c+0−18
@@ -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"
src/sox_sample_test.h+0−207
@@ -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
src/spectrogram.c+3−4
@@ -186,21 +186,20 @@ static int flow(sox_effect_t * effp, · 185 unmodified lines
186186 size_t * isamp, size_t * osamp)
187187 {
188188 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);
190190 int i;
191191
192192 memcpy(obuf, ibuf, len * sizeof(*obuf)); /* Pass on audio unaffected */
193193 *isamp = *osamp = len;
194194
195195 while (sox_true) {
196− SOX_SAMPLE_LOCALS;
197196 if (p->read == p->step_size) {
198197 memmove(p->buf, p->buf + p->step_size,
199198 (p->dft_size - p->step_size) * sizeof(*p->buf));
200199 p->read = 0;
201200 }
202201 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++);
204203 if (p->read != p->step_size)
205204 break;
206205
@@ -494,7 +493,7 @@ static int stop(sox_effect_t * effp) · 287 unmodified lines
494493 sox_effect_handler_t const * sox_spectrogram_effect_fn(void)
495494 {
496495 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)};
498497 static char const * lines[] = {
499498 "[options]",
500499 "\t-x num\tX-axis pixels/second, default 100",
src/splice.c+1−1
@@ -185,7 +185,7 @@ buffering: · 184 unmodified lines
185185 break;
186186 }
187187 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++);
189189 }
190190 break;
191191 }
src/stat.c+2−3
@@ -141,8 +141,7 @@ static int sox_stat_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_samp · 140 unmodified lines
141141
142142 if (stat->fft) {
143143 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]);
146145
147146 if (stat->fft_offset >= stat->fft_size) {
148147 stat->fft_offset = 0;
@@ -321,7 +320,7 @@ static int sox_stat_stop(sox_effect_t * effp) · 172 unmodified lines
321320 static sox_effect_handler_t sox_stat_effect = {
322321 "stat",
323322 "[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]",
324− SOX_EFF_MCHAN,
323+ SOX_EFF_MCHAN | SOX_EFF_MODIFY,
325324 sox_stat_getopts,
326325 sox_stat_start,
327326 sox_stat_flow,
src/synth.c+6−10
@@ -168,7 +168,6 @@ typedef struct { · 167 unmodified lines
168168 char * length_str;
169169 channel_t * getopts_channels;
170170 size_t getopts_nchannels;
171− sox_sample_t max;
172171 size_t samples_done;
173172 size_t samples_to_do;
174173 channel_t * channels;
@@ -378,7 +377,6 @@ static int start(sox_effect_t * effp) · 203 unmodified lines
378377 priv_t * synth = (priv_t *) effp->priv;
379378 size_t i, j;
380379
381− synth->max = lsx_sample_max(effp->out_encoding);
382380 synth->samples_done = 0;
383381
384382 if (synth->length_str)
@@ -438,9 +436,6 @@ static int start(sox_effect_t * effp) · 53 unmodified lines
438436 return SOX_SUCCESS;
439437 }
440438
441−
442−
443−#define sign(d) ((d) < 0? -1. : 1.)
444439 #define elapsed_time_s synth->samples_done / effp->in_signal.rate
445440
446441 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
607602 synth_out = synth_out * (1 - fabs(chan->offset)) + chan->offset;
608603
609604 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;
614609 }
610+ *obuf++ = floor(synth_out + .5);
615611 }
616612 if (++synth->samples_done == synth->samples_to_do)
617613 result = SOX_EOF;
@@ -649,7 +645,7 @@ const sox_effect_handler_t *sox_synth_effect_fn(void) · 31 unmodified lines
649645 {
650646 static sox_effect_handler_t handler = {
651647 "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,
653649 getopts, start, flow, 0, stop, kill, sizeof(priv_t)
654650 };
655651 return &handler;
src/tempo.c+1−1
@@ -272,7 +272,7 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, · 271 unmodified lines
272272 if (*isamp && odone < *osamp) {
273273 float * t = tempo_input(p->tempo, NULL, *isamp / effp->in_signal.channels);
274274 for (i = *isamp; i; --i)
275− *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++, effp->clips);
275+ *t++ = SOX_SAMPLE_TO_FLOAT_32BIT(*ibuf++);
276276 tempo_process(p->tempo);
277277 }
278278 else *isamp = 0;
src/tests.sh+0−2
@@ -200,8 +200,6 @@ skip_check () { · 199 unmodified lines
200200
201201 # Run tests
202202
203−${builddir}/sox_sample_test || exit 1
204−
205203 skip_check caf flac mat4 mat5 paf w64 wv
206204
207205 vectors=0
src/trim.c+1−1
@@ -172,7 +172,7 @@ void sox_trim_clear_start(sox_effect_t * effp) · 171 unmodified lines
172172 const sox_effect_handler_t *sox_trim_effect_fn(void)
173173 {
174174 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,
176176 sox_trim_getopts, sox_trim_start, sox_trim_flow,
177177 NULL, NULL, kill, sizeof(priv_t)
178178 };
src/util.c+6−0
@@ -37,6 +37,12 @@ int strncasecmp(char const * s1, char const * s2, size_t n) · 36 unmodified lines
3737 }
3838 #endif
3939
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+
4046 char const * lsx_find_file_extension(char const * pathname)
4147 {
4248 /* First, chop off any path portions of filename. This
src/util.h+12−2
@@ -31,14 +31,22 @@ · 30 unmodified lines
3131
3232 #ifdef _MSC_VER
3333 #define __STDC__ 1
34−#define S_IFMT _S_IFMT
35−#define S_IFREG _S_IFREG
3634 #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
3743 #define fstat _fstat
3844 #define ftime _ftime
3945 #define inline __inline
4046 #define isatty _isatty
47+#define mktemp _mktemp
4148 #define off_t _off_t
49+#define open _open
4250 #define popen _popen
4351 #define stat _stat
4452 #define strdup _strdup
@@ -92,6 +100,8 @@ · 47 unmodified lines
92100 #define M_SQRT2 sqrt(2.)
93101 #endif
94102
103+#define sign(x) ((x) < 0? -1 : 1)
104+
95105 /* Numerical Recipes in C, p. 284 */
96106 #define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
97107 #define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
src/vectors/intermediate1_44100_-u_-1_wav_-N.s1+0−0

Binary file not shown.

src/vectors/intermediate1_44100_-u_-1_wav_-X.s1+0−0

Binary file not shown.

src/vectors/intermediate1_44100_-u_-1_wav_-X_-N.s1+0−0

Binary file not shown.

src/vectors/intermediate1_44100_-u_-1_wav_.s1+0−0

Binary file not shown.

src/voc.c+3−5
@@ -347,14 +347,13 @@ static size_t read_samples(sox_format_t * ft, sox_sample_t * buf, · 346 unmodified lines
347347 /* Read the data in the file */
348348 if (v->size <= 4) {
349349 if (!v->adpcm.setup.sign) {
350− SOX_SAMPLE_LOCALS;
351350 if (lsx_readb(ft, &uc) == SOX_EOF) {
352351 lsx_warn("VOC input: short file");
353352 v->block_remaining = 0;
354353 return done;
355354 }
356355 *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));
358357 ++buf;
359358 --v->block_remaining;
360359 ++done;
@@ -490,12 +489,11 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, · 129 unmodified lines
490489 }
491490 v->samples += len;
492491 while (done < len) {
493− SOX_SAMPLE_LOCALS;
494492 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++);
496494 lsx_writeb(ft, uc);
497495 } else {
498− sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++, ft->clips);
496+ sw = (int) SOX_SAMPLE_TO_SIGNED_16BIT(*buf++);
499497 lsx_writesw(ft, sw);
500498 }
501499 done++;
src/vol.c+1−22
@@ -178,28 +178,7 @@ static int stop(sox_effect_t * effp) · 177 unmodified lines
178178 sox_effect_handler_t const * sox_vol_effect_fn(void)
179179 {
180180 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)
182182 };
183183 return &handler;
184184 }
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−}
src/wav.c+1−2
@@ -331,10 +331,9 @@ static size_t wavgsmwrite(sox_format_t * ft, const sox_sample_t *buf, size_t len · 330 unmodified lines
331331 ft->sox_errno = SOX_SUCCESS;
332332
333333 while (done < len) {
334− SOX_SAMPLE_LOCALS;
335334 while ((wav->gsmindex < 160*2) && (done < len))
336335 wav->gsmsample[(wav->gsmindex)++] =
337− SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++], ft->clips);
336+ SOX_SAMPLE_TO_SIGNED_16BIT(buf[done++]);
338337
339338 if (wav->gsmindex < 160*2)
340339 break;
src/wavpack.c+5−6
@@ -120,14 +120,13 @@ static size_t write_samples(sox_format_t * ft, const sox_sample_t * buf, size_t · 119 unmodified lines
120120 int result;
121121
122122 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;
127126 obuf[i] >>= 8; break;
128127 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]);
131130 break;
132131 }
133132 result = WavpackPackSamples(p->codec, obuf, (uint32_t) len / ft->signal.channels);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t