a crude audio compressor

Status
Not open for further replies.

Moo

Well-known member
I'd like to share my crude audio compression effect for teensy audio library:
https://github.com/newdigate/teensy-audio-multipressor

Its a very basic attempt at a compression effect

If there is any interest I would be happy to integrate into cloned teensy audio library repo and send pull request.

There is a directive in the sketch to switch between SGTL5000 and TGAPro sound card by BlackAddr.

The sketch uses two AudioFilterStateVariable filters on i2s stereo input and applies a compression effect to each of 6 filter outputs before combining outputs of each compressor back to left and right channels.

The audio queue objects are used to display oscilliscope view. you may need to comment out, until I add some extra compiler directives. I am using ST7735 display (128 x 128) to display the input and output oscilliscope view.

Please feel free to criticise, review, question, modify, extend, improve...
 
I'd like to share my crude audio compression effect for teensy audio library:
https://github.com/newdigate/teensy-audio-multipressor

Its a very basic attempt at a compression effect

If there is any interest I would be happy to integrate into cloned teensy audio library repo and send pull request.

There is a directive in the sketch to switch between SGTL5000 and TGAPro sound card by BlackAddr.

The sketch uses two AudioFilterStateVariable filters on i2s stereo input and applies a compression effect to each of 6 filter outputs before combining outputs of each compressor back to left and right channels.

The audio queue objects are used to display oscilliscope view. you may need to comment out, until I add some extra compiler directives. I am using ST7735 display (128 x 128) to display the input and output oscilliscope view.

Please feel free to criticise, review, question, modify, extend, improve...

hi Moo, I'm testing the compressor but I'm not sure how is it supposed to work,
setting the input gain to 0.5 attenuates the signal but as far as I see (and hear) no compression is applied,
and setting the gain to 1.5 clips the output,
not using your example, instead I've inserted before the out in a project I'm working on
btw, interesting to see that this post has no comments at all
 
Hey Mangu :) I was just looking at the code and spotted something that looked very wrong... line 62 in effect_compressor.cpp

I think if you comment that line out it will probably work -- looks like the output sample is being overwritten by the post-gain sample, ignoring the compressor... If it works let me know and I'll update the repo.

The code is basically a wave shaper which applies a logarithmic shape to the wave -- Its very crude, i was thinking of converting it to use the more efficient waveshaper algorithm,

Subsequently I was using MarkzP's https://github.com/MarkzP/AudioEffectDynamics which I had converted to a side-chaining compressor, which was making nice progress... but unfortunately, as it is at the moment, it applies a single gain across an entire audio buffer. so the gain is constant per buffer, and when the gain changes, there is a discontinuity in the signal. If the gain change is big between buffers you can hear and see the issue. I've been thinking about modifying this otherwise awesome repo to calculate overall gain on a per-sample basis - but just haven't managed to find the time. I don't think its alot of work.
 
FYI, I've updated and deleted line 62 of effect_compressor.cpp :) but I've havent tested it....
 
Screenshot 2021-04-25 at 12.31.12.jpg

awesome. thanks :) looks like the comp.mp3 has much smaller dynamic range - the quiet bits are amplified and the loud beats are quieter.
 
btw: no, I don't think it is a wave-folder. a wave folder is a subset of wave shapers, but wave shapers aren't necessarily wave-folders. a rectifier is an example of a wave folder... a wave shaper basically maps an input value to an output value, as far as I know, thou I stand to be corrected.
 
btw: no, I don't think it is a wave-folder. a wave folder is a subset of wave shapers, but wave shapers aren't necessarily wave-folders. a rectifier is an example of a wave folder... a wave shaper basically maps an input value to an output value, as far as I know, thou I stand to be corrected.

you're probably correct, but was commenting about how does it sound, and to me sounds like a folder/distortion
 
yep theres definitely alot of noise on the comp.mp3 signal compared to the original signal. not sure if thats a result of the effect, input noise, or output noise.
 
it has to be the effect, because both clips are processed by 2 channels of the same gear, but one channel has the compressor and the other not.
 
I'd like to share my crude audio compression effect for teensy audio library:
https://github.com/newdigate/teensy-audio-multipressor

Its a very basic attempt at a compression effect

That's a distortion effect, not a compression effect. To compress you need to use a linear response whose gain
varies over time at scales longer than 50ms. (possibly several independent sections for different frequencies).

But here you have a logarithmic response which will generate large amounts of harmonic distortion and
intermodulation distortion directly. This generates spurious tones not present in the original signal.
 
I think I've found the issue with my "compressor" distortion effect -- it was a divide by an int, causing decimation - effectively it was a bit-crusher!

I've committed a fix for that now, but its a theoretic fix because I haven't tested it, unfortunately.
 
I do not understand the purpose of this logarithmic transformation (call it wave-shaping or "compression")
being non-linear it creates a lot of intermodulation products, that cannot be un-done (as noted by MarkT).
Could you elaborate in the use application?
 
You might take a look here for some inspiration, not sure if it's tested but on first glance looks okay: https://github.com/MarkzP/AudioEffectDynamics

Yes thats a very nice example of a real compressor with bells and whistles. I absolutely love it, except for the fact that it applies a constant gain to an entire audio buffer (not so good when delta RMS is big between audio buffers - perhaps I am using it incorrectly...)

It was more of an experiment to find out how it would sound. I was thinking of using this process for side-chain ducking -- using the amplitude of the kick signal to reduce gain on the bass signal - it was quite a while ago, I just updated recently because there was some interest.
 
The fork by newdigate is patched in a way that it does not work on blocks, but on samples.

I'd like to see this in the official audio library.
 
Hi Frank, I've created a PR to add this to the audio library. https://github.com/PaulStoffregen/Audio/pull/398

Although I have subsequently realised that it really should have updates to the audio-gui and perhaps add #include in Audio.h

No Problem, i can add a additional PR when it is merged.
It needs a #ifdef to prevent compile-errors on Teensy, LC, too ;)

I see it has an additional file for log.
Is that needed? (almost) all other components have two files only, and it would be more clean without it.

What do you think about nics PR? Do you merge it?

@nic, what is const static unsigned int sampleBufferSize = 4410;

Is that simply sample rate / 10? If so, could you calculate it instead?
It would then adapt to a changed sample rate (audiostream.h).
 
Thanks Frank! Good suggestions...

I'll close the PR and re-open a new one when Im ready...
 
...and it is the non-"bitcrusher" version, right?
Have not looked at the sourcecode so much..

That is a separate component I use for side-chaining "compression" / ducking. It's not much of a compressor as it is a wave shaper. It makes a punchier kik when using the kik to suppress the bassline.
 
Opened a new pull request: https://github.com/PaulStoffregen/Audio/pull/399

Let me know if theres any other improvements I should/could make. Thanks!

No Problem, i can add a additional PR when it is merged.
It needs a #ifdef to prevent compile-errors on Teensy, LC, too ;)
Done.

I see it has an additional file for log.
Is that needed? (almost) all other components have two files only, and it would be more clean without it.
This file is not shared between other files, so makes sense to include in the effect cpp

@nic, what is const static unsigned int sampleBufferSize = 4410;
Is that simply sample rate / 10? If so, could you calculate it instead?
It would then adapt to a changed sample rate (audiostream.h).

Yep, exactly - this is the duration in samples of the running RMS window, i.e. 1/10th of a second sliding window to calculate RMS
 
Status
Not open for further replies.
Back
Top