Discrete preamp / headamp based on cascaded diamond amp

This is another design stemming from my forays into low power, reasonably high performance amps with jellybean transistors (BC547, 2N3904/3906, BD179/180).

My "power amp" designs from this are in the single-digit PPM distortion range, so I wanted something to preserve that and give me an accurate volume control.

The first section is a three-stage amp with a diamond follower after the VAS, this then drives a six-bit relay based attenuator, then the output of that goes into a driver stage (another three-stage amp), with a cascaded diamond driver on the output.

On simulation for the composite amp I'm getting around 3nV/sqrtHz input referred noise, gain adjustable from -31dB to +32dB (in 63 1dB steps), and 1 PPM 10KHz THD pushing 10V into 50 ohms.

It's designed to be reasonably friendly, with DC servo to keep offset down, plus clipping management in the output stage. It'll drive loads down to ~8Ω with no problems, including headphones and little full-range speakers.

I've added a few parts to the input to allow flexibility in source - it can be set up so that either (or both) sides are inverting or non, so can be used as either a stereo single-ended preamp or a mono differential preamp.

I've added a regulator for the front end stage and DC servo, as the DC servo compromises PSRR a little (reducing it from ~90dB to ~60dB). The reg adds ~60dB PSRR.

The whole lot is on a simple 127mm x 100mm PCB. MELF resistors and diodes, 1206 caps, and a mere 157 through-hole transistors. With no exotic parts it should be fairly straightforward and reasonably inexpensive to build.

Attached LTspice sim of the amplifier chain, plus a couple of screen grabs of schematic and PCB, plus zip file containing all the design files in KiCAD format, including Gerbers for manufacture.
 

Attachments

  • Complete Preamp 3nVrtHz 1ppm.asc
    33.5 KB · Views: 183
  • Screen Shot 2018-02-24 at 4.03.34 pm.jpg
    Screen Shot 2018-02-24 at 4.03.34 pm.jpg
    294.9 KB · Views: 1,104
  • Screen Shot 2018-02-24 at 4.02.33 pm.jpg
    Screen Shot 2018-02-24 at 4.02.33 pm.jpg
    725.1 KB · Views: 1,120
  • Discrete Stereo Preamp Rev 1.0 24 Feb 2018.zip
    531.2 KB · Views: 144
Here's a couple of pics of the prototype. It's mostly working, and I'm listening to some Alan Parsons Project through my headphones (Sennheiser HD595s) using it as I write this.

Assembly took a while - I'd estimate about ten hours. There are a fair few components. I got a bit of a crick in my neck from hunching over for so long.

Initially I was running the first stage at a gain of 10, and the second stage at a gain of 4, so a gain of 40 overall flat-out. Alas the second stage bursts into oscillation at about 9-10 MHz with the gain of 4. 470pF across R150 and R151 helps, but doesn't get rid of it completely. I shut it up for now by increasing second stage gain to 11, so the overall gain is now 110 flat out, but I'd like to work further on the second stage compensation to solve the problem at the root.

The DC servo also doesn't work properly - I dunno what I was thinking when I connected it up to the first stage - changing the volume setting really messes with it - I'll patch it in to the second stage after the attenuator relays, but for now it's simply disabled (I removed R8 & R10). Output DC is about 40mV with no DC servo, which is pretty poor.

The relays work a treat. I couldn't find a single pair of resistors to give me an accurate 32dB attenuator, so ended up with a 27Ω and 680Ω in parallel as the shunt with 1K in series - thus far I'm 1dB per step +/-0.1dB across the whole 64dB range.

Now one thing is that the whole lot has _way_ more gain than I need - at least with my Mac as the source and driving my Sennheiser cans. With the Mac volume control at about 1/3, minimum setting is still quite audible. I've got 41dB gain in the two stages, so minimum setting is -22dB and max setting is +41dB. I probably want to run it with a 20dB input attenuator when using the Mac as the source. Really though I need to further work on the compensation so I can push the gain stages down - something like x4 and x4 (-39dB to +24dB) would probably be ideal.

I'm measuring ~6nV/√Hz input referred noise at 1KHz, which is a little higher than I was anticipating. I wonder if that also isn't due to the compensation issues... In any case, I can't hear anything at all through my cans when the input is turned off, so that's promising. It sounds completely clear, with no hint of saltiness, and just the right level of snark (Sorry, I'm completely useless at audiophile ******** words, so have to be completely objective). Interestingly, it all works fine down to about +/-5V, even with the first stage reg completely out of regulation, which is nice.

Power consumption is a thoroughly shameful 250mA at +/-15V, or 7.5W. I might reduce the final stage bias current by a pile, as I'm being terribly wasteful. That said, nothing is too hot to touch.

Anyway, much more to come - I'll get back to working on compensation so I can get my gain back down.
 

Attachments

  • IMG_0231.jpg
    IMG_0231.jpg
    982.9 KB · Views: 915
  • IMG_0232.jpg
    IMG_0232.jpg
    1 MB · Views: 821
Last edited:
It sounds completely clear, with no hint of saltiness, and just the right level of snark (Sorry, I'm completely useless at audiophile ******** words, so have to be completely objective).
Would love to see this sort of language in a magazine review - it's much easier to understand than the usual drivel they write :D

Nice to see that it works, even if there are a few hiccups still left to sort out ;)

/U.
 
Okay - got the compensation for the output stage sorted so I can drop the output stage back down to 4:

- reduced C58-C61 from 1n to 470p,
- increased C53-C66 from 22p to 100p,
- reduced R212, R213, R216, R217 from 680Ω to 220Ω.

Similarly worked the input stage compensation to get it's gain down to 4:

- decreased C31-C34 from 150p to 100p

I also reduced the bias current in the first stage diamond output, as it was running pretty warm - I increased R113, R115, R116, & R119 from 100Ω to 220Ω. Overall quiescent current is now 220mA at +/-15V, down from 250mA.

So it's stable now with max gain of x16 (overall gain range setting from -39dB to +24dB in 1dB increments). Works much better with my Mac as a source.

With the improved stability I ditched the dodgy 470p caps I previously added at the input to the second stage.

I measure noise at 70nV/√Hz at the output, with gain set to max and input shorted. That's 4.3nV/√Hz input referred - I guess with just x4 gain in the first stage, my second stage is adding 1nV/√Hz or thereabouts, which is no doubt why I went for 20dB first stage gain in the first place. With most gain settings (up to about +15dB gain setting) I just see the output - measuring 23nV/√Hz output referred. This is getting pretty close to the noise floor of my spectrum analyser, so isn't a terribly accurate figure - in any case, it's quiet.

So that's the good news. Bad news is the input stage has a huge H2 (and only H2, from what I've been able to ascertain) spike at about -75dB. It's there regardless of input level and gain setting. I've attached a spectrum analyser shot (1V RMS out into 47Ω, attenuator setting of 3dB).

So I'm going to have to revise my earlier statement of it sounding completely clear with no hint of saltiness. It sounds warm. Way too bloody warm for my tastes. Actually I have to admit my cloth ears can't tell the difference from this god-awful distortion and much better amplifiers, but that's totally beside the point.

Looking at the layout, I really didn't worry too much about the placement of the input stage feedback components - they're just plonked wherever they'd fit. I'm reasonably confident that's the culprit.

Between that and the DC servo stuff-up, I reckon I'll be ordering some Rev 1.1 PCBs shortly.

One day I'll design something that works perfectly on the first try. Actually that's not really true - I design stuff that works fine all the time - it's just they're boring things that aren't stretching anything.
 

Attachments

  • IMG_0421.jpg
    IMG_0421.jpg
    633.5 KB · Views: 715
Last edited:
Founder of XSA-Labs
Joined 2012
Paid Member
So that's the good news. Bad news is the input stage has a huge H2 (and only H2, from what I've been able to ascertain) spike at about -75dB. It's there regardless of input level and gain setting. I've attached a spectrum analyser shot (1V RMS out into 47Ω, attenuator setting of 3dB).

-75dB of H2 and only H2 under all conditions is very nice for a headphone amp. One person’s bad news is another’s good news. :)

Is it still H2 dominant at 8vrms into 47ohms?
 
Last edited:
You could have -75 dB of H2 with a much more simple circuit though (like 3-4 transistors or so?)... this one is ridiculously complex for what it does. I mean, folded cascode - WHY? You've got a +/-12V supply and maximum input levels of 2..2.5 Vrms, nobody needs anything close to rail/rail input here. Besides, folded cascodes with discrete parts tend to suck. Just use a regular bootstrapped cascode and be done with it. And having 3 differential stages is luxurious for a gain of 20 dB but downright silly at 12 dB.

BTW, do the math on input overload levels. At 12 dB the input stage would just about accept 2 Vrms in before clipping, which is rather too tight for my tastes. I'd go closer to 6 dB, or even unity gain - reduce impedance levels between stages accordingly and increase second stage gain as needed, also consider making it low-noise input. SNR = signal power / noise power, so it can be the same at lower impedance with lower voltage and higher current levels or higher impedance with higher voltage and lower current levels, whatever is most practical given your constraints. In a headphone amp you spend most of the time with volume turned down, meaning the second stage tends to be the more critical noise-wise.

What's the point of R8? I don't want to see output DC offset at high gain given a higher-impedance or AC-coupled output. Also, 2n2 of input capacitance? Seems a tad high.

The value of very low noise in a line-level input stage is rather debatable. In all likelihood, the output noise level of whatever source you connect it to is going to be approximately a gazillion times higher, and it's going to be attenuated severely by the volume control, so why bother? One input pair run at 200 µA is going to do the job just fine. (I've argued the same with the O2 headphone amp.) Keep in mind you'll want to accomodate source impedances of up to 2.2 kOhms or so, so it won't hurt if input current noise levels and input bias current related nonlinearity are at least semi-reasonable.

IMHO, this design elegantly manages to miss the systems engineering forest for the circuit design trees.
 
Last edited:
I think I've got my head around the excess H2 in the first stage, and fixed the DC servo so it works properly.

Essentially for the DC servo I disconnected R8 from the first stage and connect it to the input of the second stage instead. I also reduced the trimpot from 1M to 10K, and removed R49 to better balance the impedance seen by either side of the DC servo diff amp. Reducing R51 and R63 to 220K (from 470K) also helps reduce the DC servo's own offset.

The DC servo still doesn't work when the attenuator is set to minimum, as the impedance looking back into the first stage is then very low, so any first stage offset carries straight through. For now I'm just not setting the attenuator to 0dB, but for the next rev I'll add a fixed attenuator on the output of the first stage so I'm always seeing a reasonable impedance.

I then set to work improving the impedance balance at the first stage to reduce it's offset. I changed R1 and R3 to 4K7 each (giving me a 6dB attenuator on the input), and increased the input stage feedback resistors from 300Ω/100Ω to 3K/1K.

As well as reducing first stage DC offset this also significantly improved H2 to around -82dB, as there is an imbalance in the first stage feedback layout, so feedback currents aren't taken evenly from both source and sink. Increasing the feedback resistors again to 5K/15K makes slightly better H2, to the point where I'm hitting the spec-an limit so will need to use my notch.

I've included a picture - despite saying 100mV this is actually a 1V output (I've been using a X10 CRO probe on the spec-an, as it's more convenient than making up cables). Anyway, this is 1KHz, 1V RMS out into 47Ω, with the attenuator set to -3dB.

So I'm confident that by simply changing where I sample the first stage output to the input of the attenuator, plus a few mods to the DC servo, I should be seeing single digit THD performance.
 

Attachments

  • IMG_0422.jpg
    IMG_0422.jpg
    667 KB · Views: 171
Last edited:
Here's a 50 KHz square wave and an overdriven 50KHz sine wave, to show slew rate and clipping behaviour.

There's a teensy bit of HF ringing on the square wave response - I'll keep playing with the compensation networks to see if I can't clobber that. Slew rate is around 9V/µs. As with previous iterations of the output driver the clipping control circuit works well and ensures there's no sticking.

Supplies are set to +/-15V here with a output load of 47Ω, -3dB attenuator setting. My CRO, unlike my spec-an, is clever enough to know I've got a X10 probe connected and display the right numbers.
 

Attachments

  • IMG_0424.jpg
    IMG_0424.jpg
    565.3 KB · Views: 375
  • IMG_0423.jpg
    IMG_0423.jpg
    573.8 KB · Views: 381
And a bit more hardware to make the whole lot work. This little board will, once programmed, convert gray scale from the Bourns EM14 rotary encoder to six bit binary for the relays, plus display a handy number on the 7 segment display.

Last time I did a micro controller was a decade ago, and I chose a Microchip PIC based on the availability of a free Hitech C compiler. So naturally I just grabbed the 28 pin version of the same chip, so that I can recycle as much code from my previous preamp as possible.

Alas now I find that Microchip bought Hitech, and discontinued the free C compiler. So I've gotta do some searching to work out how I can write code for the little PIC16F876 on here without spending a fortune.
 

Attachments

  • IMG_0426.jpg
    IMG_0426.jpg
    587.1 KB · Views: 383
  • IMG_0430.jpg
    IMG_0430.jpg
    598.3 KB · Views: 377
One of the fun things about testing amps with RF test gear is that you're able to test rather silly meaningless things.

For example here's a plot of 100KHz THD, putting 1V RMS into 47Ω. This is done using my HP3325B as a source, which while pretty awful at audio frequencies is good for 20 MHz.

The only harmonic above the noise here is H2, down 72dB. So that's 0.03% :p

Anyway, nice to know it's reasonably fast.
 

Attachments

  • IMG_0431.jpg
    IMG_0431.jpg
    640.1 KB · Views: 334
This micro controller development is proving to be a real pain.

I built a preamp perhaps ten years ago, based loosely on Hennessy's (Audio Projects › Hi-Fi Preamp). Details are at A HiFi Preamp

Fairly straightforward - source select relays, PGA2310 volume control, optical encoder, nice VFD for displaying source and level. I wrote the code in C using the free Hitech PICC-Lite tool, which is crippled but good enough for the purpose. This has been running happily in my lounge room ever since.

So I figured I'd keep the design of this similar, for code reuse etc. I picked a PIC16F876A MCU (28 pin version of the 44 pin PIC16F877 I used previously), and simplified things a bit, for example using seven segment LEDs rather than the expensive VFD, and no source select stuff.

Rather than using another power supply, I included a little low noise Linear Tech LT1777 buck converter. This generated 5V for the processor and relays directly from +/-15V (quite nicely actually - it's really quiet - both on input and output)

I've attached a schematic.

So that's the straightforward part. Now onto code problems. It appears Microchip bought Hitech PICC years ago and absorbed it. Not to worry, I downloaded the new tools and hit the first stumbling block. They don't work with my MPLAB ICD2 that I bought for the previous development, and the new MPLAB ICD3 is $270. Or more than I've spent for everything else on the preamp.

Okay, I can find a copy of Hitech PICC Lite (http://www.cs.ucr.edu/~eblock/pages/pictools/install.html) and use that. All goes well until I try to build, then the compiler borks saying it doesn't support the PIC16F876A. Turns out the Lite version of PICC has an astonishingly small list of supported chips (and what's with the literally thousands of PICs that essentially do the same thing, anyway?), and while the PIC16F877 is supported, the PIC16F876A (which shares the same data sheet, and is the same in practically every way except for pinout) isn't.

Bummer. Okay, let's keep searching. Turns out that if you dig really deeply, there's an FTP server at Microchip with archive versions of the old Hitech PICC products (HI-TECH Software Archive).

So I download PICC standard 9.5 and point to that. It bleats that it's going to stop working in 45 days, which is really the way to put the pressure on. Now I can at least build the code, but I'm unable to connect to my MPLAB ICD2. This may be because I run windows in a VM on my Mac, but really I've just totally lost patience with this rubbish.

It shouldn't be this hard. I'm wondering if the cheapest way to progress this is simply to abandon the microchip stuff and try again with an Atmel AVR. Certainly there's gotta be a cheaper way forward than $270 for an ICD3.
 

Attachments

  • Screen Shot 2018-04-29 at 6.04.45 am.png
    Screen Shot 2018-04-29 at 6.04.45 am.png
    287.2 KB · Views: 212
Last edited:
Yeah, the Arduino duo is based on an ATmega328. I figure I can use the ATmega328 (28 pins) and do what I want to do. Only downside is that it's not available in a SOIC, but rather a 32 pin QFP, which is a bit harder to solder.

Before I do a board respin though, I've discovered the PICKIT3, which is a stripped down basic download cable that appears to support the trifecta of PIC16F876A, MPLAB X (current IDE) and MacOS... And it's $60, which is a whole lot more palatable than $260.
 
I've managed to work out how to program the chip - the secret was buying a "pickit 3", which allows programming of the PIC16F876A from MPLAB X, which also works (natively under MacOS) with the PIC16F876A.

So, all good. I've attached a few photos of the mostly sorted thing. Power is from a pair of little Traco 15W SMPS moduless. The display works really well (and looks a lot better than my phone photos show), the little Bourns EM14 rotary encoder is quite nice, with a good solid feel

It isn't completely silent with no input - I suspect the switching supplies - there's a barely perceptible murmur. Also I'm getting pops with multiple-bit steps at higher levels - 31-32, 47-48, 55-56 are particularly noticeable. I'll have to do some reading on algorithms for popless switching. But really, it's never going to be quiet when spinning the volume knob with all the relay clicking going on.

I've also attached a photo of the whole setup, with this driving my little noiseunit 2 way transmission line speakers sitting on their new active crossover/amplifier boxes.
 

Attachments

  • IMG_0273.jpg
    IMG_0273.jpg
    915.3 KB · Views: 174
  • IMG_0274.jpg
    IMG_0274.jpg
    983.1 KB · Views: 166
  • IMG_0278.jpg
    IMG_0278.jpg
    660.9 KB · Views: 185
Here's the code I'm running now. It's all in one file, as It's been many years since I've done any programming at uni and I couldn't be bothered making it look pretty. For the same reason it's nowhere near as modular as it should be.

However, it works nicely.

The encoder I bought has a pushbutton as well as the spinny bit. That's used both for toggling power and for setting brightness of the display. If you simply press the knob, the power turns on or off. If you press the knob and turn it while pressed, the display brightness can be set over five levels including no display. This is important for me as I typically have these things next to my bed, and really dislike glowing LEDs at night.

There's an oops - Port RA4 on the PIC is open collector, so it isn't able to source current to turn on Q4 and thus toggle the 2dB attenuator relay. Additionally the load of six little attenuator relays plus the display plus the big mute relay on the preamp board is a bit much for the LT1777 DC-DC converter that I'm using to get 5V, which runs uncomfortably warm. I decided to do away with the mute relay, which is the biggest load, and reorganised the attenuator relay drive lines to skip RA4. That way no PCB changes are needed.

There's a bit of a pop from the 31-32 transition, and also from the 47-48 transition. I really haven't been able to get rid of these, despite lots of stuffing around in the code in an attempt to do so. I think the only real way to do it is to ensure that the relays change on a zero crossing so there's no possibility of latching DC. However by slowing the relay update a lot I did significantly reduce the amount of clicking when you spin the encoder, as it's able to do up to 8dB in level change on a single relay update cycle.

The forum won't let me upload a .c file, so I changed the extension to .txt.

Anyway, here's the code, warts and all.
 

Attachments

  • preamp.txt
    15.2 KB · Views: 93