PG8X (inspired by the JX8P): new beta version uploaded

VST, AU, AAX, CLAP, etc. Plugin Virtual Instruments Discussion
Locked New Topic
RELATED
PRODUCTS
pg-8x

Post

martin_l wrote: There is a tiny amount of noise I added on top of the filter and chorus noise. This is basically to avoid the denormals. The noise should be at about -120 dB and should always be there (the constant noise floor of the hardware is somewhere around -70, if I remember right).

What is strange, though, is that is seems to disappear when a voice is active. Something is definitely not quite right. I will look at it.

Martin
Your denormals will typically only come from the IIRs (the filters). Unless you're performing some kind of true reverse exponential decay on the filters (which I doubt you are as it wouldn't be faithful to how the original's digital envelopes worked).

So it doesn't really make sense to fill silence between notes with noise for that purpose. (I assume your voices stop executing once their envelopes have run out, right? Otherwise the CPU load would be constant instead of increasing with the number of played voices, as it does.) And self-noise, while certainly an artifact of the original hardware, typically isn't something we model in software. Even in faithful emulations. VOICE noise (like your Filter Noise feature) sure, I can see doing that. And yeah, if you want to hear the constant hiss of the chorus you could add that too. But with Chorus off and no voices active, I don't see much value in adding noise to the signal. (If anyone wanted that they could just mix it in from another source.) If I did implement something like that I'd certainly provide an option to turn it off.

I cured the denormal problem in Poly-Ana by applying a very tiny DC offset to the filter inputs. No noise (and no extra CPU load from calculating the noise) necessary.

Post

AdmiralQuality wrote:
martin_l wrote: There is a tiny amount of noise I added on top of the filter and chorus noise. This is basically to avoid the denormals. The noise should be at about -120 dB and should always be there (the constant noise floor of the hardware is somewhere around -70, if I remember right).

What is strange, though, is that is seems to disappear when a voice is active. Something is definitely not quite right. I will look at it.

Martin
Your denormals will typically only come from the IIRs (the filters). Unless you're performing some kind of true reverse exponential decay on the filters (which I doubt you are as it wouldn't be faithful to how the original's digital envelopes worked).

So it doesn't really make sense to fill silence between notes with noise for that purpose. (I assume your voices stop executing once their envelopes have run out, right? Otherwise the CPU load would be constant instead of increasing with the number of played voices, as it does.) And self-noise, while certainly an artifact of the original hardware, typically isn't something we model in software. Even in faithful emulations. VOICE noise (like your Filter Noise feature) sure, I can see doing that. And yeah, if you want to hear the constant hiss of the chorus you could add that too. But with Chorus off and no voices active, I don't see much value in adding noise to the signal. (If anyone wanted that they could just mix it in from another source.) If I did implement something like that I'd certainly provide an option to turn it off.

I cured the denormal problem in Poly-Ana by applying a very tiny DC offset to the filter inputs. No noise (and no extra CPU load from calculating the noise) necessary.

In fact, the VCF's don't have a denormal problem, as they are sitting before the VCA and always have non-denormal input. The filter noise, which I add (and which can be switched off) is actually quite important for some typical JX8P sounds.

The other noise, I was talking about is to eliminate denormals in the anti-aliasing filter. Currently (and I plan to improve on that) this filter, which acts on the total signal of all voices, is constantly running. This "denormal-noise" is not meant to be audible, and I am sure I could decrease the level even further.

I might revert back to a DC offset (which I was using in previous versions), but I am not yet convinced that it helps, as my filter implementation has terms which are the difference between delayed signals. I still have to convince myself, that these differences are not going to 0 for constant input, which again might give rise to denormals.

Adding the noise does not cost me any extra CPU time, as I am using the same noise signal, which was added for chorus noise anyway.

But, as I said earlier, something is still wrong, as this "denormal noise" should not vanish if a voice is active. What you see (and I have confirmed that as well) might indeed have a different origin.

Cheers,
Martin

Post

Ah, wasn't thinking of a post-proc AA filter. IIR, eh? Interesting. (Though even that shouldn't need to run during silence, should it?) The DC offset trick will still work for that, I'd think.

There are also CPU flags that can be set to inhibit denormal-ing, but I've had some trouble getting them to work consistently. Also, my current CPUs never seem to denormal, where my old ones did all the time, so it's become something that's hard to test.

https://software.intel.com/sites/produc ... 6061C7.htm

Post

It's quite obvious that pics from an actual PG were used for both knobs and sliders.

I also feel that these need to be redone completely in digital realm, no image manipulation. :)

Post

EvilDragon wrote:It's quite obvious that pics from an actual PG were used for both knobs and sliders.

I also feel that these need to be redone completely in digital realm, no image manipulation. :)
Actually, the knob graphics appear to have smaller tops and be of an overall smaller diameter relative to the rest of the interface, vs. the real knobs.

Problem with the original knobs is the only aspect of them that rotates is the dot. The rest is perfectly smooth and circular, and so will look exactly the same at whatever rotation angle, and to reproduce that would be perceived as lacking by some who expect more animation.

Anyway, I'm sure somebody can whip something up in Knobman that's very close to the existing one but is more tidy looking. (I don't have an issue with the sliders, they look fine to me.)

Post

I have an issue with the sliders. The slider groove looks kinda jagged and "dirty" and irregular. This could be done nicer with an actual render.

Post

AdmiralQuality wrote:
EvilDragon wrote:It's quite obvious that pics from an actual PG were used for both knobs and sliders.

I also feel that these need to be redone completely in digital realm, no image manipulation. :)
Actually, the knob graphics appear to have smaller tops and be of an overall smaller diameter relative to the rest of the interface, vs. the real knobs.

Problem with the original knobs is the only aspect of them that rotates is the dot. The rest is perfectly smooth and circular, and so will look exactly the same at whatever rotation angle, and to reproduce that would be perceived as lacking by some who expect more animation.

Anyway, I'm sure somebody can whip something up in Knobman that's very close to the existing one but is more tidy looking. (I don't have an issue with the sliders, they look fine to me.)
I assume you are talking about the knobs in the current beta versions (non-SynthEdit). The old knobs were simply rotated images. The new knobs are re-done in KnobMan. I agree that they need some more work to smooth things out.

Actually, it is not only the dot which rotates, but also the underlying bitmap is rotating (hence the artefact, just opposite to the red/green dot. This artefact clearly still has to be removed. But I first want to get the functionality working, before returning to details of the GUI.

Cheers,
Martin

Post

EvilDragon wrote:I have an issue with the sliders. The slider groove looks kinda jagged and "dirty" and irregular. This could be done nicer with an actual render.
I guess it is a matter of taste. For my taste, I would not want 100% clean images. Even if rendering them digitally, I would try to make them look a bit irregular.

For this GUI, I want the "photo-realistic" look. Once the whole thing is finished, I will look into what is required to make a plugin skinnable, then it is up to every user to choose their own skin. But that _might_ happen only at a later stage. There are many other things I need to sort out before that...

Martin

Post

layzer wrote:Image
i made a special, lighter "Brushed aluminum" GUI version for PG8X.

my desire was to make all sections aluminum, but some of the control labels on the right hand side
do not have a font color that can be changed via png manipulation. so i just made it 2-toned.
looks kinda cool that way, i think.

I'll release a skin bitmap pack if i get an OK from Martin.
Awesome skin Layzer :tu: :clap: would love to see it like that.
:tu: All is good

Post

AdmiralQuality wrote:Here's a weird one, Martin.

I just put it up on an oscilloscope to take a look at what the "pulse" waveform looks like and I noticed, when PG-8X first instantiates, it produces noise output. (I can't hear it, but I clearly see it in the 'scope.) This stops as soon as I play the first note.

This is with the default INIT patch/bank loaded. Just the simple open filter, single sawtooth sound. Chorus Noise is off. Filter Noise is at the default (mid) position, but of course we shouldn't be hearing a filter as the gates and envelopes should (you'd think) instantiate to a closed state.

Oh wait, it came back! About 30 seconds after the last note ends (regardless of whether VCA is in Env or Gate mode) the noise comes back. It looks rather low frequency and again, I can't readily hear it, but it must be there as it disappears from the 'scope as soon as I bypass or remove PG-8X.

Certainly not a show-stopper, but weird and possibly indicative of another issue?

Image

I think, what you see is an artefact of the JS gfxscope.

With that scope, I can reproduce it, but with no other scope plugin.
If you open the edit pane of the scope, you see what happens: When there is silence, the values oscillate randolmy (due to the de-normal noise) between something like 224.999990 and 225.0000001. gfxscope seems to have implemented a simple truncation to integer when plotting, hence the wiggly line.

Why does it not show up just after releasing a note? Due to the asymmetry of the wave functions, there is a tiny DC offset, which only slowly dies to 0 (in the anti alias filter). Only when this bias falls below the level of the denormal noise, you start seeing the noise in the scope. If the noise falls into the range 225.000001 to 225.000002, you don't see it.

So, everything seems fine (apart from the other bugs...)

Cheers,
Martin

Post

If you someday decide to implement 'snap' sliders you can look at my class for WDL/IPlug here http://forum.cockos.com/showthread.php?t=130245 which i made when i was interested in programming :dog: .

Image

Post

tico-tico wrote:If you someday decide to implement 'snap' sliders you can look at my class for WDL/IPlug here http://forum.cockos.com/showthread.php?t=130245 which i made when i was interested in programming :dog: .

Image
Thats cool.

If i was in Martins place i would definitely use this.


BTW, Martin, is the UI layout final or do you intend to change any of the element sizes and positions?

PG8X would be a nice project. :)

Post

A more generic way to do this:

Code: Select all

// No denormal in SSE ( prior to loop)
const int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting
const int newMXCSR = oldMXCSR | 0x8040; // set DAZ and FZ bits
_mm_setcsr( newMXCSR ); //write the new MXCSR setting

// return flag in SSE (post loop, don't forget this part - the flags are sticky)
_mm_setcsr( oldMXCSR ); // restore old mode 
Just to note, for 64bit your compiler will default to using the SSE unit, for 32bit it may use the x87 unit - so you have to change it ( in gcc this is -mfpmath=sse). I prefer the above method, simple/clean and costs nothing.

As for global noise, I prefer it gated(or at least the option to do it). Simply because some(most?) effects plugins require either silence or a very low signal to deactivate(sleep). So the synth might create some unnecessary downstream CPU consumption in real-life usage.

This is a great synth, and the quality versus CPU ratio usage is... :clap:

Regards
Andrew

Post

Ichad.c wrote:
A more generic way to do this:

Code: Select all

// No denormal in SSE ( prior to loop)
const int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting
const int newMXCSR = oldMXCSR | 0x8040; // set DAZ and FZ bits
_mm_setcsr( newMXCSR ); //write the new MXCSR setting

// return flag in SSE (post loop, don't forget this part - the flags are sticky)
_mm_setcsr( oldMXCSR ); // restore old mode 
Just to note, for 64bit your compiler will default to using the SSE unit, for 32bit it may use the x87 unit - so you have to change it ( in gcc this is -mfpmath=sse). I prefer the above method, simple/clean and costs nothing.

As for global noise, I prefer it gated(or at least the option to do it). Simply because some(most?) effects plugins require either silence or a very low signal to deactivate(sleep). So the synth might create some unnecessary downstream CPU consumption in real-life usage.

This is a great synth, and the quality versus CPU ratio usage is... :clap:

Regards
Andrew
Hi Andrew,

at which point, exactly, would you have to insert this code? At every entry and exit point to a routine, using SSE math? Or does it persist, and you can set it somewhere in the constructor, or initialisation routines?

As for the gating, I will do that. In fact, I am planning to implement a sleep for the downsampler, when all voices are sleeping. Just have not done it yet.
I do have the information on every voice whether it is active or sleeping; I just need to sum them up to get information on whether all are asleep, and then stop the whole engine.

This will be done after I find that nasty voice-cutting bug. ENV1 sent me a MIDI file (without overlapping notes) which does produce the effect, albeit for me only about once in ten loops of the file. I have a suspicion, but need more detailed debugging sessions to confirm it ....


Cheers,
Martin

Post

martin_l wrote: Hi Andrew,

at which point, exactly, would you have to insert this code? At every entry and exit point to a routine, using SSE math? Or does it persist, and you can set it somewhere in the constructor, or initialisation routines?
Global Constructor/Destructor should be fine, it does persist - hence why they call it a 'sticky' flag, returning the state is just good coding practice. Only set it once, and return it once. All 64bit code is SSE math(because by default it uses the SSE fp unit) - just not vectorized. That's why setting the compiler flags to "-mfpmath=sse" with 32bit code is important, otherwise it uses the x87 floating point unit.
martin_l wrote: As for the gating, I will do that. In fact, I am planning to implement a sleep for the downsampler, when all voices are sleeping. Just have not done it yet.
I do have the information on every voice whether it is active or sleeping; I just need to sum them up to get information on whether all are asleep, and then stop the whole engine.
That would be the cherry on the cake. Btw, did you ever get the 'exporting patches' form old to new version thing sorted? (I'm on the SE usergroup too btw). That seems like a real pita.

Locked

Return to “Instruments”