I’m a sucker for those fridge magnets and badges with the pithy apothegms. One of my favorites is “The people who say it shouldn’t be done shouldn’t interrupt the people who are doing it.” I like that because I’m also a sucker for having a go at the things that people say can’t be done.
A project from about a year ago was triggered by someone’s observation that something probably couldn’t be done. I showed that it could, which was nice. And it involved adding a transistor — well, a pair of them — which is why it made it into the current theme of this blog. Let me give you some background.
Someone wanted to try out our latest programmable SoC, the PSoC 4200, as an audio interface, taking the signal from a small, low-cost MEMS microphone. “Of course, I think the customer will want more than 12 bits,” said my colleague, referring to the 12-bit, 1 Msps ADC on that device.
Now, “bits” are not a measure of quality, and I generally bristle at statements like that. But there’s no doubt that ADC quantization can be a dominant source of noise in a digital audio system. This noise is largely uncorrelated with the signal itself, and it can actually be mitigated quite effectively by converting at a higher rate than needed and filtering or averaging the dataset before reducing the output sample rate to where you want it to be. There’s a lot of interesting stuff to be written about reducing quantization noise by filtering the output of an ADC — perhaps when we’ve got all this transistor stuff out of our systems.
Because our ADC can sample so much faster than we really need in an audio application, my plan was to use the ADC’s built-in hardware averaging (look, Ma, no CPU) to average 16 samples of the 12-bit output (it can do up to 256). This gives you a 16-bit output word, with a 14-bit noise floor at the target 16 ksps sample rate.
This noise level is still higher than that from the microphone (calculated from its datasheet). The noise properties of the op amps on the PSoC 4 are good — I calculated that the effective input noise of a preamp built with them would be comparable to the intrinsic noise from the microphone, and that was acceptable for this use. But how much gain to implement in that preamp? Too little gain, and the overall noise is too high because the ADC still dominates. Too much gain, and it could overload in a harsh and poorly controlled way when signal levels (either wanted ones or unwanted additional background noises) get too high.
Dedicated microphone front-end chips often have some form of automatic level control. When the sound level is low, they gradually ramp the channel gain up, until BOOM — something happens and they have to turn it back down because they went too far.
Some speech recognition algorithms can be impaired by fluctuating channel gain from such a fast-acting level control. So what’s often done is to keep the gain constant, but dial in a fair amount of overload margin so that the system can process a wide range of speech amplitudes successfully. If you have access to a super-low-noise dedicated audio ADC, no problem. But I didn’t. So I ended up choosing a preamp with a gain of 10, bringing the nominal signal level up to 126 mVrms (with 94 dBSPL applied at the microphone’s input port). But for really big signals, I wanted a way to knock the incremental gain down.
The technique I turned to in order to optimize the signal path for this application is one that has often found favour in audiophile circles — soft clipping . In contrast to hard clipping, the gradual reduction of incremental gain on larger signals does much less damage to the complex audio signal. We might also want the incremental gain to fall, not to zero, but to some lower finite value. Perhaps we should call that very soft clipping .
Using regular silicon diodes in an attenuator to limit signal levels is a common technique, but not very adjustable. I was looking for something a little more elegant. What would be really satisfying would be a circuit whose clipping behaviour can be adjusted by user-selectable components. So, all together now: Just Add A Transistor! Or, rather, two transistors, because this is an AC circuit and we’d quite like the behavior to be symmetrical around the zero signal state.
There’s a useful configuration, familiar to transistor amplifier designers, called the “amplified diode.” It uses a transistor and a pair of resistors to mimic a diode with an adjustable knee voltage (always greater than the intrinsic silicon diode knee voltage). The amplified diode ends up with some resistance in parallel with it — and that’s just fine, for what we want. Figure 1 shows the final circuit. The transistor type is non-critical.
A dual 2N3904 device is available in a tiny 1 mm x 1 mm package from ON Semiconductor. The resistor chain that controls the base-emitter voltages of the transistors also serves as the feedback resistor. For small signal levels the incremental gain is 1+ (R1+R2+R3+R4)/R2. When the signal level rises too high, either Q1 or Q2 will begin to conduct and pull the incremental gain down. In this non-inverting configuration the minimum gain is unity (in this case). Further splitting R2 into two can control the fully clipped incremental gain (homework!).
The clamping threshold is easily modified by adjusting the relative value of the middle resistor in the chain, while keeping the total value set to whatever is needed for the required gain. In this simple configuration, the clamping threshold will be quite dependent on temperature. Due to the temperature dependence of the transistor’s saturation current parameter, a lower base-emitter voltage is needed as the temperature rises, for any given collector current. Therefore the clamping level will fall as the temperature rises.
The input and output signals of Figure 1 when fed with a sinewave of swept amplitude are shown in Figure 2. When this configuration is used to drive our SoC’s ADC, we get the benefit of signal gain on low-level signals while still providing good intelligibility if someone is talking too loudly into the microphone.
With some care, this configuration can be used to control the gain of the sustaining amplifier in a Sallen-Key filter. You need to take the feedback component of the filter from the inverting input rather than from the output, and make the impedance of the filter network much higher than the impedance of the gain network. But it can still save you an op amp if you are really in trouble. Really useful for pulling down the size of the occasional fast input spike.
There we are. SoC functionality once more enhanced with the humble BJT. Give your audio signals a soft landing!