History

synth pluck improvements

robs committed 17 years ago

Commit 8f84c481 parent 7e6aa6d11 files · +275 −76Browse files

Unified · Split

11 files
  1. scripts/alert.sh +1 −2
  2. scripts/synth.sh +117 −12
  3. scripts/testtones.sh +5 −6
  4. sox.1 +2 −2
  5. src/effects_i.c +21 −1
  6. src/sox.c +1 −1
  7. src/sox.h +2 −1
  8. src/sox_i.h +2 −1
  9. src/synth.c +116 −45
  10. src/util.c +7 −4
  11. src/vol.c +1 −1
scripts/alert.sh+1−2
@@ -26,7 +26,6 @@ · 25 unmodified lines
2626 # ---------------------------------------------------------------------------
2727
2828 SOX=../src/sox
29−PLAY=../src/play
3029
3130 rm -f 2tones.ul # Make sure we append to a file that's initially empty
3231
@@ -45,4 +44,4 @@ done · 12 unmodified lines
4544 $SOX -c 1 -r 8000 alert.ul alert.au # Add a file header
4645 rm 2tones.ul alert.ul # Tidy up intermediate files
4746
48−$PLAY alert.au
47+$SOX alert.au -d
scripts/synth.sh+117−12
@@ -1,6 +1,6 @@
11 #!/bin/sh
22
3−# SoX script: synth.sh (c) 2008 robs@users.sourceforge.net
3+# SoX script: synth.sh (c) 2008-9 robs@users.sourceforge.net
44 #
55 # This program is free software; you can redistribute it and/or modify it
66 # under the terms of the GNU General Public License as published by the
@@ -17,7 +17,6 @@ · 10 unmodified lines
1717 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818
1919 sox=../src/sox
20−play=../src/play
2120
2221 G0="pl %-26 pl %-19 pl %-14 pl %-10 pl %-7 pl %-2"
2322 A0="pl %-24 pl %-17 pl %-12 pl %-8 pl %-5 pl %0"
@@ -26,12 +25,22 @@ D0="pl %-24 pl %-19 pl %-12 pl %-7 pl %-3 pl %0" · 2 unmodified lines
2625 E0="pl %-22 pl %-17 pl %-10 pl %-5 pl %-1 pl %2"
2726 Bb0="pl %-23 pl %-16 pl %-11 pl %-7 pl %-4 pl %1"
2827
29−o="overdrive 40 gain -8"
30−e="delay 0 .02 .04 .06 .08 .1 remix - $o fade 0"
31−s="$sox -q -n -p synth 0 0 0 80 87"
32−l="$sox -q -n -p synth 0 0 0 80 0 0"
28+o="overdrive 27 gain -11"
29+e="delay 0 .02 .04 .06 .08 .1 remix - overdrive 33 gain -8 fade 0"
30+s="$sox -q -n -p synth 0 0 1 60 90"
31+l="$sox -q -n -p synth 0 0 0 50 20"
3332
34−$play -m -v .8 \
33+b="$sox -np synth 0 0 0 30 20 pl"
34+c3="fade h 0 .75"
35+c="fade h 0 .25"
36+cs="fade h 0 .25 .05"
37+m="fade h 0 .5"
38+sb="fade h 0 1"
39+r="$sox -np trim 0 .25"
40+r2="$sox -np trim 0 .5"
41+r3="$sox -np trim 0 .75"
42+
43+$sox -m -v .8 \
3544 "|$sox \
3645 \"|$sox -n -p synth noise fade 0 .5 .48 trim 0 .15\" \
3746 \"|$sox -n -p synth noise fade h 0 .26 .11 gain -35 lowpass -1 12k\" \
@@ -63,15 +72,15 @@ equalizer 1500 10 8 pad 0 .21 remix 1 1 reverb 10 repeat 56" \ · 25 unmodified lines
6372 \"|$l pl %10 $o trim 0 .5 bend .2,-300,.1\" \
6473 \"|$l pl %5 $o trim 0 .5 bend .2,-200,.1\" \
6574 \"|$l pl %0 $o fade 0 .55 .1 bend .2,-200,.1\" \
66−\"|$l pl %0 $o fade 0 2 .1\" \
75+\"|$l pl %0 $o fade h 0 2 .5\" \
6776 \"|$sox -n -p trim 0 3.95\" \
6877 \"|$l pl %12 $o trim 0 .5 bend .2,-200,.1\" \
6978 \"|$l pl %12 $o trim 0 .5 bend .2,-200,.1\" \
7079 \"|$l pl %12 $o fade 0 .8 .1 bend .2,-200,.1\" \
7180 \"|$l pl %12 $o trim 0 .3 bend .1,-200,.1\" \
72−\"|$l pl %12 $o trim 0 1.95 bend .3,-50,1\" \
73−\"|$l pl %10 $o trim 0 2 bend .3,-50,1\" \
74−\"|$l pl %9 $o trim 0 2 gain -3\" \
81+\"|$l pl %12 $o fade 0 1.95 .6 bend .0,-50,1.75 gain 3\" \
82+\"|$l pl %10 $o fade 0 2 .6 bend .0,-50,1.9\" \
83+\"|$l pl %9 $o trim 0 2 gain -1\" \
7584 \"|$l pl %8 $o fade h 0 1 .3\" \
7685 \"|$l pl %8 $o fade h 0 1 .1 gain 1.5\" \
7786 \"|$l pl %2 pl %7 delay 0 .02 remix - $o trim 0 .25\" \
@@ -83,4 +92,100 @@ equalizer 1500 10 8 pad 0 .21 remix 1 1 reverb 10 repeat 56" \ · 5 unmodified lines
8392 \"|$l pl %2 pl %7 delay 0 .02 remix - $o trim 0 .25\" \
8493 \"|$l pl %-5 $o trim 0 .25\" \
8594 \"|$l pl %2 pl %7 delay 0 .02 remix - $o fade h 0 6 6\" \
86−-p gain -4 remix 1 1 flanger"
95+-p gain -4 remix 1 1 flanger" \
96+"|$sox \
97+\"|$sox -n -p trim 0 1.5\" \
98+\"|$b G1 $m contrast\" \
99+\"|$b A1 $c3 contrast\" \
100+\"|$b G#1 $c\" \
101+\"|$b A1 $c3\" \
102+\"|$r\" \
103+\
104+\"|$b C2 $cs\" \
105+\"|$b C2 $cs\" \
106+\"|$r\" \
107+\"|$b B1 $cs\" \
108+\"|$b C2 $c3\" \
109+\"|$r\" \
110+\
111+\"|$b D2 $cs\" \
112+\"|$b D2 $cs\" \
113+\"|$r\" \
114+\"|$b C#2 $cs\" \
115+\"|$b D2 $c\" \
116+\"|$b C#2 $m\" \
117+\"|$r\" \
118+\
119+\"|$b D2 $cs\" \
120+\"|$b D2 $cs\" \
121+\"|$r\" \
122+\"|$b C#2 $cs\" \
123+\"|$b D2 $c\" \
124+\"|$b C#2 $c\" \
125+\"|$b D2 $c\" \
126+\"|$b E2 $c\" \
127+\
128+\"|$b A1 $c3 contrast\" \
129+\"|$b B1 $c\" \
130+\"|$b A1 $c\" \
131+\"|$b G#1 $c\" \
132+\"|$b A1 $c\" \
133+\"|$b B1 $c\" \
134+\
135+\"|$b C2 $c3\" \
136+\"|$b B1 $c\" \
137+\"|$b C2 $c\" \
138+\"|$b D2 $c\" \
139+\"|$b C2 $c\" \
140+\"|$b B1 $c\" \
141+\
142+\"|$b D2 $c3\" \
143+\"|$b E2 $c\" \
144+\"|$b D2 $c\" \
145+\"|$b C#2 $c\" \
146+\"|$b D2 $c\" \
147+\"|$b E2 $c\" \
148+\
149+\"|$b D2 $c3\" \
150+\"|$b C#2 $c\" \
151+\"|$b D2 $c\" \
152+\"|$b E2 $c\" \
153+\"|$b D2 $c\" \
154+\"|$b C#2 $c\" \
155+\
156+\"|$b A1 $cs\" \
157+\"|$b A1 $cs\" \
158+\"|$r\" \
159+\"|$b G#1 $c\" \
160+\"|$b A1 $c3\" \
161+\"|$b B1 $c\" \
162+\
163+\"|$b C2 $c\" \
164+\"|$b B1 $c\" \
165+\"|$b C2 $c\" \
166+\"|$b D2 $c\" \
167+\"|$b C2 $c3\" \
168+\"|$r\" \
169+\
170+\"|$b D2 $m\" \
171+\"|$b E2 $m\" \
172+\"|$b D2 $c\" \
173+\"|$b C#2 $c\" \
174+\"|$b D2 $c\" \
175+\"|$b E2 $c\" \
176+\
177+\"|$b F2 $m\" \
178+\"|$b Bb1 $m\" \
179+\"|$b C2 $c\" \
180+\"|$b F2 $c\" \
181+\"|$b D2 $c\" \
182+\"|$b Bb1 $c\" \
183+\
184+\"|$b E1 $m\" \
185+\"|$b E2 $m\" \
186+\"|$b D2 $c\" \
187+\"|$b E2 $m\" \
188+\"|$b B1 $c\" \
189+\
190+\"|$b E1 $sb\" \
191+-p lowpass -1 1k remix 1p-12 1p-12" -d
scripts/testtones.sh+5−6
@@ -273,7 +273,7 @@ if [ $soxver -ge 1403 ]; then · 272 unmodified lines
273273 echo; echo "Plucked scale:"
274274
275275 options=
276− overdrive=
276+ overdrive="gain -3"
277277 for f in pluck pluck_dist; do
278278 next_file $f 42
279279 note=-29
@@ -289,14 +289,13 @@ if [ $soxver -ge 1403 ]; then · 9 unmodified lines
289289 $input -t s32 - synth .4 pluck %$note $options >> tmp.s32
290290 note=$(($note - 1))
291291 done
292− $input -t s32 - synth pluck %$note $options fade h 0 2 .1 >> tmp.s32
292+ $input -t s32 - synth pluck %$note $options fade t 0 4 3.6 >> tmp.s32
293293
294− $sox -r $rate -c 1 tmp.s32 $output compand .1,.2 6:-70,-60,-20 -7 -15 .1 \
295− $overdrive pad 0 2 remix 1 1 reverb 30
294+ $sox -r $rate -c 1 tmp.s32 $output $overdrive remix 1 1 reverb 30
296295
297296 rm -f tmp.s32
298− options="0 0 60 60"
299− overdrive="overdrive 30 gain -9"
297+ options="0 0 60 75 0"
298+ overdrive="overdrive gain -10"
300299 done
301300 fi
302301
sox.1+2−2
@@ -1891,8 +1891,8 @@ The following (one long) command plays a chime sound: · 1890 unmodified lines
18911891 and this plays a guitar chord:
18921892 .EX
18931893 .ne 2
1894− play -n synth -j -2 pl %-26 pl %-22 pl %-19 pl %-14 pl %-7 \\
1895− pl %-2 delay 0 .05 .1 .15 .2 .25 remix - fade 0 4 .1 norm -1
1894+ play -n synth pl G2 pl B2 pl D3 pl G3 pl D4 pl G4 \\
1895+ delay 0 .05 .1 .15 .2 .25 remix - fade 0 4 .1 norm -1
18961896 .EE
18971897 .TP
18981898 \fBdither\fR [\fB\-a\fR] [\fB\-S\fR\^|\^\fB\-s\fR\^|\^\fB\-f \fIfilter\fR]
src/effects_i.c+21−1
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 #define LSX_EFF_ALIAS
2222 #include "sox_i.h"
2323 #include <string.h>
24+#include <ctype.h>
2425
2526 int lsx_usage(sox_effect_t * effp)
2627 {
@@ -290,9 +291,24 @@ static double calc_note_freq(double note, int key) · 263 unmodified lines
290291 return 440 * pow(2., note / 12);
291292 }
292293
294+int lsx_parse_note(char const * text, char * * end_ptr)
295+{
296+ int result = INT_MAX;
297+
298+ if (*text >= 'A' && *text <= 'G') {
299+ result = (int)(5/3. * (*text++ - 'A') + 9.5) % 12 - 9;
300+ if (*text == 'b') {--result; ++text;}
301+ else if (*text == '#') {++result; ++text;}
302+ if (isdigit(*text))
303+ result += 12 * (*text++ - '4');
304+ }
305+ *end_ptr = (char *)text;
306+ return result;
307+}
308+
293309 /* Read string 'text' and convert to frequency.
294310 * 'text' can be a positive number which is the frequency in Hz.
295− * If 'text' starts with a hash '%' and a following number the corresponding
311+ * If 'text' starts with a '%' and a following number the corresponding
296312 * note is calculated.
297313 * Return -1 on error.
298314 */
@@ -306,6 +322,10 @@ double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key) · 7 unmodified lines
306322 return -1;
307323 return calc_note_freq(result, key);
308324 }
325+ if (*text >= 'A' && *text <= 'G') {
326+ int result = lsx_parse_note(text, end_ptr);
327+ return result == INT_MAX? - 1 : calc_note_freq((double)result, key);
328+ }
309329 result = strtod(text, end_ptr);
310330 if (end_ptr) {
311331 if (*end_ptr == text)
src/sox.c+1−1
@@ -2091,7 +2091,7 @@ static lsx_enum_item const encodings[] = { · 2090 unmodified lines
20912091
20922092 static int enum_option(int option_index, lsx_enum_item const * items)
20932093 {
2094− lsx_enum_item const * p = lsx_find_enum_text(lsx_optarg, items);
2094+ lsx_enum_item const * p = lsx_find_enum_text(lsx_optarg, items, 0);
20952095 if (p == NULL) {
20962096 size_t len = 1;
20972097 char * set = lsx_malloc(len);
src/sox.h+2−1
@@ -565,7 +565,8 @@ void lsx_debug(const char *, ...) PRINTF; · 564 unmodified lines
565565 typedef struct {char const *text; unsigned value;} lsx_enum_item;
566566 #define LSX_ENUM_ITEM(prefix, item) {#item, prefix##item},
567567
568−lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * lsx_enum_items);
568+lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * lsx_enum_items, unsigned flags);
569+#define LSX_FET_CASE 1
569570 lsx_enum_item const * lsx_find_enum_value(unsigned value, lsx_enum_item const * lsx_enum_items);
570571 int lsx_enum_option(int c, lsx_enum_item const * items);
571572 sox_bool lsx_strends(char const * str, char const * end);
src/sox_i.h+2−1
@@ -82,6 +82,7 @@ void lsx_generate_wave_table( · 81 unmodified lines
8282 double max, /* Maximum value on the y-axis. (e.g. +1) */
8383 double phase); /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
8484 char const * lsx_parsesamples(sox_rate_t rate, const char *str, size_t *samples, int def);
85+int lsx_parse_note(char const * text, char * * end_ptr);
8586 double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
8687 #define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
8788 FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
@@ -283,7 +284,7 @@ char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n); · 195 unmodified lines
283284 #define TEXTUAL_PARAMETER(name, enum_table) { \
284285 lsx_enum_item const * e; \
285286 if (argc == 0) break; \
286− e = lsx_find_enum_text(*argv, enum_table); \
287+ e = lsx_find_enum_text(*argv, enum_table, 0); \
287288 if (e != NULL) { \
288289 p->name = e->value; \
289290 --argc, ++argv; \
src/synth.c+116−45
@@ -6,6 +6,25 @@ · 5 unmodified lines
66 * This source code is freely redistributable and may be used for any purpose.
77 * This copyright notice must be maintained. The authors are not responsible
88 * for the consequences of using this software.
9+ *
10+ * Except for synth types: pluck, tpdf, & brownnoise, and sweep types: linear
11+ * square & exp, which are:
12+ *
13+ * Copyright (c) 2006-2009 robs@users.sourceforge.net
14+ *
15+ * This library is free software; you can redistribute it and/or modify it
16+ * under the terms of the GNU Lesser General Public License as published by
17+ * the Free Software Foundation; either version 2.1 of the License, or (at
18+ * your option) any later version.
19+ *
20+ * This library is distributed in the hope that it will be useful, but
21+ * WITHOUT ANY WARRANTY; without even the implied warranty of
22+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
23+ * General Public License for more details.
24+ *
25+ * You should have received a copy of the GNU Lesser General Public License
26+ * along with this library; if not, write to the Free Software Foundation,
27+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
928 */
1029
1130 #include "sox_i.h"
@@ -152,12 +171,12 @@ typedef struct { · 140 unmodified lines
152171 double p1, p2, p3; /* Use depends on synth type */
153172
154173 /* internal stuff */
155− double cycle_start_time_s;
156− double last_out;
174+ double lp_last_out, hp_last_out, hp_last_in, ap_last_out, ap_last_in;
175+ double cycle_start_time_s, c0, c1, c2, c3, c4;
157176 PinkNoise pink_noise;
158177
159178 double * buffer;
160− size_t buffer_len, pos, dx, dy, acc;
179+ size_t buffer_len, pos;
161180 } channel_t;
162181
163182
@@ -208,12 +227,12 @@ static void set_default_parameters(channel_t * chan, size_t c) · 44 unmodified lines
208227 chan->p1 = 0.1;
209228 chan->p2 = 0.5;
210229 chan->p3 = 0.6;
211− } else if (chan->p2 < 0) { /* try a symetric waveform */
230+ } else if (chan->p2 < 0) { /* try a symmetric waveform */
212231 if (chan->p1 <= 0.5) {
213232 chan->p2 = (1 - 2 * chan->p1) / 2;
214233 chan->p3 = chan->p2 + chan->p1;
215234 } else {
216− /* symetric is not possible, fall back to asymetrical triangle */
235+ /* symetric is not possible, fall back to asymmetrical triangle */
217236 chan->p2 = chan->p1;
218237 chan->p3 = 1;
219238 }
@@ -237,7 +256,7 @@ static void set_default_parameters(channel_t * chan, size_t c) · 17 unmodified lines
237256 if (chan->p1 < 0)
238257 chan->p1 = .4;
239258 if (chan->p2 < 0)
240− chan->p2 = 0;
259+ chan->p2 = .2, chan->p3 = .9;
241260
242261 default: break;
243262 }
@@ -267,12 +286,15 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 23 unmodified lines
267286 priv_t * p = (priv_t *) effp->priv;
268287 channel_t master, * chan = &master;
269288 int key = INT_MAX, argn = 0;
270− char dummy;
289+ char dummy, * end_ptr;
271290 --argc, ++argv;
272291
273292 if (argc && !strcmp(*argv, "-n")) p->no_headroom = sox_true, ++argv, --argc;
274293
275− if (argc > 1 && !strcmp(*argv, "-j") && sscanf(argv[1], "%i %c", &key, &dummy) == 1) {
294+ if (argc > 1 && !strcmp(*argv, "-j") && (
295+ sscanf(argv[1], "%i %c", &key, &dummy) == 1 || (
296+ (key = lsx_parse_note(argv[1], &end_ptr)) != INT_MAX &&
297+ !*end_ptr))) {
276298 argc -= 2;
277299 argv += 2;
278300 }
@@ -299,8 +321,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 20 unmodified lines
299321 }
300322
301323 while (argn < argc) { /* type [combine] [f1[-f2] [off [ph [p1 [p2 [p3]]]]]] */
302− char * end_ptr;
303− lsx_enum_item const *enum_p = lsx_find_enum_text(argv[argn], synth_type);
324+ lsx_enum_item const * enum_p = lsx_find_enum_text(argv[argn], synth_type, LSX_FET_CASE);
304325
305326 if (enum_p == NULL) {
306327 lsx_fail("no type given");
@@ -314,7 +335,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 7 unmodified lines
314335 break;
315336
316337 /* maybe there is a combine-type in next arg */
317− enum_p = lsx_find_enum_text(argv[argn], combine_type);
338+ enum_p = lsx_find_enum_text(argv[argn], combine_type, LSX_FET_CASE);
318339 if (enum_p != NULL) {
319340 chan->combine = enum_p->value;
320341 if (++argn == argc)
@@ -322,16 +343,21 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 1 unmodified line
322343 }
323344
324345 /* read frequencies if given */
325− if (isdigit((int) argv[argn][0]) ||
326− argv[argn][0] == '.' || argv[argn][0] == '%') {
346+ if (!lsx_find_enum_text(argv[argn], synth_type, LSX_FET_CASE) &&
347+ argv[argn][0] != '-') {
327348 static const char sweeps[] = ":+/-";
328349
329350 chan->freq2 = chan->freq = lsx_parse_frequency_k(argv[argn], &end_ptr, key);
330− if (chan->freq < 0) {
351+ if (chan->freq < (chan->type == synth_pluck? 27.5 : 0) ||
352+ (chan->type == synth_pluck && chan->freq > 4220)) {
331353 lsx_fail("invalid freq");
332354 return SOX_EOF;
333355 }
334356 if (*end_ptr && strchr(sweeps, *end_ptr)) { /* freq2 given? */
357+ if (chan->type >= synth_noise) {
358+ lsx_fail("can't sweep this type");
359+ return SOX_EOF;
360+ }
335361 chan->sweep = strchr(sweeps, *end_ptr) - sweeps;
336362 chan->freq2 = lsx_parse_frequency_k(end_ptr + 1, &end_ptr, key);
337363 if (chan->freq2 < 0) {
@@ -384,7 +410,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 46 unmodified lines
384410 static int start(sox_effect_t * effp)
385411 {
386412 priv_t * p = (priv_t *)effp->priv;
387− size_t i, j;
413+ size_t i, j, k;
388414
389415 p->samples_done = 0;
390416
@@ -399,24 +425,64 @@ static int start(sox_effect_t * effp) · 8 unmodified lines
399425 *chan = p->getopts_channels[i % p->getopts_nchannels];
400426 set_default_parameters(chan, i);
401427 if (chan->type == synth_pluck) {
402− int32_t r = 0;
403− double colour = pow(2., 4 * (chan->p2 - 1));
404− double dc = 0, a = 6.9 / (chan->p2 < .25? chan->p2 / .25 * 11 + 7 :
405− chan->p2 <= .55? 18 : (1-chan->p2) / .45 * 3 + 15);
406− chan->buffer_len = effp->in_signal.rate / chan->freq + .5;
407− chan->dx = chan->freq * 1000 + .5;
408− chan->dy = effp->in_signal.rate / chan->buffer_len * 1000 + .5;
409− chan->pos = chan->acc = 0;
410− chan->buffer = malloc(chan->buffer_len * sizeof(*chan->buffer));
411− chan->buffer[0] = 0;
412− for (j = 1; j < chan->buffer_len; dc += chan->buffer[j++])
413− do chan->buffer[j] =
414− chan->buffer[j - 1] + (chan->p3 == 0? DRANQD1:dranqd1(r)) * colour;
415− while (fabs(chan->buffer[j]) > 1);
416− for (dc /= chan->buffer_len, j = 0; j < chan->buffer_len; ++j)
417− chan->buffer[j] = range_limit(chan->buffer[j] - dc, -1, 1) * a;
418− chan->p3 = .5 * exp(log(.6) / chan->freq / chan->p1);
419− lsx_debug("a=%g colour=%g", a, 1/colour);
428+ double min, max, frac, p2;
429+ double const decay_rate = -2; /* dB / s */
430+ double const decay_f = min(912, 266 + 106 * log(chan->freq));
431+ double d = sqr(dB_to_linear(decay_rate / chan->freq));
432+ d = (d * cos(2 * M_PI * decay_f / effp->in_signal.rate) - 1) / (d - 1);
433+ chan->c0 = d - sqrt(d * d - 1);
434+ chan->c1 = 1 - chan->c0;
435+
436+ chan->c1 *= exp(-2e4/ (.05+chan->p1)/ chan->freq/ effp->in_signal.rate);
437+
438+ chan->c2 = exp(-2 * M_PI * 10 / effp->in_signal.rate);
439+ chan->c3 = (1 + chan->c2) * .5;
440+
441+ if (effp->in_signal.rate < 44100 || effp->in_signal.rate > 48000) {
442+ lsx_fail("sample rate for pluck must be 44100-48000; use `rate' to resample");
443+ return SOX_EOF;
444+ }
445+ d = chan->c0 / (chan->c0 + chan->c1);
446+
447+ chan->buffer_len = effp->in_signal.rate / chan->freq - d;
448+ frac = effp->in_signal.rate / chan->freq - d - chan->buffer_len;
449+ chan->c4 = (1 - frac) / (1 + frac);
450+ chan->pos = 0;
451+
452+ chan->buffer = lsx_calloc(chan->buffer_len, sizeof(*chan->buffer));
453+ for (k = 0, p2 = chan->p2; k < 2 && p2 >= 0; ++k, p2 = chan->p3) {
454+ double d1 = 0, d, colour = pow(2., 4 * (p2 - 1));
455+ int32_t r = p2 * 100 + .5;
456+ for (j = 0; j < chan->buffer_len; ++j) {
457+ do d = d1 + (chan->phase? DRANQD1:dranqd1(r)) * colour;
458+ while (fabs(d) > 1);
459+ chan->buffer[j] += d * (1 - .3 * k);
460+ d1 = d * (colour != 1);
461+#ifdef TEST_PLUCK
462+ chan->buffer[j] = sin(2 * M_PI * j / chan->buffer_len);
463+#endif
464+ }
465+ }
466+ for (j = 0, min = max = 0; j < chan->buffer_len; ++j) {
467+ double d, t = (double)j / chan->buffer_len;
468+ chan->lp_last_out = d =
469+ chan->buffer[j] * chan->c1 + chan->lp_last_out * chan->c0;
470+
471+ chan->ap_last_out =
472+ d * chan->c4 + chan->ap_last_in - chan->ap_last_out * chan->c4;
473+ chan->ap_last_in = d;
474+
475+ chan->buffer[j] = chan->buffer[j] * (1 - t) + chan->ap_last_out * t;
476+ min = min(min, chan->buffer[j]);
477+ max = max(max, chan->buffer[j]);
478+ }
479+ for (j = 0, d = 0; j < chan->buffer_len; ++j) {
480+ chan->buffer[j] = (2 * chan->buffer[j] - max - min) / (max - min);
481+ d += sqr(chan->buffer[j]);
482+ }
483+ lsx_debug("rms=%f c0=%f c1=%f c2=%f c3=%f df=%f d3f=%f",
484+ 10 * log(d / chan->buffer_len), chan->c0, chan->c1, chan->c2,
485+ chan->c3, decay_f, log(chan->c0)/ -2 / M_PI * effp->in_signal.rate);
420486 }
421487 switch (chan->sweep) {
422488 case Linear: chan->mult = p->samples_to_do?
@@ -587,22 +653,27 @@ static int flow(sox_effect_t * effp, const sox_sample_t * ibuf, sox_sample_t * o · 164 unmodified lines
587653 break;
588654
589655 case synth_brownnoise:
590− do synth_out = chan->last_out + DRANQD1 * (1. / 16);
656+ do synth_out = chan->lp_last_out + DRANQD1 * (1. / 16);
591657 while (fabs(synth_out) > 1);
592− chan->last_out = synth_out;
658+ chan->lp_last_out = synth_out;
593659 break;
594660
595661 case synth_pluck: {
596− size_t pos1 = chan->pos + 1 == chan->buffer_len? 0 : chan->pos + 1;
597− double t = (double)chan->acc / chan->dy;
598− synth_out = chan->buffer[chan->pos] * (1-t) + chan->buffer[pos1] * t;
599− for (chan->acc+=chan->dx; chan->acc>=chan->dy; chan->acc-=chan->dy) {
600− t = chan->buffer[chan->pos];
601− chan->buffer[chan->pos] =
602− chan->p3 * (chan->buffer[chan->pos] + chan->last_out);
603− chan->last_out = t;
604− chan->pos = chan->pos + 1 == chan->buffer_len? 0 : chan->pos + 1;
605− }
662+ double d = chan->buffer[chan->pos];
663+
664+ chan->hp_last_out =
665+ (d - chan->hp_last_in) * chan->c3 + chan->hp_last_out * chan->c2;
666+ chan->hp_last_in = d;
667+
668+ synth_out = range_limit(chan->hp_last_out, -1, 1);
669+
670+ chan->lp_last_out = d = d * chan->c1 + chan->lp_last_out * chan->c0;
671+
672+ chan->ap_last_out = chan->buffer[chan->pos] =
673+ (d - chan->ap_last_out) * chan->c4 + chan->ap_last_in;
674+ chan->ap_last_in = d;
675+
676+ chan->pos = chan->pos + 1 == chan->buffer_len? 0 : chan->pos + 1;
606677 break;
607678 }
608679
src/util.c+7−4
@@ -58,14 +58,17 @@ char const * lsx_find_file_extension(char const * pathname) · 57 unmodified lines
5858 return result;
5959 }
6060
61−lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * enum_items)
61+lsx_enum_item const * lsx_find_enum_text(char const * text, lsx_enum_item const * enum_items, unsigned flags)
6262 {
6363 lsx_enum_item const * result = NULL; /* Assume not found */
64+ sox_bool sensitive = !!(flags & LSX_FET_CASE);
6465
6566 while (enum_items->text) {
66− if (strcasecmp(text, enum_items->text) == 0)
67+ if ((!sensitive && !strcasecmp(text, enum_items->text)) ||
68+ ( sensitive && ! strcmp(text, enum_items->text)))
6769 return enum_items; /* Found exact match */
68− if (strncasecmp(text, enum_items->text, strlen(text)) == 0) {
70+ if ((!sensitive && !strncasecmp(text, enum_items->text, strlen(text))) ||
71+ ( sensitive && ! strncmp(text, enum_items->text, strlen(text)))) {
6972 if (result != NULL && result->value != enum_items->value)
7073 return NULL; /* Found ambiguity */
7174 result = enum_items; /* Found sub-string match */
@@ -85,7 +88,7 @@ lsx_enum_item const * lsx_find_enum_value(unsigned value, lsx_enum_item const * · 13 unmodified lines
8588
8689 int lsx_enum_option(int c, lsx_enum_item const * items)
8790 {
88− lsx_enum_item const * p = lsx_find_enum_text(lsx_optarg, items);
91+ lsx_enum_item const * p = lsx_find_enum_text(lsx_optarg, items, sox_false);
8992 if (p == NULL) {
9093 size_t len = 1;
9194 char * set = lsx_malloc(len);
src/vol.c+1−1
@@ -60,7 +60,7 @@ static int getopts(sox_effect_t * effp, int argc, char **argv) · 59 unmodified lines
6060 }
6161
6262 if (have_type) {
63− lsx_enum_item const * p = lsx_find_enum_text(type_ptr, vol_types);
63+ lsx_enum_item const * p = lsx_find_enum_text(type_ptr, vol_types, 0);
6464 if (!p)
6565 return lsx_usage(effp);
6666 switch (p->value) {

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