I'm writing 2 externals that implement an LPC algorithm, to make the results as acurate as possible I need to record some values from the previous frame, I've found that after doing this I sometimes as far as I can tell randomly get the output values of nan (for the values in the output signal vector) This is normally due to one of the values that I'm doing calculations on being nan, but when i check the calculation of that value it has an actual value.
It happens at random times but it seems that I can make it happen when I open a patch with a graph in it (whilst the signal is running)
Is this something to do with the way pd handles lots of computation? Am I simply doing too much computation in the externals? If not then is there any reason why I would be getting these results?
Thanks Andrew
Andrew Hassal wrote:
I'm writing 2 externals that implement an LPC algorithm, to make the results as acurate as possible I need to record some values from the previous frame, I've found that after doing this I sometimes as far as I can tell randomly get the output values of nan (for the values in the output signal vector)
...
It happens at random times but it seems that I can make it happen when I open a patch with a graph in it (whilst the signal is running)
Did you already find the answer? The fact that the problem specially arises when you open a patch with a graph in it, may indicate that your code is accessing memory locations which are not allocated to it. Stand alone executables would by definition exit with segmentation fault, but with Pd externals I have experienced more than once that the problem was only revealed in a conflict with another object in the Pd process, notably when using multiple instances of the newly written class.
Katja
On Thu, Apr 14, 2011 at 1:55 PM, katja katjavetter@gmail.com wrote:
Andrew Hassal wrote:
I'm writing 2 externals that implement an LPC algorithm, to make the results as acurate as possible I need to record some values from the previous frame, I've found that after doing this I sometimes as far as I can tell randomly get the output values of nan (for the values in the output signal vector)
...
It happens at random times but it seems that I can make it happen when I open a patch with a graph in it (whilst the signal is running)
Did you already find the answer? The fact that the problem specially arises when you open a patch with a graph in it, may indicate that your code is accessing memory locations which are not allocated to it. Stand alone executables would by definition exit with segmentation fault, but with Pd externals I have experienced more than once that the problem was only revealed in a conflict with another object in the Pd process, notably when using multiple instances of the newly written class.
Katja
No not yet, it doesn't specifically just appear when there is a graph, but it virtually always triggers it when a patch with a graph is opened, but not immediately often the graph flashes up a few blocks of signal then it breaks. I'm not currently using multiple instances, but is there any easy way of testing if I'm using memory not allocated to the external? I've tried to do some basic tests and they all seem to be working correctly, as far as I can tell.
Andy
Quoting "Andrew Hassall" a.r.hassall@gmail.com:
I'm not currently using multiple instances, but is there any easy way of testing if I'm using memory not allocated to the external? I've
$ valgrind pd
mfad IOhannes
---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.
I'm not currently using multiple instances, but is there any easy way of testing if I'm using memory not allocated to the external? I've
$ valgrind pd
Is there a specific version of valgrind for pd? or do I have to run valgrind with a specific command? (I couldn't find any information of valgrind with pd from searching)
Andy
Quoting "Andrew Hassall" a.r.hassall@gmail.com:
I'm not currently using multiple instances, but is there any easy way of testing if I'm using memory not allocated to the external? I've
$ valgrind pd
Is there a specific version of valgrind for pd?
no.
or do I have to run valgrind with a specific command? (I couldn't find any information of valgrind with pd from searching)
no.
simply run $ valgrind pd -my -pd -flags and have a look what it tells.
note: Pd itself allocates a number of memory which it never frees (most prominently, the symbol hashtable, but also the list of classes); valgrind considers them as memleaks, but normally you can safely ignore these warnings as false positives.
mghrt IOhannes
---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.
apologies for the late reply.
I've managed to set up and run valgrind and it repeatly outputs
" ==29216== Invalid read of size 4 ==29216== at 0x9CF892F: lpcsynthesis_tilde_perform (in /usr/lib/pd/extra/lpcsynthesis~.pd_linux) ==29216== by 0x487C14: dsp_tick (in /usr/bin/pd) ==29216== by 0x473F5C: m_mainloop (in /usr/bin/pd) ==29216== by 0x478734: sys_main (in /usr/bin/pd) ==29216== by 0x5C1BD8D: (below main) (libc-start.c:226) ==29216== Address 0x7feffdb78 is not stack'd, malloc'd or (recently) free'd ==29216== ==29216== Invalid write of size 4 ==29216== at 0x9CF8931: lpcsynthesis_tilde_perform (in /usr/lib/pd/extra/lpcsynthesis~.pd_linux) ==29216== by 0x487C14: dsp_tick (in /usr/bin/pd) ==29216== by 0x473F5C: m_mainloop (in /usr/bin/pd) ==29216== by 0x478734: sys_main (in /usr/bin/pd) ==29216== by 0x5C1BD8D: (below main) (libc-start.c:226) ==29216== Address 0x7fefff490 is not stack'd, malloc'd or (recently) free'd
"
before finally giving up and saying its exceeded the max number of errors it will process.
will this be because both objects are accessing memory outside their allocation? or could it just be other problems with the audio setup (I still haven't got the pd audio settings correct on ubuntu, but it still manages to process input from the mic).
Andy
2011/4/15 zmoelnig@iem.at:
Quoting "Andrew Hassall" a.r.hassall@gmail.com:
I'm not currently using multiple instances, but is there any easy way of testing if I'm using memory not allocated to the external? I've
$ valgrind pd
Is there a specific version of valgrind for pd?
no.
or do I have to run valgrind with a specific command? (I couldn't find any information of valgrind with pd from searching)
no.
simply run $ valgrind pd -my -pd -flags and have a look what it tells.
note: Pd itself allocates a number of memory which it never frees (most prominently, the symbol hashtable, but also the list of classes); valgrind considers them as memleaks, but normally you can safely ignore these warnings as false positives.
mghrt IOhannes
This message was sent using IMP, the Internet Messaging Program.
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
On Fri, Apr 22, 2011 at 1:31 PM, Andrew Hassall a.r.hassall@gmail.comwrote:
will this be because both objects are accessing memory outside their allocation? or could it just be other problems with the audio setup
Why not attach or insert your code so we can read along?
Katja
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 04/22/2011 01:31 PM, Andrew Hassall wrote:
or could it just be other problems with the audio setup (I still haven't got the pd audio settings correct on ubuntu, but it still manages to process input from the mic).
given that valgrind produces an error each time "lpcsynthesis_tilde_perform()" is called and that hundreds if not thousands of people do not experience spurious crashes with their Pd that are related to (improper) soundcard settings, i would say it is your code (or whoever wrote lpcsynthesis_tile_perform())
fgmadr IOhannes
Yeah I thought it must be my code.
But I've also noticed a difference in the performance of the code from windows to linux, in linux the graph doesn't crash, but the externals are behaving differently. (In windows the external has the correct behaviour then crashes, but in linux it doesn't crash but still has nan values but also doesn't have the correct behaviour)
I've also noticed that there is another problem in one of my other files, in lpcanalysis_tilde_perform()
the code for both perform functions is below but as a quick explanation, I'm assuming an overlap of 50% and need the last 40 values from the previous frame in order for the algorithm to work correctly.
I think the problem must be to with copying the previous values but they do seem to copy across correctly if I output a value from one frame and compare it to the corresponding value in prev in the next frame.
lpcanalysis " t_int *lpcanalysis_tilde_perform(t_int *w)
{ t_lpcanalysis_tilde *x = (t_lpcanalysis_tilde *)(w[1]); t_sample *in1 = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)w[4];
t_sample *in = x->in; t_sample *win = x->win;
float *phis = x->phis; float *ks = x->ks; float *es = x->es; float *as = x->as; int p = x->p;
t_sample *prev = x->previous;
int i=0; int k=0; int m=0; int j=0; float sum=0; float window; int np = n+p; int halfn = n*0.5;
// copy previous values and input into one array for (i=0;i<p;i++){ *(in+i) = *(prev+39-(p-1)+i); } for (i=p;i<np;i++){ *(in+i) = *(in1+i-p); }
// windowing using a hamming window not hanning for (i=0; i<np;i++) { window = 0.54-(0.46*(cos((2*i*M_PI)/(np-1)))); *(win+i) = window*(*(in+i)); }
// autocorrelation for (k=0;k<=p;k++) { sum=0; for (m=0;(m+k)<np;m++){ sum+= *(win+m) * *(win+m+k); } *(phis+k) = sum; }
// levinson durbin algorithm *es = *phis; for (i=1;i<=p;i++) { sum=0; for (j=1;j<=(i-1);j++){ sum += x->alphas[j][i-1]* *(phis+i-j); } *(ks+i) = (float)(*(phis+i)-sum)/(float)(*(es+i-1)); x->alphas[i][i] = *(ks+i); if (i>1){ for (j=1;j<=(i-1);j++){ x->alphas[j][i] = x->alphas[j][i-1]-*(ks+i)*x->alphas[i-j][i-1]; } } *(es+i) = (1-pow(*(ks+i),2))* *(es+i-1); }
for(j=1;j<=p;j++){ SETFLOAT(x->a_at+(j-1),x->alphas[j][p]); *(as+j-1) = x->alphas[j][p]; }
//filter signal for (m=p;m<np;m++){ sum = 0; for (k=1;k<=p;k++) { sum += *(in+m-k) * *(as+(k-1)); } *(out+(m-p)) = *(in+m)-sum; }
// output alphas outlet_list(x->p_list_out,0,p,x->a_at);
// copy last 40 values for (i=0;i<40;i++) { *(prev+i) = *(in+halfn+p-40+i); } return (w+5);
} "
lpcsynthesis
" t_int *lpcsynthesis_tilde_perform(t_int *w) { t_lpcsynthesis_tilde *x = (t_lpcsynthesis_tilde *)(w[1]); t_sample *in = (t_sample *)(w[2]); t_sample *out1 = (t_sample *)(w[3]); int n = (int)w[4];
float *as = x->as; int p = x->p; t_sample *out = x->out; t_sample *prev = x->previous;
int i; int k; float sum; int np = n+p; int halfn = n*0.5;
// copy previous values into start of array for (i=0;i<p;i++) { *(out+i) = *(prev+39-(p-1)+i); }
// filter for (i=p;i<np;i++) { sum = 0; for (k=1;k<=p;k++){ sum += *(out+i-k) * (*(as+k-1)); } }
//copy new values into out array for (i=0;i<n;i++) { *(out1+i) = *(out+i+p); }
// save previous values for (i=0;i<40;i++) { *(prev+i) = *(out+p+halfn-40+i); }
return (w+5); } "
2011/4/22 IOhannes m zmölnig zmoelnig@iem.at:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 04/22/2011 01:31 PM, Andrew Hassall wrote:
or could it just be other problems with the audio setup (I still haven't got the pd audio settings correct on ubuntu, but it still manages to process input from the mic).
given that valgrind produces an error each time "lpcsynthesis_tilde_perform()" is called and that hundreds if not thousands of people do not experience spurious crashes with their Pd that are related to (improper) soundcard settings, i would say it is your code (or whoever wrote lpcsynthesis_tile_perform())
fgmadr IOhannes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAk2xlUkACgkQkX2Xpv6ydvRNqQCfVCy7CMQFrRP4Mgvx1NVyl1xQ nNsAnj2mVM9z/Row1qN/xeJGZrfYhZY9 =OiXz -----END PGP SIGNATURE-----
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
Andrew Hassall wrote:
Yeah I thought it must be my code.
Can't check whether all the pointer arithmetic is correct... When I cause an illegal memory access on OSX and Pd crashes on it, the crash log report gives exactly the line nr. of the offending code. Don't you get such information?
Katja
pd never crashes completely, the graph crashes and the signal output from the external is constantly nan. so there is no errors or crash reports.
so I'm not getting any illegal memory access errors. I'll try to check the pointer arithmetic to make sure I'm not though.
Andrew
On Sat, Apr 23, 2011 at 1:17 AM, katja katjavetter@gmail.com wrote:
Andrew Hassall wrote:
Yeah I thought it must be my code.
Can't check whether all the pointer arithmetic is correct... When I cause an illegal memory access on OSX and Pd crashes on it, the crash log report gives exactly the line nr. of the offending code. Don't you get such information? Katja
Andrew Hassall wrote:
pd never crashes completely, the graph crashes
Sorry I misunderstood you. Never seen a graph crashing.
so there is no errors or crash reports.
Your lpcsynthesis_tilde_perform() method is simple and you've probably checked pointer arithmetic a dozen times. Yet valgrind attributes invalid reads and writes to it. How frustrating. Pd does not crash, the invalid access is probably happening within it's allocated space. Best thing would be if you can force Pd to crash on it. Instantiate a lot of your objects, delete some of them, or close/open patch several times etc. Pd's allocated memory is not a continuous block. Under circumstances, Pd must crash on an illegal access, and you'll be pointed to the culprit code. Well this is my not-so-educated guess. I've had similar situations with my own homebrew objects. Good luck anyway.
Katja