Skip to content

Lesson 2: set(), triggers and meter_()

Nicola Pisanti edited this page Apr 10, 2016 · 23 revisions

In this lesson we will learn about more basic functions. We will start again from an empty example. First we need to declare some modules we will use:

    // pdsp modules
    ofxPDSPEngine engine; 

    pdsp::PRNoiseGen noise;
    pdsp::Amp amp;
    pdsp::TriggerControl gate;
    pdsp::ADSR env;

now in the ofApp.cpp code:

void ofApp::setup(){
    ofSetWindowShape(640, 360); // we don't need fancy graphics at the moment

    //--------PATCHING-------
   0.0f  >> amp.in_mod();
   noise >> amp >> engine.audio_out(0);
            amp >> engine.audio_out(1);

    //------------SETUPS AND START AUDIO-------------
    engine.listDevices();
    engine.setDeviceID(0); // REMEMBER TO SET THIS AT THE RIGHT INDEX!!!!
    engine.setup( 44100, 512, 3); 
}

void ofApp::mousePressed(int x, int y, int button){
    0.25f >> amp.in_mod();
}

void ofApp::mouseReleased(int x, int y, int button){
    0.0f >> amp.in_mod();
}

Compile and run. Now if you click on the app window you should hear a some noise, and silence again when you release the mouse. pdsp::Amp, in our case amp has two input: in_mod() and in_signal(). in_signal() is the default input. The signal input is multiplied for the mod input. You can learn more on why 'pdsp::Amp' inputs have different functions in the documentation.

Anyway a 0/1 control for the amp volume is not the best, we could use the help of an envelope. Change the app code:

void ofApp::setup(){
    ofSetWindowShape(640, 360); // we don't need fancy graphics at the moment

    //--------PATCHING-------
    gate.out_trig() >> env.set(0.0f, 70.0f, 0.3f, 700.0f);
                       env * 0.5f >> amp.in_mod();
                            noise >> amp >> engine.audio_out(0);
                                     amp >> engine.audio_out(1);

    //------------SETUPS AND START AUDIO-------------
    engine.listDevices();
    engine.setDeviceID(0); // REMEMBER TO SET THIS AT THE RIGHT INDEX!!!!
    engine.setup( 44100, 512, 3); 
}

void ofApp::mousePressed(int x, int y, int button){
    gate.trigger(1.0f);
}

void ofApp::mouseReleased(int x, int y, int button){
    gate.off();
}

Compile and run. Now if you click on the app window you should hear a snappy burst of noise, when you release the mouse the noise fade outs to zero in precisely 700ms. pdsp::ADSR is an Attack-Decay-Sustain-Release envelope, and it needs an out_trig() patched to its in_trig() (that is also the default input). pdsp::TriggerControl is an object with an out_trig() that can be controlled with thread-safe functions (the ones we have put into the mouse oF functions).

Sometimes in pdsp there are some outputs that should be connected only to output with the same name. If you're not planning on making your own oscillator modules you will mostly just remember about out_trig() and in_trig(). If an input requires an output with a matching name it is specified in the documentation.

Also we have used the set() method of pdsp::ADSR. Set methods let you choose some default values for a module, and sometimes also some extra variables, and return the module ready to be patched so you can use a set() function with a module in a chain. Remember that patching something to an input, even a float number, will disable those default values. In our case we are setting env's in_attack(), in_decay(), in_sustain(), in_release() default values, but gate.out_trig() is being patched to in_trig() (the default input for env).

Some modules have also some meter_____() functions. Those functions returns a value that usually it's updated once for every process() call and they are a thread-safe way of monitoring modules values. For example pdsp::ADSR has a meter_output() function that gives a value in the 0.0f-1.0f range. Add this to our code:

void ofApp::draw(){
    ofBackground( env.meter_output() * 255 );
}

now compile and run. When you click you should see a white flash, and the grey background will fade to black when you release the mouse button.

Last thing: some modules are sensible to the input values you give as trigger. Usually you should use values in the 0.0f > x >= 1.0f range. Lower values will scale the envelope output, so try to change the code like this:

void ofApp::mousePressed(int x, int y, int button){
    float trig = ofMap(y, 0, ofGetHeight(), 1.0f, 0.0f);
    gate.trigger(trig);
}

now compile and run. Now clicking lower in the window will produce sounds with lower amplitude (and darker window flashes).

As usual you can find this lesson code in the lessons repo.