diff options
Diffstat (limited to 'pd/extra/fiddle~')
-rw-r--r-- | pd/extra/fiddle~/fiddle~.c | 121 | ||||
-rw-r--r-- | pd/extra/fiddle~/help-fiddle~.pd | 107 | ||||
-rw-r--r-- | pd/extra/fiddle~/makefile | 25 |
3 files changed, 88 insertions, 165 deletions
diff --git a/pd/extra/fiddle~/fiddle~.c b/pd/extra/fiddle~/fiddle~.c index 373a43eb..3c0b2719 100644 --- a/pd/extra/fiddle~/fiddle~.c +++ b/pd/extra/fiddle~/fiddle~.c @@ -39,7 +39,7 @@ #define fsqrt sqrt #endif -char fiddle_version[] = "fiddle version 1.1 TEST3"; +char fiddle_version[] = "fiddle version 1.1 TEST4"; #ifdef JMAX #include "fts.h" @@ -319,6 +319,7 @@ void sigfiddle_vibrato(t_sigfiddle *x, t_floatarg vibtime, t_floatarg vibdepth); void sigfiddle_npartial(t_sigfiddle *x, double npartial); void sigfiddle_auto(t_sigfiddle *x, t_floatarg f); +void sigfiddle_setnpoints(t_sigfiddle *x, t_floatarg f); int sigfiddle_doinit(t_sigfiddle *x, long npoints, long npitch, long npeakanal, long npeakout); static t_int *fiddle_perform(t_int *w); @@ -693,11 +694,11 @@ void sigfiddle_doit(t_sigfiddle *x) for (npitch = 0; npitch < x->x_npitch; npitch++) { - int index; + int indx; float best; if (npitch) { - for (best = 0, index = -1, j=1; j < maxbin-1; j++) + for (best = 0, indx = -1, j=1; j < maxbin-1; j++) { if (histogram[j] > best && histogram[j] > histogram[j-1] && histogram[j] > histogram[j+1]) @@ -717,7 +718,7 @@ void sigfiddle_doit(t_sigfiddle *x) if (histogram[j + sigfiddle_intpartialonset[k]] > histogram[j]) goto peaknogood; } - index = j; + indx = j; best = histogram[j]; } peaknogood: ; @@ -725,13 +726,13 @@ void sigfiddle_doit(t_sigfiddle *x) } else { - for (best = 0, index = -1, j=0; j < maxbin; j++) + for (best = 0, indx = -1, j=0; j < maxbin; j++) if (histogram[j] > best) - index = j, best = histogram[j]; + indx = j, best = histogram[j]; } - if (index < 0) break; + if (indx < 0) break; histvec[npitch].h_value = best; - histvec[npitch].h_index = index; + histvec[npitch].h_index = indx; } #if 1 if (x->x_nprint) @@ -1003,6 +1004,7 @@ void sigfiddle_debug(t_sigfiddle *x) void sigfiddle_print(t_sigfiddle *x) { + post("npoints %d,", 2 * x->x_hop); post("amp-range %f %f,", x->x_amplo, x->x_amphi); post("reattack %d %f,", x->x_attacktime, x->x_attackthresh); post("vibrato %d %f", x->x_vibtime, x->x_vibdepth); @@ -1051,16 +1053,70 @@ void sigfiddle_auto(t_sigfiddle *x, t_floatarg f) x->x_auto = (f != 0); } +static void sigfiddle_freebird(t_sigfiddle *x) +{ + if (x->x_inbuf) + { + freebytes(x->x_inbuf, sizeof(float) * x->x_hop); + x->x_inbuf = 0; + } + if (x->x_lastanalysis) + { + freebytes(x->x_lastanalysis, + sizeof(float) * (2 * x->x_hop + 4 * FILTSIZE)); + x->x_lastanalysis = 0; + } + if (x->x_spiral) + { + freebytes(x->x_spiral, sizeof(float) * 2 * x->x_hop); + x->x_spiral = 0; + } + x->x_hop = 0; +} + +int sigfiddle_setnpoints(t_sigfiddle *x, t_floatarg fnpoints) +{ + int i, npoints = fnpoints; + sigfiddle_freebird(x); + if (npoints < MINPOINTS || npoints > MAXPOINTS) + { + error("fiddle~: npoints out of range; using %d", + npoints = DEFAULTPOINTS); + } + if (npoints != (1 << sigfiddle_ilog2(npoints))) + { + error("fiddle~: npoints not a power of 2; using %d", + npoints = (1 << sigfiddle_ilog2(npoints))); + } + x->x_hop = npoints >> 1; + if (!(x->x_inbuf = (float *)getbytes(sizeof(float) * x->x_hop))) + goto fail; + if (!(x->x_lastanalysis = (float *)getbytes( + sizeof(float) * (2 * x->x_hop + 4 * FILTSIZE)))) + goto fail; + if (!(x->x_spiral = (float *)getbytes(sizeof(float) * 2 * x->x_hop))) + goto fail; + for (i = 0; i < x->x_hop; i++) + x->x_inbuf[i] = 0; + for (i = 0; i < npoints + 4 * FILTSIZE; i++) + x->x_lastanalysis[i] = 0; + for (i = 0; i < x->x_hop; i++) + x->x_spiral[2*i] = cos((3.14159*i)/(npoints)), + x->x_spiral[2*i+1] = -sin((3.14159*i)/(npoints)); + x->x_phase = 0; + return (1); +fail: + sigfiddle_freebird(x); + return (0); +} + int sigfiddle_doinit(t_sigfiddle *x, long npoints, long npitch, long npeakanal, long npeakout) { float *buf1, *buf2, *buf3; t_peakout *buf4; - int i, hop; + int i; - if (npoints < MINPOINTS || npoints > MAXPOINTS) npoints = DEFAULTPOINTS; - npoints = 1 << sigfiddle_ilog2(npoints); - hop = npoints>>1; if (!npeakanal && !npeakout) npeakanal = DEFNPEAK, npeakout = 0; if (!npeakanal < 0) npeakanal = 0; else if (npeakanal > MAXPEAK) npeakanal = MAXPEAK; @@ -1070,50 +1126,25 @@ int sigfiddle_doinit(t_sigfiddle *x, long npoints, long npitch, else if (npitch > MAXNPITCH) npitch = MAXNPITCH; if (npeakanal && !npitch) npitch = 1; - - if (!(buf1 = (float *)getbytes(sizeof(float) * hop))) - { - error("fiddle~: out of memory"); - return (0); - } - if (!(buf2 = (float *)getbytes(sizeof(float) * (npoints + 4 * FILTSIZE)))) - { - freebytes(buf1, sizeof(float) * hop); - error("fiddle~: out of memory"); - return (0); - } - if (!(buf3 = (float *)getbytes(sizeof(float) * npoints))) + if (!sigfiddle_setnpoints(x, npoints)) { - freebytes(buf1, sizeof(float) * hop); - freebytes(buf2, sizeof(float) * (npoints + 4 * FILTSIZE)); error("fiddle~: out of memory"); return (0); } if (!(buf4 = (t_peakout *)getbytes(sizeof(*buf4) * npeakout))) { - freebytes(buf1, sizeof(float) * hop); - freebytes(buf2, sizeof(float) * (npoints + 4 * FILTSIZE)); - freebytes(buf3, sizeof(float) * npoints); + sigfiddle_freebird(x); error("fiddle~: out of memory"); return (0); } - for (i = 0; i < hop; i++) buf1[i] = 0; - for (i = 0; i < npoints + 4 * FILTSIZE; i++) buf2[i] = 0; - for (i = 0; i < hop; i++) - buf3[2*i] = cos((3.14159*i)/(npoints)), - buf3[2*i+1] = -sin((3.14159*i)/(npoints)); for (i = 0; i < npeakout; i++) buf4[i].po_freq = buf4[i].po_amp = 0; - x->x_inbuf = buf1; - x->x_lastanalysis = buf2; - x->x_spiral = buf3; x->x_peakbuf = buf4; x->x_npeakout = npeakout; x->x_npeakanal = npeakanal; x->x_phase = 0; x->x_histphase = 0; - x->x_hop = npoints>>1; x->x_sr = 44100; /* this and the next are filled in later */ for (i = 0; i < MAXNPITCH; i++) { @@ -1364,6 +1395,8 @@ static t_int *fiddle_perform(t_int *w) int n = (int)(w[3]); int count; float *fp; + if (!x->x_hop) + goto nono; for (count = 0, fp = x->x_inbuf + x->x_phase; count < n; count++) *fp++ = *in++; if (fp == x->x_inbuf + x->x_hop) @@ -1374,6 +1407,7 @@ static t_int *fiddle_perform(t_int *w) if (x->x_nprint) x->x_nprint--; } else x->x_phase += n; +nono: return (w+4); } @@ -1469,6 +1503,8 @@ void fiddle_tilde_setup(void) gensym("dsp"), 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_debug, gensym("debug"), 0); + class_addmethod(sigfiddle_class, (t_method)sigfiddle_setnpoints, + gensym("npoints"), A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_amprange, gensym("amp-range"), A_FLOAT, A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_reattack, @@ -1632,8 +1668,7 @@ void sigfiddle_dsp(t_sigfiddle *x, t_signal **sp) { if (sp[0]->s_n > x->x_hop) { x->x_downsample = sp[0]->s_n / x->x_hop; - post("* warning: fiddle~: will downsample input by -%ld",x->x_downsample); + post("* warning: fiddle~: will downsample input by %ld",x->x_downsample); x->x_sr = sp[0]->s_sr / x->x_downsample; } else { x->x_downsample = 1; @@ -1644,8 +1679,7 @@ void sigfiddle_dsp(t_sigfiddle *x, t_signal **sp) dsp_add(fiddle_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); } -void sigfiddle_tick(t_sigfiddle *x) /* callback function for the clock -MSP*/ +void sigfiddle_tick(t_sigfiddle *x) /* callback function for the clock MSP*/ { int i; t_pitchhist *ph; @@ -1762,6 +1796,7 @@ A_DEFLONG, A_DEFLONG, 0); addmess((method)sigfiddle_dsp, "dsp", A_CANT, 0); addmess((method)sigfiddle_debug, "debug", 0); + addmess((method)sigfiddle_setnpoints, "npoints", A_FLOAT, 0); addmess((method)sigfiddle_amprange, "amp-range", A_FLOAT, A_FLOAT, 0); addmess((method)sigfiddle_reattack, "reattack", A_FLOAT, A_FLOAT, 0); addmess((method)sigfiddle_vibrato, "vibrato", A_FLOAT, diff --git a/pd/extra/fiddle~/help-fiddle~.pd b/pd/extra/fiddle~/help-fiddle~.pd deleted file mode 100644 index a7feb4f7..00000000 --- a/pd/extra/fiddle~/help-fiddle~.pd +++ /dev/null @@ -1,107 +0,0 @@ -#N canvas 93 26 980 745 10; -#X obj 262 522 phasor~; -#X obj 531 616 unpack; -#X floatatom 531 666; -#X msg 437 449 print; -#X obj 262 500 sig~; -#X floatatom 262 478; -#X obj 262 456 mtof; -#X floatatom 262 434; -#X floatatom 545 643; -#X obj 531 576 route 1 2 3 4; -#X obj 614 616 unpack; -#X floatatom 614 666; -#X floatatom 628 643; -#X obj 698 616 unpack; -#X floatatom 698 666; -#X floatatom 712 643; -#X obj 389 616 unpack; -#X floatatom 389 666; -#X floatatom 403 643; -#X obj 334 545 *~; -#X obj 322 394 loadbang; -#X obj 353 522 sig~; -#X floatatom 353 500; -#X msg 322 478 1; -#X msg 353 478 0; -#X floatatom 466 666; -#X obj 281 666 print attack; -#X obj 190 666 print pitch; -#X msg 555 45 \; pd dsp 1; -#X text 460 39 click here; -#X text 460 61 to start DSP; -#X text 226 4 FIDDLE - pitch estimator and sinusoidal peak finder; -#X text 8 70 The Fiddle object estimates the pitch and amplitude of an incoming sound \, both continuously and as a stream of discrete "note" events. Fiddle optionally outputs a list of detected sinusoidal peaks used to make the pitch determination. Fiddle is described theoretically in the 1998 ICMC proceedings \, reprinted on http://man104nfs.ucsd.edu/~mpuckett.; -#X text 8 170 Fiddle's creation arguments specify an analysis window size \, the maximum polyphony (i.e. \, the number of simultaneous "pitches" to try to find) \, the number of peaks in the spectrum to consider \, and the number of peaks \, if any \, to output "raw." The outlets give discrete pitch (a number) \, detected attacks in the amplitude envelope (a bang) \, one or more voices of continuous pitch and amplitude \, overall amplitude \, and optionally a sequence of messages with the peaks.; -#X text 8 296 The analysis hop size is half the window size so in the example shown here \, one analysis is done every 512 samples (11.6 msec at 44K1) \, and the analysis uses the most recent 1024 samples (23.2 msec at 44K1). The minimum frequency that Fiddle will report is 2-1/2 cycles per analysis windows \, or about 108 Hz. (just below MIDI 45.); -#X text 669 535 number of pitch outlets (1-3 \, default 1); -#X text 669 557 number of peaks to find (1-100 \, default 20); -#X text 669 579 number of peaks to output (default 0.); -#X msg 441 107 amp-range 40 50; -#X msg 439 227 reattack 100 10; -#X msg 438 282 npartial 7; -#X msg 438 170 vibrato 50 0.5; -#X text 560 91 a low and high amplitude threshold: if signal amplitude is below the low threshold \, no pitches or peaks are output. The high threshold is a minimum at which "cooked" outputs may appear.; -#X text 560 152 A period in milliseconds (50) over which the raw pitch may not deviate more than an interval in half-tones (0.5) from the average pitch to report it as a note to the "cooked" pitch outlet.; -#X text 560 213 A period in milliseconds (100) over which a re-attack is reported if the amplitude rises more than (1) dB. The re-attack will result in a "bang" in the attack outlet and may give rise to repeated notes in the cooked pitch output.; -#X text 142 432 test input pitch; -#X text 330 444 test input; -#X text 330 457 amplitude; -#X obj 410 545 fiddle~ 1024 1 20 3; -#X text 538 690 individual sinusoidal components; -#X text 466 688 amplitude; -#X text 476 703 (dB); -#X text 389 688 raw pitch; -#X text 376 712 and amplitude; -#X text 364 729 (up to 3 outputs); -#X text 287 686 bang on; -#X text 287 708 attack; -#X text 185 686 cooked pitch; -#X text 202 703 output; -#X text 545 545 ------ arguments:; -#X msg 262 412 57; -#X msg 440 340 auto 1; -#X msg 440 362 auto 0; -#X msg 440 407 bang; -#X text 561 405 poll current values --- useful if not in auto mode \,; -#X text 560 274 Higher partials are weighed less strongly than lower ones in determining the pitch. This specifies the number of the partial (7) which will be weighted half as strongly as the fundamental.; -#X text 560 335 start and stop "auto" mode (on by default.) If off \, output only appears on "bang" (poll mode).; -#X text 561 448 print out all settings; -#X text 669 513 window size (128-2048 \, default 1024); -#X connect 0 0 19 0; -#X connect 1 0 2 0; -#X connect 1 1 8 0; -#X connect 3 0 48 0; -#X connect 4 0 0 0; -#X connect 5 0 4 0; -#X connect 6 0 5 0; -#X connect 7 0 6 0; -#X connect 9 0 1 0; -#X connect 9 1 10 0; -#X connect 9 2 13 0; -#X connect 10 0 11 0; -#X connect 10 1 12 0; -#X connect 13 0 14 0; -#X connect 13 1 15 0; -#X connect 16 0 17 0; -#X connect 16 1 18 0; -#X connect 19 0 48 0; -#X connect 20 0 60 0; -#X connect 20 0 23 0; -#X connect 21 0 19 1; -#X connect 22 0 21 0; -#X connect 23 0 22 0; -#X connect 24 0 22 0; -#X connect 38 0 48 0; -#X connect 39 0 48 0; -#X connect 40 0 48 0; -#X connect 41 0 48 0; -#X connect 48 0 27 0; -#X connect 48 1 26 0; -#X connect 48 2 16 0; -#X connect 48 3 25 0; -#X connect 48 4 9 0; -#X connect 60 0 7 0; -#X connect 61 0 48 0; -#X connect 62 0 48 0; -#X connect 63 0 48 0; diff --git a/pd/extra/fiddle~/makefile b/pd/extra/fiddle~/makefile index a23303d3..6f6a963c 100644 --- a/pd/extra/fiddle~/makefile +++ b/pd/extra/fiddle~/makefile @@ -12,13 +12,13 @@ pd_nt: $(NAME).dll PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo VC="C:\Program Files\Microsoft Visual Studio\Vc98" -PDNTINCLUDE = /I. /I\tcl\include /I\ftp\pd\src /I$(VC)\include +PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include PDNTLDIR = $(VC)\lib PDNTLIB = $(PDNTLDIR)\libc.lib \ $(PDNTLDIR)\oldnames.lib \ $(PDNTLDIR)\kernel32.lib \ - \ftp\pd\bin\pd.lib + ..\..\bin\pd.lib .c.dll: cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c @@ -37,8 +37,7 @@ SGIINCLUDE = -I../../src .c.pd_irix5: cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o - rm -f $*.o ../$*.pd_linux - ln -s $*.pd_linux .. + rm $*.o # ----------------------- IRIX 6.x ----------------------- @@ -52,7 +51,7 @@ SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ .c.pd_irix6: cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c - ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o rm $*.o # ----------------------- LINUX i386 ----------------------- @@ -61,20 +60,17 @@ pd_linux: $(NAME).pd_linux .SUFFIXES: .pd_linux -LINUXCFLAGS = -fPIC -DPD -O2 -funroll-loops -fomit-frame-pointer \ +LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \ -Wall -W -Wshadow -Wstrict-prototypes -Werror \ -Wno-unused -Wno-parentheses -Wno-switch LINUXINCLUDE = -I../../src -LSTRIP = strip --strip-unneeded -R .note -R .comment - .c.pd_linux: cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - cc -Wl,-export_dynamic --shared -o $*.pd_linux $*.o -lm - $(LSTRIP) $*.pd_linux - rm -f $*.o ../$*.pd_linux - ln -s $*/$*.pd_linux .. + ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm + strip --strip-unneeded $*.pd_linux + rm -f $*.o # ----------------------- Mac OSX ----------------------- @@ -87,9 +83,8 @@ DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ .c.pd_darwin: cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o - rm -f $*.o ../$*.pd_darwin - ln -s $*/$*.pd_darwin .. + cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o # ---------------------------------------------------------- |