aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/puredata/Makefile.am4
-rw-r--r--examples/puredata/xtract/a_bavg.pd36
-rw-r--r--examples/puredata/xtract/a_hann.pd30
-rw-r--r--examples/puredata/xtract/a_mton.pd66
-rw-r--r--examples/puredata/xtract/a_output~.pd71
-rw-r--r--examples/puredata/xtract/a_spigot~.pd21
-rw-r--r--examples/puredata/xtract/f0.pd292
-rw-r--r--examples/puredata/xtract/mfcc.pd154
-rw-r--r--examples/puredata/xtract/sonogram.pd1
-rw-r--r--examples/puredata/xtract/xtract-help.pd69
-rw-r--r--src/scalar.c364
11 files changed, 925 insertions, 183 deletions
diff --git a/examples/puredata/Makefile.am b/examples/puredata/Makefile.am
index 97bad90..dda94f4 100644
--- a/examples/puredata/Makefile.am
+++ b/examples/puredata/Makefile.am
@@ -27,7 +27,9 @@ AM_LDFLAGS = @PD_LDFLAGS@ -lxtract -L$(top_builddir)/src/
## Install the documentation.
install:
- -mv $(top_builddir)/examples/puredata/.libs/xtract.@PD_SUFFIX@ $(pdinstalldir)/xtract~.@PD_SUFFIX@
+ install -m 644 $(top_builddir)/examples/puredata/.libs/xtract.@PD_SUFFIX@ $(pdinstalldir)/xtract~.@PD_SUFFIX@
+ install -d $(pddir)/doc/5.reference/xtract
+ cp xtract/* $(PDDIR)/doc/5.reference/xtract
#pdinstallref_DATA = \
# help/aubioonset-help.pd \
diff --git a/examples/puredata/xtract/a_bavg.pd b/examples/puredata/xtract/a_bavg.pd
new file mode 100644
index 0000000..38c8c71
--- /dev/null
+++ b/examples/puredata/xtract/a_bavg.pd
@@ -0,0 +1,36 @@
+#N canvas 0 0 450 300 10;
+#X obj 140 183 +;
+#X obj 243 216 f;
+#X obj 242 124 f;
+#X obj 275 124 + 1;
+#X msg 244 193 0;
+#X obj 175 223 f;
+#X obj 175 245 / \$1;
+#X obj 242 147 % \$1;
+#X obj 319 172 f \$1;
+#X obj 319 192 - 1;
+#X obj 243 170 sel;
+#X obj 319 146 loadbang;
+#X obj 161 60 inlet;
+#X obj 165 84 t b f;
+#X obj 175 271 outlet;
+#X text 28 12 Averages a series of N numbers where N is given by the
+first arument (works in blocks);
+#X connect 0 0 1 0;
+#X connect 0 0 5 1;
+#X connect 1 0 0 1;
+#X connect 2 0 3 0;
+#X connect 2 0 7 0;
+#X connect 3 0 2 1;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 6 0 14 0;
+#X connect 7 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 1;
+#X connect 10 0 4 0;
+#X connect 10 0 5 0;
+#X connect 11 0 8 0;
+#X connect 12 0 13 0;
+#X connect 13 0 2 0;
+#X connect 13 1 0 0;
diff --git a/examples/puredata/xtract/a_hann.pd b/examples/puredata/xtract/a_hann.pd
new file mode 100644
index 0000000..bc150b0
--- /dev/null
+++ b/examples/puredata/xtract/a_hann.pd
@@ -0,0 +1,30 @@
+#N canvas 379 192 709 463 10;
+#X obj 368 85 samplerate~;
+#X obj 371 153 phasor~;
+#X msg 457 83 0;
+#X obj 371 182 expr~ 0.5 - cos($v1 * 6.28) * 0.5;
+#X obj 618 10 block~ \$1;
+#X obj 368 107 /~ \$1;
+#X text 43 20 Creation arg gives window size;
+#X obj 346 38 t b b b b;
+#X obj 490 58 float \$1;
+#X obj 346 10 inlet;
+#X obj 40 268 tabreceive~ \$0-hann;
+#X obj 40 307 outlet~;
+#X msg 491 80 resize \$1;
+#X obj 493 104 s \$0-hann;
+#X obj 373 308 table \$0-hann;
+#X obj 371 207 tabwrite~ \$0-hann;
+#X connect 0 0 5 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 1;
+#X connect 3 0 15 0;
+#X connect 5 0 1 0;
+#X connect 7 0 15 0;
+#X connect 7 1 2 0;
+#X connect 7 2 0 0;
+#X connect 7 3 8 0;
+#X connect 8 0 12 0;
+#X connect 9 0 7 0;
+#X connect 10 0 11 0;
+#X connect 12 0 13 0;
diff --git a/examples/puredata/xtract/a_mton.pd b/examples/puredata/xtract/a_mton.pd
new file mode 100644
index 0000000..7829dbe
--- /dev/null
+++ b/examples/puredata/xtract/a_mton.pd
@@ -0,0 +1,66 @@
+#N canvas 165 175 599 406 10;
+#X obj 151 123 inlet;
+#X obj 151 179 % 12;
+#X obj 151 232 sel 0 1 2 3 4 5 6 7 8 9 10 11;
+#X obj 483 268 / 12;
+#X obj 483 291 int;
+#X obj 483 313 outlet;
+#X msg 80 272 C;
+#X msg 110 272 C#;
+#X msg 142 273 D;
+#X msg 174 273 D#;
+#X msg 203 273 E;
+#X msg 236 274 F;
+#X msg 269 274 F#;
+#X msg 299 274 G;
+#X msg 329 274 G#;
+#X msg 359 275 A;
+#X msg 393 275 A#;
+#X msg 425 275 B;
+#X obj 235 342 symbol;
+#X obj 235 368 outlet;
+#X obj 569 206 int;
+#X obj 537 184 t f f;
+#X obj 537 207 -;
+#X obj 538 313 outlet;
+#X text 51 30 a_mton takes midi note number as a float and outputs
+note name \, octave and deviation in cents.;
+#X obj 537 231 * 100;
+#X obj 537 250 - 50;
+#X connect 0 0 1 0;
+#X connect 0 0 3 0;
+#X connect 0 0 21 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 2 1 7 0;
+#X connect 2 2 8 0;
+#X connect 2 3 9 0;
+#X connect 2 4 10 0;
+#X connect 2 5 11 0;
+#X connect 2 6 12 0;
+#X connect 2 7 13 0;
+#X connect 2 8 14 0;
+#X connect 2 9 15 0;
+#X connect 2 10 16 0;
+#X connect 2 11 17 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 6 0 18 0;
+#X connect 7 0 18 0;
+#X connect 8 0 18 0;
+#X connect 9 0 18 0;
+#X connect 10 0 18 0;
+#X connect 11 0 18 0;
+#X connect 12 0 18 0;
+#X connect 13 0 18 0;
+#X connect 14 0 18 0;
+#X connect 15 0 18 0;
+#X connect 16 0 18 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 20 0 22 1;
+#X connect 21 0 22 0;
+#X connect 21 1 20 0;
+#X connect 22 0 25 0;
+#X connect 25 0 26 0;
+#X connect 26 0 23 0;
diff --git a/examples/puredata/xtract/a_output~.pd b/examples/puredata/xtract/a_output~.pd
new file mode 100644
index 0000000..8cbf956
--- /dev/null
+++ b/examples/puredata/xtract/a_output~.pd
@@ -0,0 +1,71 @@
+#N canvas 0 0 757 675 12;
+#X obj 516 522 t b;
+#X obj 516 469 f;
+#X obj 516 547 f;
+#X msg 630 546 0;
+#X obj 516 499 moses 1;
+#X obj 630 518 t b f;
+#X obj 596 479 moses 1;
+#X obj 29 97 dbtorms;
+#X obj 85 170 inlet~;
+#X msg 278 300 \; pd dsp 1;
+#X obj 29 170 line~;
+#X obj 64 242 *~;
+#X obj 64 272 dac~;
+#X obj 29 127 pack 0 50;
+#X text 121 146 audio in;
+#X text 301 496 test if less than 1 -->;
+#X text 267 523 if true convert to bang -->;
+#X text 100 96 <-- convert from dB to linear units;
+#X floatatom 31 13 3 0 100 0 dB - -;
+#X obj 44 37 bng 15 250 50 0 empty empty mute -38 7 0 10 -262144 -1
+-1;
+#X text 118 126 <-- make a ramp to avoid clicks or zipper noise;
+#X obj 148 170 inlet~;
+#X obj 154 241 *~;
+#X text 502 399 MUTE logic:;
+#X obj 293 247 s \$0-master-out;
+#X obj 29 71 r \$0-master-out;
+#X obj 596 450 r \$0-master-out;
+#X text 182 8 Level control abstraction \, used in many of the Pd example
+patches. The level and mute controls show up on the parent \, calling
+patch.;
+#X text 229 549 previous nonzero master-lvl -->;
+#X text 301 453 recall previous;
+#X text 301 471 value of master-lvl -->;
+#X text 16 310 automatically start DSP -->;
+#X obj 85 192 hip~ 3;
+#X obj 147 192 hip~ 3;
+#X text 26 608 NOTE: This abstraction was written by Miller Puckette
+\, and is include with the PD examples as part of the 'standard' PD
+documentation. JB 23/05/05;
+#X obj 278 193 r \$0-master-lvl-stereo;
+#X obj 516 573 s \$0-master-lvl-stereo;
+#X obj 623 215 inlet;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 2 0 36 0;
+#X connect 3 0 36 0;
+#X connect 4 0 0 0;
+#X connect 4 1 5 0;
+#X connect 5 0 3 0;
+#X connect 6 1 2 1;
+#X connect 7 0 13 0;
+#X connect 8 0 32 0;
+#X connect 10 0 22 0;
+#X connect 10 0 11 0;
+#X connect 11 0 12 0;
+#X connect 13 0 10 0;
+#X connect 18 0 9 0;
+#X connect 18 0 24 0;
+#X connect 19 0 1 0;
+#X connect 21 0 33 0;
+#X connect 22 0 12 1;
+#X connect 25 0 7 0;
+#X connect 26 0 1 1;
+#X connect 26 0 6 0;
+#X connect 32 0 11 1;
+#X connect 33 0 22 1;
+#X connect 35 0 18 0;
+#X connect 37 0 18 0;
+#X coords 0 0 1 1 65 55 1 0 0;
diff --git a/examples/puredata/xtract/a_spigot~.pd b/examples/puredata/xtract/a_spigot~.pd
new file mode 100644
index 0000000..86ebd54
--- /dev/null
+++ b/examples/puredata/xtract/a_spigot~.pd
@@ -0,0 +1,21 @@
+#N canvas 0 0 450 300 10;
+#X obj 153 112 inlet~;
+#X obj 152 229 outlet~;
+#X obj 153 186 expr~ $v1 * $v2;
+#X obj 252 162 line~;
+#X msg 258 121 1 20;
+#X msg 299 121 0 20;
+#X obj 255 14 inlet;
+#X obj 255 36 > 0;
+#X obj 255 63 select 1 0;
+#X text 49 261 Audio spigot. Same behaviour as spigot but for audio
+;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 1;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 4 0;
+#X connect 8 1 5 0;
diff --git a/examples/puredata/xtract/f0.pd b/examples/puredata/xtract/f0.pd
new file mode 100644
index 0000000..d178c82
--- /dev/null
+++ b/examples/puredata/xtract/f0.pd
@@ -0,0 +1,292 @@
+#N canvas 814 127 584 590 10;
+#N canvas 162 173 901 522 guts 0;
+#X obj 205 48 osc~;
+#X obj 338 70 a_spigot~;
+#X obj 205 70 a_spigot~;
+#X obj 331 -26 line;
+#X msg 331 -50 \$1 50;
+#X obj 357 282 ftom;
+#X obj 3 48 ftom;
+#N canvas 0 0 450 300 fm 0;
+#X obj 181 114 osc~;
+#X obj 138 175 osc~;
+#X obj 137 154 +~;
+#X obj 144 209 outlet~;
+#X obj 182 82 *;
+#X obj 137 26 inlet;
+#X obj 204 6 inlet;
+#X obj 179 54 f;
+#X obj 204 30 t b f;
+#X obj 182 143 *~;
+#X obj 238 81 - 2;
+#X obj 225 113 * 100000;
+#X connect 0 0 9 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 4 0 0 0;
+#X connect 5 0 2 0;
+#X connect 5 0 4 0;
+#X connect 5 0 7 1;
+#X connect 6 0 8 0;
+#X connect 7 0 4 0;
+#X connect 7 0 2 0;
+#X connect 8 0 7 0;
+#X connect 8 1 4 1;
+#X connect 8 1 10 0;
+#X connect 9 0 2 1;
+#X connect 10 0 11 0;
+#X connect 11 0 9 1;
+#X restore 339 47 pd fm;
+#X obj 459 69 a_spigot~;
+#X obj 253 168 +~;
+#N canvas 0 0 450 300 noise 0;
+#X obj 260 126 noise~;
+#X obj 269 161 *~;
+#X obj 270 194 lop~;
+#X obj 305 161 * 10000;
+#X obj 320 124 inlet;
+#X obj 268 236 outlet~;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 5 0;
+#X connect 3 0 2 1;
+#X connect 4 0 3 0;
+#X connect 4 0 1 1;
+#X restore 587 66 pd noise;
+#N canvas 604 77 496 580 pda 0;
+#X obj 99 100 xtract~ f0;
+#X obj 197 6 inlet~;
+#X obj 147 195 xtract~ magnitude_spectrum;
+#X obj 149 299 xtract~ lowest_match;
+#X msg 361 203 list \$1;
+#X obj 244 115 *~;
+#X obj 59 25 r sr;
+#X obj 148 222 xtract~ peaks;
+#X obj 148 245 tabsend~ freqs;
+#X obj 401 30 table freqs;
+#X obj 148 276 tabreceive~ freqs;
+#X obj 6 220 != 0;
+#X obj 4 331 spigot;
+#X obj 57 331 spigot;
+#X obj 67 217 == 0;
+#X obj 27 369 f;
+#X obj 28 415 lop~ 20;
+#X obj 27 393 sig~;
+#X obj 29 469 snapshot~;
+#X obj 95 434 bang~;
+#X obj 26 529 outlet;
+#X obj 29 499 a_bavg 4;
+#X obj 197 29 lop~ 5000;
+#X obj 402 8 block~ 2048;
+#X obj 200 51 hip~ 20;
+#X msg 60 48 list \$1;
+#X obj 274 80 a_hann 2048;
+#X obj 274 59 r \$0-window-gen;
+#X connect 0 0 4 0;
+#X connect 0 0 11 0;
+#X connect 0 0 12 0;
+#X connect 0 0 14 0;
+#X connect 1 0 22 0;
+#X connect 2 0 7 0;
+#X connect 3 0 13 0;
+#X connect 4 0 3 1;
+#X connect 5 0 2 0;
+#X connect 6 0 25 0;
+#X connect 7 0 8 0;
+#X connect 10 0 3 0;
+#X connect 11 0 12 1;
+#X connect 12 0 15 0;
+#X connect 13 0 15 0;
+#X connect 14 0 13 1;
+#X connect 15 0 17 0;
+#X connect 16 0 18 0;
+#X connect 17 0 16 0;
+#X connect 18 0 21 0;
+#X connect 19 0 18 0;
+#X connect 21 0 20 0;
+#X connect 22 0 24 0;
+#X connect 24 0 0 0;
+#X connect 24 0 5 0;
+#X connect 25 0 0 1;
+#X connect 26 0 5 1;
+#X connect 27 0 26 0;
+#X restore 357 262 pd pda;
+#N canvas 0 0 596 417 d_saw 0;
+#X obj 382 176 phasor~;
+#X obj 397 96 noise~;
+#X obj 346 116 sig~;
+#X obj 381 149 +~;
+#X obj 397 117 *~;
+#X obj 242 198 phasor~;
+#X obj 319 283 outlet~;
+#X obj 385 215 *~ 0.5;
+#X obj 240 227 *~ 0.3;
+#X obj 270 173 * 0.01;
+#X obj 241 174 +;
+#X obj 460 97 * 0.1;
+#X obj 312 249 lop~ 10000;
+#X obj 369 51 inlet;
+#X obj 261 55 inlet fund;
+#X obj 258 138 f;
+#X obj 286 105 t b f;
+#X connect 0 0 7 0;
+#X connect 1 0 4 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 1;
+#X connect 5 0 8 0;
+#X connect 7 0 12 0;
+#X connect 8 0 12 0;
+#X connect 9 0 10 1;
+#X connect 10 0 5 0;
+#X connect 11 0 4 1;
+#X connect 12 0 6 0;
+#X connect 13 0 16 0;
+#X connect 14 0 2 0;
+#X connect 14 0 11 0;
+#X connect 14 0 15 1;
+#X connect 14 0 10 0;
+#X connect 15 0 10 0;
+#X connect 15 0 9 0;
+#X connect 16 0 15 0;
+#X connect 16 1 9 1;
+#X restore 457 45 pd d_saw;
+#X obj 160 262 fiddle~ 2048;
+#X obj 75 47 adc~;
+#X obj 76 71 a_spigot~;
+#X obj 2 69 a_mton;
+#X obj 160 283 a_mton;
+#X obj 357 301 a_mton;
+#X obj 733 -70 loadbang;
+#X obj 68 241 loadbang;
+#X msg 67 263 symbol;
+#X text 411 283 <-The magic happens in here;
+#X obj 660 323 a_output~;
+#X msg 747 271 0;
+#X obj 263 46 r \$0-sine;
+#X obj 134 48 r \$0-adc;
+#X obj 396 48 r \$0-fm;
+#X obj 521 43 r \$0-saw;
+#X obj 586 41 r \$0-noisiness;
+#X obj 473 -1 r \$0-inharmonicity;
+#X obj 161 409 s \$0-fidd_f0_note;
+#X obj 178 386 s \$0-fidd_f0_8ve;
+#X obj 197 361 s \$0-fidd_f0_cent;
+#X obj 356 367 s \$0-pda_f0_note;
+#X obj 333 -73 r \$0-fund;
+#X obj 375 345 s \$0-pda_f0_8ve;
+#X obj 395 326 s \$0-pda_f0_cent;
+#X obj 745 230 r \$0-master-lvl-stereo;
+#X obj 747 252 r \$0-master-lvl-mute;
+#X obj 747 291 s \$0-master-lvl-stereo;
+#X msg 733 -20 \; pd dsp 1 \; \; \$1-window-gen bang \; sr 44100 \;
+\; \$1-master-lvl-stereo 50;
+#X obj 733 -45 f \$0;
+#X obj 38 357 s \$0-f0_cent;
+#X obj 19 378 s \$0-f0_8ve;
+#X obj 0 406 s \$0-f0_note;
+#X obj 254 261 s~ \$0-dacs;
+#X obj 670 281 r~ \$0-dacs;
+#X connect 0 0 2 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 0 0;
+#X connect 3 0 12 0;
+#X connect 3 0 7 0;
+#X connect 3 0 6 0;
+#X connect 4 0 3 0;
+#X connect 5 0 18 0;
+#X connect 6 0 16 0;
+#X connect 7 0 1 0;
+#X connect 8 0 9 0;
+#X connect 9 0 11 0;
+#X connect 9 0 13 0;
+#X connect 9 0 46 0;
+#X connect 10 0 9 1;
+#X connect 11 0 5 0;
+#X connect 12 0 8 0;
+#X connect 13 0 17 0;
+#X connect 14 0 15 0;
+#X connect 15 0 9 0;
+#X connect 16 0 45 0;
+#X connect 16 1 44 0;
+#X connect 16 2 43 0;
+#X connect 17 0 31 0;
+#X connect 17 1 32 0;
+#X connect 17 2 33 0;
+#X connect 18 0 34 0;
+#X connect 18 1 36 0;
+#X connect 18 2 37 0;
+#X connect 19 0 42 0;
+#X connect 20 0 21 0;
+#X connect 21 0 31 0;
+#X connect 21 0 34 0;
+#X connect 21 0 45 0;
+#X connect 24 0 23 2;
+#X connect 24 0 40 0;
+#X connect 25 0 2 1;
+#X connect 26 0 15 1;
+#X connect 27 0 1 1;
+#X connect 28 0 8 1;
+#X connect 29 0 10 0;
+#X connect 30 0 7 1;
+#X connect 35 0 4 0;
+#X connect 38 0 23 2;
+#X connect 39 0 24 0;
+#X connect 42 0 41 0;
+#X connect 47 0 23 0;
+#X connect 47 0 23 1;
+#X restore 519 -226 pd guts;
+#X obj 11 -226 cnv 15 500 200 empty empty PDA_comparison 20 12 0 14
+-261681 -66577 0;
+#X obj 34 -94 hsl 128 15 2 2.05 0 0 \$0-inharmonicity empty fm-inharmonicity
+-2 -6 0 8 -225271 -1 -1 0 1;
+#X obj 34 -50 hsl 128 15 0 0.5 0 0 \$0-noisiness empty noisiness -2
+-6 0 8 -225271 -1 -1 0 1;
+#X obj 33 -135 hsl 128 15 30 3000 0 0 \$0-fund empty f0 -2 -6 0 8 -225271
+-1 -1 0 1;
+#X obj 32 -172 tgl 15 0 \$0-sine empty sine 0 -6 0 8 -225280 -1 -1
+0 1;
+#X obj 73 -172 tgl 15 0 \$0-fm empty fm 0 -6 0 8 -225280 -1 -1 0 1
+;
+#X obj 110 -172 tgl 15 0 \$0-saw empty saw 0 -6 0 8 -225280 -1 -1 0
+1;
+#X obj 227 -133 cnv 15 200 100 empty empty empty 20 12 0 14 -262131
+-66577 0;
+#X obj 226 -199 cnv 15 200 60 empty empty empty 20 12 0 14 -225280
+-66577 0;
+#X symbolatom 242 -170 5 0 0 0 f0 #0-f0_note -;
+#X floatatom 312 -170 5 0 0 0 8ve #0-f0_8ve -;
+#X symbolatom 245 -112 5 0 0 0 f0 #0-fidd_f0_note -;
+#X floatatom 313 -112 5 0 0 0 8ve #0-fidd_f0_8ve -;
+#X text 304 -200 Input;
+#X text 308 -93 xtract~;
+#X text 305 -134 fiddle~;
+#X floatatom 315 -62 5 0 0 0 8ve #0-pda_f0_8ve -;
+#X symbolatom 247 -62 5 0 0 0 f0 #0-pda_f0_note -;
+#X text 20 8 Notes:;
+#X text 20 36 In this patch xtract~ is used to provide a combination
+of time domain and frequency domain fundamental frequency estimation.
+;
+#X text 27 233 A block size of 2048 has been used in this example.
+Which allows for a theoretical limit of 21Hz. In reality xtract~ can
+be used to detect frequencies down to 30Hz with this block size \,
+but with a larger block size it could go lower!;
+#X text 23 88 [xtract~ f0] uses a method based on the AMDF function
+\, with centre and peak clipping used to provide noise robustness.
+This could be further improved \, as could the efficiency of the algorithm.
+;
+#X text 26 154 If [xtract~ f0] is unable to find a fundamental (i.e.
+its output is 0 \, the lowest frequency in the peak spectrum is used.
+In general this happens for very low frequencies. [xtract~ magnitude_spectrum]
+\, [xtract~ peaks] \, and [xtract~ lowest_match] are used to achieve
+this.;
+#X obj 147 -172 tgl 15 0 \$0-adc empty adc~ 0 -6 0 8 -257472 -1 -1
+0 1;
+#X floatatom 386 -171 5 0 0 0 cent #0-f0_cent -;
+#X floatatom 386 -63 5 0 0 0 cent #0-pda_f0_cent -;
+#X floatatom 386 -113 5 0 0 0 cent #0-fidd_f0_cent -;
+#X obj 465 -187 vsl 10 100 0 127 0 0 \$0-master-lvl-stereo \$0-master-lvl-stereo
+out -4 -8 0 8 -262131 -1 -1 3898 1;
+#X obj 465 -77 bng 10 250 50 0 \$0-master-lvl-mute empty mute -6 16
+0 8 -262131 -1 -1;
diff --git a/examples/puredata/xtract/mfcc.pd b/examples/puredata/xtract/mfcc.pd
new file mode 100644
index 0000000..7e12479
--- /dev/null
+++ b/examples/puredata/xtract/mfcc.pd
@@ -0,0 +1,154 @@
+#N canvas 667 28 576 568 10;
+#N canvas 397 309 590 228 guts 0;
+#X obj 318 37 loadbang;
+#X obj 318 64 f \$0;
+#N canvas 0 0 450 300 dacs 0;
+#X obj 164 152 a_output~;
+#X msg 251 100 0;
+#X obj 249 59 r \$0-master-lvl-stereo;
+#X obj 251 81 r \$0-master-lvl-mute;
+#X obj 251 120 s \$0-master-lvl-stereo;
+#X obj 174 110 inlet~;
+#X connect 1 0 0 2;
+#X connect 1 0 4 0;
+#X connect 2 0 0 2;
+#X connect 3 0 1 0;
+#X connect 5 0 0 0;
+#X connect 5 0 0 1;
+#X restore 85 126 pd dacs;
+#N canvas 0 0 450 300 analysis 0;
+#X obj 191 201 xtract~ mfcc;
+#X obj 195 176 xtract~ magnitude_spectrum;
+#X obj 194 153 *~;
+#X obj 219 104 r \$0-window-gen;
+#X obj 190 225 tabsend~ \$0-mfcc;
+#X obj 181 69 inlet~;
+#X obj 299 45 block~ 1024 2 1;
+#X obj 219 125 a_hann 1024;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 7 0;
+#X connect 5 0 2 0;
+#X connect 7 0 2 1;
+#X restore 32 167 pd analysis;
+#X obj 16 24 r \$0-fund;
+#X msg 318 88 \; pd dsp 1 \; \$1-master-lvl-stereo 60 \; \$1-window-gen
+bang \; \$1-mfcc xticks 0 5 5 \; \$1-mfcc yticks 0 50 1 \; \$1-mfcc
+xlabel -120 0 5 10 15 20;
+#N canvas 308 141 679 510 paf 0;
+#X obj 331 95 / 10;
+#X obj 331 120 pack 0 50;
+#X obj 139 412 fexpr~ $x1 * $x2;
+#X obj 241 188 cos~;
+#X obj 241 166 expr~ ($v1 * 0.5) - 0.25;
+#X obj 380 197 *~ 256;
+#X obj 462 209 line~;
+#X obj 462 189 pack 0 50;
+#X obj 289 194 *~;
+#X obj 282 216 +~ 256;
+#X obj 118 328 cos~;
+#X obj 118 305 *~;
+#X obj 161 328 cos~;
+#X obj 161 305 +~;
+#X obj 154 358 -~;
+#X obj 174 390 *~;
+#X obj 136 390 +~;
+#X obj 230 291 wrap~;
+#X obj 199 291 -~;
+#X obj 199 259 samphold~;
+#X obj 331 142 line~;
+#X obj 138 438 outlet~;
+#X obj 462 167 inlet bandwidth;
+#X obj 47 121 phasor~;
+#X obj 48 100 line~;
+#X msg 47 78 \$1 20;
+#X obj 48 57 inlet fund;
+#X obj 331 73 inlet cf;
+#X obj 282 316 tabread4~ \$0-hann;
+#X obj 466 426 table \$0-hann;
+#X connect 0 0 1 0;
+#X connect 1 0 20 0;
+#X connect 2 0 21 0;
+#X connect 3 0 8 0;
+#X connect 4 0 3 0;
+#X connect 5 0 8 1;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 9 0;
+#X connect 9 0 28 0;
+#X connect 10 0 14 1;
+#X connect 10 0 16 0;
+#X connect 11 0 13 0;
+#X connect 11 0 10 0;
+#X connect 12 0 14 0;
+#X connect 13 0 12 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 1;
+#X connect 16 0 2 0;
+#X connect 17 0 18 1;
+#X connect 17 0 15 1;
+#X connect 18 0 11 1;
+#X connect 19 0 18 0;
+#X connect 19 0 17 0;
+#X connect 20 0 19 0;
+#X connect 22 0 7 0;
+#X connect 23 0 19 1;
+#X connect 23 0 13 1;
+#X connect 23 0 11 0;
+#X connect 23 0 4 0;
+#X connect 24 0 23 0;
+#X connect 25 0 24 0;
+#X connect 26 0 25 0;
+#X connect 27 0 0 0;
+#X connect 28 0 2 1;
+#X restore 35 80 pd paf;
+#X obj 85 25 r \$0-cf;
+#X obj 140 23 r \$0-bw;
+#X connect 0 0 1 0;
+#X connect 1 0 5 0;
+#X connect 4 0 6 0;
+#X connect 6 0 2 0;
+#X connect 6 0 3 0;
+#X connect 7 0 6 1;
+#X connect 8 0 6 2;
+#X restore 516 -222 pd guts;
+#X obj 6 -225 cnv 15 500 200 empty empty MFCC 20 12 0 14 -261681 -66577
+0;
+#X obj 184 -202 cnv 15 250 150 empty empty empty 20 12 0 14 -262131
+-66577 0;
+#X obj 465 -187 vsl 10 100 0 127 0 0 \$0-master-lvl-stereo \$0-master-lvl-stereo
+out -4 -8 0 8 -262131 -1 -1 4677 1;
+#X obj 465 -77 bng 10 250 50 0 \$0-master-lvl-mute empty mute -6 16
+0 8 -262131 -1 -1;
+#X obj 32 -114 hsl 128 15 20 2000 0 0 \$0-cf empty centre_frequency
+-2 -6 0 8 -225271 -1 -1 4000 1;
+#X obj 33 -153 hsl 128 15 80 2000 0 0 \$0-fund empty fundamental -2
+-6 0 8 -225271 -1 -1 3100 1;
+#X text 19 7 Notes:;
+#X text 20 36 In this patch [xtract~ magnitude_spectrum] is first used
+to extract the magnitude spectrum from an audio signal in overlapping
+blocks of 1024 samples.;
+#X text 20 87 [xtract~ mfcc] outputs a series 20 Mel-Frequency Cepstral
+Coefficients. When it is instantiated \, an initialisation function
+creates a bank of 20 mel-spaced filters \, between 80Hz and 1800Hz
+on a linear scale. All filters have the same gain;
+#X text 23 165 Whilst DSP is running the input vector (magnitude spectrum)
+is filtered by this filterbank \, and the total energy output from
+each filter is appended to a new vector. This new vector (mel-filtered
+spectrum) is then subjected to a fast cosine transfor. The output can
+be visualised in the graph labelled \$0-mfcc.;
+#X text 23 255 With LibXtract it is possible to change the number of
+Mel filters as well as the range of frequencies over which they operate
+\, and the filter scaling (equal area/equal gain). With this PD example
+\, sensible defaults have been chosen to improve usability;
+#N canvas 0 0 450 300 graph2 0;
+#X array \$0-mfcc 20 float 5;
+#A 0 -173.776 -23.5876 -0.366171 -3.06397 -0.349543 -1.22577 -0.205707
+-0.846186 -0.420453 -0.62197 -0.362943 -0.731029 -0.492134 -0.787504
+-0.453503 -0.578885 -0.402549 -0.51454 -0.395146 -0.515564;
+#X coords 0 50 19 -100 200 100 1;
+#X restore 212 -178 graph;
+#X text 28 -188 PAF synthesiser;
+#X obj 34 -71 hsl 128 15 1 500 0 0 \$0-bw empty formant_bandwidth -2
+-6 0 8 -225271 -1 -1 5300 1;
diff --git a/examples/puredata/xtract/sonogram.pd b/examples/puredata/xtract/sonogram.pd
new file mode 100644
index 0000000..78a7b42
--- /dev/null
+++ b/examples/puredata/xtract/sonogram.pd
@@ -0,0 +1 @@
+#N canvas 0 0 450 300 10;
diff --git a/examples/puredata/xtract/xtract-help.pd b/examples/puredata/xtract/xtract-help.pd
new file mode 100644
index 0000000..eff8381
--- /dev/null
+++ b/examples/puredata/xtract/xtract-help.pd
@@ -0,0 +1,69 @@
+#N canvas 685 60 450 725 10;
+#X text 21 12 [xtract~];
+#X text 24 19 ________;
+#X text 22 52 [xtract~] provides a wrapper for the feature extraction
+library: LibXtract. Please refer to the documentation at libxtract.sourceforge.net
+\, for a full explanation of the library and the functions it provides.
+Only the operation of the PD external will be explained here along
+with a few use case scenarios.;
+#X text 20 148 [xtract~] must always be called with one argument \,
+in the following form: [xtract~ <feature>] \, where <feature> is a
+feature supported by the LibXtract library. A complete list of features
+may be obtained by sending the external a |help( message:;
+#X obj 27 262 xtract~;
+#X msg 27 233 help;
+#X text 26 298 Other than this help message \, the data sent to the
+left inlet should always be a 'signal' (i.e. audio rate). This is the
+data from a which a given feature will be extracted.;
+#X text 27 405 Any additional arguments that need to be passed to the
+feature extraction funtion must be provided as a list to the right
+inlet \, e.g.;
+#X obj 182 490 xtract~ mean;
+#X floatatom 132 586 10 0 0 0 - - -;
+#X floatatom 253 523 5 0 0 0 - - -;
+#X msg 182 522 list \$1;
+#X obj 132 556 xtract~ variance;
+#X obj 181 466 phasor~ 0.1;
+#X text 39 641 Below are some possible use cases (click to open):;
+#X text 26 352 The outlet may be a scalar (control rate) \, or a vector
+(audio rate) \, depending on the nature of the feature that is being
+extracted.;
+#X obj 44 674 cnv 15 82 22 empty empty empty 20 12 0 14 -99865 -66577
+0;
+#X obj 47 675 bng 15 250 50 0 f0-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 64 675 bng 15 250 50 0 f0-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 79 675 bng 15 250 50 0 f0-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 96 675 bng 15 250 50 0 f0-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 42 672 cnv 15 80 20 f0-open empty f0 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 450 300 hidden 0;
+#X msg 27 133 \; pd open f0.pd ./ \;;
+#X obj 27 110 r f0-open;
+#X obj 26 42 r mfcc-open;
+#X msg 26 65 \; pd open mfcc.pd ./ \;;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X restore 379 736 pd hidden;
+#X obj 136 675 cnv 15 82 22 empty empty empty 20 12 0 14 -99865 -66577
+0;
+#X obj 140 678 bng 15 250 50 0 mfcc-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 155 678 bng 15 250 50 0 mfcc-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 170 678 bng 15 250 50 0 mfcc-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 185 678 bng 15 250 50 0 mfcc-open empty empty 0 -6 0 8 -262144
+-1 -1;
+#X obj 134 673 cnv 15 80 20 f0-open empty MFCC 20 12 0 14 -195568 -66577
+0;
+#X connect 5 0 4 0;
+#X connect 8 0 10 0;
+#X connect 8 0 11 0;
+#X connect 11 0 12 1;
+#X connect 12 0 9 0;
+#X connect 13 0 8 0;
+#X connect 13 0 12 0;
diff --git a/src/scalar.c b/src/scalar.c
index 8767621..d5d9837 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -26,104 +26,104 @@
#include <stdlib.h>
int xtract_mean(float *data, int N, void *argv, float *result){
-
+
int n = N;
while(n--)
- *result += *data++;
-
+ *result += *data++;
+
*result /= N;
}
int xtract_variance(float *data, int N, void *argv, float *result){
-
+
int n = N;
while(n--)
- *result += *data++ - *(float *)argv;
-
+ *result += *data++ - *(float *)argv;
+
*result = SQ(*result) / (N - 1);
}
int xtract_standard_deviation(float *data, int N, void *argv, float *result){
-
+
*result = sqrt(*(float *)argv);
-
+
}
int xtract_average_deviation(float *data, int N, void *argv, float *result){
-
+
int n = N;
while(n--)
- *result += fabs(*data++ - *(float *)argv);
-
+ *result += fabs(*data++ - *(float *)argv);
+
*result /= N;
}
int xtract_skewness(float *data, int N, void *argv, float *result){
-
+
int n = N;
while(n--)
- *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
-
+ *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
+
*result = pow(*result, 3) / N;
}
int xtract_kurtosis(float *data, int N, void *argv, float *result){
-
+
int n = N;
while(n--)
- *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
-
+ *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
+
*result = pow(*result, 4) / N - 3;
-
+
}
int xtract_centroid(float *data, int N, void *argv, float *result){
-
+
int n = N;
- float *freqs, *amps, FA, A;
+ float *freqs, *amps, FA, A;
+
+ freqs = data;
+ amps = data + (N >> 1);
- freqs = data;
- amps = data + (N >> 1);
-
while(n--){
- FA += freqs[n] * amps[n];
- A += amps[n];
- }
-
- *result = FA / A;
+ FA += freqs[n] * amps[n];
+ A += amps[n];
+ }
+
+ *result = FA / A;
}
int xtract_irregularity_k(float *data, int N, void *argv, float *result){
-
+
int n,
- M = M - 1;
+ M = M - 1;
for(n = 1; n < M; n++)
- *result += abs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
+ *result += abs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
}
int xtract_irregularity_j(float *data, int N, void *argv, float *result){
-
+
int n = N;
float num, den;
while(n--){
- num += data[n] - data[n+1];
- den += data[n] * data[n];
+ num += data[n] - data[n+1];
+ den += data[n] * data[n];
}
-
+
*result = num / den;
}
@@ -135,52 +135,52 @@ int xtract_tristimulus_1(float *data, int N, void *argv, float *result){
float den;
while(n--)
- den += data[n];
+ den += data[n];
*result = data[0] / den;
}
int xtract_tristimulus_2(float *data, int N, void *argv, float *result){
-
+
int n = N;
float den;
while(n--)
- den += data[n];
+ den += data[n];
*result = (data[1] + data[2] + data[3]) / den;
-
+
}
int xtract_tristimulus_3(float *data, int N, void *argv, float *result){
-
+
int n = N;
float den, num;
while(n--)
- den += data[n];
+ den += data[n];
num = den - data[0] + data[1] + data[2] + data[3];
-
+
*result = num / den;
-
+
}
int xtract_smoothness(float *data, int N, void *argv, float *result){
-
+
int n = N;
if (data[0] <= 0) data[0] = 1;
if (data[1] <= 0) data[1] = 1;
-
+
for(n = 2; n < N; n++){
- if(data[n] <= 0) data[n] = 1;
- *result += abs(20 * log(data[n-1]) - (20 * log(data[n-2]) +
- 20 * log(data[n-1]) + 20 * log(data[n])) / 3);
- }
+ if(data[n] <= 0) data[n] = 1;
+ *result += abs(20 * log(data[n-1]) - (20 * log(data[n-2]) +
+ 20 * log(data[n-1]) + 20 * log(data[n])) / 3);
+ }
}
int xtract_spread(float *data, int N, void *argv, float *result){
@@ -190,49 +190,49 @@ int xtract_spread(float *data, int N, void *argv, float *result){
float num, den, tmp;
while(n--){
- tmp = n - *(float *)argv;
- num += SQ(tmp) * data[n];
- den += data[n];
+ tmp = n - *(float *)argv;
+ num += SQ(tmp) * data[n];
+ den += data[n];
}
*result = sqrt(num / den);
-
+
}
int xtract_zcr(float *data, int N, void *argv, float *result){
int n = N;
-
+
for(n = 1; n < N; n++)
- if(data[n] * data[n-1] < 0) (*result)++;
-
+ if(data[n] * data[n-1] < 0) (*result)++;
+
*result /= N;
-
+
}
int xtract_rolloff(float *data, int N, void *argv, float *result){
int n = N;
float pivot, temp;
-
+
while(n--) pivot += data[n];
-
+
pivot *= *(float *)argv;
-
+
for(n = 0; temp < pivot; temp += data[n++]);
*result = n;
-
+
}
int xtract_loudness(float *data, int N, void *argv, float *result){
-
+
int n = BARK_BANDS;
-
+
/*if(n != N) return BAD_VECTOR_SIZE; */
while(n--)
- *result += pow(data[n], 0.23);
+ *result += pow(data[n], 0.23);
}
@@ -241,43 +241,43 @@ int xtract_flatness(float *data, int N, void *argv, float *result){
int n = N;
float num, den;
-
+
while(n--){
- if(data[n] !=0){
- num *= data[n];
- den += data[n];
- }
+ if(data[n] !=0){
+ num *= data[n];
+ den += data[n];
+ }
}
num = pow(num, 1 / N);
den /= N;
-
+
*result = 10 * log10(num / den);
-
+
}
int xtract_tonality(float *data, int N, void *argv, float *result){
-
+
float sfmdb, sfm;
-
+
sfm = *(float *)argv;
sfmdb = (sfm > 0 ? (10 * log10(sfm)) / -60 : 0);
-
+
*result = MIN(sfmdb, 1);
-
+
}
int xtract_crest(float *data, int N, void *argv, float *result){
-
- NOT_IMPLEMENTED;
-
+
+ NOT_IMPLEMENTED;
+
}
int xtract_noisiness(float *data, int N, void *argv, float *result){
-
- NOT_IMPLEMENTED;
-
+
+ NOT_IMPLEMENTED;
+
}
int xtract_rms_amplitude(float *data, int N, void *argv, float *result){
@@ -287,32 +287,32 @@ int xtract_rms_amplitude(float *data, int N, void *argv, float *result){
while(n--) *result += SQ(data[n]);
*result = sqrt(*result / N);
-
+
}
int xtract_inharmonicity(float *data, int N, void *argv, float *result){
int n = N;
float num, den,
- *fund, *freq;
+ *fund, *freq;
fund = *(float **)argv;
freq = fund+1;
-
+
while(n--){
- num += abs(freq[n] - n * *fund) * SQ(data[n]);
- den += SQ(data[n]);
+ num += abs(freq[n] - n * *fund) * SQ(data[n]);
+ den += SQ(data[n]);
}
*result = (2 * num) / (*fund * den);
-
+
}
int xtract_power(float *data, int N, void *argv, float *result){
- NOT_IMPLEMENTED;
-
+ NOT_IMPLEMENTED;
+
}
int xtract_odd_even_ratio(float *data, int N, void *argv, float *result){
@@ -322,161 +322,161 @@ int xtract_odd_even_ratio(float *data, int N, void *argv, float *result){
float num, den;
while(n--){
- j = n * 2;
- k = j - 1;
- num += data[k];
- den += data[j];
+ j = n * 2;
+ k = j - 1;
+ num += data[k];
+ den += data[j];
}
*result = num / den;
-
+
}
int xtract_sharpness(float *data, int N, void *argv, float *result){
NOT_IMPLEMENTED;
-
+
}
int xtract_slope(float *data, int N, void *argv, float *result){
NOT_IMPLEMENTED;
-
+
}
int xtract_lowest_match(float *data, int N, void *argv, float *result){
-
+
float lowest_match = SR_LIMIT;
int n = N;
while(n--) {
- if(data[n] > 0)
- lowest_match = MIN(lowest_match, data[n]);
+ if(data[n] > 0)
+ lowest_match = MIN(lowest_match, data[n]);
}
*result = (lowest_match == SR_LIMIT ? 0 : lowest_match);
-
+
}
int xtract_hps(float *data, int N, void *argv, float *result){
int n = N, M, m, l, peak_index, position1_lwr;
float *coeffs2, *coeffs3, *product, L,
- largest1_lwr, peak, ratio1, sr;
+ largest1_lwr, peak, ratio1, sr;
+
+ sr = *(float*)argv;
- sr = *(float*)argv;
-
coeffs2 = (float *)malloc(N * sizeof(float));
coeffs3 = (float *)malloc(N * sizeof(float));
product = (float *)malloc(N * sizeof(float));
-
+
while(n--) coeffs2[n] = coeffs3[n] = 1;
M = N >> 1;
L = N / 3;
while(M--){
- m = M << 1;
- coeffs2[M] = (data[m] + data[m+1]) * 0.5f;
+ m = M << 1;
+ coeffs2[M] = (data[m] + data[m+1]) * 0.5f;
- if(M < L){
- l = M * 3;
- coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3;
- }
+ if(M < L){
+ l = M * 3;
+ coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3;
+ }
}
-
+
peak_index = peak = 0;
-
+
for(n = 1; n < N; n++){
- product[n] = data[n] * coeffs2[n] * coeffs3[n];
- if(product[n] > peak){
- peak_index = n;
- peak = product[n];
- }
+ product[n] = data[n] * coeffs2[n] * coeffs3[n];
+ if(product[n] > peak){
+ peak_index = n;
+ peak = product[n];
+ }
}
largest1_lwr = position1_lwr = 0;
for(n = 0; n < N; n++){
- if(data[n] > largest1_lwr && n != peak_index){
- largest1_lwr = data[n];
- position1_lwr = n;
- }
+ if(data[n] > largest1_lwr && n != peak_index){
+ largest1_lwr = data[n];
+ position1_lwr = n;
+ }
}
ratio1 = data[position1_lwr] / data[peak_index];
if(position1_lwr > peak_index * 0.4 && position1_lwr <
- peak_index * 0.6 && ratio1 > 0.1)
- peak_index = position1_lwr;
+ peak_index * 0.6 && ratio1 > 0.1)
+ peak_index = position1_lwr;
*result = sr / (float)peak_index;
-
+
free(coeffs2);
free(coeffs3);
free(product);
-
+
}
int xtract_f0(float *data, int N, void *argv, float *result){
- int M, sr, tau, n;
- float f0, err_tau_1, err_tau_x, array_max, threshold_peak, threshold_centre;
-
- sr = *(float *)argv;
-/* threshold_peak = *((float *)argv+1);
- threshold_centre = *((float *)argv+2);
- printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
- /* add temporary dynamic control over thresholds to test clipping effects */
-
-/* FIX: tweak and make into macros */
- threshold_peak = .8;
- threshold_centre = .3;
- M = N >> 1;
- err_tau_1 = 0;
- array_max = 0;
-
- /* Find the array max */
- for(n = 0; n < N; n++){
- if (data[n] > array_max)
- array_max = data[n];
- }
-
- threshold_peak *= array_max;
-
- /* peak clip */
- for(n = 0; n < N; n++){
- if(data[n] > threshold_peak)
- data[n] = threshold_peak;
- else if(data[n] < -threshold_peak)
- data[n] = -threshold_peak;
- }
-
- threshold_centre *= array_max;
-
- /* Centre clip */
- for(n = 0; n < N; n++){
- if (data[n] < threshold_centre)
- data[n] = 0;
- else
- data[n] -= threshold_centre;
- }
-
- /* Estimate fundamental freq */
- for (n = 1; n < M; n++)
- err_tau_1 = err_tau_1 + fabs(data[n] - data[n+1]);
- /* FIX: this doesn't pose too much load if it returns 'early', but if it can't find f0, load can be significant for larger block sizes M^2 iterations! */
- for (tau = 2; tau < M; tau++){
- err_tau_x = 0;
- for (n = 1; n < M; n++){
- err_tau_x = err_tau_x + fabs(data[n] - data[n+tau]);
+ int M, sr, tau, n;
+ float f0, err_tau_1, err_tau_x, array_max, threshold_peak, threshold_centre;
+
+ sr = *(float *)argv;
+ /* threshold_peak = *((float *)argv+1);
+ threshold_centre = *((float *)argv+2);
+ printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
+ /* add temporary dynamic control over thresholds to test clipping effects */
+
+ /* FIX: tweak and make into macros */
+ threshold_peak = .8;
+ threshold_centre = .3;
+ M = N >> 1;
+ err_tau_1 = 0;
+ array_max = 0;
+
+ /* Find the array max */
+ for(n = 0; n < N; n++){
+ if (data[n] > array_max)
+ array_max = data[n];
+ }
+
+ threshold_peak *= array_max;
+
+ /* peak clip */
+ for(n = 0; n < N; n++){
+ if(data[n] > threshold_peak)
+ data[n] = threshold_peak;
+ else if(data[n] < -threshold_peak)
+ data[n] = -threshold_peak;
+ }
+
+ threshold_centre *= array_max;
+
+ /* Centre clip */
+ for(n = 0; n < N; n++){
+ if (data[n] < threshold_centre)
+ data[n] = 0;
+ else
+ data[n] -= threshold_centre;
+ }
+
+ /* Estimate fundamental freq */
+ for (n = 1; n < M; n++)
+ err_tau_1 = err_tau_1 + fabs(data[n] - data[n+1]);
+ /* FIX: this doesn't pose too much load if it returns 'early', but if it can't find f0, load can be significant for larger block sizes M^2 iterations! */
+ for (tau = 2; tau < M; tau++){
+ err_tau_x = 0;
+ for (n = 1; n < M; n++){
+ err_tau_x = err_tau_x + fabs(data[n] - data[n+tau]);
+ }
+ if (err_tau_x < err_tau_1) {
+ f0 = sr / (tau + (err_tau_x / err_tau_1));
+ *result = f0;
+ return SUCCESS;
+ }
}
- if (err_tau_x < err_tau_1) {
- f0 = sr / (tau + (err_tau_x / err_tau_1));
- *result = f0;
- return SUCCESS;
- }
- }
- return NO_RESULT;
+ return NO_RESULT;
}