Temper from Creative Intent (Digital distortion plugin, VST, VST3, AU).
-
- KVRist
- 35 posts since 1 Mar, 2017 from Boston, MA
Temper is a modern digital distortion plugin which combines a rich saturation curve and a unique phase distortion.
https://www.creativeintent.co/products/temper
Temper’s phase distortion offers unique harmonic excitement in the higher frequency components of your sound, bringing character and clarity to any element of your mix. And with a classic overdrive and versatile resonant lowpass pre-filter, Temper delivers a modern tone that brings an all new edge to your sound.
This is our first plugin, and the source code is available under GPLv3. We'd love to hear what you think, get in touch!
https://www.creativeintent.co/products/temper
Temper’s phase distortion offers unique harmonic excitement in the higher frequency components of your sound, bringing character and clarity to any element of your mix. And with a classic overdrive and versatile resonant lowpass pre-filter, Temper delivers a modern tone that brings an all new edge to your sound.
This is our first plugin, and the source code is available under GPLv3. We'd love to hear what you think, get in touch!
-
- KVRAF
- 1791 posts since 17 Sep, 2002
Interesting... so someone could download your source code for free, compile it, and sell it themselves, legally?
-
- KVRist
- 137 posts since 22 May, 2017
I just tried the demo, and it seems to be one of the only distortion plugins I've come across that doesn't blur or muddy the low mids on vocals. Is there an explanation for this, or am I just crazy and hearing things?
EDIT: I just purchased it, because it's actually quite nice for $10. The only downside that jumps out at me is the lack of wet/dry control. I think the plugin would shine on parallel processing tracks like recieves/aux tracks, but that's difficult to do with no wet/dry controls. Thoughts?
EDIT: I just purchased it, because it's actually quite nice for $10. The only downside that jumps out at me is the lack of wet/dry control. I think the plugin would shine on parallel processing tracks like recieves/aux tracks, but that's difficult to do with no wet/dry controls. Thoughts?
-
- KVRist
- Topic Starter
- 35 posts since 1 Mar, 2017 from Boston, MA
@funky lime Indeed, someone could do that. To be frank, though, none of the algorithms I've used here are particularly new. Temper itself is novel but its internal algorithms are well known. So there's really not a lot to take and run away with in terms of reselling this. I think this move is more an opportunity to help new developers find resources and examples to help them start building plugins (because the barrier to entry, from my experience, is quite high). That's my intention with open sourcing the code, and I hope that the community receives it that way.
@BRBWaffles thank you! That's wonderful feedback. I suspect what you're hearing is due to that the saturation stage precedes the phase distortion stage– so when you saturate the low/mid range, you'll introduce harmonics that feed the mid/hi range of the phase distortion stage, which in turn delivers something of a harmonic excitement effect. So as you dial in the saturation, you'll also be getting a bit of clarity on the high end. I'm glad you noticed! I've been using it for parallel processing on vox as well.
As for the wet/dry suggestion, very happy to take that feedback. What host are you using? Most of the hosts I was testing in offered a bypass knob for effect slots, so I was setting the bypass at ~50% and adding gain or compression after Temper to simulate a wet/dry knob. But that's easy enough to add to the plugin itself.
@BRBWaffles thank you! That's wonderful feedback. I suspect what you're hearing is due to that the saturation stage precedes the phase distortion stage– so when you saturate the low/mid range, you'll introduce harmonics that feed the mid/hi range of the phase distortion stage, which in turn delivers something of a harmonic excitement effect. So as you dial in the saturation, you'll also be getting a bit of clarity on the high end. I'm glad you noticed! I've been using it for parallel processing on vox as well.
As for the wet/dry suggestion, very happy to take that feedback. What host are you using? Most of the hosts I was testing in offered a bypass knob for effect slots, so I was setting the bypass at ~50% and adding gain or compression after Temper to simulate a wet/dry knob. But that's easy enough to add to the plugin itself.
-
- KVRist
- 137 posts since 22 May, 2017
Thanks for the quick reply. I was thinking more along the lines of how a wet/dry knob seems to function in a typical reverb, where all you really hear is the delta with no dry signal at all.ncthom wrote:@funky lime Indeed, someone could do that. To be frank, though, none of the algorithms I've used here are particularly new. Temper itself is novel but its internal algorithms are well known. So there's really not a lot to take and run away with in terms of reselling this. I think this move is more an opportunity to help new developers find resources and examples to help them start building plugins (because the barrier to entry, from my experience, is quite high). That's my intention with open sourcing the code, and I hope that the community receives it that way.
@BRBWaffles thank you! That's wonderful feedback. I suspect what you're hearing is due to that the saturation stage precedes the phase distortion stage– so when you saturate the low/mid range, you'll introduce harmonics that feed the mid/hi range of the phase distortion stage, which in turn delivers something of a harmonic excitement effect. So as you dial in the saturation, you'll also be getting a bit of clarity on the high end. I'm glad you noticed! I've been using it for parallel processing on vox as well.
As for the wet/dry suggestion, very happy to take that feedback. What host are you using? Most of the hosts I was testing in offered a bypass knob for effect slots, so I was setting the bypass at ~50% and adding gain or compression after Temper to simulate a wet/dry knob. But that's easy enough to add to the plugin itself.
-
- KVRist
- Topic Starter
- 35 posts since 1 Mar, 2017 from Boston, MA
Ah right, I misunderstood. That's a really interesting idea, I'd love to hear how that sounds. I'll have to spend some time with how to implement it, but will definitely take your feedback. Thanks!
- KVRAF
- 2772 posts since 22 May, 2017
Love that dark GUI!
I'll have to download the demo and check it out!
I'll have to download the demo and check it out!
-
- KVRist
- 137 posts since 22 May, 2017
Here's a cool trick, haha. You can use parameter modulation in Reaper to turn Temper into an automatic fuzz wah.
- KVRist
- 415 posts since 3 Jun, 2017
Had a quick look at the source. You use JUCE and Faust in parallel... why not just use JUCE, or Faust? Looking at the DSP part, seems to me like you could've just added that all up in JUCE. Don't both at once bloat the plugin more than necessary?
Also, and I didn't check reeeally intensely, but from my first glance it doesn't look like you're LP filtering after up- and before downsampling... wouldn't that introduce one hell of an aliasing mess with higher distortion amounts?
(Please don't mistake my critical comments as hostility, I appreciate your "open" approach a lot and I'm just trying to understand and learn.)
Also, and I didn't check reeeally intensely, but from my first glance it doesn't look like you're LP filtering after up- and before downsampling... wouldn't that introduce one hell of an aliasing mess with higher distortion amounts?
(Please don't mistake my critical comments as hostility, I appreciate your "open" approach a lot and I'm just trying to understand and learn.)
Confucamus.
-
- KVRist
- Topic Starter
- 35 posts since 1 Mar, 2017 from Boston, MA
Thanks!Russell Grand wrote:Love that dark GUI!
I'll have to download the demo and check it out!
That's awesome, definitely going to have to check out Reaper's param modulation after that!BRBWaffles wrote:Here's a cool trick, haha. You can use parameter modulation in Reaper to turn Temper into an automatic fuzz wah.
Yep, JUCE doesn't have much in the way of a DSP library, and Faust doesn't have much in the way of a GUI/Cross-platform library. I find actually they're really nice complements. I'm able to quickly prototype, develop, and test the signal path with Faust and FaustLive, and then generate a small C++ file for inclusion in my JUCE build (see https://github.com/creativeintent/tempe ... perDsp.cpp). So in terms of overhead, it seems quite minimal to me other than managing the two tools in one project. I'll write up a more detailed blog post on this soon, I'm getting a lot of interest on this one.Rockatansky wrote:Had a quick look at the source. You use JUCE and Faust in parallel... why not just use JUCE, or Faust? Looking at the DSP part, seems to me like you could've just added that all up in JUCE. Don't both at once bloat the plugin more than necessary?
Also, and I didn't check reeeally intensely, but from my first glance it doesn't look like you're LP filtering after up- and before downsampling... wouldn't that introduce one hell of an aliasing mess with higher distortion amounts?
As for the aliasing, yes, definitely that would introduce a mess. I do have an upsample/filter and filter/downsample stage, take a look at https://github.com/creativeintent/tempe ... r.dsp#L101 and at https://github.com/creativeintent/tempe ... ip.dsp#L66. I zero pad the input buffer in the AudioProcessor and then send it through the Faust chain which begins and ends with an eighth order elliptic lowpass filter, then downsample again afterwards. It's a 2x oversample and I found that addressed most of the unwanted aliasing I was hearing. There are likely better practices than what I've done here, but given the toolset I chose, I'm really happy with this approach. Happy to answer more questions there.
- KVRist
- 415 posts since 3 Jun, 2017
Thanks for the reply! 
I didn't try it with your Faust filter (yet), but I already did a lot of confusing experiments with oversampling today.
For one, 0-stuffing gave me weirdness. I did it like you do in Temper's code: copy each sample from one buffer into another, and insert X samples with 0.0f in between, so that 4x oversampling will copy each sample and stuff three 0.0f samples in before the next "real" sample, resulting in a buffer with 4x the original sample count.
Doing that was OK and reversible without quality loss, but the signal coming out of the process was consistently 3 dBfs quieter than the original. Only when I started stuffing the input samples into the new buffer multiple times rather than using 0.0f samples, the signal came out at the same volume as it had going in. Strange.
And no matter what LP filters I tried after up- and before down-sampling, they either showed a significant and audible HF loss (running gaussian noise through into Span), or chewed up significant CPU, a beautiful 50-tap FIR took something like 3% CPU... *sigh* Is that elliptical in Faust so much cleaner and steeper and lighter on CPU? Or do you just put up with the HF loss?
Interestingly, and FYI - if you care, the best overall solution in my experiments was JUCE's very own Lagrange Interpolator, not even the CatmullRom that people love so much. 16x up- and down-sampling with only low to medium HF bending at 0.1% CPU on an old Mac Mini.
While browsing Temper's PluginProcessor.cpp, I noticed that you point from the processor into the editor and basically shove values into the GUI part at realtime... umm-kay. I thought that was a huge no-no because it's a source of performance issues, making GUI components refresh too often and so on? At least that's what I read somewhere on the JUCE forums.
Wouldn't it be better to have the buffer in the processor part and give it a getBuffer() method that the GUI part calls at its own pace? Rather than constantly stuffing buffers into the FIFO and calculating windows and FFTs really fast, as they are basically "lost" because several times they'll happen between actual GUI refresh cycles?
For example, at 44.1 kHz with a buffer of 256 samples, the processBlock is called over 172 times per second. This means the Sprectroscope in the GUI part is being pushBuffer-ed 172+ times every second, calculating 172+ windows and 172+ FFTs and so on every second. Even if the GUI was refreshing at superfast 60 Hz, equals 60 times every second, that would still mean 112+ FFT and window calculations are done but not actually displayed... and there are two Spectroscopes.
If the buffer (or rather FIFO) was in the processor part and the GUI just came to collect from it every time it refreshes, that would still mean the processBlock writes into a buffer 172+ times each second, but the GUI part only does its window and FFT calculations at the frequency it refreshes itself at.
Or am I missing something here?
(Always a possibility)
I didn't try it with your Faust filter (yet), but I already did a lot of confusing experiments with oversampling today.
For one, 0-stuffing gave me weirdness. I did it like you do in Temper's code: copy each sample from one buffer into another, and insert X samples with 0.0f in between, so that 4x oversampling will copy each sample and stuff three 0.0f samples in before the next "real" sample, resulting in a buffer with 4x the original sample count.
Doing that was OK and reversible without quality loss, but the signal coming out of the process was consistently 3 dBfs quieter than the original. Only when I started stuffing the input samples into the new buffer multiple times rather than using 0.0f samples, the signal came out at the same volume as it had going in. Strange.
And no matter what LP filters I tried after up- and before down-sampling, they either showed a significant and audible HF loss (running gaussian noise through into Span), or chewed up significant CPU, a beautiful 50-tap FIR took something like 3% CPU... *sigh* Is that elliptical in Faust so much cleaner and steeper and lighter on CPU? Or do you just put up with the HF loss?
Interestingly, and FYI - if you care, the best overall solution in my experiments was JUCE's very own Lagrange Interpolator, not even the CatmullRom that people love so much. 16x up- and down-sampling with only low to medium HF bending at 0.1% CPU on an old Mac Mini.
While browsing Temper's PluginProcessor.cpp, I noticed that you point from the processor into the editor and basically shove values into the GUI part at realtime... umm-kay. I thought that was a huge no-no because it's a source of performance issues, making GUI components refresh too often and so on? At least that's what I read somewhere on the JUCE forums.
Wouldn't it be better to have the buffer in the processor part and give it a getBuffer() method that the GUI part calls at its own pace? Rather than constantly stuffing buffers into the FIFO and calculating windows and FFTs really fast, as they are basically "lost" because several times they'll happen between actual GUI refresh cycles?
For example, at 44.1 kHz with a buffer of 256 samples, the processBlock is called over 172 times per second. This means the Sprectroscope in the GUI part is being pushBuffer-ed 172+ times every second, calculating 172+ windows and 172+ FFTs and so on every second. Even if the GUI was refreshing at superfast 60 Hz, equals 60 times every second, that would still mean 112+ FFT and window calculations are done but not actually displayed... and there are two Spectroscopes.
If the buffer (or rather FIFO) was in the processor part and the GUI just came to collect from it every time it refreshes, that would still mean the processBlock writes into a buffer 172+ times each second, but the GUI part only does its window and FFT calculations at the frequency it refreshes itself at.
Or am I missing something here?
Last edited by Rockatansky on Fri Jul 07, 2017 8:47 pm, edited 1 time in total.
Confucamus.
- Banned
- 7624 posts since 13 Nov, 2015 from Norway
Only 10$. Its a steal! Will try this one out. 
EnergyXT3 - LMMS - FL Studio | Roland SH201 - Waldorf Rocket | SoundCloud - Bandcamp
-
- KVRist
- Topic Starter
- 35 posts since 1 Mar, 2017 from Boston, MA
@camsr the strings demo preset isn't included exactly, but the first two presets are fairly similar. I can dig up the exact preset from that demo and send it over if you'd like!
@Rockatansky yea oversampling can be tricky, I think there are just tradeoffs to weigh when considering your filter choice. For me, the elliptic filter was easy to model in Faust, performs well, and gave a frequency response that I'm satisfied with. One of the downsides of that filter specifically is the phase warping; a lot of people lean towards poly-phase/linear phase filters for oversampling, but that wasn't a constraint I was particularly worried about, as one of the main features of the plugin is a phase distortion. As far as I'm concerned, the phase warping from the oversampling process is just a minimal contribution to the phase madness.
As for the gain loss, I think that's expected. Most of the implementations I've seen (and in Temper as well) have a gain stage, or roll gain into their filter coefficients, to accommodate the loss in the oversampling process.
And to your point about GUI updates, you're totally right that you want to avoid excessive updates to the GUI. In Temper's PluginProcessor I do copy the input & output buffer into a FIFO in the PluginEditor, if and when the PluginEditor is available. But, I only compute the FFT and repaint at 60Hz using JUCE's Timer module (see the timer callback here https://github.com/creativeintent/tempe ... nt.cpp#L85). Whether or not the FIFO lives on the processor and is accessed from the editor, or lives on the editor and is accessed from the processor I think is a pretty minimal part of the performance complexity here.
Also, I'll take a look at JUCE's LagrangeInterpolator class, very interested in improving my oversampling toolkit!
Happy to take more questions too, I could chat about the internals all day. Perhaps we should move to the DSP forum? Or I'd be happy to chat over email as well.
@Rockatansky yea oversampling can be tricky, I think there are just tradeoffs to weigh when considering your filter choice. For me, the elliptic filter was easy to model in Faust, performs well, and gave a frequency response that I'm satisfied with. One of the downsides of that filter specifically is the phase warping; a lot of people lean towards poly-phase/linear phase filters for oversampling, but that wasn't a constraint I was particularly worried about, as one of the main features of the plugin is a phase distortion. As far as I'm concerned, the phase warping from the oversampling process is just a minimal contribution to the phase madness.
As for the gain loss, I think that's expected. Most of the implementations I've seen (and in Temper as well) have a gain stage, or roll gain into their filter coefficients, to accommodate the loss in the oversampling process.
And to your point about GUI updates, you're totally right that you want to avoid excessive updates to the GUI. In Temper's PluginProcessor I do copy the input & output buffer into a FIFO in the PluginEditor, if and when the PluginEditor is available. But, I only compute the FFT and repaint at 60Hz using JUCE's Timer module (see the timer callback here https://github.com/creativeintent/tempe ... nt.cpp#L85). Whether or not the FIFO lives on the processor and is accessed from the editor, or lives on the editor and is accessed from the processor I think is a pretty minimal part of the performance complexity here.
Also, I'll take a look at JUCE's LagrangeInterpolator class, very interested in improving my oversampling toolkit!
Happy to take more questions too, I could chat about the internals all day. Perhaps we should move to the DSP forum? Or I'd be happy to chat over email as well.
- KVRAF
- 2772 posts since 22 May, 2017
I went to purchase Temper and for some reason my CC won't go through via Paypal; most likely because it's a prepaid debit. Since I refuse to open up a Paypal account, I'll have to hold off from buying Temper until I can sort out my CC issues.
Temper sounds fantastic though, and I intend to buy this one way or another! Excellent plug!
Temper sounds fantastic though, and I intend to buy this one way or another! Excellent plug!
