Audio Compressor/AGC in C or C++
CASTalk.com Forum Index CASTalk.com
Discussion of DSP, FPGA, storage and embedded system.
 
 FAQFAQ   MemberlistMemberlist     RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Google
 
Web castalk.com
Audio Compressor/AGC in C or C++
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CASTalk.com Forum Index -> DSP
Author Message
Richard Dobson
Guest





Posted: Sat Dec 10, 2005 5:15 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

__GG wrote:

...
Quote:
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?


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.



Quote:
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
Back to top
Jerry Avins
Guest





Posted: Sat Dec 10, 2005 5:16 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

__GG wrote:

...

Quote:
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.
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Back to top
Richard Dobson
Guest





Posted: Sat Dec 10, 2005 5:16 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Jerry Avins wrote:

...
Quote:
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
Back to top
Jerry Avins
Guest





Posted: Sat Dec 10, 2005 11:35 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Richard Dobson wrote:
Quote:
Jerry Avins wrote:

...

Quote:
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.
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Back to top
Vladimir Vassilevsky
Guest





Posted: Sat Dec 10, 2005 11:53 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Jerry Avins wrote:


Quote:
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
Back to top
__GG
Guest





Posted: Sun Dec 11, 2005 1:16 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

On Sat, 10 Dec 2005 13:55:29 GMT, Richard Dobson
<richarddobson@blueyonder.co.uk> wrote:

Quote:
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.

Quote:
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.

Quote:
G:
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.

Quote:
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.

Quote:
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.
Back to top
__GG
Guest





Posted: Sun Dec 11, 2005 1:16 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
<richarddobson@blueyonder.co.uk> wrote:

Quote:
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.
Back to top
Richard Dobson
Guest





Posted: Sun Dec 11, 2005 1:16 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

__GG wrote:

...
Quote:
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
Back to top
Guest






Posted: Sun Dec 11, 2005 7:29 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

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
Back to top
Jerry Avins
Guest





Posted: Sun Dec 11, 2005 8:01 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Richard Dobson wrote:
Quote:
__GG wrote:

..

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.
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Back to top
Jerry Avins
Guest





Posted: Sun Dec 11, 2005 5:15 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Richard Dobson wrote:
Quote:
Jerry Avins wrote:
..

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.
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Back to top
Richard Dobson
Guest





Posted: Sun Dec 11, 2005 5:15 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

Jerry Avins wrote:
...
Quote:
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
Back to top
Richard Dobson
Guest





Posted: Sun Dec 11, 2005 5:15 pm    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

robert.w.adams@verizon.net wrote:

Quote:
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
Back to top
Martin Eisenberg
Guest





Posted: Mon Dec 12, 2005 3:52 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

__GG wrote:

Quote:
On Fri, 09 Dec 2005 21:52:25 GMT, Richard Dobson
richarddobson@blueyonder.co.uk> wrote:

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.

Quote:
Another... I don't see where AttRelEnvelope is used.

Right, the main class duplicates the functionality.


Martin

--
Quidquid latine scriptum sit, altum viditur.
Back to top
Jon Harris
Guest





Posted: Tue Dec 13, 2005 9:15 am    Post subject: Re: Audio Compressor/AGC in C or C++ Reply with quote

"Vladimir Vassilevsky" <antispam_bogus@hotmail.com> wrote in message
news:ICEmf.35582$Zv5.15048@newssvr25.news.prodigy.net...
Quote:


Jerry Avins wrote:

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.
Back to top
 
Post new topic   Reply to topic    CASTalk.com Forum Index -> DSP All times are GMT
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum




VoIP Electronics Powered by phpBB