Hello list,
I need some help understanding whats going on with my external, and I havent coded in a long time. I appologize if I do newbie things, All I do is try to make the errors go away by trying things. For example I try to cast (t_float *) to (float) for truncf but I get errors unless I make *(t_float *)...
Problem 1, Basic functionality. I want to return the Nth sample from a block of samples. Is others have pointed out there may be other ways of doing this using other externals and combonations of objects, but I want to write my own object, in order to both learn more about writing externals, and to have a cleaner solution.
Problem 2, Weird errors. I get a werid warning: implicit declaration of function `truncf' when using a simple math.h function, and if I connect my external to fft~ while enabling a small piece of code I color the FFT~ output. When I then disconnect my object, the fft~ stops putting output out.
Problem 1: a closer look. Ive included my code at the bottom of this email. I really appreciate if someone could point out what Im doing wrong. Ive looked at snapshot~ and tried to adopt some of its methods, but it doesnt seem to work when compaired to print~ output.
Problem 2: a closer look. The peice of code: int n = (int)(w[3]); t_float *bin = (t_float *)(w[4]); *bin = truncf(*bin); if (*bin > n) *bin = n; if (*bin < 0) *bin = 0; Gives me the error: warning: implicit declaration of function `truncf'. Im not redefining the function... Also when this piece of code is enabled, and I connect to FFT~ real output I get colored output, then when I break the connection, FFT~ doesnt output anything, it seems. w[3]=sp[0]->s_n - 1 w[4]=&ref->x_bin t_float x_bin;
-------------The Code----------------- #include <m_pd.h> #include <math.h>
/*-------------------------------------------------------*/ /*fftbin~ */ /* A tool to extract specific bins from the output of */ /* fft~. Inlets are (from left to right): */ /* The output of fft~ and bang, the bin number to */ /* capture. */ /* The outlet is a control rate float equal to the value */ /* of the bin in question. */ /*-------------------------------------------------------*/
static t_class *fftbin_tilde_class;
typedef struct _fftbin { t_object x_obj; t_float x_n; t_float x_bin; t_float x_binval; float x_f; } t_fftbin;
void *fftbin_tilde_new(t_floatarg f) { t_fftbin *ref = (t_fftbin *)pd_new(fftbin_tilde_class); ref->x_bin = f; ref->x_binval=0; ref->x_f = 0; ref->x_n=64; //Signal inlet exists by default outlet_new(&ref->x_obj, &s_float); //bin value outlet floatinlet_new(&ref->x_obj, &ref->x_bin); //bin number inlet return (void *)ref; }
t_int *fftbin_tilde_perform(t_int *w) { t_float *in1 = (t_float *)(w[1]); //fft~ output t_float *binval = (t_float *)(w[2]); //value requested int n = (int)(w[3]); //block size t_float *bin = (t_float *)(w[4]); //bin request
//make sure bin requested is within block, and an integer *bin = truncf(*bin); if (*bin > n) *bin = n; if (*bin < 0) *bin = 0;
*binval = *in1;
return (w+5); }
void fftbin_tilde_dsp(t_fftbin *ref, t_signal **sp) { dsp_add(fftbin_tilde_perform, 4, sp[0]->s_vec + (int)ref->x_bin, &ref->x_binval, sp[0]->s_n - 1, &ref->x_bin); }
void fftbin_tilde_set(t_fftbin *ref, t_floatarg f) { ref->x_bin = f; }
void fftbin_tilde_bang(t_fftbin *ref) { outlet_float(ref->x_obj.ob_outlet, ref->x_binval); }
void fftbin_tilde_setup(void) { fftbin_tilde_class = class_new(gensym("fftbin~"), (t_newmethod)fftbin_tilde_new, 0, sizeof(t_fftbin), CLASS_DEFAULT, A_DEFFLOAT, 0);
class_addmethod(fftbin_tilde_class, (t_method)fftbin_tilde_dsp, gensym("dsp"), 0); class_addmethod(fftbin_tilde_class, (t_method)fftbin_tilde_set, gensym("set"), A_DEFFLOAT, 0); class_addbang(fftbin_tilde_class, fftbin_tilde_bang);
CLASS_MAINSIGNALIN(fftbin_tilde_class, t_fftbin, x_f); post("fftbin~: written by thewade with help from the PD list"); }
Zitiere thewade pdman@aproximation.org:
Hello list,
hi.
problem 2: a) why use truncf() instead of a simple cast to integer ? t_float f=1.3; int i=(int)f; b) you will have to link against the mathlib (-lm)
to cast (t_float *) to (float) for truncf but I get errors unless I make *(t_float *)...
probably it is a bad idea to cast a pointer to a float-value to a float-value itself. read a good C-book.
Problem 1: a closer look. Ive included my code at the bottom of this email. I really appreciate if someone could point out what Im doing wrong. Ive looked at snapshot~ and tried to adopt some of its methods, but it doesnt seem to work when compaired to print~ output.
a) i'd suggest to pass the whole object-structure to the _perform routine rather than just selected values. (but of course you are free to do as you please)
b) it is NOT a good idea to manipulate data in the _dsp routine !!! the _dsp() routine is called only ONCE!!!! you do not get the signal-data into your _perform-routine but the data + an offset (that cannot be changed at runtime) i'd suggest just using dsp_add(fftbin_tilde_perform, 3, ref, sp[0]->s_vec, sp[0]->s_n); and then reference your values as described in the externals-HOWTO.
c) just at tip: you probably could move part of your value-checking into the set()-routine (everything but the check for >=n)
mfg.ads.r IOhannes
PS: i have found (and sometimes still find) it very useful to put post()s into all crucial points of my objects that happen to function not properly (and most of them are misbehaving in the beginning) of course this will flood your console when trying to debug dsp-objects. but still...you will most probably see a lot of interesting thing
PPS: an alternative would be to learn how to handle a real debugger (like gdb) - but i must admit, my knowledge for this is *very* rudimentary.