Discussion:
Audio Compressor/AGC in C or C++
(too old to reply)
__GG
2005-12-09 13:46:14 UTC
Permalink
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
mlimber
2005-12-09 15:16:32 UTC
Permalink
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
Try http://google.com. I found, for instance, this site:

http://datacompression.info/NonCommercialLibs.shtml

Cheers! --M
Mark
2005-12-09 21:09:31 UTC
Permalink
I think the op is asking about dynamic range compressor i.e. AGC, i.e
automatic loudness adj... not data reduction type of compression...

Mark
Erik de Castro Lopo
2005-12-09 21:46:20 UTC
Permalink
Post by mlimber
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://datacompression.info/NonCommercialLibs.shtml
Those a data compressors. The OP was asking about dynamic
range compressors which are very different.

Erik
--
+-----------------------------------------------------------+
Erik de Castro Lopo
+-----------------------------------------------------------+
"We can build a better product than Linux" -- Microsoft
Corp.'s Windows operating-system chief, Jim Allchin.
One has to wonder why, with their huge resources, they haven't.
__GG
2005-12-10 01:43:57 UTC
Permalink
On Sat, 10 Dec 2005 08:46:20 +1100, Erik de Castro Lopo
Post by Erik de Castro Lopo
Post by mlimber
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://datacompression.info/NonCommercialLibs.shtml
Those a data compressors. The OP was asking about dynamic
range compressors which are very different.
Erik
Correct. Unfortunate that the term 'compressor' is overloaded.
That's why I said 'AGC' in the title.

Huge number of hits on Google, of course, and many are data
compressors. Of the others, I have no idea how well they work.
I was hoping that those on this group would have tried various
algorithms.

In particular, I'm wondering about fast envelope/peak detection
and signal averaging. That seems to be one of the keys, esp as
regards CPU cycles.

In this particular app, it's important that the initial attack does
not spike (as it would if gain were up and the env detector did not
react instantly). Something analogous (no pun intended) to the
traditional diode/cap peak detector still has a finite ramp-up time,
so buffer 'look ahead' is desirable. On the other hand, I don't
want to delay any longer than necessary. So the lookahead
interval should be roughly sync'd (or greater than) the attack
response of the envelope filter.

All this might be wishful thinking. Commercial apps probably do this,
but I'm not hopeful about finding C++ code that's optimized in this
respect.

Back to the envelope detector: How is this usually done? I think
peak is the way to go in general (don't want to waste cycles on RMS
if it's not going to help). I seem to remember some algorithms that
simply added each new sample into a running tally of absolute values.
There was a 'magic number' multiplier in the picture, 0.999, I
believe. Anyone know about that?

I've seen
Vladimir Vassilevsky
2005-12-10 02:04:51 UTC
Permalink
Look through the datasheets of TAS3103, AD1954. The operation of the
lookahead compressor is explained there very clearly.
The C implementation is pretty obvious and straightforward, it is just
5-10 lines of code.
The main point about the compressors is there is no universal rule about
the parameters; it all depends on the desired effect and the audio content.

Vladimir Vassilevsky

DSP and Mixed Signal Design Consultant

http://www.abvolt.com
Post by __GG
In particular, I'm wondering about fast envelope/peak detection
and signal averaging. That seems to be one of the keys, esp as
regards CPU cycles.
In this particular app, it's important that the initial attack does
not spike (as it would if gain were up and the env detector did not
react instantly). Something analogous (no pun intended) to the
traditional diode/cap peak detector still has a finite ramp-up time,
so buffer 'look ahead' is desirable. On the other hand, I don't
want to delay any longer than necessary. So the lookahead
interval should be roughly sync'd (or greater than) the attack
response of the envelope filter.
All this might be wishful thinking. Commercial apps probably do this,
but I'm not hopeful about finding C++ code that's optimized in this
respect.
Back to the envelope detector: How is this usually done? I think
peak is the way to go in general (don't want to waste cycles on RMS
if it's not going to help). I seem to remember some algorithms that
simply added each new sample into a running tally of absolute values.
There was a 'magic number' multiplier in the picture, 0.999, I
believe. Anyone know about that?
robert bristow-johnson
2005-12-10 02:16:34 UTC
Permalink
Post by __GG
On Sat, 10 Dec 2005 08:46:20 +1100, Erik de Castro Lopo
Post by Erik de Castro Lopo
Post by mlimber
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://datacompression.info/NonCommercialLibs.shtml
Those a data compressors. The OP was asking about dynamic
range compressors which are very different.
Correct. Unfortunate that the term 'compressor' is overloaded.
That's why I said 'AGC' in the title.
"sample", and "modulation" are other terms that often means something
different to the audio/music folks.
Post by __GG
... I'm wondering about fast envelope/peak detection
and signal averaging. That seems to be one of the keys, esp as
regards CPU cycles.
what does the speed and smoothing (averaging) of your envelope/peak
detection have anything to do with CPU cycles?
Post by __GG
In this particular app, it's important that the initial attack does
not spike (as it would if gain were up and the env detector did not
react instantly). Something analogous (no pun intended)
it's *not* a pun! that is precisely why we call it "analog" electronics or
"analog" processing.
Post by __GG
to the traditional diode/cap peak detector still has a finite ramp-up time,
so buffer 'look ahead' is desirable. On the other hand, I don't
want to delay any longer than necessary. So the lookahead
interval should be roughly sync'd (or greater than) the attack
response of the envelope filter.
sounds to me that you understand the issues quite well. so why is it that
you need help? you should be telling us how to do it! :-)
Post by __GG
All this might be wishful thinking. Commercial apps probably do this,
but I'm not hopeful about finding C++ code that's optimized in this
respect.
pretty easy to write. 50 lines of code or less.
Post by __GG
Back to the envelope detector: How is this usually done?
how about an analog to the diode/capacitor/load peak detector? or how about
squaring, LPFing, and square root (last step usually not necessary) for an
RMS envelope?
Post by __GG
I think
peak is the way to go in general (don't want to waste cycles on RMS
if it's not going to help).
it depends on what you're trying to do? are you trying to maintain a
certain perceptual loudness characteristic (then you need to do
"A-weighting" or "C-weighting" or even "E-weighting" (if you have the CPU
cycles) and RMS envelope detection. if you're trying to limit peak
excursions into the forbidden saturation region, then it's
diode/capacitor/resistor peak detection.
Post by __GG
I seem to remember some algorithms that
simply added each new sample into a running tally of absolute values.
There was a 'magic number' multiplier in the picture, 0.999, I
believe. Anyone know about that?
never seen it. why is 999/1000 so "magic"?
--
r b-j ***@audioimagination.com

"Imagination is more important than knowledge."
__GG
2005-12-10 04:56:26 UTC
Permalink
On Fri, 09 Dec 2005 21:16:34 -0500, robert bristow-johnson
Post by robert bristow-johnson
Post by __GG
... I'm wondering about fast envelope/peak detection
and signal averaging. That seems to be one of the keys, esp as
regards CPU cycles.
what does the speed and smoothing (averaging) of your envelope/peak
detection have anything to do with CPU cycles?
More sophisticated detection probably requires conversion to float.
RMS requires square and square root, which would be computationally
expensive. I'm thinking that there may be much faster algorithms that
stay in int domain and still work well.

By the way, I'm just trying to get max energy from the input channel
for a speech-rec app. I want to avoid spikes and other harmonic-rich
artifacts, hence the desired lookahead buffer.
Post by robert bristow-johnson
Post by __GG
to the traditional diode/cap peak detector still has a finite ramp-up time,
so buffer 'look ahead' is desirable. On the other hand, I don't
want to delay any longer than necessary. So the lookahead
interval should be roughly sync'd (or greater than) the attack
response of the envelope filter.
sounds to me that you understand the issues quite well. so why is it that
you need help? you should be telling us how to do it! :-)
Yeah, right! <g> I've seen some of the tech posts on this group.
Besides, there is a big difference between knowing how it works and
having good intuition for algorithms. You guys live there.
Post by robert bristow-johnson
pretty easy to write. 50 lines of code or less.
I was hoping that's the case. Surprising that there isn't more code
floating around then.
Post by robert bristow-johnson
Post by __GG
Back to the envelope detector: How is this usually done?
how about an analog to the diode/capacitor/load peak detector? or how about
squaring, LPFing, and square root (last step usually not necessary) for an
RMS envelope?
Still talking 50 lines of code? I do like this stuff, but
unfortunately I can't schedule play time. Otherwise I'd try to write
each of those building blocks and play with configurations. That
would take a while.

The comp is a small block in a large non-DSP app. That's the reason
I'm trying to minimize cycles, and why I'm looking for a starting
point for the code.
Post by robert bristow-johnson
Post by __GG
I think
peak is the way to go in general (don't want to waste cycles on RMS
if it's not going to help).
it depends on what you're trying to do? are you trying to maintain a
certain perceptual loudness characteristic (then you need to do
"A-weighting" or "C-weighting" or even "E-weighting" (if you have the CPU
cycles) and RMS envelope detection. if you're trying to limit peak
excursions into the forbidden saturation region, then it's
diode/capacitor/resistor peak detection.
All this depends on a very temperamental speech-rec module. I have no
idea what will make it barf, but I'm pretty sure it won't like
artifacts from spikes or clipping. I bet some breathing or other
normal compressor side-effects won't bother it.
Post by robert bristow-johnson
Post by __GG
I seem to remember some algorithms that
simply added each new sample into a running tally of absolute values.
There was a 'magic number' multiplier in the picture, 0.999, I
believe. Anyone know about that?
never seen it. why is 999/1000 so "magic"?
No idea. I've seen it in a couple different programs, but maybe it's
coincidence. I guess they both chose to average 1000 samples. That
averaging window would have direct bearing on the attack response, so
I would have expected it to be a variable rather than a #define.

I'll have to find that code again and take a closer look, but I
thought that attack and release settings would directly affect the
length of that averaged buffer.
Jerry Avins
2005-12-10 05:13:20 UTC
Permalink
__GG wrote:

...
Post by __GG
More sophisticated detection probably requires conversion to float.
RMS requires square and square root, which would be computationally
expensive. I'm thinking that there may be much faster algorithms that
stay in int domain and still work well.
No square root is needed, If you know the target root, you know the
target square.

...

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Jerry Avins
2005-12-10 04:02:38 UTC
Permalink
Post by __GG
On Sat, 10 Dec 2005 08:46:20 +1100, Erik de Castro Lopo
Post by Erik de Castro Lopo
Post by mlimber
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://datacompression.info/NonCommercialLibs.shtml
Those a data compressors. The OP was asking about dynamic
range compressors which are very different.
Erik
Correct. Unfortunate that the term 'compressor' is overloaded.
That's why I said 'AGC' in the title.
Huge number of hits on Google, of course, and many are data
compressors. Of the others, I have no idea how well they work.
I was hoping that those on this group would have tried various
algorithms.
In particular, I'm wondering about fast envelope/peak detection
and signal averaging. That seems to be one of the keys, esp as
regards CPU cycles.
In this particular app, it's important that the initial attack does
not spike (as it would if gain were up and the env detector did not
react instantly). Something analogous (no pun intended) to the
traditional diode/cap peak detector still has a finite ramp-up time,
so buffer 'look ahead' is desirable. On the other hand, I don't
want to delay any longer than necessary. So the lookahead
interval should be roughly sync'd (or greater than) the attack
response of the envelope filter.
All this might be wishful thinking. Commercial apps probably do this,
but I'm not hopeful about finding C++ code that's optimized in this
respect.
Back to the envelope detector: How is this usually done? I think
peak is the way to go in general (don't want to waste cycles on RMS
if it's not going to help). I seem to remember some algorithms that
simply added each new sample into a running tally of absolute values.
There was a 'magic number' multiplier in the picture, 0.999, I
believe. Anyone know about that?
I've seen
There's no assurance that a any sample in a modest number rill be near a
peak unless the oversampling ratio is high. That's why envelope
detection is often done with a Hilbert transform and computing I^2 +
Q^2. Even without bothering to take the square root, that's not cheap.

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
__GG
2005-12-10 05:09:44 UTC
Permalink
Post by Jerry Avins
There's no assurance that a any sample in a modest number rill be near a
peak unless the oversampling ratio is high. That's why envelope
detection is often done with a Hilbert transform and computing I^2 +
Q^2. Even without bothering to take the square root, that's not cheap.
Jerry
Not sure about the CPU expense of a Hilbert transform, but that's why
I thought RMS may not work (and may be overkill anyway). Given that I
(probably) don't need to maintain perceived loudness, can you think of
a faster approach for the detector?

If memory serves, you worked on compressors for NASA, right? Maybe
analog, but the same general approach should work here: just deliver
loud intelligible energy without clipping.

The envelope detector has to be the most complicated component, so
it's worth some thought. In simplistic form, it seems like you'd want
to average X number of samples for the attack (depending on designated
attack time) and Y number of samples for release. X and Y could be
derived by dividing designated attack and release times (resp) by
1/sample rate.

Now that I think about this, it seems that it could still be prone to
clipping unless there was another mechanism akin to a non-slew-limited
diode/cap. That limiter would have to be integral to the compressor's
control path so it could override the gain structure.
Jerry Avins
2005-12-10 05:24:33 UTC
Permalink
Post by __GG
Post by Jerry Avins
There's no assurance that a any sample in a modest number rill be near a
peak unless the oversampling ratio is high. That's why envelope
detection is often done with a Hilbert transform and computing I^2 +
Q^2. Even without bothering to take the square root, that's not cheap.
Jerry
Not sure about the CPU expense of a Hilbert transform, but that's why
I thought RMS may not work (and may be overkill anyway). Given that I
(probably) don't need to maintain perceived loudness, can you think of
a faster approach for the detector?
If memory serves, you worked on compressors for NASA, right? Maybe
analog, but the same general approach should work here: just deliver
loud intelligible energy without clipping.
You have a long memory, and that was a long time ago. Mercury orbital
flights. The compressor used only diodes, resistors and capacitors. The
design wasn't mine, but I built plenty of them.

I don't know that good RMS (MS is enough) is easy either, but I think
that Parcival's Theorem might say it is. There's the same energy in
sin(xt) + sin(3xt) as there is in sin(xt) - sin(3xt), but the peaks are
very different. If you want to control the peaks, you have to sense
peaks, not power.
Post by __GG
The envelope detector has to be the most complicated component, so
it's worth some thought. In simplistic form, it seems like you'd want
to average X number of samples for the attack (depending on designated
attack time) and Y number of samples for release. X and Y could be
derived by dividing designated attack and release times (resp) by
1/sample rate.
Now that I think about this, it seems that it could still be prone to
clipping unless there was another mechanism akin to a non-slew-limited
diode/cap. That limiter would have to be integral to the compressor's
control path so it could override the gain structure.
Analog Devices makes at least one analog audio compressor. I can dig out
the number if you need it. A look at the data sheet will give you some
good ideas about what's worth doing. What to do is at least as important
as the implementation method.

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Richard Dobson
2005-12-09 21:52:25 UTC
Permalink
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
There's a few in the musicdsp archive. One has just been added using C++:

http://www.musicdsp.org/archive.php?classid=4#204

Richard Dobson
__GG
2005-12-10 04:11:46 UTC
Permalink
On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
Post by Richard Dobson
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://www.musicdsp.org/archive.php?classid=4#204
Richard Dobson
Thanks, Richard.

The 'Chunkware' code (your link) looks well written, but I was
actually expecting something more complex. If that works well,
all the better.

I also found this:

http://www.music.helsinki.fi/research/spkit

It looks interesting. Rather involved set of classes, though.
Also, the 'SonicFlow' compressor on SourceForge.net.

I'd still like to get pro opinions on those implementations if
any of you have reviewed the code or run them.
__GG
2005-12-10 12:26:18 UTC
Permalink
On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
Post by Richard Dobson
Post by __GG
I'd like to find source for audio compression classes or functions
in C or C++. It would be nice if it had lookahead (slight delay is
OK).
http://www.musicdsp.org/archive.php?classid=4#204
Richard Dobson
Here's another thought: If I were to use instantaneous peak detection
instead of RMS or other slower envelope, then lookahead would not be
necessary. The attack would track instantly.

ref: http://www.musicdsp.org/archive.php?classid=0#19

That should use very few cycles.

Questions:

What is the flaw here? If I don't need musical-sounding output, just
maximized clean signal, is there any drawback to simply
feed-forwarding the peak-detected, slower-decay envelope to a virtual
VCA?

What is the best way to control decay/release? Given that the release
does not have to be micro-second accurate, I could add groups of, say,
100 sample abs values, then feed each into a fifo. Accumulate the
total in the FIFO by adding each new value, subtracting each old value
as it gets bumped. The groups of 100 would eliminate the need for a
long buffer. Possible stepping noise due to time granularity from
grouping?

This may also help with noise gating. I'd have x milliseconds of
amplitudes in the fifo. If the total is below the noise threshold,
turn off output.


?
Richard Dobson
2005-12-10 13:55:29 UTC
Permalink
__GG wrote:

..
Post by __GG
Here's another thought: If I were to use instantaneous peak detection
instead of RMS or other slower envelope, then lookahead would not be
necessary. The attack would track instantly.
ref: http://www.musicdsp.org/archive.php?classid=0#19
That should use very few cycles.
What is the flaw here? If I don't need musical-sounding output, just
maximized clean signal, is there any drawback to simply
feed-forwarding the peak-detected, slower-decay envelope to a virtual
VCA?
Any compressor is a non-linear effect, that modulates the source (watch out for
aliasing if the "corners" of the envelope are too sharp) and one way or another
will always have some sort of personality, which may or may not be deemed "musical".

I think you really need to try all these ideas out for yourself, and decide! I
doubt you will get a complete answer here "do it this way" (but I do suggest you
ask on the music-dsp list, and check the list archives, there were major
discussions about compressors a few months ago). Different sources and
requirements indicate different compression techniques, so that in a practical
compressor you will need to offer at least peak and RMS options, and very
possibly average too. Offering Peak and average might be OK, especially if you
want minimum CPU cost. The high-end models of course offer multi-band
compression, and/or seek to emulate analog optical compressors, but the basic
algorithms such as you find in the music-dsp archive are very useful starting
points.
Post by __GG
What is the best way to control decay/release? Given that the release
does not have to be micro-second accurate, I could add groups of, say,
100 sample abs values, then feed each into a fifo. Accumulate the
total in the FIFO by adding each new value, subtracting each old value
as it gets bumped. The groups of 100 would eliminate the need for a
long buffer. Possible stepping noise due to time granularity from
grouping?
Yes, that is a standard "closed-form" of averaging.
Envelope detection is a form of filtering, and filters can have all sorts of
slopes. The answers you seek may not be solely technical ones. For some
material, one style will work, for another it won't. The window over which
samples are scanned is itelf an important parameter, when doing averaging or
RMS. You need an envelope extractor, which is a filter of one form or another,
and an envelope synthesiser that generates the final envelope to be applied to
the source sound. There is more than one way of designing both, and the criteria
may be CPU load, etc, but may also likely be aesthetic ("hey this works on drums
but is bad on a voice/sax/whatever"), so you really will have to try ideas out
the hard way.

One approach you might like to consider is to start by inspecting the behaviour
of some published compressors (download a few demos!), by feeding in a special
stereo source: one track contains simple dynamically changing waveforms (even a
signal modulated with a plain LF square wave is useful; but it can be even more
useful to have steps at a range of amplitudes, especially when evaluating the
relationship between A/R slopes and threshold); the other a constant-amplitude
sine, and make sure the compressor links the channels. The output on channel 2
will effectively show the envelope the compressor is applying, and you can check
it directly against the source on the other channel. Then correlate your
observations with musical evaluation. This is simple to do in an offline editor
hosting VST plugins; load in your custom file, run the effect, and inspect the
output waveform at your leisure. How the host manages (or not) delay
compensation naturally matters too.

And (ahem) when the product is launched for which I was commissioned to supply a
"simple" compressor, you will be able to analyse that too! As a primarily
classically-oriented musician, I don't make much use of compressors, so it was
always a bit nerve-wracking designing something destined for unfamiliar musical
styles, but I was told by my commissioner that the result was very good, and
especially so on drums <grin>. For me in the end the hardest part was simply
finding a wide enough range of sound sources (voice, slap bass guitar, Bach?) to
test the da*** thing with; with synthetic test waveforms it all ~looked~ OK...


Richard Dobson
__GG
2005-12-10 23:08:27 UTC
Permalink
On Sat, 10 Dec 2005 13:55:29 GMT, Richard Dobson
Post by Richard Dobson
Any compressor is a non-linear effect, that modulates the source (watch out for
aliasing if the "corners" of the envelope are too sharp) and one way or another
will always have some sort of personality, which may or may not be deemed "musical".
Given that a sharp-cornered modulation will create harmonics, it would
seem that even a slowly ramped mod would create harmonics, albeit low
frequencies. Yet I don't remember seeing low-cut filtering on any
post-mod stages.
Post by Richard Dobson
I think you really need to try all these ideas out for yourself, and decide! I
doubt you will get a complete answer here "do it this way"
Already got some valuable insights here. If I can get enough info and
opinions on digital-domain approaches I'll be able to get a first
version running and improve it later on.
Post by Richard Dobson
Post by __GG
What is the best way to control decay/release? Given that the release
does not have to be micro-second accurate, I could add groups of, say,
100 sample abs values, then feed each into a fifo. Accumulate the
total in the FIFO by adding each new value, ...
Yes, that is a standard "closed-form" of averaging.
Envelope detection is a form of filtering, and filters can have all sorts of
slopes. The answers you seek may not be solely technical ones. For some
material, one style will work, for another it won't. The window over which
samples are scanned is itelf an important parameter,
I've also seen an approach that doesn't use a window per se. Each
time a new sample comes in, the current tally is multiplied by
(N - 1) / N. The new sample is divided by N and added in.
I'm sure there's a specific name for that type of integration.
Post by Richard Dobson
One approach you might like to consider is to start by inspecting the behaviour
of some published compressors (download a few demos!), by feeding in a special
stereo source: one track contains simple dynamically changing waveforms (even a
Great idea.
Post by Richard Dobson
And (ahem) when the product is launched for which I was commissioned to supply a
"simple" compressor, you will be able to analyse that too! As a primarily
classically-oriented musician, I don't make much use of compressors, so it was
always a bit nerve-wracking designing something destined for unfamiliar musical
styles,
Can you tell us the name of the product?

Obviously you'll lose the original range of a classical recording if
compression is applied, but there are times that I'd like to raise the
lower dynamic range above ambient traffic noise. Maybe that could be
done in the CD player or playback chain, but I'm sure your compressor
will serve a useful purpose.
Richard Dobson
2005-12-11 01:11:03 UTC
Permalink
__GG wrote:

..
Post by __GG
Can you tell us the name of the product?
Not yet; but I am told it may be released in January (unless there are delays
etc, usual caveats), so remind me sometime in the new year. Like I said, it is a
simple and basic compressor (just another leaf in the forest), maybe
indistinguishable from dozens of other simple compressors out there, and not
something there would be any point in "announcing" on public lists, even
supposing that would be a proper thing to do. I mentioned it mainly to affirm
that the suggestions I have offered reflect my own mini R&D journey making a
compressor.

Richard Dobson
r***@verizon.net
2005-12-11 01:29:33 UTC
Permalink
I have done lots of digital compressors. RMS detection is a good way to
go because of the following;

When you play a musical note on an instrument like a piano, the
harmonics are NOT pure multiples of the fundamental. So if you look at
the waveform on a scope, after the initial attack you will see parts of
the waveform that have large peaks (because the instantaneous phase of
the harmonics is aligned in a certain way) and others where the
peak-to-average ratio is quite small. Your ear does not perceive this
as a change in amplitude because it seems to just add all the harmonics
together without regard to phase (in terms of judging amplitude). Now
the only method of detection that also has this property is RMS
detection. If you use peak detection you will hear un-natural sounding
modulation artifacts on supposedly steady tones from most real
instruments as the phase of the harmonics wanders around.

RMS detectors have strange transient behavior because they look like a
1st-order lowpass filter fed by the square of the input signal. That
means the attack time-constant is dependant on the size of the
amplitude step you are making, since it gets squared before being
applied to the filter. But there is a workable compromise for the time
constant that is fast enough for most normal applications, without
causing too much distortion on steady sine-waves (RMS detectors produce
a ripple on their outputs at 2X the input frequency, causing
3rd-harmonic distortion).

Of course multi-band compressor work better in general, and allow you
to tailor the time constants to the frequency band you are controlling.
But that's a whole different topic!

Bob Adams
Richard Dobson
2005-12-11 12:45:30 UTC
Permalink
Post by r***@verizon.net
I have done lots of digital compressors. RMS detection is a good way to
go because of the following;
When you play a musical note on an instrument like a piano, the
harmonics are NOT pure multiples of the fundamental. So if you look at
the waveform on a scope, after the initial attack you will see parts of
the waveform that have large peaks (because the instantaneous phase of
the harmonics is aligned in a certain way) and others where the
peak-to-average ratio is quite small. ..
There are two distinct applications of a compressor. The first is what one might
call macro-compression, perhaps applied to a whole vocal phrase. The goal here
is to keep the overall loudness down, without (hopefully)otherwise colouring the
sound. The likely confuration would be an RMS detector, with a medium to long
attack and release times (could be as much as 300msecs). This is for example the
job of an analog conditioning chain, to tame exuberant vocals before they are
digitised.

A second application is peak transient reduction, most especially in drums,
which can generate extreme peaks which force the overlal level down to avoid
clipping. The goal here is lodness maximisation, by compressing the peaks so
that the overall level can be raised. Here a PEAK detector (typically combined
with lookahead) can work extremely well, to compress a peak that may only last a
few msecs. In other words, used this way the compressor effectively changes the
envelope of a single sound; both attack and release times may be just a few
msecs. Inevitably, the sound may be more coloured, but with drums that seems
less important than regaining all that lost headroom. Of course, one can
compromise by doing RMS detection over a very short window (say, 5msecs or even
less), and I suspect some "Peak" options in compressors actually do it this way.
I did find however that a plain peak detector, combined with a soft-ish knee,
works pretty well on drums. But on something like a piano, using this form of
compression is likely to change the character of the sound, by changing its
envelope. On drums, the timbre change between the hit and the tail is important,
so you can get away with heavy comression (which is of course a desired sound in
it own right these days) while for a piano the envelope itself is also
important; you run the risk of turning an acoustic piano into an electronic one!

Or, described yet another way, short-window or peak compression is suited to the
processing of a single (monophonic) voice, whereas macro-RMS compression may be
applied to a whole (polyphonic) mix.

Imagine the problems in compressing a polyphonic piano track, where a first note
or chord is sustained, while a second note is struck. If you set the compressor
fast enough to modify the envelope of the second note, that modification will be
applied to the sustained note too!


Richard Dobson
Jon Harris
2005-12-13 08:09:13 UTC
Permalink
Post by r***@verizon.net
I have done lots of digital compressors. RMS detection is a good way to
go because of the following;
RMS detectors have strange transient behavior because they look like a
1st-order lowpass filter fed by the square of the input signal. That
means the attack time-constant is dependant on the size of the
amplitude step you are making, since it gets squared before being
applied to the filter. But there is a workable compromise for the time
constant that is fast enough for most normal applications, without
causing too much distortion on steady sine-waves (RMS detectors produce
a ripple on their outputs at 2X the input frequency, causing
3rd-harmonic distortion).
Bob, would you mind elaborating on that a bit, i.e. the time constant compromise
stuff?
Jerry Avins
2005-12-11 02:01:24 UTC
Permalink
Post by Richard Dobson
..
Post by __GG
Can you tell us the name of the product?
Not yet; but I am told it may be released in January (unless there are
delays etc, usual caveats), so remind me sometime in the new year. Like
I said, it is a simple and basic compressor (just another leaf in the
forest), maybe indistinguishable from dozens of other simple compressors
out there, and not something there would be any point in "announcing"
on public lists, even supposing that would be a proper thing to do. I
mentioned it mainly to affirm that the suggestions I have offered
reflect my own mini R&D journey making a compressor.
Richard,

The simplest way I came up with to make a well behaved compressor with
variable compression was to use a very flat compressor (1 dB variation
of output level for 10 dB variation of input) output to one end of a
fader pot and the uncompressed signal to the other end. Setting the
slider chose the compression amount. Is your new product easily variable?

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Richard Dobson
2005-12-11 12:21:00 UTC
Permalink
Jerry Avins wrote:
..
Post by Jerry Avins
Richard,
The simplest way I came up with to make a well behaved compressor with
variable compression was to use a very flat compressor (1 dB variation
of output level for 10 dB variation of input) output to one end of a
fader pot and the uncompressed signal to the other end. Setting the
slider chose the compression amount. Is your new product easily variable?
Jerry
Not exactly in the way you describe. My design is entirely orthodox in that
there is a user-variable threshold above which the compression applies, together
with a variable compression slope. Your ratio of 10 is moderately steep (getting
towards acting as a limiter). The only other standard refinement is to offer a
choice of "hard" or "soft" knee, which simply says the transition between
uncompressed and compressed is not represented by two lines at an angle, but by
a nice rounded curve at the transition point. Just how rounded that curve might
be is where the most individuality in a compressor can come in - in the limit it
can make the whole transfer function a curve, rather than two straight lines
with a rounded corner. The "simple" code examples one sees of compressors all
use a 100% hard knee, as the code simply says "if above this value, do that". A
soft knee requires a more elaborate approach - several ways to do it, needless
to say, including the use of a literal stored transfer function. Quite a few
commercial examples offer a custom user interface where you can see the transfer
function drawn graphically, and even with control points to set parameters
graphically with the mouse**.

It is not usual in a compressor to offer a wet/dry mix control, which is what
you describe, (depends in any case on the lookahead delay compensation being
accurate, and unfortunately one cannot always rely on hosts doing that).


** One example of this is the "Cakewalk FX Compressor/Gate", supplied with
SONAR, whrere indeed you have control of two turning points withkn the one effect.



Richard Dobson
Jerry Avins
2005-12-11 16:07:57 UTC
Permalink
Post by Richard Dobson
..
Post by Jerry Avins
Richard,
The simplest way I came up with to make a well behaved compressor with
variable compression was to use a very flat compressor (1 dB variation
of output level for 10 dB variation of input) output to one end of a
fader pot and the uncompressed signal to the other end. Setting the
slider chose the compression amount. Is your new product easily variable?
Jerry
Not exactly in the way you describe. My design is entirely orthodox in
that there is a user-variable threshold above which the compression
applies, together with a variable compression slope. Your ratio of 10 is
moderately steep (getting towards acting as a limiter). The only other
standard refinement is to offer a choice of "hard" or "soft" knee, which
simply says the transition between uncompressed and compressed is not
represented by two lines at an angle, but by a nice rounded curve at the
transition point. Just how rounded that curve might be is where the most
individuality in a compressor can come in - in the limit it can make the
whole transfer function a curve, rather than two straight lines with a
rounded corner. The "simple" code examples one sees of compressors all
use a 100% hard knee, as the code simply says "if above this value, do
that". A soft knee requires a more elaborate approach - several ways to
do it, needless to say, including the use of a literal stored transfer
function. Quite a few commercial examples offer a custom user interface
where you can see the transfer function drawn graphically, and even with
control points to set parameters graphically with the mouse**.
It is not usual in a compressor to offer a wet/dry mix control, which
is what you describe, (depends in any case on the lookahead delay
compensation being accurate, and unfortunately one cannot always rely on
hosts doing that).
** One example of this is the "Cakewalk FX Compressor/Gate", supplied
with SONAR, whrere indeed you have control of two turning points withkn
the one effect.
My cobbled-together version was a variation of Mercury's microphone
compressor, but only half as good. With fast attack and modestly long
release, it was good with voice and acceptable for music. I'm sure there
are lots of ways to vary the compression with a knob. The one I used
seemed simple, so I did it. Although the compressor uses voltage
dividers with diodes as one of the elements, distortion never exceeded
.2% THD when I tested it at various levels. The design inherently has a
long tail to the decay which can be mitigated with a shunt resistor.

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Jerry Avins
2005-12-10 15:41:16 UTC
Permalink
__GG wrote:

...
Post by __GG
Here's another thought: If I were to use instantaneous peak detection
instead of RMS or other slower envelope, then lookahead would not be
necessary. The attack would track instantly.
That's probably not what you want. A very large signal following a small
one where the compressor is working at high gain will be clipped in the
first cycle, generating audible harmonics. Look-ahead gives you time to
ramp the gain down more slowly.

You should also keep the gain low when the input signal is negligible.
That keeps background noise from becoming prominent in the absence of
real signal.

...

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Richard Dobson
2005-12-10 16:55:06 UTC
Permalink
Jerry Avins wrote:

..
Post by Jerry Avins
That's probably not what you want. A very large signal following a small
one where the compressor is working at high gain will be clipped in the
first cycle, generating audible harmonics. Look-ahead gives you time to
ramp the gain down more slowly.
You should also keep the gain low when the input signal is negligible.
That keeps background noise from becoming prominent in the absence of
real signal.
In music applications this is almost always done by means of a separate
expander/gate stage. The canonical operation of a compressor is to progrssively
reduce signals above a threshold, while leaving signals below it unchanged.
There are plugins that offerthe use of arbitrary (and even hand-drawn) transfer
functions, to do both, but even here they will still tend to be thought of as a
"compressor/gate" compound device. Usually a compressor will be extended to
offer hard/soft limiting/clipping, while an expander (reduces below a threshold)
will be extended to a full gate.

Richard Dobson
Jerry Avins
2005-12-10 17:35:15 UTC
Permalink
...
Post by Richard Dobson
Post by Jerry Avins
You should also keep the gain low when the input signal is negligible.
That keeps background noise from becoming prominent in the absence of
real signal.
In music applications this is almost always done by means of a separate
expander/gate stage. The canonical operation of a compressor is to
progrssively reduce signals above a threshold, while leaving signals
below it unchanged. There are plugins that offerthe use of arbitrary
(and even hand-drawn) transfer functions, to do both, but even here they
will still tend to be thought of as a "compressor/gate" compound device.
Usually a compressor will be extended to offer hard/soft
limiting/clipping, while an expander (reduces below a threshold) will
be extended to a full gate.
Everything is a separate module in software. I was thinking of the
facilities provided in Analog Devices' SSM2166 "Microphone Preamplifier
with Variable Compression & Noise Gating". (I couldn't get their demo
board to stop oscillating, but I eventually got one working with my own
layout.) I wish car radios had compressors so I could ride over road
noise with open windows without blasting myself on louder passages. It's
not a great way to listen to music, but it's better than not listening.

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Vladimir Vassilevsky
2005-12-10 17:53:44 UTC
Permalink
Post by Jerry Avins
I wish car radios had compressors so I could ride over road
noise with open windows without blasting myself on louder passages. It's
not a great way to listen to music, but it's better than not listening.
The modern car radios have the compressors as well as the modern TVs.
The trick is how to get to the service mode so you can adjust the
parameters. The FM broadcast is usually heavily compressed too.

Vladimir Vassilevsky

DSP and Mixed Signal Design Consultant

http://www.abvolt.com
Jon Harris
2005-12-13 08:06:29 UTC
Permalink
I wish car radios had compressors so I could ride over road noise with open
windows without blasting myself on louder passages. It's not a great way to
listen to music, but it's better than not listening.
...The FM broadcast is usually heavily compressed too.
Almost always true for pop music stations, but much less so for classical
stations.
Richard Owlett
2005-12-13 20:42:25 UTC
Permalink
Post by Jon Harris
I wish car radios had compressors so I could ride over road noise with open
windows without blasting myself on louder passages. It's not a great way to
listen to music, but it's better than not listening.
...The FM broadcast is usually heavily compressed too.
Almost always true for pop music stations, but much less so for classical
stations.
I once was a studio engineer for a student operated full commercial
license FM station that was a member of the QXR network (rebroadcasting
WQXR out of NYC).

You would have been drawn, quartered, salted, boiled in oil and *THEN*
tortured for even thinking compressors etc ;!
Jerry Avins
2005-12-13 21:20:39 UTC
Permalink
Post by Richard Owlett
Post by Jon Harris
I wish car radios had compressors so I could ride over road noise
with open windows without blasting myself on louder passages. It's
not a great way to listen to music, but it's better than not listening.
...The FM broadcast is usually heavily compressed too.
Almost always true for pop music stations, but much less so for
classical stations.
I once was a studio engineer for a student operated full commercial
license FM station that was a member of the QXR network (rebroadcasting
WQXR out of NYC).
You would have been drawn, quartered, salted, boiled in oil and *THEN*
tortured for even thinking compressors etc ;!
Not at the transmitter, but in the (car) receiver. Or did you miss that?

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Richard Owlett
2005-12-15 13:02:29 UTC
Permalink
Post by Jerry Avins
Post by Richard Owlett
Post by Jon Harris
I wish car radios had compressors so I could ride over road noise
with open windows without blasting myself on louder passages. It's
not a great way to listen to music, but it's better than not listening.
...The FM broadcast is usually heavily compressed too.
Almost always true for pop music stations, but much less so for
classical stations.
I once was a studio engineer for a student operated full commercial
license FM station that was a member of the QXR network
(rebroadcasting WQXR out of NYC).
You would have been drawn, quartered, salted, boiled in oil and *THEN*
tortured for even thinking compressors etc ;!
Not at the transmitter, but in the (car) receiver. Or did you miss that?
Jerry
yes

Jon Harris
2005-12-14 06:54:44 UTC
Permalink
Post by Jon Harris
I wish car radios had compressors so I could ride over road noise with open
windows without blasting myself on louder passages. It's not a great way to
listen to music, but it's better than not listening.
...The FM broadcast is usually heavily compressed too.
Almost always true for pop music stations, but much less so for classical
stations.
I once was a studio engineer for a student operated full commercial license FM
station that was a member of the QXR network (rebroadcasting WQXR out of NYC).
You would have been drawn, quartered, salted, boiled in oil and *THEN*
tortured for even thinking compressors etc ;!
OK, but since you were just re-broadcasting other content, it would presumably
already have been squeezed where it originated.
Nowadays, many stations use a "broadcast processor", which is basically a
multi-band (like 5) compressor, plus other bells and whistles to squeeze the
heck out of the audio. Examples can be found at http://www.orban.com/ and
http://www.omniaaudio.com/.
__GG
2005-12-10 23:34:03 UTC
Permalink
On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
Post by Richard Dobson
http://www.musicdsp.org/archive.php?classid=4#204
Thanks again for the reference, Richard. I've looked through that
code and realized that I'm missing something. For one, the DC_OFFSET
that's added in "to avoid log(0)."

Another... I don't see where AttRelEnvelope is used. It looks like it
was designed to wrap two EnvelopeDetector objects (for attack and
release). However, the SimpleComp class uses two EnvelopeDetector
objects directly. No visible AttRelEnvelope.
Martin Eisenberg
2005-12-11 21:52:30 UTC
Permalink
Post by __GG
On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
Post by Richard Dobson
http://www.musicdsp.org/archive.php?classid=4#204
Thanks again for the reference, Richard. I've looked through
that code and realized that I'm missing something. For one, the
DC_OFFSET that's added in "to avoid log(0)."
The logarithm has a pole at zero, corresponding to -infinity dB. So
the code clamps the gain to some small value.
Post by __GG
Another... I don't see where AttRelEnvelope is used.
Right, the main class duplicates the functionality.


Martin
--
Quidquid latine scriptum sit, altum viditur.
Loading...