# Automatic Gain Control for voice

I am tasked with designing the logic for an automatic gain control. It won't be a traditional AGC in that it has to run on a computer and continuously modifying the volume is not possible in the same way as it is in hardware. It will be more of a "roughly set the input gain for me automatically if it's way off" than an AGC per se. However, I plan to approach the design in the same way.

This will be used primarily for voice/speech, so what I want to do is prevent incoming silence (when the speaker is not speaking) from causing the gain to be set too high. I would like to avoid anything as complex as voice activity detection as well as complex ad-hoc methods that involve deriving more than a few simple parameters -- at least for now.

Are there any simple tricks I can use to to help with this problem, or is the best approach to use full-fledged voice activity detection?

-
It sounds like you might be able to use typical AGC techniques, only with a long time constant. This would allow you to make changes infrequently (since the recommended gain setting will change slowly over time), and to suppress problems caused by short periods of silence (by averaging over a long time period). For longer periods of silence, you could implement a simple activity detector that would cease updating the loop in the event that there was no significant energy for a long time. Is there a lot of background noise? Do you have latency requirements for the initial adjustment? – Jason R Sep 21 '12 at 20:24
in some cases there may be a lot of background noise, and latency must be very short (though it's not technically specified) because this is not for conversations, but rather short phrases and sentences. Nevertheless, your solution might be good enough for prototyping, which is the current goal. – Bjorn Roche Sep 21 '12 at 20:55
To use compressor parlance, I may have options for different attack and release times, so not letting it increase gain too fast, but clamping down fast in the event of distortion might be okay, especially for the first prototype. – Bjorn Roche Sep 21 '12 at 20:58

Two things come to mind.

First, let's address the low-amplitude noise problem. This one is a typical textbook case for a noise gate. To give you an extreme example, these are sometimes even used on guitar distortion effects which are essentially insane amounts of controlled overdrive. I have to admit that I failed to find any literature on creating digital noise gates, but they exist abundantly as plugins so maybe digging through some open-source projects will score you a good basis for learning how to implement them. In essence, you measure windowed energy of a signal, and if it falls below a certain threshold, you fade your gain to zero (usually decaying exponentials are used). In any case, I'm sure you know what a noise gate is and I'm beating around the bush here. Make one and use it.

Secondly, when you say roughly set the input gain for me automatically if it's way off, that sounds like a textbook case for using a fuzzy controller. I'm linking to the Wikipedia page because I'm feeling a bit lazy, but you can find tons of great papers out there just on the first ten pages of Google results. The concept is exactly as you described it. You'll have several (say five for the sake of a simple example) levels of how close the gain is to what you think it should be:

- Way too low
- Low
- High
- Way too high


Based on these you will have some sort of fuzzy response like:

- Increase at a high rate
- Increase at a low rate
- Do nothing
- Decrease at a low rate
- Decrease at a high rate


These are my thoughts on how I would do it. You still need some means of measuring your fuzzy control input (assessing how good current gain level is), but that's something for you to work out. I'd say that if you're riding very close to clipping, that's High, if you've clipped, that's Way too high, and so on. Depending on what the spec considers acceptable, fuzzy control can sometimes let you get away with very simple solutions.

-
1. Yes, noise gating (or really downward expansion) is obviously being considered, as are other methods, but how to set the gate threshold? Even once that's set, it changes if you change the input gain, since, as I said in the question, I'm using AGC. 2. Saying "use fuzzy logic" doesn't really help answer the question. Central to my question is, "I want to... prevent incoming silence (when the speaker is not speaking) from causing the gain to be set too high" And this doesn't help. – Bjorn Roche Sep 27 '12 at 4:19