Lots of improvements for ofxPDSP (addon for synthesis and generative music)


#21

i think i will deprecate some methods when i have time, deprecated methods will stay a lot in the code for backward-compatibility anyway but at least they will trigger a warning.

As rule a class has in_pitch() is when the input is in semitones and in_freq() when the input is in hertz, EQ and basic building blocks have in_freq(), musical oscillators and filters have in_pitch().


#22

reply to that answer of yours earlier in this thread…

std::vector<pdsp::PatchNode*> nodes;

thanks for that insight… still have problems getting it to work… maybe you can post a simple example?
anyway… great work… thanks for this amazing addon…


#24

are you talking about resizing the vector in realtime, using pointers? maybe it can be done even safer than what i wrote, by using c++ smart pointers


#25

hi nicola…
thanks for your quick reply…
exactly… resizing vectors in realtime… referring to your answer from september '18… did not manage to post my reply right below…
i try to use your addon for an interactive installation where soundobjects can be added during runtime… so like everytime you click the mouse a new node (with a little higher pitch) is created… sounds are then triggered by a moving scanline… or contours from the kinect…
still learning/figuring out your examples…


#26

to add or remove objects by pdsp in realtime you should use pointers as i stated above, but it would be hard to me to explain it to you if you don’t know about pointers and allocating / deallocating memory in c++. Have you already read this chapter of the ofBook?
https://openframeworks.cc/ofBook/chapters/memory.html


#27

i did read the chapter about memory as you already recommended this earlier… but i have to admit that i’m not considering myself as such an advanced programmer to fully understand this topic… specially the last chapter about smart pointers gets a little confusing…


#28

it is a bit confusing because it tries to explain why using raw pointers is such a bad move, but i still have to study smart pointers so i couldn’t explain it better ( it’s in my TODO list ). Anyway you can do the same with raw pointers, when a new object is needed you allocate with

  yourvector.push_back( new YourObject() ); 

and when is not needed anymore you have to rememeber to delete it, otherwise you will leak memory:

    delete yourvector.back();
    yourvector.resize( yourvector.size() -1 );

#29

also: if you are making this to play a new note each time the mouse is clicked, this wouldn’t be the best solution, allocating and deallocating memory is a really expensive operation for the computer, in that case allocate a reasonable number of voices in advance and then use the mouse click to trigger on/off the envelope of one of the voices


#30

thanks a lot…
right now re-reading the memory chapter again…
also checking your example_basics5_channels and probably use this as a starting point…
is there a maximum of voices playing at the same time you recommend? does this depend on the computers memory?
specially when the code should also work on a rPi…
or is the number of voices related to the soundcard used?


#31

the number of voices that can play together is related mostly to the cpu and to the complexity of the voice architecture. The number of available voices can be a lot higher and it is only bound by memory (as each voice allocate memory for the buffers). I think the best solution would be anyway to have different voices and to trigger them on/off with by having a pdsp::TriggerControl" connected to the trigger input of apdsp::ADSR` controlling the voice amp

    triggerControl >> adsr.in_trig();
                      adsr >> amp.in_mod();
               voicesignal >> amp;

everything in your class, you can use triggerControl.trigger(1.0f) to trigger the voice and triggerControl.off() or triggerControl.trigger(0.0f) to release the voice, and then you have control about the fade in and fade out of the voice with the adsr attack and release inputs.


#32

still working on the vector issue…
i tried both in .h…

std::vector<pdsp::PatchNode*> nodes;
std::vector <shared_ptr<pdsp::PatchNode> > nodes;

in combination in .cpp…

shared_ptr<pdsp::PatchNode> n = shared_ptr<pdsp::PatchNode>(new pdsp::PatchNode);
nodes.push_back(n);

for(size_t i = 0; i < nodes.size(); i++){
	pitches[i] >> oscillators[i].in_pitch();
	oscillators[i].out_saw() >> amps[i] >> nodes[i];
	pitches[i].set(36 + 8*i);
	amps[i].set(0.1f);
}

but the compiler (xcode) doesn’t like this…
how would i combine this >> operator used in ofxPDSP with -> for pointers?

if i do…

pdsp::PatchNode node;

for(size_t i = 0; i < nodes.size(); i++){
	pitches[i] >> oscillators[i].in_pitch();
	oscillators[i].out_saw() >> amps[i] >> node;
	pitches[i].set(36 + 8*i);
	amps[i].set(0.1f);
}

it compiles… but crashes most of the time when i add a 2nd object… for some strange reason it works sometimes… which is even more confusing…


#33

wait, the best thing you can do is to make a class that is representing your whole voice (like in some pdsp examples, like the polysynth one), patching all the things for each voice is doable but it is a bad design.

To access a pointer to pdsp::PatchNode for patching you should use the dereference operator, so

*(nodes[i])

instead of

nodes[i]

#34

awesome… that does the trick…
thanks a lot…