[Apologies in advance for possible misuse of terminology. I don't have any formal education in EE and am mostly self taught, so I may be lacking in some fundamentals.]
I am trying to design a discrete VCO (for modular synthesizer) using only transistors (2n3904/06 BJT and 2n5457 JFET) and passive components. The architecture is pretty typical for a synth VCO including expo converter, sawtooth core, and shapers for the other waveshapes. Frequency of the output waveforms is intended to cover lower range (1/1000 Hz - 20 Hz) and audible range (20 Hz - 50 kHz) enabling the VCO function as both an audio source and modulation source.
The issue that I am currently having is with the sawtooth core: the output waveform includes an unwanted DC offset by what appears to be some function of the charge current/frequency; at lower frequencies this offset is negligible but around 20 kHz it increases to as much as 500mV. In addition, the amplitude of the waveform seems to change (or the peak and trough are shifted by unequal amounts). The only effect on the signal as an audio source is a slight decrease in volume [with the offset contributing no perceivable change], however when used as a modulation source to vary the frequency of another 1v/oct oscillator the result is up to half an octave of unwanted pitch shift in the carrier waveform.

The LTspice simulation is not accurate to real life and even required several adjustments to cause oscillation, however it does demonstrate the offset issues. Offset of the waveform viewed from the node at the capacitor lead increases by about 70mV at the peak and 100mv at the trough when the frequency is swept from 10kHz to 20kHz. This signal is also amplified by the JFET input amplifier (I can't get this part of the circuit to work in LTspice), further increasing the offset at the final output.
JFET J1 is used as high impedance buffer, intended to buffer the voltage over the capacitor and nothing else; however it seems impossible to find a configuration that avoids creating a path for the charge current to enter as well. The same goes for J3. My guess is that a portion of the charge current enters the JFETs superimposing a DC offset on both the schmitt trigger input (base of Q1) and the final output signal (collector of Q7).
Any ideas on how to get rid of this offset and/or on what exactly is causing it?
One solution I have proposed is to mirror the charge current and subtract its voltage drop over a resistance from the buffered output at J1 and the final output as a sort of offset compensation. I have not had any luck with this approach, but perhaps I have implemented it incorrectly. Another solution is to AC couple the outputs, but I have not had any luck with this either.
I've spent about a week trying to resolve this with little success, so any help would be greatly appreciated. Thanks in advance.
Below are the .asc file contents:
Version 4
SHEET 1 1448 1128
WIRE 144 64 32 64
WIRE 32 144 -112 144
WIRE 176 144 32 144
WIRE 336 144 176 144
WIRE 112 224 32 224
WIRE 256 224 176 224
WIRE 336 224 336 144
WIRE -32 272 -160 272
WIRE 112 272 112 224
WIRE 256 272 256 224
WIRE 272 272 256 272
WIRE 176 320 32 320
WIRE 32 352 32 320
WIRE 336 400 304 400
WIRE 576 432 416 432
WIRE 752 432 576 432
WIRE 32 480 32 432
WIRE 336 480 32 480
WIRE 832 480 336 480
WIRE -112 512 -112 144
WIRE -16 512 -112 512
WIRE 512 512 -16 512
WIRE 576 512 512 512
WIRE 656 512 576 512
WIRE 672 512 656 512
WIRE 512 528 512 512
WIRE 656 528 656 512
WIRE 128 560 32 560
WIRE 416 560 416 432
WIRE 752 560 752 432
WIRE 32 576 32 560
WIRE 128 608 128 560
WIRE 208 608 128 608
WIRE 512 608 480 608
WIRE 688 608 656 608
WIRE 128 624 128 608
WIRE -16 640 -16 512
WIRE 32 640 -16 640
WIRE 512 640 512 608
WIRE 656 640 656 608
WIRE 32 656 32 640
WIRE 336 656 336 480
WIRE 416 656 336 656
WIRE 832 656 832 480
WIRE 304 672 304 400
WIRE 304 672 256 672
WIRE 128 704 128 688
WIRE 128 704 112 704
WIRE 208 704 128 704
WIRE 464 704 432 704
WIRE 720 704 704 704
WIRE 784 704 720 704
WIRE 912 704 864 704
WIRE 112 720 112 704
WIRE 112 720 80 720
WIRE 128 736 128 704
WIRE 432 736 432 704
WIRE 432 736 128 736
WIRE 576 736 512 736
WIRE 656 736 576 736
WIRE 32 752 32 736
WIRE 672 752 672 512
WIRE -160 768 -160 272
WIRE 32 768 32 752
WIRE 32 768 -160 768
WIRE 576 784 576 736
WIRE 576 784 496 784
WIRE 496 832 496 784
WIRE 720 832 720 784
WIRE 720 832 672 832
WIRE 1008 832 720 832
WIRE 752 880 752 656
WIRE 752 880 736 880
WIRE 128 896 128 736
WIRE 592 1008 496 1008
WIRE 672 1008 592 1008
FLAG 144 64 0
FLAG 32 576 0
FLAG 912 704 0
FLAG 832 880 0
FLAG 352 880 0
FLAG 592 1088 0
FLAG 128 976 0
SYMBOL voltage 32 160 R180
WINDOW 0 24 96 Left 2
WINDOW 3 24 16 Left 2
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName V1
SYMATTR Value 12
SYMBOL res 16 128 R0
SYMATTR InstName R1
SYMATTR Value 1k
SYMBOL res 160 128 R0
SYMATTR InstName R2
SYMATTR Value 5k
SYMBOL npn -32 224 R0
SYMATTR InstName Q1
SYMATTR Value 2N3904
SYMBOL npn 112 224 R0
SYMATTR InstName Q2
SYMATTR Value 2N3904
SYMBOL npn 272 224 R0
SYMATTR InstName Q3
SYMATTR Value 2N3904
SYMBOL res 16 336 R0
SYMATTR InstName R3
SYMATTR Value 1.5k
SYMBOL res 320 304 R0
SYMATTR InstName R4
SYMATTR Value 530
SYMBOL res 320 384 R0
SYMATTR InstName R5
SYMATTR Value 1k
SYMBOL voltage 32 464 R0
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName V2
SYMATTR Value -12
SYMBOL njf 256 608 M0
WINDOW 0 53 -51 Left 2
WINDOW 3 -21 -18 Left 2
SYMATTR InstName J2
SYMATTR Value J2N5457
SYMBOL cap 112 624 R0
SYMATTR InstName C1
SYMATTR Value 47n
SYMBOL njf 464 640 R0
WINDOW 3 54 50 Left 2
SYMATTR Value J2N5457
SYMATTR InstName J3
SYMBOL njf 704 640 M0
SYMATTR InstName J4
SYMATTR Value J2N5457
SYMBOL pnp 480 656 R180
SYMATTR InstName Q4
SYMATTR Value 2N3906
SYMBOL pnp 688 656 M180
SYMATTR InstName Q5
SYMATTR Value 2N3906
SYMBOL res 560 416 R0
SYMATTR InstName R6
SYMATTR Value 390
SYMBOL res 496 512 R0
SYMATTR InstName R7
SYMATTR Value 5.1k
SYMBOL res 640 512 R0
SYMATTR InstName R8
SYMATTR Value 5.1k
SYMBOL res 848 640 R90
WINDOW 0 8 95 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R9
SYMATTR Value 100
SYMBOL res 880 688 R90
WINDOW 0 8 31 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R10
SYMATTR Value 15k
SYMBOL res 704 688 R0
SYMATTR InstName R11
SYMATTR Value 36k
SYMBOL res 656 736 R0
SYMATTR InstName R12
SYMATTR Value 50k
SYMBOL npn 432 832 R0
SYMATTR InstName Q6
SYMATTR Value 2N3904
SYMBOL npn 736 832 M0
SYMATTR InstName Q7
SYMATTR Value 2N3904
SYMBOL res 448 864 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R13
SYMATTR Value 1k
SYMBOL res 848 864 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R14
SYMATTR Value 1.5k
SYMBOL res 480 912 R0
SYMATTR InstName R15
SYMATTR Value 10k
SYMBOL res 656 912 R0
SYMATTR InstName R16
SYMATTR Value 8.2k
SYMBOL voltage 592 992 R0
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName V3
SYMATTR Value -12
SYMBOL current 128 976 R180
WINDOW 0 24 80 Left 2
WINDOW 3 24 0 Left 2
WINDOW 123 0 0 Left 0
WINDOW 39 0 0 Left 0
SYMATTR InstName I1
SYMATTR Value PWL(0 500u 10 10m)
SYMBOL njf 80 656 M0
SYMATTR InstName J1
SYMATTR Value J2N5457
TEXT -160 1112 Left 2 !.tran 0 10s 0 0.0001s startup
I am using the following model for the 2n5457s:
.model J2N5457 NJF(Beta=1.125m Betatce=-.5 Rd=1 Rs=1 Lambda=2.3m Vto=-1.372 + Vtotc=-2.5m Is=181.3f Isr=1.747p N=1 Nr=2 Xti=3 Alpha=2.543u + Vk=152.2 Cgd=4p M=.3114 Pb=.5 Fc=.5 Cgs=4.627p Kf=10.45E-18 + Af=1)