using UGen++ outside of JuceIOHost context

17 views
Skip to first unread message

Karsten Gebbert

unread,
Apr 30, 2012, 4:49:16 PM4/30/12
to UGen++
Hi!

I just discovered the project and am trying to build some simple
plugins using juce. Since I am a c++ beginner, I have slight troubles
understanding how UGen++ is meant to be used in a context which
doesn't make use of JuceIOHost for initialisation. What I'd like to
achieve fr now is to simply generate some noise and write it to the
out buf of a vst for a test. I assume I'll have to set up a Plug::AR
and pass it a ugen graph just like JuceIOHost passes it on with
constructGraph and call prepareAndProcessBlock on it for each block of
samples. Is this correct? D o I also need to call pre- and postTick
and pass on a blockID (and what for)? A simple outline of the process
could look like this I guess:

UGen::initialise();
UGen::prepareToPlay(currentSampleRate(), currentBufferSizeSamples());
UGen sin = SinOsc::AR(400);
Plug output = Plug::AR(UGen::emptyChannels(numOutputs_), false);
output.setSource(sin, true, 0.005f);
output.setOutputs(outBuffer, numSamples, numOutputChannels);
....
output.prepareAndProcessBlock(.....);
....

Does that look about ok? Experimentation has gotten me quite far, but
I can't hear anything yet :)


Cheers,

karsten

Martin Robinson

unread,
May 1, 2012, 5:07:08 AM5/1/12
to uge...@googlegroups.com
Hello

Have you seen the UGenPlug and UGenInstrument projects in /examples ? These are Juce-based plug-ins being an effect and synth respectively.

Also it would be useful to know:
- what platform you are on (Mac, Windows) and which OS version
- what version of Juce you are using
- what version of UGen++ you are using (svn or zipped download release)

Regards
Martin

Sent from my iPhone

Karsten Gebbert

unread,
May 1, 2012, 5:16:44 AM5/1/12
to UGen++


On 1 Mai, 11:07, Martin Robinson <0x4...@gmail.com> wrote:
> Hello
>
> Have you seen the UGenPlug and UGenInstrument projects in /examples ? These are Juce-based plug-ins being an effect and synth respectively.
>

Woops, shame on me, didn't notice them. Thanks for the hint! Exactly
what I needed..

> Also it would be useful to know:
> - what platform you are on (Mac, Windows) and which OS version

Arch Linux actually

> - what version of Juce you are using

git, contains quite a few important fixes over 2.0

> - what version of UGen++ you are using (svn or zipped download release)
>

the svn version actually.


> Regards
> Martin
>
> Sent from my iPhone
>

Martin Robinson

unread,
May 1, 2012, 8:40:07 AM5/1/12
to uge...@googlegroups.com
Ok. I'll need to check everything against the Juce git version especially the plug-in stuff.

Martin

Sent from my iPhone

Karsten Gebbert

unread,
May 2, 2012, 4:29:55 PM5/2/12
to UGen++
Hey!

I managed to make it work, a filter type plugin using the examples as
a base! Really nice, looking forward to diving more into this neat
toolkit (and possibly closing some of the wide gaps in my
unfortunately otherwise rather thin linux-vst arsenal).

I do have a question or two though: how does the voicing work exactly
in the instrument example? The processBlock sends the "voicerUGen"
midi messages which calls on the spawnEvent member? Not sure I
understand it quite yet. Secondly, one big thing I'm interested in is
building filters plugins like the PV UGens in SC. I see there are FFT
base classes which also use fftw, so I should be able to get it
working on linux, but what structure could a PV ugen take if I were to
attempt to re-create them for use with your FFT classes? I suppose, it
would probably boil down to processing a buffer with phases &
magnitudes, but there is most likely more to it than I think now :)
Any hints appreciated...

Cheers,
karsten

On 1 Mai, 14:40, Martin Robinson <0x4...@gmail.com> wrote:
> Ok. I'll need to check everything against the Juce git version especially the plug-in stuff.
>
> Martin
>
> Sent from my iPhone
>

Martin Robinson

unread,
May 3, 2012, 2:43:13 AM5/3/12
to uge...@googlegroups.com
Hello,

> I managed to make it work, a filter type plugin using the examples as
> a base! Really nice, looking forward to diving more into this neat
> toolkit (and possibly closing some of the wide gaps in my
> unfortunately otherwise rather thin linux-vst arsenal).

Great! You're the first I'm aware of that definitely has it running on Linux. Good to know it works with the current Juce too, although I have been using the modules version I haven't officially moved to that version for UGen++.


> I do have a question or two though: how does the voicing work exactly
> in the instrument example? The processBlock sends the "voicerUGen"
> midi messages which calls on the spawnEvent member? Not sure I
> understand it quite yet.

Yes, each time a new voice is requested (from a key press) this calls spawnEvent() in your custom event class which should return a UGen (this is then linked to the MIDI note that created it). This gets added to an array of live UGens in the voicer. When a key is released, the UGen linked to the relevant MIDI note is released (this relies on your UGen returned from spawnEvent() using an Env that is releasable like End::adsr),


> Secondly, one big thing I'm interested in is
> building filters plugins like the PV UGens in SC. I see there are FFT
> base classes which also use fftw, so I should be able to get it
> working on linux, but what structure could a PV ugen take if I were to
> attempt to re-create them for use with your FFT classes? I suppose, it
> would probably boil down to processing a buffer with phases &
> magnitudes, but there is most likely more to it than I think now :)

Yes, have a look in the UGen/convolution folder there is a partitioned convolution UGen (a bit like the SC one although I used different code). There's also a very sketchy SimpleConvolution UGen that just does cross-synthesis of two sources. You need to enable the convolution features with the preprocessor flag UGEN_CONVOLUTION=1.

You should be able to just use the supplied FFTReal library but fftw will be faster (although tricker to get linking etc).


> Any hints appreciated...


I'm actually in the middle of a fairly major ground-up re-write. The main reason for this is to separate it completely from SC in terms of the GPL license (only a handful of code was actually taken from SC but this means UGen++ has to be GPL).

The new project pl-nk and is here http://code.google.com/p/pl-nk/ but has no starter projects yet like UGen++ does. It has a BSD-style license (meaning it can be used in closed source commercial apps).

But through the redesign I've added features that will help support what you want to do. The most relevant change is that all units can run at any sample rate and block size (which is how kr vs ar works, but in UGen++ KR is generally no saving over AR). This means it was relatively straightforward to support having subgraphs that run a different rates and this is how you can have a kind-of "spectral rate" like SC does. So a "subgraph" would have an FFT unit at the top (taking some audio data in) and an IFFT unit at the bottom (transforming spectral data back to audio) then you could have your spectral processing in the middle. In pl-nk, blocks can even overlap in time so this makes overlapping FFT-based processing a possibility.

The API for pl-nk is like UGen++ so any transition in the future should be simple but some things will have been renamed etc. But it also (theoretically) supports any sample type rather than being locked to 32-bit floats. (Doubles should just work, but I'm hoping to allow support for int-based sample streams and possibly fixed point.)

Anyway, I hope to spend some more time on this in the summer.

Let me know if you hit any other problems.

Martin








Karsten Gebbert

unread,
May 8, 2012, 7:44:10 PM5/8/12
to UGen++


On 3 Mai, 08:43, Martin Robinson <0x4...@gmail.com> wrote:
> Hello,
>
> > I managed to make it work, a filter type plugin using the examples as
> > a base! Really nice, looking forward to diving more into this neat
> > toolkit (and possibly closing some of the wide gaps in my
> > unfortunately otherwise rather thin linux-vst arsenal).
>
> Great! You're the first I'm aware of that definitely has it running on Linux. Good to know it works with the current Juce too, although I have been using the modules version I haven't officially moved to that version for UGen++.

cool!

>
> > I do have a question or two though: how does the voicing work exactly
> > in the instrument example? The processBlock sends the "voicerUGen"
> > midi messages which calls on the spawnEvent member? Not sure I
> > understand it quite yet.
>
> Yes, each time a new voice is requested (from a key press) this calls spawnEvent() in your custom event class which should return a UGen (this is then linked to the MIDI note that created it). This gets added to an array of live UGens in the voicer. When a key is released, the UGen linked to the relevant MIDI note is released (this relies on your UGen returned from spawnEvent() using an Env that is releasable like End::adsr),
>

thanks for the explanation, it makes this quite a bit clearer!

> > Secondly, one big thing I'm interested in is
> > building filters plugins like the PV UGens in SC. I see there are FFT
> > base classes which also use fftw, so I should be able to get it
> > working on linux, but what structure could a PV ugen take if I were to
> > attempt to re-create them for use with your FFT classes? I suppose, it
> > would probably boil down to processing a buffer with phases &
> > magnitudes, but there is most likely more to it than I think now :)
>
> Yes, have a look in the UGen/convolution folder there is a partitioned convolution UGen (a bit like the SC one although I used different code). There's also a very sketchy SimpleConvolution UGen that just does cross-synthesis of two sources. You need to enable the convolution features with the preprocessor flag UGEN_CONVOLUTION=1.
>
> You should be able to just use the supplied FFTReal library but fftw will be faster (although tricker to get linking etc).d
>

I put together a bare bones project that builds using UGEN_FFTW=1 and
UGEN_CONVOLUTION=1 and actually loads in a vst host, although without
doing anything useful just yet (I don't often find time to sit down
and fiddle with this..). Quite nice! It does post "FFTEngine using
FFTW" in the hosts log output, so I'm fairly sure its working. The
only thing I couldn't figure out (which is arguably not that
important) is how to statically link fftw, but hey... here is a little
patch with all the changes I made for your reference https://gist.github.com/2640417
- not much, and I re-used the LINUX=1 pre-processor directive that
comes with juce for singling out these includes.

> > Any hints appreciated...
>
> I'm actually in the middle of a fairly major ground-up re-write. The main reason for this is to separate it completely from SC in terms of the GPL license (only a handful of code was actually taken from SC but this means UGen++ has to be GPL).
>
> The new project pl-nk and is herehttp://code.google.com/p/pl-nk/but has no starter projects yet like UGen++ does. It has a BSD-style license (meaning it can be used in closed source commercial apps).

nice! I had actually noticed it but not actually played with the code
as it seemed less complete than UGen++, so to speak. Now it all makes
sense ;)

> But through the redesign I've added features that will help support what you want to do.  The most relevant change is that all units can run at any sample rate and block size (which is how kr vs ar works, but in UGen++ KR is generally no saving over AR). This means it was relatively straightforward to support having subgraphs that run a different rates and this is how you can have a kind-of "spectral rate" like SC does. So a "subgraph" would have an FFT unit at the top (taking some audio data in) and an IFFT unit at the bottom (transforming spectral data back to audio) then you could have your spectral processing in the middle. In pl-nk, blocks can even overlap in time so this makes overlapping FFT-based processing a possibility.

One question I do have regarding the format of fft buffers FFTEngine
will be juggling around: I read here and there (in the SC sources for
example) that the fft buffer contains some padding and/or DC and
Nyquist somewhere at the beginning and end of the buffer, I'd like to
ask for a quick note on how it is structured in your Code. Anyways,
I'm excited about the project, new and old and learning more about it
all.

> The API for pl-nk is like UGen++ so any transition in the future should be simple but some things will have been renamed etc. But it also (theoretically) supports any sample type rather than being locked to 32-bit floats. (Doubles should just work, but I'm hoping to allow support for int-based sample streams and possibly fixed point.)
>

.. meaning it could be built to work on processors without FPU? mmm
interesting!

Thanks!

karsten

Martin Robinson

unread,
May 10, 2012, 2:18:39 AM5/10/12
to uge...@googlegroups.com

On 9 May 2012, at 00:44, Karsten Gebbert wrote:
>
> I put together a bare bones project that builds using UGEN_FFTW=1 and
> UGEN_CONVOLUTION=1 and actually loads in a vst host, although without
> doing anything useful just yet (I don't often find time to sit down
> and fiddle with this..). Quite nice! It does post "FFTEngine using
> FFTW" in the hosts log output, so I'm fairly sure its working. The
> only thing I couldn't figure out (which is arguably not that
> important) is how to statically link fftw, but hey... here is a little
> patch with all the changes I made for your reference https://gist.github.com/2640417
> - not much, and I re-used the LINUX=1 pre-processor directive that
> comes with juce for singling out these includes.

So is LINUX=1 defined on Linux builds or just under Juce? (Sorry I really should know this stuff but have just never got round to a Linux install...)

I guess the static linking of FFTw is a general issue rather than specific to UGen++? Again not sure on Linux, I can't even remember how I tested this on Mac and Windows but I suspect it was statically linked as mixing static and dylibs on Windows can be a pain due to the different runtime libs you need to use in each context.

I'll reply to your second post..


>> But through the redesign I've added features that will help support what you want to do. The most relevant change is that all units can run at any sample rate and block size (which is how kr vs ar works, but in UGen++ KR is generally no saving over AR). This means it was relatively straightforward to support having subgraphs that run a different rates and this is how you can have a kind-of "spectral rate" like SC does. So a "subgraph" would have an FFT unit at the top (taking some audio data in) and an IFFT unit at the bottom (transforming spectral data back to audio) then you could have your spectral processing in the middle. In pl-nk, blocks can even overlap in time so this makes overlapping FFT-based processing a possibility.
>
> One question I do have regarding the format of fft buffers FFTEngine
> will be juggling around: I read here and there (in the SC sources for
> example) that the fft buffer contains some padding and/or DC and
> Nyquist somewhere at the beginning and end of the buffer, I'd like to
> ask for a quick note on how it is structured in your Code. Anyways,
> I'm excited about the project, new and old and learning more about it
> all.

Yes it's the same format as Apple's vDSP where the data is packed to remove the imaginary parts of the DC and Nyquist (as they're always zero) as this results in output data the same size as the input. It's also effectively the same format as FFTReal. There's a brief note in ugen_FFTEngineInternal.h lines 172-186. So, if your FFT size was 8 the first five values would be real parts of bins 0-4 then the next three values would be the imag parts of bins 1-3. Or as Apple document it, if you think of the real and imag as two separate arrays then the real Nyquist value is packed into the imag slot for the DC bin (bin 0). Equates to the same thing.
http://developer.apple.com/library/ios/#documentation/Performance/Conceptual/vDSP_Programming_Guide/UsingFourierTransforms/UsingFourierTransforms.html

Martin

Martin Robinson

unread,
May 10, 2012, 2:42:02 AM5/10/12
to uge...@googlegroups.com
OK, I've just committed some pending local changes I had sitting on my working copy. I'll need to unpick your diffs to merge the changes as there were minor changes in some of those files...

Martin
Reply all
Reply to author
Forward
0 new messages