snd-add mem leak and snd-xform bugs EXPLAINED!
Posted: Mon Nov 25, 2013 12:28 am
I haven't yet built Audacity to test these fixes, but I think I found the causes of known bugs while reading some source code this weekend.
I refer to source code versions found here: http://code.google.com/p/audacity/sourc ... 253Dclosed
I refer to source code versions found here: http://code.google.com/p/audacity/sourc ... 253Dclosed
- The memory leak discussed in this thread: http://forum.audacityteam.org/viewtopic ... 39&t=75022
I believe this is the fault of lines 471:and 721:Code: Select all
susp->s1 = NULL;of file add.c. I believe these lines can just be commented out without harm. I believe the bug in the addition of two sounds will happen whenever two sounds are added with snd-add, and the sum is completely evaluated, and one sound outlasts the physical stop of the other sound (by at least one internal block of samples), and this later-ending sound is not otherwise referenced: then it leaks. Note that if you add many sounds with sim or sum, the last two are added with snd-add, and the others accumulated right to left onto that result with more calls to snd-add. Perhaps nobody detected this common occurrence until I wrote effects that cause this to happen many thousands of times?Code: Select all
susp->s2 = NULL; - The problems with results of snd-xform given to snd-add, with the resulting sound sometimes incorrect in a way dependent on the sequence of the summands, discussed here: http://forum.audacityteam.org/viewtopic ... 39&t=72398
The fault is again in add.c, not in snd-xform. Change line 405 to:and analogously at line 650:Code: Select all
susp->s1->get_next == SND_get_next && susp->s1->stop == MAX_STOP &&Those changes will have the effect of disabling some "optimizations" in snd-add for more structure sharing, which were applied incorrectly to sounds that were shortened by snd-xform: the shortening was ignored and the underlying sound sequence copied to its physical stop. A better fix might be written that does not sacrifice sharing in this case, but it would not be as simple.Code: Select all
susp->s2->get_next == SND_get_next && susp->s2->stop == MAX_STOP &&
To see the bug, generate 1 second of a 100Hz wave, do this in Nyquist prompt:Whereas if you change the result to (sum s1 s2 s3), you get a different (and correct) result, which should just be three isolated samples of the original wave.Code: Select all
(defun extract-global (snd start end) (let* ((t0 (snd-t0 snd)) (result (shift-time (snd-xform snd (snd-srate snd) t0 start end 1.0) start))) result)) (let* ( (s1 (extract-global s 0.5 0.51)) (s2 (extract-global s 0.6 0.61)) (s3 (extract-global s 0.7 0.71)) ) (sum s3 s2 s1) )