Threads and debug/release modes


#1

Hey, i'm writing a synth that generates audio waves from modulated bézier paths. At a certain interval of samples the class that handles the wave generation recalculates a wavetable from the bézier path with the current modulation values (supplied by envelopes or lfos). The update function looks something like this:

void update(double mod[]) {

    x_sections.clear();
    y_sections.clear();
    
    ValueTree current = pathData.getChild(0);
    ValueTree next = current.getSibling(1);
    
    while(next != ValueTree::invalid) {
        x_sections.push_back (makeSectionX(current, next, mod));
        y_sections.push_back (makeSectionY(current, next, mod));
        current = next;
        next = current.getSibling(1);
    }
    next = pathData.getChild(0);
    x_sections.push_back (makeSectionX(current, next, mod));
    y_sections.push_back (makeSectionY(current, next, mod));

    // calculate the paths current legth
    double arclen = 0;
    for(int i=0; i<x_sections.size(); i++) {
        arclen += getArcLength(x_sections[i], y_sections[i]);
    }

    // calculate wavetable
    double step = arclen/512.0;
    for(double i=0; i<512; i++) {
        (*buffer)[i] = getNextValueNormalized(step);
    }
 }

This gets called from the audio callback of the corrosponding SynthesizerVoice every 1024 samples. Now when i run this in debug mode, everything crackles terribly and i never get a clean signal. Yesterday i tried using the profiler that comes with xcode to do some optimisation and i thought i found the problem but as it turns out the code runs ok when i use the profiler and it also runs ok when i run it in release mode, but its too much for my cpu in debug mode. Now i have tree questions:

1. Is it normal that there is such an extreme difference between debug and release modes? (in debug my macbook can hardly handle one voice while in release it playes 4 voices with around 10-20% of the cpu beeing used).

2. Is it a good idea to call this update function from the audio-thread oder would it be wiser to call it from a timer or something like that? I'm relatively new to programming audio and especially to the thread related topics..

3. If i wanted to push the updated wavetable information to the UI, would the AsyncUpdater be a good option for that?

Thank you all for you time!


#2

ValueTrees are not real-time classes! They send out all kinds of callbacks and use the message thread, you can't use them in an audio callback. Nor is the audio callback a place to be worrying about graphics - you should just push the raw data into some kind of low-level lock-free container and let your UI thread deal with it later.


#3

As newbie i appreciated that blog, a good introduction for Real-Time peculiarities :

( http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing ).

HTH. 


#4

Thank you both for your replies!

That blog post was very helpful. The main problem turned out to be in the function that recursively calculated the n-th curve derivative. I used std::vector to store the control-point coordinates and passed the updated values down to the next derivative. The memory allocation in std::vector seems to have been the problem. Now i implemented seperate functions for first and second derivative without passing anything around and it works way faster.

Just out of interest, how would i go about implementing something like the recursive derivative calculation for realtime use? Maybe doing it in a for-loop instead and working on the same array? Would i be ok to use std::vector as long as i don't allocate memory by using push_back or anything like that? Or would you recommend using plain arrays instead?