Previous Thread
Next Thread
Print Thread
Page 1 of 7 1 2 3 4 5 6 7
Netlist: 280-ZZZAP sound problems #117139 04/11/20 09:58 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
For the last week or so, I've been working on a netlist sound implementation for Midway's 280-ZZZAP and Laguna Racer. (Both use the same sound circuits, with only a few minor component variations in some Laguna Racer versions. These same circuits also provide the sound for Taito/Midway's Super Speed Race (sspeedr.cpp).) If I could get this working acceptably, it would give sound to the last remaining soundless games in the mw8080bw.cpp driver.

Unfortunately, although I've created a complete netlist for the sound circuits (everything from the TTL latch outputs to the audio power amp inputs), I'm not at all happy with the result. It's much too slow, and much of this slowness is because it's plagued with convergence problems. When run by nltool, it spews many many warnings of NEWTON_LOOPS being exceeded.

I think most of the convergence issues are caused by three oscillators that generate the game's "engine" sound. This means they're running all the time, and since they vary in frequency with the car's speed, they can't be easily substituted with samples. (I assume this is why samples-based sound has never been added to this driver.)

The oscillators are voltage-controlled triangle-wave generators, with the input voltage controlling frequency (amplitude is fixed). Each is built around a pair of LM3900 Norton (current-differencing) op-amps and a CD4016 switch. Here's a schematic of one of them, taken from the Laguna Racer audio board schematics. (The 280-ZZZAP board schematic is identical, but this one is a bit clearer.)

[Linked Image from i.imgur.com]

(The MC3340 isn't part of this oscillator but accepts its output as an amplitude-modulation signal for the summed output from the other two oscillators; the result is the overall engine sound.)

The left op-amp is an integrator that generates the triangle wave output. The right op-amp generates a square wave which switches the CD4016 on and off, reversing the sign of the integration, and thus the triangle wave's slope.

I think the convergence problems are happening because the square wave makes the circuit state change so abruptly at each edge that the solver can get far off track, and it isn't able to return to a sane solution before running out of iterations (hence, NEWTON_LOOPS is exceeded).

I tested a smaller netlist, containing only the fastest oscillator at a fixed input voltage of 3.7 volts, about the highest input voltage the actual circuit should receive:

Code
#include "netlist/devices/net_lib.h"

NETLIST_START(oscillator)

	SOLVER(Solver, 48000)

	ANALOG_INPUT(I_V12, 12)
	ANALOG_INPUT(I_V5, 5)
	ANALOG_INPUT(I_V_CONTROL, 3.7)

	CD4016_DIP(J4)
	NET_C(J4.7, GND)
	NET_C(J4.14, I_V5.Q)
	NET_C(GND, J4.6, J4.8, J4.9, J4.3, J4.4, J4.5, J4.10, J4.11, J4.12)

	LM3900(J3_2)
	LM3900(J3_1)

	NET_C(I_V5.Q, J3_2.VCC, J3_1.VCC)
	NET_C(GND, J3_2.GND, J3_1.GND)

	RES(R29, RES_K(220))
	RES(R30, RES_K(110))
	RES(R28, RES_K(100))
	RES(R26, RES_K(470))
	RES(R27, RES_K(270))

	RES(R25, RES_K(3.3))
	NET_C(R25.2, GND)

	RES(R23, RES_K(10))
	NET_C(R23.1, I_V12.Q)

	CAP(C14, CAP_U(0.01))
	CAP(C13, CAP_U(10))

	NET_C(I_V_CONTROL, R29.1, R30.1)
	NET_C(R30.2, J4.1)
	NET_C(J4.2, J3_2.PLUS)
	NET_C(R29.2, J3_2.MINUS, C14.1)
	NET_C(J3_2.OUT, C14.2, R28.1, C13.1)
	NET_C(R28.2, J3_1.MINUS)
	NET_C(J3_1.OUT, R27.1, J4.13)
	NET_C(I_V5.Q, R26.1)
	NET_C(J3_1.PLUS, R26.2, R27.2)
	NET_C(R23.2, C13.2, R25.1)

NETLIST_END()


Running this netlist in nltool, a simulated 20-second run takes about 6.8 seconds (3 x speedup) and generates about 10,300 NEWTON_LOOPS warnings, which works out to at least one warning on every oscillation cycle. The resulting output waveform looks pretty ragged when zoomed out, due to variations in level which can be seen clearly when zoomed in. This raggedness turns out to be plainly audible, giving a ragged sound.

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

The switching square-wave waveform is worse: it is absolutely full of spikes which are presumably correlated with the NEWTON_LOOPS warnings. Some of these spikes reach extreme, quite unrealistic voltages, though most are more moderate.

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

The obvious problem here is the timestep: a static timestep at 48000 Hz is much too long for such a fast-switching circuit. By using dynamic timestepping, I was able to completely eliminate the NEWTON_LOOPS warnings for this oscillator over a 20-second run, but only by reducing the minimum timestep to an extremely short value of 1e-8 (10 nanoseconds). This small netlist actually ran a bit faster with that (6.1 seconds for a simulated 20 seconds) and the output waveform looked and sounded much smoother:

[Linked Image from i.imgur.com]

[Linked Image from i.imgur.com]

The switching waveform still has spikes, but only relatively short ones which don't seem to affect the output.

However, for the full game netlist, using dynamic timestepping with such a small minimum timestep is totally impractical—in fact, it proved to be so unbelievably slow that I gave up trying to test it!

I'm not sure how to solve this problem, but it seems to me that the most efficient approach would be to not simulate the oscillators at the component level at all, but instead replace them with functional blocks that generate the variable-frequency triangle waves directly. (The old discrete code has such blocks, of course.) Is such an approach considered compatible for netlist? Is this sort of usage something that FUNC parameters or the AFUNC device can handle?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117143 04/13/20 12:39 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by Colin Howell
I'm not sure how to solve this problem, but it seems to me that the most efficient approach would be to not simulate the oscillators at the component level at all, but instead replace them with functional blocks that generate the variable-frequency triangle waves directly. (The old discrete code has such blocks, of course.) Is such an approach considered compatible for netlist? Is this sort of usage something that FUNC parameters or the AFUNC device can handle?


After further thought, and better understanding of the limitations of FUNC parameters and the AFUNC device, I've decided that it would be better to solve this problem with an abstract functional device for this type of op-amp-based voltage-controlled oscillator, somewhat akin to how the old discrete system handles such oscillators. (This type of oscillator closely resembles DISC_OP_AMP_OSCILLATOR_VCO_2 in that system.) Such a device would take the component values (resistors and capacitor) as parameters to describe the timing, and with only the control voltage and time as inputs, would produce a triangle-wave output voltage, or a non-oscillating voltage if the control voltage was below the oscillation limit.

Obviously this is a more radical solution than just tweaking the netlist, but I suspect that a circuit like this, which has analog components that depend on abrupt, very accurately timed voltage changes, needs such a solution to have good real-time performance in the netlist system.

Hopefully I'm not biting off more than I can chew. I'd still appreciate whatever comments or feedback anyone can give.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117144 04/13/20 04:19 AM
Joined: Feb 2004
Posts: 2,157
Vas Crabb Offline
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,157
Originally Posted by Colin Howell
I've decided that it would be better to solve this problem with an abstract functional device for this type of op-amp-based voltage-controlled oscillator, somewhat akin to how the old discrete system handles such oscillators. (This type of oscillator closely resembles DISC_OP_AMP_OSCILLATOR_VCO_2 in that system.)

The trouble is, once you do that, you go back to interpreting the circuitry into high-level functional blocks, which is what we want to get away from by using netlists in the first place. It’s at odds with the whole purpose.

Re: Netlist: 280-ZZZAP sound problems [Re: Vas Crabb] #117145 04/13/20 04:46 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by Vas Crabb
Originally Posted by Colin Howell
I've decided that it would be better to solve this problem with an abstract functional device for this type of op-amp-based voltage-controlled oscillator, somewhat akin to how the old discrete system handles such oscillators. (This type of oscillator closely resembles DISC_OP_AMP_OSCILLATOR_VCO_2 in that system.)

The trouble is, once you do that, you go back to interpreting the circuitry into high-level functional blocks, which is what we want to get away from by using netlists in the first place. It’s at odds with the whole purpose.

Well, I'm not yet committed, especially if there's a better way to solve the problem.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117146 04/13/20 08:02 AM
Joined: May 2009
Posts: 1,861
J
Just Desserts Offline
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,861
The best thing you can do is get hold of couriersud directly. He only comes here fairly rarely. However, his availability is much higher on both IRC and Discord.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117169 04/15/20 08:41 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Use the following:

Code
	
        SOLVER(Solver, 4800)
	PARAM(Solver.DYNAMIC_TS, 1)
	PARAM(Solver.DYNAMIC_LTE, 1e-4)
	PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-8)


This enables dynamic time stepping with a maximum time step of 1s/4800 and a minimum time step of 10ns. The DYNAMIC_LTE parameter determines the rate of change for the dynamic time stepping. The bigger, the faster.

The issue here was correctly identified by you. Like in all SPICE implementations, the issue has to be attacked by decrementing the time step.
With these modifications the circuit runs at about 450% on my machine. I expect about 800% to 900% with static solvers.

The LM3900 is a norton opamp and implemented using 6 BJTs in netlist. This is expensive. You may try using e.g. a the LM324 which uses the generic and much faster netlist opamp model. That should really be sufficient for a triangle wave generator working in the kHz arena.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117170 04/15/20 08:47 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
I should have read everything before replying and I would have seen that you already used dynamic time stepping.

There are more options available like frontiers but to further help you I need the complete netlist and the schematics.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117178 04/15/20 02:55 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
OK, I can do that, but I need a little time to clean it up first.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117182 04/15/20 05:24 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
And please forget my tip on using a LM324. LM3900 are norton type opamp with very specific input stages. You can replace them only with other norton type opamps. I tried the more simple LM3900 models which kind of work in other circuits and those fail.

If all goes wrong I'll implement a tridiag function. Than a simple voltage source can be used to model the whole circuits. Can be added with some #ifdefs.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117214 04/17/20 08:24 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
The following settings will bring the performance on my machine to ~1050%

Code
	SOLVER(Solver, 4800)
	PARAM(Solver.DYNAMIC_TS, 1)
	PARAM(Solver.DYNAMIC_LTE, 2e-4)
	PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-8)
	PARAM(Solver.RELTOL, 1e-2)
	PARAM(Solver.VNTOL, 5e-3)


RELTOL is the maximum relative deviation (1%) and VNTOL the maximum absolute voltage deviation (5mV). With static solvers the performance should be > 1500%.

I tried some more stuff - there is more than one solution to solving linear differential equations.
Rewriting the 4016 into a three terminal MNA element with a continuous and differentiable transfer function worked but was a lot slower. At least I can use the code later for a generic three terminal element implementation and base the BJT stuff on this.
The key element with convergence according to the literature is step limiting. This is currently applied locally for diodes (and thus BJTs as well) but there is no step limiting for the whole voltage vector. This may be worth testing.
Another try would be to switch from BE (backwards euler) to trapezoidal time integration. I added this to my to-do list.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117215 04/17/20 11:45 AM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
1050% sounds plenty fast, to be honest. 280ZZAP isn't a very demanding driver otherwise.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117217 04/17/20 12:32 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Well, there are three oscillators of this kind and some more LM3900 :-( Getting this to perform is a challenge, but manageable.
In the worst case we need to add some frontier statements and as a last resort use some function controlled voltage sources as replacements for the oscillators. We will get there. The nice thing is you can do that with a couple of #ifdefs. Basically with that one can always run the slow and complete/detail netlist to have a reference.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117285 04/29/20 07:22 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
After much trial and error and many false starts, I've come up with a somewhat faster model for the LM3900 Norton opamp that may help. This same technique should work for other Norton opamps, should they appear in MAME systems.

The idea is based on LM3900 model 2 in mame/src/lib/netlist/macro/nlm_opamp.cpp, and follows the same basic idea of converting the LM3900 inputs to a form acceptable to the standard voltage-based opamp model, but with some modifications to make it work better. (Hence the name "LM3900_2M" I've given it here; feel free to change it if you prefer.) An ideal current mirror, based on a CCCS, is used so that the .PLUS input current can be subtracted from the .MINUS input current. The resulting difference current is then converted into a voltage with a CCVS, using a very high gain parameter of 200000. This voltage difference is then fed to a standard voltage-based opamp using a model appropriate for the LM3900's behavior.

The high CCVS gain was chosen so that the final result would have an open-loop gain consistent with datasheet figures. It's not as unreasonably high as you might think: the LM3900 works with small voltage differences (on the order of millivolts) which then pass through high-value external resistors (in the hundreds of kiloohms to several megaohms), so the current differences it sees are tiny, as low as a few nanoamps. Thus, getting the final open-loop voltage-to-voltage gain of a few thousand requires a corresponding inverse multiplication on top of the gain already provided by the voltage-based opamp model.

Each input also has a corresponding diode to ensure that its voltage level is one diode drop above ground (550 mV at 10 µA current for the LM3900, according to one source I found). This is needed to make sure that the input currents are correct; with a current generated from a source of a few volts, a half-volt difference in the voltage drop matters. To ensure that the .MINUS input is consistently at this level even with a minimal difference current, as it would be in the real device, I use a bias current source (CS_BIAS) to bias the diode; having that current enter the diode at the exit point of the CCVS input keeps the bias current distinct from the input difference current.

Code
static NETLIST_START(LM3900_2M)
	OPAMP(A, "LM3900")

	DIODE(D1, "D(IS=6e-15 N=1)")
	DIODE(D2, "D(IS=6e-15 N=1)")
	CCCS(CS1, 1) // Current Mirror
	// NOTE: unlike an ordinary CS (current source), which takes
	// in positive current from .P and outputs it from .N, the
	// positive output current of a CCCS (current-controlled
	// current source) is taken in from *.ON* and output from
	// *.OP*.

	ALIAS(VCC, A.VCC)
	ALIAS(GND, A.GND)
	ALIAS(OUT, A.OUT)

	ALIAS(PLUS, CS1.IP)
	NET_C(D1.A, CS1.IN)
	NET_C(A.GND, D1.K)

	CS(CS_BIAS, 10e-6)
	NET_C(A.VCC, CS_BIAS.P)

	ALIAS(MINUS, CS1.ON)
	NET_C(CS1.OP, A.GND)

	CCVS(VS1, 200000) // current-to-voltage gain
	NET_C(CS1.ON, VS1.IP)
	NET_C(VS1.IN, CS_BIAS.N, D2.A)
	NET_C(D2.K, A.GND)
	NET_C(VS1.OP, A.MINUS)
	NET_C(VS1.ON, A.PLUS, A.GND)
NETLIST_END()


I also tweaked the LM3900's OPAMP model a bit:

Code
OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=2k DAB=0.0015)


I lowered VLH (National Semiconductor, who created the LM3900, proudly claimed that it can raise its output to just one diode drop below the positive rail—again, this matters when that rail is only 5 volts), lowered the unity-gain frequency (2.5 MHz according to National Semiconductor), and reduced the slew rate (the LM3900 has a rising slew rate of only half a volt per microsecond, so 1 volt per microsecond better fits a cycle-time average).

Though I haven't tried this model with the full 280-ZZZAP emulation yet, I have tested it with a couple of its subcircuits and various other trial circuits. It seems to work well and performs faster than the 6-BJT version. The gain is actually higher than that version, closer to the actual device, and its falloff with frequency also better matches the device.

However, the higher gain does cause a potential problem. 280-ZZZAP's oscillator circuits turn out to be quite sensitive to this gain, with more gain increasing the numerical instability and requiring shorter timesteps to get a stable solution. The good news is that you can simply adjust the gain downward to eliminate this by tweaking the CCVS gain, thus making the model *easier* to stabilize—and this can be done on a case-by-case basis by using multiple models (crude) or parameterizing the model (better, though I'm not sure how). The only downside here is that reducing the gain also seems to reduce the oscillation period, so that this approach may require tweaking the resistor values (or other components) to maintain an accurate oscillation frequency.

Last edited by Colin Howell; 04/29/20 07:26 PM. Reason: Minor tweak for accuracy.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117287 05/01/20 02:03 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Hi Colin,
thanks a lot. Really looks great! The big test will be the monymony sound.
Regarding the numerical instability: I have changes ready here which significantly improve the solution off Newton-Raphson not converging. This usually happens if the timestep is too big. In this case the new code will do a couple of solver iterations with a very small timestep before trying the computed one again. If this fails, same procedure. Works actually well.
But it needs some structural changes and time stepping devices now need "backstep" functionality. Hope to have that ready soon.

Update: Great, the model seems to work well with monymony and jackrabt.

Last edited by couriersud; 05/01/20 02:25 PM.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117288 05/01/20 03:49 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Hi Colin,
thanks a lot for spotting the current controlled current source issue (CCCS). I will fix this now. It is definitely not implemented according to general SPICE conventions.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117289 05/01/20 04:09 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
One comment: last night I found one place in 280-ZZZAP where I needed to adjust the OPAMP model I used a bit more, reducing RO to 100:

Code
OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=100 DAB=0.0015)


I needed to do this because RO controls the output current gain, and with 2k the amplifier simply couldn't produce enough output current for the noise generator circuit to work. That circuit includes a 1 kiloohm resistor from the output to ground as well as about 100 kiloohms of feedback resistance, so the LM3900 must generate 2.5 mA of total output current to get 25 µA of matching feedback current to the inverting input. For the actual LM3900, National Semiconductor's original datasheet says that it typically can source 10 mA of output current (and an accompanying graph gives 20 mA, even with 5 V power), so this should be well within its capability.

I know 100 ohms is a long way from the stated "output resistance" of 8 kiloohms given in the datasheet, but I notice that is listed under "Open Loop", so I'm not sure whether that's an inherent output resistance or just the value of the external output resistor used for measuring the open-loop gain.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117290 05/01/20 04:11 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
and the updated netlist:

Code
static NETLIST_START(LM3900)
	OPAMP(A, "OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=2k DAB=0.0015)")

	DIODE(D1, "D(IS=6e-15 N=1)")
	DIODE(D2, "D(IS=6e-15 N=1)")
	CCCS(CS1, 1) // Current Mirror

	ALIAS(VCC, A.VCC)
	ALIAS(GND, A.GND)
	ALIAS(OUT, A.OUT)

	ALIAS(PLUS, CS1.IP)
	NET_C(D1.A, CS1.IN)
	NET_C(A.GND, D1.K)

	CS(CS_BIAS, 10e-6)
	NET_C(A.VCC, CS_BIAS.P)

	ALIAS(MINUS, CS1.OP)
	NET_C(CS1.ON, A.GND)

	CCVS(VS1, 200000) // current-to-voltage gain
	NET_C(CS1.OP, VS1.IP)
	NET_C(VS1.IN, CS_BIAS.N, D2.A)
	NET_C(D2.K, A.GND)
	NET_C(VS1.OP, A.MINUS)
	NET_C(VS1.ON, A.PLUS, A.GND)
NETLIST_END()

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117291 05/01/20 04:19 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Whoops, our posts crossed, I think. smile Anyway, thanks for your quick help on this.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117292 05/01/20 04:48 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Looking at the datasheet there seems to be a disparity between the sourcing ability (just C-E) and the sinking ability. According to the datasheet it constantly sinks 1mA (current source). The C-E should be able to deliver 20mA. Which at 5V translates to 250 ohms with 1V output drop. So 100 ohms looks reasonable.
Changed this now. I have added this now to nlm_opamps.cpp and plan to commit over the weenkend after some more tests. Is it ok to be credited as Colin Howell or do you prefer something else?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117293 05/01/20 05:05 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
No, Colin Howell is fine.

I have a question about your timestep proposal. How would this (and how do timesteps in general) affect random white noise sources like those in cheekyms and gunfight which generate their value by calling rand()? I'm using a similar source in 280-ZZZAP, and it seems to be re-evaluated every timestep, regardless of its size. (As I suppose it should; if it's really a white noise source it should look random at all timescales.) That would affect convergence, would it not?

Incidentally, I have another question regarding your rand() implementation. If I understand right, it seems to be based on an LFSR which is only 16 bits. This is noticeable if you listen to or look at the output, because the 16-bit size means it repeats every 65536 timesteps—just over a second at 48 kHz, and much shorter if timesteps are shortened by dynamic timestepping. Why did you abandon the native random number generator, and why is the LFSR so short?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117294 05/01/20 07:50 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Good catch! From an academic point of view I agree. However, there is always a death to die. I opted for speed instead of (sometimes spurious) accuracy. Netlist is about being bold in leaving away detail.

The cheekyms noise circuit is basically a BJT with the collector not connected and the noise of the B-E is amplified. In cheekyms a simple voltage source driven by a function is used to replace this. Having the lfsr in pfunction was a hack to get noise working. I will remove it again since it causing grief.

You are right, in this setup a new random value is created whenever the function is called. A better implementation would be an AFUNC driven by a CLOCK. That would address the time stepping issue. But this approach mean less performance. But it would be worth a try.

Even better would be fast NOISE device. Open for suggestions :-)

But please, no rand(). I had so much fun with different hash implementations across platforms and standard libraries that I will never again rely on implementation details.

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117295 05/01/20 09:02 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Well, the thing that bothers me about the short repetition cycle is the fact that you can hear it, which is a problem if the noise-based sound effect is long enough and fairly constant. Stops sounding like real noise at that point.

It shouldn't be any slower on modern hardware to have a 32-bit LFSR or some other implementation with a 32-bit period, should it? And if varying implementations across platforms is a problem, wouldn't using your own implementation of a standard pseudorandom generator function be enough?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117296 05/01/20 09:53 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by Colin Howell
It shouldn't be any slower on modern hardware to have a 32-bit LFSR or some other implementation with a 32-bit period, should it?

No issue, even 64bit will work.

Originally Posted by Colin Howell
And if varying implementations across platforms is a problem, wouldn't using your own implementation of a standard pseudorandom generator function be enough?

That's the reason for the lfsr implemenation:-)
I'll think about something better.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117297 05/02/20 06:48 AM
Joined: Feb 2004
Posts: 2,157
Vas Crabb Offline
Very Senior Member
Offline
Very Senior Member
Joined: Feb 2004
Posts: 2,157
You can use the C++11 standard library's pseudo-random number generation module. The Mersenne twister has a very long period and will always give the same output given the same entropy.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117298 05/02/20 08:04 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
I would love to do so. But state saving kicks in here :-(
To save the state, I could do a binary save of the variable. But that's not portable at all. I could use the "<<" and ">>" operators to get into a string but than have a string with unpredictable length. That is something the state save system doesn't handle.
Any help welcome here. Currently the overhead on save state makes it easier to implement the algo myself.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117299 05/02/20 08:28 PM
Joined: Sep 2004
Posts: 388
A
AaronGiles Offline
Senior Member
Offline
Senior Member
A
Joined: Sep 2004
Posts: 388
Something like TinyMT might make sense here. He has a 32-bit and 64-bit version, both with minimal state. The code is pretty small and BSD, so you could probably just rip it off and insert it into your framework. Happy to look into it if you're interested.

https://github.com/MersenneTwister-Lab/TinyMT

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117302 05/03/20 12:24 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
I now have written a MT implementation from scratch following the wikipedia entry and adopted it to be compatible to the c++11 standard. It delivers the same sequence as the std:: counterpart.

It compiles as a random provider for std::normal_distribution.

This will be implemented as a voltage source which is externally clocked. This way you can have one clock triggering a number of noise source.
Can be extended to current and conductivity noise and other distributions. This is getting too academic :-)

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117303 05/03/20 01:45 AM
Joined: Sep 2004
Posts: 388
A
AaronGiles Offline
Senior Member
Offline
Senior Member
A
Joined: Sep 2004
Posts: 388
You're having too much fun. ;-)

I started down the path of making a prandom.h in plib which would have support for multiple random number sources (including TinyMT and your 16-bit LFSR) so that they could be selectable at compile time for whatever needs. Thought that might be handy.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117308 05/03/20 03:26 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
commit b2c40086e6b003121e61719da93944f4e360e33d
Branches: master, origin/master

netlist: Add two noise sources. [Couriersud]

The two sources act as voltage sources, though noise may also be
injected as conductivy or current noise.

SYS_NOISE_MT_U: Mersenne Twister uniform noise
SYS_NOISE_MT_N: Mersenne Twister normal noise

nld_sys_noise is templated:

Code
	
using NETLIB_NAME(sys_noise_mt_u) =
	NETLIB_NAME(sys_noise)<plib::mt19937_64, plib::uniform_distribution_t>;

Thus the approach is scalable. The implementation is state save aware,
and thus reproducible results are guaranteed.

An example use case is provided as well, see examples/noise.cpp.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117326 05/13/20 11:59 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
I know it's been a while since you heard from me; out of disappointment with the result, I sort of put this on the back burner for a while. I've included the most recent version of the netlist I've developed below. (Sorry about the 800 lines of source. I would have made it an attachment, but those seem to be disabled.) This netlist does work, after a fashion. I'm not really satisfied with it, but I'm not sure how much else can be squeezed out. Even with a whole bunch of speedups: *lots* of frontiers, reduced opamp gain on the oscillators, static timestepping, and reduced RELTOL, VNTOL, and ACCURACY, I can only get 140-145% speedup out of 280zzzap running unthrottled without frameskipping on my 2.5 GHz Core i7 (Mid 2014 Macbook Pro). It does run and is playable on my system, but that's very little headroom left from what is otherwise a very low-impact driver, and I wouldn't expect it to be accepted. Trying other speedups (trying different solvers or matrix sorting methods, turning on parallelism) didn't help at all. Also, I'm not very happy with the "BOOM" sound, since I only hear a burst of noise with no sense of an initial "boom". The circuit looks correct; it may be that my little laptop speakers just don't have enough bass response, I'm not sure.

There are 16 opamps in this netlist, as there are in the original sound hardware. I may be able to remove the two final ones at the output stage, but that's still a lot of opamps. The MC3340 voltage-controlled amplifier/attenuator, which is an important part of the engine sound circuits, is also a problem: it has 10 BJTs in it, which has to hurt performance. I assume it's possible to make a stripped down sham-MC3340 circuit with equivalent behavior, but I'm not sure how to do so.

I haven't yet tried your new noise circuits or Zener diode implementation; I wanted to show this progress first.

Code
// license:CC0
// copyright-holders:Colin Douglas Howell

#include "netlist/devices/net_lib.h"

static NETLIST_START(mc3340)

	// A netlist description of the Motorola MC3340 Electronic Attenuator.
	// This IC is actually a voltage-controlled attenuator/amplifier.  It
	// can produce a small amount of positive gain (about 12-13 dB, or
	// about a factor of 4 in voltage), but its main purpose is to
	// attentuate an input signal by the voltage level of a second control
	// signal; higher control voltages lead to greater attenuation. The
	// netlist here is based on the circuit schematic given in Motorola's
	// own data books, mainly the most recent ones published in the 1990s
	// (e.g. _Motorola Analog/Interface ICs Device Data, Vol. II_ (1996),
	// p. 9-67). However, the 1990s schematics are missing one crossover
	// connection which is present in older schematics published in the
	// 1970s (e.g. Motorola Linear Integrated Circuits (1979), p. 5-130).
	// This missing connection has been included in this netlist; without
	// it, the circuit only generates a very weak output signal.

	// The Motorola schematics do not label components, so I've created my
	// own labeling scheme based on numbering components from left to
	// right, top to bottom, with resistors also getting their value
	// (expressed European-style to avoid decimal points) as part of the
	// name.

	// I have not provided a model for the transistors here; instead I
	// left them as the generic default for NPN. All the transistor models
	// currently in the netlist library are for discrete transistors and
	// would not be very appropriate for those on an IC. The default
	// values seem similar to those of SPICE, whose device model defaults
	// were deliberately chosen to resemble IC-based devices.

	// Incidentally, the MC3340 has the same circuit internally as an
	// older Motorola device, the MFC6040, which was replaced by the
	// MC3340 in the mid-1970s. The two chips differ only in packaging.
	// (Noting this in case a system containing the older chip ever shows
	// up in MAME.)

	RES(R1_5K1, RES_K(5.1))

	RES(R2_4K7, RES_K(4.7))

	QBJT_EB(Q1, "NPN")

	RES(R3_750, RES_R(750))
	RES(R4_10K, RES_K(10))

	QBJT_EB(Q2, "NPN")

	RES(R5_750, RES_R(750))
	RES(R6_3K9, RES_K(3.9))

	RES(R7_5K1, RES_K(5.1))
	RES(R8_20K, RES_K(20))

	RES(R9_510, RES_R(510))

	QBJT_EB(Q3, "NPN")

	QBJT_EB(Q4, "NPN")

	QBJT_EB(Q5, "NPN")

	RES(R10_1K3, RES_K(1.3))

	QBJT_EB(Q6, "NPN")

	RES(R11_5K1, RES_K(5.1))

	QBJT_EB(Q7, "NPN")

	QBJT_EB(Q8, "NPN")

	RES(R12_1K5, RES_K(1.5))

	RES(R13_6K2, RES_K(6.2))

	QBJT_EB(Q9, "NPN")

	RES(R14_5K1, RES_K(5.1))

	QBJT_EB(Q10, "NPN")

	RES(R15_5K1, RES_K(5.1))

	RES(R16_200, RES_R(200))

	RES(R17_5K1, RES_K(5.1))

	DIODE(Dinternal, 1N914)

	RES(R18_510, RES_R(510))

	ALIAS(MC3340_VCC, R1_5K1.1)
	NET_C(R1_5K1.1, Q1.C, Q2.C, R7_5K1.1, Q3.C, Q4.C, Q7.C,
		R13_6K2.1, Q10.C, R17_5K1.1)
	NET_C(R1_5K1.2, R2_4K7.1, Q1.B)
	NET_C(R2_4K7.2, GND)

	NET_C(Q1.E, R3_750.1, R5_750.1)
	NET_C(R3_750.2, R4_10K.1, Q2.B)
	NET_C(R4_10K.2, GND)

	NET_C(R5_750.2, R6_3K9.1, Q3.B)
	ALIAS(MC3340_CONTROL, R6_3K9.2)

	ALIAS(MC3340_INPUT, Q5.B)

	NET_C(MC3340_INPUT, R8_20K.1)
	NET_C(R7_5K1.2, R8_20K.2, R9_510.1)
	NET_C(R9_510.2, GND)

	NET_C(Q4.E, Q6.E, Q5.C)
	NET_C(Q5.E, R10_1K3.1)
	NET_C(R10_1K3.2, GND)

	NET_C(Q6.B, Q7.B, Q2.E, R11_5K1.1)
	NET_C(R11_5K1.2, GND)

	NET_C(Q7.E, Q9.E, Q8.C)
	NET_C(Q8.E, R12_1K5.1)
	NET_C(R12_1K5.2, GND)

	NET_C(Q4.B, Q9.B, Q3.E, R14_5K1.1)
	NET_C(R14_5K1.2, GND)

	NET_C(Q6.C, R13_6K2.2, Q9.C, Q10.B)

	ALIAS(MC3340_ROLLOFF, Q10.B)

	NET_C(Q10.E, R16_200.1, R15_5K1.1)
	NET_C(R15_5K1.2, GND)
	ALIAS(MC3340_OUTPUT, R16_200.2)

	NET_C(R17_5K1.2, Dinternal.A, Q8.B)
	NET_C(Dinternal.K, R18_510.1)
	NET_C(R18_510.2, GND)

NETLIST_END()


static NETLIST_START(zzzap_schematics)

	RES(R22, RES_R(470))

	DIODE(D1, 1N914)

	NET_C(I_V5.Q, R22.1)
	NET_C(I_F4_5.Q, R22.2, D1.A)

	// The 4-bit accelerator pedal input is converted to an analog voltage
	// by the first LM3900 op-amp H5_3, whose output is passed to the
	// second op-amp H5_4. H5_4's output voltage serves as an "engine
	// speed" signal.  With the engine on (ENGINE SOUND *low*) this signal
	// ramps up as capacitor C18 charges, with the rise slowing as time
	// passes. It ramps faster with a greater accelerator level, and ramps
	// faster in low gear (LO SHIFT high) than in high gear (HI SHIFT
	// high). If ENGINE SOUND goes high, CD4016 switch G5_A (G5 pins 1, 2,
	// 13) is closed and capacitor C18 is discharged, dropping the voltage
	// enough to cut off the engine sound entirely.

	// Although the schematics don't show the CD4016s' power input,
	// they need 5-volt power to respond at the proper voltage levels.
	CD4016_DIP(G5)
	NET_C(G5.7, GND)
	NET_C(G5.14, I_V5.Q)
	NET_C(GND, G5.10, G5.11, G5.12)

	LM3900(H5_3)
	LM3900(H5_4)

	RES(R42, RES_K(1))
	RES(R43, RES_K(1))
	RES(R44, RES_K(1))
	RES(R45, RES_K(1))
	RES(R62, RES_K(1))
	RES(R61, RES_K(1))

	RES(R51, RES_K(480))  // 470 Kohm in later Laguna and SS Race
	RES(R46, RES_M(2))  // 2.2 Mohm in later Laguna and SS Race
	RES(R47, RES_M(1))
	RES(R48, RES_K(480))  // 470 Kohm in later Laguna and SS Race
	RES(R49, RES_K(240))

	RES(R50, RES_K(100))
	// SS Race also has a 1 uF capacitor in parallel with R50.
	RES(R53, RES_K(47))
	RES(R52, RES_K(10))
	RES(R56, RES_R(270))

	RES(R54, RES_K(560))
	RES(R55, RES_M(4.7))

	RES(R57, RES_M(2.7))
	RES(R58, RES_K(560))

	RES(R59, RES_K(560))
	RES(R60, RES_K(10))

	CAP(C18, CAP_U(47))  // 22 uF in later Laguna and SS Race
	NET_C(C18.2, GND)

	CAP(C19, CAP_U(2.2))

	DIODE(D4, 1N914)
	DIODE(D5, 1N914)

	NET_C(I_V5.Q, R42.1, R43.1, R44.1, R45.1, R62.1, R61.1, R51.1,
		R55.1, R57.1)

	NET_C(I_F5_2.Q, R42.2, R46.1)
	NET_C(I_F5_5.Q, R43.2, R47.1)
	NET_C(I_F5_7.Q, R44.2, R48.1)
	NET_C(I_F5_10.Q, R45.2, R49.1)
	NET_C(H5_3.PLUS, R46.2, R47.2, R48.2, R49.2, R51.2)
	NET_C(H5_3.MINUS, R50.2)
	NET_C(H5_3.OUT, R50.1, R53.1, D4.K)
	// SS Race also has a 1 uF capacitor in parallel with R50.
	NET_C(R53.2, R52.1, C18.1, R56.2, R54.1)
	NET_C(R52.2, D4.A)
	NET_C(H5_4.PLUS, R54.2, R55.2)
	NET_C(H5_4.MINUS, R58.2, R57.2, G5.4)
	NET_C(H5_4.OUT, D5.A, R59.1)  // see below for further connections...
	NET_C(D5.K, R58.1)
	NET_C(C19.1, R59.2, R60.2)

	NET_C(G5.1, GND)
	NET_C(G5.2, R56.1)
	NET_C(G5.13, I_F4_5.Q)  // ENGINE SOUND (high for *off*)

	NET_C(G5.5, R62.2, I_F5_12.Q)  // HI SHIFT

	NET_C(G5.3, G5.8, C19.2)
	NET_C(G5.9, R60.1)
	NET_C(G5.6, R61.2, I_F5_15.Q)  // LO SHIFT

	// Engine sound oscillators. There are three of these, at different
	// frequencies; all three are triangle-wave oscillators whose frequency
	// is controlled by the voltage signal output from LM3900 op-amp H5_4.
	// Each oscillator is a cascaded pair of LM3900s and a CD4016 switch.
	// The switch feeds into the non-feedback input of the first op-amp,
	// whose output is also the final oscillator output; the second op-amp
	// acts as a Schmitt trigger on the first op-amp's output, generating
	// a square wave that controls the switch. Two of the oscillators are
	// combined to drive the signal input of an MC3340 voltage-controlled
	// amplifier/attenuator; one has four times the frequency of the
	// other, producing a ragged waveform.  The third oscillator, whose
	// frequency is somewhat above the faster of the first two, drives the
	// MC3340's control input to amplitude-modulate the signal input from
	// the first two oscillators.  Greater voltages on this control signal
	// produce greater attenuation, and thus the final signal has a
	// "hilly" profile.

	// Like the other CD4016, this one needs 5 volt power.
	CD4016_DIP(J4)
	NET_C(J4.7, GND)
	NET_C(J4.14, I_V5.Q)
	NET_C(GND, J4.6, J4.8, J4.9)

	// First oscillator (bottommost in schematics).
	// Frequency on schematic is 76 Hz, but the modeled maximum (in low
	// gear) is 87.02 Hz.
	// With speedups, this increases to 111.73 Hz.

	SUBMODEL(LM3900_lowgain, J5_2)
	SUBMODEL(LM3900_lowgain, J5_1)
//	LM3900(J5_2)
//	LM3900(J5_1)

	RES(R36, RES_K(560))
	RES(R37, RES_K(270))
	RES(R38, RES_K(100))
	RES(R39, RES_K(470))
	RES(R40, RES_K(270))
	RES(R41, RES_K(10))
	NET_C(R41.2, GND)

//	CAP(C17, CAP_U(0.022))
	// Oscillator capacitor increased to counter higher frequency from
	// emulation speedups (reduced LM3900 gain, use of frontiers):
	CAP(C17, CAP_U(0.02825))

	DIODE(D3, 1N914)

	NET_C(H5_4.OUT, R36.1, R37.1, R31.1, R32.1, R29.1, R30.1)
	// ... these are the remaining connections from H5_4.OUT.

	// Note the connections to this oscillator's CD4016 switch at J4 have
	// mislabeled pin numbers on the schematics for 280-ZZZAP and both
	// Laguna Racer versions; they are shown as pins 3, 4, 5, which are
	// for switch B, the same switch which is used by the middle
	// oscillator. The Super Speed Race schematic correctly shows this
	// oscillator using pins 10, 11, 12, which are for switch D of the
	// CD4016 (located at B1 in that game). It seems very unlikely that
	// the earlier games had two oscillators sharing the same switch; that
	// shouldn't work at all. I assume that this was a schematic error
	// which was not caught until much later.

	NET_C(R37.2, J4.10)
	NET_C(J4.11, J5_2.PLUS)
	NET_C(R36.2, J5_2.MINUS, C17.1)
	NET_C(J5_2.OUT, C17.2, R38.1, D3.A)
	NET_C(R38.2, J5_1.MINUS)
	NET_C(J5_1.OUT, R40.1, J4.12)
	NET_C(I_V5.Q, R39.1)
	NET_C(J5_1.PLUS, R39.2, R40.2)
	NET_C(R41.1, D3.K, D2.K, C16.1)

	// Second oscillator (middle in schematics).
	// Frequency on schematic is 315 Hz, but the modeled maximum (in low
	// gear) is 341.87 Hz.
	// With speedups, this increases to 399.91 Hz.

	SUBMODEL(LM3900_lowgain, J3_3)
	SUBMODEL(LM3900_lowgain, J3_4)
//	LM3900(J3_3)
//	LM3900(J3_4)

	RES(R31, RES_K(300))
	RES(R32, RES_K(150))
	RES(R33, RES_K(100))
	RES(R34, RES_K(470))
	RES(R35, RES_K(270))

//	CAP(C15, CAP_U(0.01))
	// Oscillator capacitor increased to counter higher frequency from
	// emulation speedups (reduced LM3900 gain, use of frontiers):
	CAP(C15, CAP_U(0.0117))
	CAP(C16, CAP_U(10))

	DIODE(D2, 1N914)

	NET_C(R32.2, J4.4)
	NET_C(J4.3, J3_3.PLUS)
	NET_C(R31.2, J3_3.MINUS, C15.1)
	NET_C(J3_3.OUT, C15.2, R33.1, D2.A)
	NET_C(R33.2, J3_4.MINUS)
	NET_C(J3_4.OUT, R35.1, J4.5)
	NET_C(I_V5.Q, R34.1)
	NET_C(J3_4.PLUS, R34.2, R35.2)
	NET_C(C16.2, MC3340_INPUT)  // to MC3340 H2 pin 1

	// Third oscillator (topmost in schematics).
	// Frequency on schematic is 428 Hz, but the modeled maximum (in low
	// gear) is 463.61 Hz.
	// With speedups, this increases to 520.16 Hz.
	// This is the amplitude-modulation oscillator.

	SUBMODEL(LM3900_lowgain, J3_2)
	SUBMODEL(LM3900_lowgain, J3_1)
//	LM3900(J3_2)
//	LM3900(J3_1)

	RES(R29, RES_K(220))
	RES(R30, RES_K(110))  // 100 Kohm in later Laguna and SS Race
	RES(R28, RES_K(100))
	RES(R26, RES_K(470))
	RES(R27, RES_K(270))

	RES(R25, RES_K(3.3))
	NET_C(R25.2, GND)

	RES(R23, RES_K(10))
	NET_C(R23.1, I_V12.Q)

//	CAP(C14, CAP_U(0.01))
	// Oscillator capacitor increased to counter higher frequency from
	// emulation speedups (reduced LM3900 gain, use of frontiers):
	CAP(C14, CAP_U(0.01122))
	CAP(C13, CAP_U(10))

	NET_C(R30.2, J4.1)
	NET_C(J4.2, J3_2.PLUS)
	NET_C(R29.2, J3_2.MINUS, C14.1)
	NET_C(J3_2.OUT, C14.2, R28.1, C13.1)
	NET_C(R28.2, J3_1.MINUS)
	NET_C(J3_1.OUT, R27.1, J4.13)
	NET_C(I_V5.Q, R26.1)
	NET_C(J3_1.PLUS, R26.2, R27.2)
	NET_C(D1.K, R23.2, C13.2, R25.1, MC3340_CONTROL)  // to MC3340 H2 pin 2

	// The MC3340 output is the complete engine sound which is sent to the
	// final mix.


	// The noise generator circuit for 280-ZZZAP and Laguna Racer is based
	// on a reverse-biased 9.1-volt 1N5239 Zener diode. 12-volt power is
	// passed through a 100-Kohm resistor and then through the diode to a
	// LM3900 Norton op-amp input, generating a noisy reference current
	// for the LM3900 of about 25 microamps. (The current drops about 2.5
	// volts through the resistor, 9 volts through the Zener, and half a
	// volt through the LM3900 input to ground, and the current is limited
	// by the resistor.) The op-amp then amplifies the noise in that
	// current to generate more intense noise for the other circuits.

	// The netlist library does not yet support Zener diodes or their
	// noise behavior, so I simulate it with this current source.

	// Super Speed Race generates its noise with a linear-feedback shift
	// register on the main motherboard, but it processes the noise signal
	// through similar circuits.

	CS(FC, 0)
	PARAM(FC.FUNC, "25e-6 + 1e-8 * rand()")
	// The op-amp appears to be set up to expect only a fraction of a
	// microamp of noise current, because much more than that will
	// saturate it. Random current of 1e-8 gives +/- 0.7 V centered
	// around 3 V.

	RES(RNOISE0, RES_K(100))
	CAP(CNOISE0, CAP_U(10))
	NET_C(CNOISE0.2, GND)

	NET_C(I_V12.Q, RNOISE0.1)
	NET_C(RNOISE0.2, CNOISE0.1, FC.P)

	LM3900(H4_2)

	RES(RNOISE1, RES_K(56))
	RES(RNOISE2, RES_K(47))
	RES(RNOISE3, RES_K(1))

	CAP(CNOISE, CAP_U(10))

	NET_C(CNOISE.1, RNOISE1.1, RNOISE2.1)
	NET_C(CNOISE.2, GND)
	NET_C(H4_2.MINUS, RNOISE1.2)
	NET_C(H4_2.PLUS, FC.N)
	NET_C(H4_2.OUT, RNOISE2.2, RNOISE3.1, C1.1)
	NET_C(RNOISE3.2, GND)

	// In Super Speed Race, which lacks the noise generator described
	// above, the noise signal enters at the point leading into capacitor
	// C1.

	CAP(C1, CAP_U(10))

	NET_C(C1.2, R1.1)

	// The noise generator is followed by a single-amplifier active
	// low-pass filter with a corner frequency of about 6.3 kHz, a very
	// broad Q of 0.014, and a gain of about 0.8. This filter basically
	// attenuates the noise's highest frequencies.

	RES(R1, RES_K(330))  // 680 Kohm in Super Speed Race.

	LM3900(H4_1)

	CAP(C2, CAP_P(6800))
	RES(R2, RES_K(10))
	RES(R3, RES_K(820))
	RES(R4, RES_K(270))
	CAP(C3, CAP_P(220))

	NET_C(R1.2, C2.1, R2.1, R4.1)
	NET_C(C2.2, GND)
	NET_C(H4_1.MINUS, R2.2, C3.1)
	NET_C(I_V5.Q, R3.1)
	NET_C(H4_1.PLUS, R3.2)
	NET_C(H4_1.OUT, C3.2, R4.2, R5.1, R17.1, C5.1, C4.1)

	// The filtered noise is passed to three different circuits, each of
	// which is also an active-filter type.

	// First noise circuit: NOISE CR 1

	// This is a two-amplifier active bandpass filter with a center
	// frequency of about 1 kHz and a high Q value of 25, giving a
	// narrow bandwidth of 40 Hz. The gain is about 15.

	// The result is a high-pitched "tire skid" screeching sound.

	// The circuit appears to be taken almost verbatim from page 19 of
	// National Semiconductor's Application Note 72 about the LM3900, with
	// only minor changes in the values of a few components to alter the
	// DC bias.

	CD4016_DIP(G4)
	NET_C(G4.7, GND)
	NET_C(G4.14, I_V5.Q)
	NET_C(GND, G4.10, G4.11, G4.12)

	LM3900(H4_3)

	RES(R5, RES_K(39))
	RES(R6, RES_R(62))
	RES(R7, RES_K(82))
	RES(R8, RES_K(39))

	CAP(C7, CAP_U(0.1))
	CAP(C8, CAP_U(0.1))

	NET_C(R5.2, R6.1, C7.1, C8.1, R12.1)
	NET_C(R6.2, GND)
	NET_C(H4_3.MINUS, C7.2, R8.1)
	NET_C(I_V5.Q, R7.1)
	NET_C(H4_3.PLUS, R7.2)
	NET_C(H4_3.OUT, R8.2, C8.2, R9.1)

	// Super Speed Race has an extra CD4016 switch (with the same control
	// line as the one downstream from here) and a 0.1 uF capacitor
	// between H4_3.OUT and R9.1 here.

	LM3900(H4_4)

	RES(R9, RES_K(39))
	RES(R10, RES_K(62))  // 240 Kohm in Super Speed Race.
	RES(R11, RES_K(100))  // 120 Kohm in later Laguna and SS Race
	RES(R12, RES_K(62))

	NET_C(H4_4.MINUS, R9.2, R11.1)
	NET_C(I_V5.Q, R10.1)
	NET_C(H4_4.PLUS, R10.2)
	NET_C(H4_4.OUT, R11.2, R12.2, G4.4)
	NET_C(G4.3, R63.1)  // NOISE CR 1
	NET_C(G4.5, I_F4_7.Q)

	// Second noise circuit: NOISE CR 2

	// This circuit is peculiar. It's structured like a single-amplifier
	// active low-pass filter, with a corner frequency of about 1 kHz and
	// a gain of 100--but its Q factor turns out to be a small *negative*
	// number. (I'm not sure what effect this has on a filter, but it
	// might indicate instability.)

	// The result is saturated, clipped noise, a bit like randomized
	// square waves, with frequencies mainly below 1 kHz.

	// I don't why the circuit was designed this way, or whether it was
	// deliberate or a design or production error which the makers decided
	// they liked or at least could accept. It doesn't look like they
	// fixed it later; this same circuit is unchanged in the schematics
	// for all three games.

	RES(R17, RES_K(10))

	CAP(C5, CAP_U(10))
	CAP(C4, CAP_U(0.022))

	LM3900(H5_2)

	RES(R16, RES_K(1.5))
	RES(R15, RES_K(15))
	RES(R14, RES_M(2.7))
	RES(R13, RES_K(150))

	CAP(C6, CAP_U(0.01))
	CAP(C9, CAP_U(0.001))

	NET_C(C4.2, R16.1)
	NET_C(R16.2, C6.1, R15.1, R13.1)
	NET_C(C6.2, GND)
	NET_C(H5_2.MINUS, R15.2, C9.1)
	NET_C(I_V5.Q, R14.1)
	NET_C(H5_2.PLUS, R14.2)
	NET_C(H5_2.OUT, C9.2, R13.2, G4.8)
	NET_C(G4.9, R64.1)  // NOISE CR 2
	NET_C(G4.6, I_F4_10.Q)

	// Third noise circuit: BOOM

	// This is a single-amplifier active bandpass filter with a center
	// frequency of about 60 Hz and a high Q value of about 19, giving a
	// narrow 3 Hz bandwidth. The gain is also very high, a little over
	// 200.

	// The filter is normally cut off from the noise signal, and thus it
	// remains quiet. When the BOOM signal is activated, CD4016 switch
	// G4_A opens, letting in the noise to be filtered and amplified until
	// the switch is cut off again, generating a loud sort of "boom".
	// (The sound doesn't have much decay, though; it gets cut abruptly.)

	LM3900(H5_1)

	RES(R18, RES_K(2.2))  // 20 Kohm in Super Speed Race.
	RES(R19, RES_K(1))
	RES(R20, RES_M(3.3))
	RES(R21, RES_M(1))  // 1.5 Mohm in Super Speed Race.

	CAP(C10, CAP_U(0.1))
	CAP(C11, CAP_U(0.1))

	NET_C(R17.2, C5.2, G4.1)
	NET_C(G4.2, R18.1)
	NET_C(I_F4_2.Q, G4.13)
	NET_C(R18.2, R19.1, C10.1, C11.1)
	NET_C(R19.2, GND)
	NET_C(H5_1.MINUS, C10.2, R21.1)
	NET_C(I_V5.Q, R20.1)
	NET_C(H5_1.PLUS, R20.2)
	NET_C(H5_1.OUT, R21.2, C11.2, R65.1)  // BOOM

	// Final mix and amplification:

	RES(R63, RES_K(12))  // 3 Kohm in Super Speed Race.
	RES(R64, RES_K(150))
	RES(R65, RES_K(12))
	RES(R66, RES_K(33))

	CAP(C20, CAP_U(10))
	CAP(C21, CAP_U(10))

	NET_C(R63.2, R64.2, R65.2, C20.1)
	NET_C(MC3340_OUTPUT, R66.1)
	NET_C(R66.2, C21.1)

	LM3900(J5_3)
	LM3900(J5_4)

	RES(R67, RES_K(2))
	CAP(C22, CAP_U(10))
	RES(R68, RES_K(220))
	RES(R74, RES_K(220))

	NET_C(I_V5.Q, R67.1)
	NET_C(R67.2, C22.1, R68.1, R74.1)
	NET_C(C22.2, GND)
	NET_C(J5_3.PLUS, R68.2)
	NET_C(J5_4.PLUS, R74.2)

	RES(R69, RES_K(100))
	RES(R70, RES_K(10))  // actually a potentiometer, at max. volume
	CAP(C23, CAP_U(10))
	CAP(C24, CAP_U(0.1))

	NET_C(R70.2, C23.2)
	NET_C(J5_3.MINUS, C20.2, C21.2, R69.1, R70.1)
	NET_C(J5_3.OUT, C23.1, R69.2, C24.1)

	RES(R73, RES_K(100))
	RES(R75, RES_K(100))

	NET_C(C24.2, R73.1)
	NET_C(J5_4.MINUS, R73.2, R75.1)
	NET_C(J5_4.OUT, R75.2)

	ALIAS(OUTPUT, J5_3.OUT)
//	LOG(LOG_OUTPUT, OUTPUT)

NETLIST_END()


static NETLIST_START(LM3900_lowgain)
	OPAMP(A, "OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=100 DAB=0.0015)")

	DIODE(D1, "D(IS=6e-15 N=1)")
	DIODE(D2, "D(IS=6e-15 N=1)")
	CCCS(CS1, 1) // Current Mirror

	ALIAS(VCC, A.VCC)
	ALIAS(GND, A.GND)
	ALIAS(OUT, A.OUT)

	ALIAS(PLUS, CS1.IP)
	NET_C(D1.A, CS1.IN)
	NET_C(A.GND, D1.K)

	CS(CS_BIAS, 10e-6)
	NET_C(A.VCC, CS_BIAS.P)

	ALIAS(MINUS, CS1.OP)
	NET_C(CS1.ON, A.GND)

	CCVS(VS1, 1000) // current-to-voltage gain
	// ^^ any greater is numerically unstable with static timestepping at
	// 48 kHz
//	CCVS(VS1, 10000) // current-to-voltage gain
	// ^^ any greater is numerically unstable with default dynamic
	// timestepping at 48 kHz
//	CCVS(VS1, 200000) // current-to-voltage gain
	NET_C(CS1.OP, VS1.IP)
	NET_C(VS1.IN, CS_BIAS.N, D2.A)
	NET_C(D2.K, A.GND)
	NET_C(VS1.OP, A.MINUS)
	NET_C(VS1.ON, A.PLUS, A.GND)
NETLIST_END()


NETLIST_START(zzzap)

	SOLVER(Solver, 48000)
	PARAM(Solver.RELTOL, 1e-2)  // default 1e-3  (faster, but costs quality)
	PARAM(Solver.VNTOL, 5e-3)  // default 1e-7  (faster, but costs quality)
	PARAM(Solver.ACCURACY, 1e-3)  // default 1e-7
//	PARAM(Solver.DYNAMIC_TS, 1)
//	PARAM(Solver.DYNAMIC_LTE, 1e-4)  // default 1e-5
//	PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-8)  // default 1e-6

	ANALOG_INPUT(I_V12, 12)
	ANALOG_INPUT(I_V5, 5)

	LOCAL_SOURCE(mc3340)
	INCLUDE(mc3340)

	// The MC3340 gets 12-volt power in 280-ZZZAP and Laguna Racer.
	// In Super Speed Race it gets 5-volt power.
	NET_C(I_V12.Q, MC3340_VCC)

	LOCAL_LIB_ENTRY(LM3900_lowgain)

	LOCAL_SOURCE(zzzap_schematics)
	INCLUDE(zzzap_schematics)

	LOGIC_INPUT(I_F5_2, 0, "74XX")  // PEDAL_BIT0
	LOGIC_INPUT(I_F5_5, 0, "74XX")  // PEDAL_BIT1
	LOGIC_INPUT(I_F5_7, 0, "74XX")  // PEDAL_BIT2
	LOGIC_INPUT(I_F5_10, 0, "74XX")  // PEDAL_BIT3
	LOGIC_INPUT(I_F4_5, 0, "74XX")  // ENGINE SOUND OFF
	LOGIC_INPUT(I_F5_12, 0, "74XX")  // HI SHIFT
	LOGIC_INPUT(I_F5_15, 0, "74XX")  // LO SHIFT
					// both shifts off when engine off

	ALIAS(I_PEDAL_BIT0, I_F5_2.IN)
	ALIAS(I_PEDAL_BIT1, I_F5_5.IN)
	ALIAS(I_PEDAL_BIT2, I_F5_7.IN)
	ALIAS(I_PEDAL_BIT3, I_F5_10.IN)
	ALIAS(I_ENGINE_SOUND_OFF, I_F4_5.IN)
	ALIAS(I_HI_SHIFT, I_F5_12.IN)
	ALIAS(I_LO_SHIFT, I_F5_15.IN)

	// Although the schematics don't show the LM3900s' power input,
	// they seem to need 5-volt power to get the proper results.
	NET_C(I_V5.Q, H5_3.VCC, H5_4.VCC, J5_2.VCC, J5_1.VCC,
	      J3_3.VCC, J3_4.VCC, J3_2.VCC, J3_1.VCC)
	NET_C(GND, H5_3.GND, H5_4.GND, J5_2.GND, J5_1.GND,
	      J3_3.GND, J3_4.GND, J3_2.GND, J3_1.GND)

	NET_C(I_V5.Q, I_F5_2.VCC, I_F5_5.VCC, I_F5_7.VCC, I_F5_10.VCC)
	NET_C(GND, I_F5_2.GND, I_F5_5.GND, I_F5_7.GND, I_F5_10.GND)

	NET_C(I_V5.Q, I_F4_5.VCC, I_F5_12.VCC, I_F5_15.VCC)
	NET_C(GND, I_F4_5.GND, I_F5_12.GND, I_F5_15.GND)

	LOGIC_INPUT(I_F4_2, 0, "74XX")  // BOOM
	LOGIC_INPUT(I_F4_7, 0, "74XX")  // NOISE CR 1
	LOGIC_INPUT(I_F4_10, 0, "74XX")  // NOISE CR 2

	ALIAS(I_BOOM, I_F4_2.IN)
	ALIAS(I_NOISE_CR_1, I_F4_7.IN)
	ALIAS(I_NOISE_CR_2, I_F4_10.IN)

	NET_C(I_V5.Q, H4_2.VCC, H4_1.VCC, H4_3.VCC, H5_2.VCC,
		H5_1.VCC, H4_4.VCC, J5_3.VCC, J5_4.VCC)

	NET_C(GND, H4_2.GND, H4_1.GND, H4_3.GND, H5_2.GND,
		H5_1.GND, H4_4.GND, J5_3.GND, J5_4.GND)

	NET_C(I_V5.Q, I_F4_2.VCC, I_F4_7.VCC, I_F4_10.VCC)
	NET_C(GND, I_F4_2.GND, I_F4_7.GND, I_F4_10.GND)

	// Cut after output of noise generator. Seems to work.
	OPTIMIZE_FRONTIER(C1.1, RES_M(1), 50)

	// Cut of skid screech generator. Seem to work.
	OPTIMIZE_FRONTIER(R5.1, RES_K(39), 50)

// for some reason this cut seems to cause sudden voltage jumps on skids
//	OPTIMIZE_FRONTIER(R63.1, RES_K(12), 50)

	// Cuts after boom and NOISE CR 2 generators. Seem to work.
	OPTIMIZE_FRONTIER(R64.1, RES_K(150), 50)
	OPTIMIZE_FRONTIER(R65.1, RES_K(12), 50)

	// Cut after engine sound generation. Seems to work, but may need
	// further checking.
	OPTIMIZE_FRONTIER(R66.1, RES_K(33), 50)

	// Cuts before MC3340 inputs. Seem to work, though may need further
	// checking.
	OPTIMIZE_FRONTIER(C16.1, RES_M(1), 50)
	OPTIMIZE_FRONTIER(C13.1, RES_M(1), 50)

	// Cuts before engine sound op-amp oscillators. Seem to work, though
	// may need further checking.
	OPTIMIZE_FRONTIER(R36.1, RES_K(560), 50)
	OPTIMIZE_FRONTIER(R37.1, RES_K(270), 50)
	OPTIMIZE_FRONTIER(R31.1, RES_K(300), 50)
	OPTIMIZE_FRONTIER(R32.1, RES_K(150), 50)
	OPTIMIZE_FRONTIER(R29.1, RES_K(220), 50)
	OPTIMIZE_FRONTIER(R30.1, RES_K(110), 50)

	// Cuts within engine sound op-amp oscillators, to speed convergence
	// rather than to partition matrices. These require retuning the
	// oscillators to keep the proper frequencies.
	OPTIMIZE_FRONTIER(R38.1, RES_K(100), 50)
	OPTIMIZE_FRONTIER(R40.1, RES_K(270), 50)
	OPTIMIZE_FRONTIER(R33.1, RES_K(100), 50)
	OPTIMIZE_FRONTIER(R35.1, RES_K(270), 50)
	OPTIMIZE_FRONTIER(R28.1, RES_K(100), 50)
	OPTIMIZE_FRONTIER(R27.1, RES_K(270), 50)

NETLIST_END()

Last edited by Colin Howell; 05/14/20 12:37 AM. Reason: Forgot to rename my low-gain opamp variant.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117327 05/14/20 01:21 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by Colin Howell
Also, I'm not very happy with the "BOOM" sound, since I only hear a burst of noise with no sense of an initial "boom". The circuit looks correct; it may be that my little laptop speakers just don't have enough bass response, I'm not sure.

OK, after dumping output to a log file, converting it to WAV format, and listening to it on my iPhone through headphones (which, sadly, use a connector that won't work with my Macbook Pro), I can confirm that there is a deep initial boom which is simply too low in frequency (around 60 Hz) to reproduce on my laptop speakers.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117333 05/15/20 03:26 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
I read from your comments that you have the netlist hooked up to a driver already.

In this case, run

Code
sh src/lib/netlist/nl_create_mame_solvers.sh


Than run "make" again to compile the updated file in src/lib/netlist/generated and to relink mame.

In the nltool log verify, that you find something along the lines
Code
 INFO: External static solver nl_gcr_f259d5f9a247b8f6_29_double_double found ...


This should give approximately 58% more performance

I can understand your frustration. Had it as well on certain circuits.

But

- Compare it to the performance of real SPICE implementations
- Bear in mind you have created a near-perfect documentation of the hardware
- Consider the future scalability.

The netlist format is kept as easy as possible - just a couple of standard elements, I even replicated the c++ preprocessor so that on separate processing of netlist files you don't even need e.g. nltool.

For the mame/discrete project I have created SPICE models e.g. for analog inputs / voltage sources. This means if you use kicad you can run very simple circuits through ngspice.

There is a ton of proof-of-concept in netlist. which needs attention, agreed.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117334 05/15/20 03:39 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
For completeness, without static solvers:

Code
10.000000 seconds emulation took 3.841246 real time ==> 260.33%


with static solvers

Code
10.000000 seconds emulation took 2.432983 real time ==> 411.02%

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117335 05/15/20 08:23 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Yes, I do indeed have it hooked up to a driver. I haven't checked it in and submitted a pull request yet, largely because of the performance issues. Also, I had to modernize the structure of the audio-related mw8080bw driver code for 280-ZZZAP to make it easier to install a netlist implementation, similar to how Vas Crabb has recently modernized the code for Gun Fight and some other mw8080bw machines.

Huh. Enabling a static solver definitely makes a difference. Unthrottled speedup without frameskipping is now around 220-225%.

Sorry, I hadn't realized that a static solver wasn't already in place; I had assumed that the static solver for MAME would have been created as part of the make process. I suppose I've missed updating a dependency somewhere.

It's good to hear that there's still room for further improvement. I'd feel worse if this was the best we could do. Other mw8080bw machines have sound circuits of similar complexity, with similar numbers of LM3900s; Midway's sound engineers seem to have been fond of using those. So to make netlist feasible for those machines, it has to be able to handle something like this.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117336 05/16/20 01:07 AM
Joined: May 2004
Posts: 1,616
H
Haze Offline
Very Senior Member
Offline
Very Senior Member
H
Joined: May 2004
Posts: 1,616
If it's still over 100% then I wouldn't worry too much about performance, it's cases where things get dragged below that on what people would still consider to be good hardware that it starts to cause issues for project reputation etc.

220-225% on currently available hardware sounds acceptable.

significant (non-incremental) improvements to real world single-core CPU performance seem unrealistic at this point so when things get dragged into the 'unobtainium' realm of CPU requirement it becomes a reason for concern.


Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117337 05/16/20 01:34 AM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
I think it should be possible to thread off netlists as well. In real life they're not even doing anything in the CPU's clock domain, and you pretty much can't buy a CPU below 4 cores now.

Re: Netlist: 280-ZZZAP sound problems [Re: R. Belmont] #117338 05/16/20 09:31 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by R. Belmont
I think it should be possible to thread off netlists as well. In real life they're not even doing anything in the CPU's clock domain, and you pretty much can't buy a CPU below 4 cores now.

Right. Parallel support currently depends on OMP and that is not optimal. I also have plans to optimize the timing of sub-solvers. Stay tuned.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117339 05/16/20 09:40 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by Colin Howell
Sorry, I hadn't realized that a static solver wasn't already in place; I had assumed that the static solver for MAME would have been created as part of the make process. I suppose I've missed updating a dependency somewhere.

There is currently no dependency, so no reason to be sorry :-)
It's a chicken-egg issue. No need the circuit to be running first, e.g. compiling, no issues.
Than you can create the static solvers and recompile.
If the static solver compiled in is outdated or doesn't match the floating point setup, it will be ignored. Background: one can select which floating type the solver uses for the matrix. This is rather academic and in a mame setup only double is used. But you can compile netlist with support for long double and float128 matrix support. Or even simple float. As indicated, that's more for academic edge cases which need ultimate precision and don't care about perfermance.

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117340 05/17/20 02:00 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by couriersud
Originally Posted by Colin Howell
Sorry, I hadn't realized that a static solver wasn't already in place; I had assumed that the static solver for MAME would have been created as part of the make process. I suppose I've missed updating a dependency somewhere.

There is currently no dependency, so no reason to be sorry :-)
It's a chicken-egg issue. No need the circuit to be running first, e.g. compiling, no issues.
Than you can create the static solvers and recompile.

Ah, I see now, the static solvers are actually under source code control in git, so they would be expected to be manually updated to incorporate any changes in the source netlists.

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117341 05/17/20 02:00 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by couriersud
Originally Posted by R. Belmont
I think it should be possible to thread off netlists as well. In real life they're not even doing anything in the CPU's clock domain, and you pretty much can't buy a CPU below 4 cores now.

Right. Parallel support currently depends on OMP and that is not optimal. I also have plans to optimize the timing of sub-solvers. Stay tuned.

What does OMP refer to?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117342 05/17/20 02:37 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Open MP : https://www.openmp.org

It's an compiler extension. I don't like it. It has the usual cheap win appeal but if e.g. you go GPU it really get's awful. nvcc is a lot nicer, more transparent and in the end better to understand. Well, in the end you abstract different backends by templates, anyhow.

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117343 05/17/20 03:39 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by couriersud
Open MP : https://www.openmp.org

It's an compiler extension. I don't like it. It has the usual cheap win appeal but if e.g. you go GPU it really get's awful. nvcc is a lot nicer, more transparent and in the end better to understand. Well, in the end you abstract different backends by templates, anyhow.

Ah, that (OpenMP). Which from checking the makefile I assume isn't built in anyway unless OPENMP is enabled for the build.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117344 05/17/20 05:39 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by Colin Howell

Ah, that (OpenMP). Which from checking the makefile I assume isn't built in anyway unless OPENMP is enabled for the build.


Yes, for certain builds, though can't remember which, it caused issues. Using c++ threads should be sufficient for the purpose as well, just need to find the time.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117386 05/29/20 07:15 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
OK, an update. At this point I'm about ready to cut a branch, commit, and submit a pull request. The driver works, though I still have some issues with it.

I'm now using an appropriate Zener with a normally-distributed noise voltage source added as the basis for the noise generator: the ad-hoc random current generator is gone.

I also abandoned the low-gain hack of the op-amp after I discovered that getting the oscillators to run at the right frequency and voltage range with that op-amp hack was no easier than with the standard op-amp model with normal gain: I was only getting increased numerical stability because the lower gain kept the oscillator running in a narrower voltage range. Instead I went back to the method of putting a frontier on the Schmitt trigger op-amp's output, which seems to remove the numerical stability problem. Some slight tweaking of the Schmitt trigger op-amp's resistors corrects any change in frequency and voltage range. I no longer adjust the oscillator capacitors.

I removed one of the op-amps in the final amplification stage, since it was effectively unused. Its only purpose in the real circuit is to invert the other op-amp's output so that the final power amps can get opposing signals in order to drive the speaker "push-pull" style.

I took out the reduced accuracy and tolerance parameters for the solver. They didn't improve speed much and reduced sound quality.

Unthrottled performance with static solvers is still around 170%-220% of full speed on my machine, depending on sound workload.

The sound seems higher in treble and lower in bass than what I hear in the few videos of real 280-ZZZAP machines I can find, and the "skid" sound is less distinct than on those machines. Oh well. That may be a difference in the machine's audio "front end" (is that the correct term?). There also may be some differences in component values between the schematic I used and real PCBs. It would be nice to compare with real PCB photos, but I can't find any.

This driver should also be able to support Laguna Racer and Super Speed Race, but there are some component value differences (and circuit differences for Super Speed Race). I don't know how best to handle that: duplicating the whole netlist with components changed seems clumsy. Is there a way to parameterize or have conditional code in a netlist?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117387 05/30/20 01:32 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Further brief update: commits made and pull request now submitted.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117388 05/30/20 03:32 PM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
BTW, the thump when you crash is actually pretty bassy on decent headphones. I imagine in the cabinet it's amplified a lot more.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117392 05/31/20 02:27 PM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
Just saw this reference video: https://www.youtube.com/watch?v=0RA-42dPnPk

The main thing I hear different is that the skid is a lot louder on the real cabinet than in MAME right now.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117393 05/31/20 02:54 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Yeah, that was one of the things I noted. Tried to make sure the noise effects were as loud as possible without distortion, but there doesn't seem to be any more headroom for that as the circuit is currently set up. One of the reasons I'd like to check against real PCBs.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117553 07/15/20 05:15 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
OK, I am now certain I made 280-ZZZAP's noise *far* too weak.

All that time messing around with Gun Fight again, which also uses a zener-diode noise generator, taught me quite a bit about how noise is generated with a "zener" (really an avalanche diode) and roughly how strong you can expect that noise to be for a given zener current. Gun Fight runs around 2 microamps of current through its zener and probably gets a few millivolts of noise from that. 280-ZZZAP runs about 25 microamps of current through its zener and so should probably get tens of millivolts of noise The noise figure I used for 280-ZZZAP is 10 *microvolts*, three orders of magnitude too low.

In 280-ZZZAP the zener noise is amplified by an LM3900 Norton op-amp, not by a simple transistor-based common-emitter amplifier as in Gun Fight. I mistakenly assumed that the noise generated was intended to be relatively undistorted by that op-amp, and based on that I figured an upper limit on the strength of the noise. The truth appears to be the opposite: the noise is expected to *completely saturate* the op-amp, which converts it into a rail-to-rail, quasi-digital noise signal. In retrospect, this makes a lot more sense, given that zener (avalanche) diodes are extremely variable in the strength of their noise, even within the same batch. This saturated op-amp setup must have been a way of getting a more controlled, predictable noise signal regardless of the particular zener's qualities. (Eventually, people switched to the even more predictable linear-feedback shift register type of digital "noise" generator.) Once the saturated rail-to-rail noise is generated, the subsequent filters convert it into the desired forms for sounds.

With the zener's noise cranked up into the millivolts range, the skid noise becomes quite prominent, and there's much more low-frequency rumble on the crash, not just the extreme bass "thump". The post-crash noise is still a peculiar screech, but that's true on real machines too—it's hard to figure out what the designer was thinking with that one.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117554 07/15/20 12:33 PM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
Neat. Can't wait to hear it.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117555 07/15/20 07:48 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
So, there's one problem here. Unfortunately, it's a big one, not just with 280-ZZZAP but with op-amps in general in the netlist system.

With the zener noise now being strong enough to saturate the op-amp, what should be happening is that the op-amp's output would be "rail-to-rail": its voltage should be swinging abruptly from values near the power supply voltage to values near the ground voltage, with little time spent in between. This is because the op-amp is amplifying the input noise with practically its full open-loop gain, a factor of several thousand times.

The problem is that in the netlist emulation, the output frequently swings far *beyond* rail-to-rail, producing voltages spikes up to hundreds of volts in magnitude, which is blatantly unphysical. It does this despite the fact that the op-amp model includes specifications which are supposed to limit how closely the output voltage can approach either power rail (power and ground, in this case). These specifications simply aren't working effectively.

The resulting extreme voltages propagate through the rest of the circuit, causing objectionable noise and probably convergence problems as well.

Looking at the details of the op-amp model, it seems that voltage limiting is implemented with a pair of internal diodes associated with the upper and lower power rails, using a model borrowed from the Output Voltage Limiting page in the discussion of op-amps at eCircuit Center. These diodes should divert voltages in excess of the output limits. The trouble with using this model here is that it assumes the gain module G1 (a voltage-controlled current source) can only produce up to a certain maximum amount of current, when one of the amplifier's input transistors is fully on and the other is fully off. The limiting diodes can then be appropriately sized to pass that current in the worst case. But in the netlist implementation, there is no mechanism to limit the gain module's current in that way. The diode can simply be overwhelmed, and the output voltage will not be limited at all.

I noticed the netlist library includes an "LVCCS" (limited voltage-controlled current source), which would seem to be what is required, but this is not presently used by anything. Just as a test, I hacked the op-amp model to use the LVCCS for G1, and set its CURLIM parameter to a low value to see what would happen. The op-amp did limit its voltage better (there were still spikes in the output, but much shorter ones). Unfortunately, performance also went into the toilet, the speed dropping by a factor of 4 or 5. frown

So we still need to come up with a more reasonable means of effectively limiting op-amp output voltage.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117558 07/15/20 09:41 PM
Joined: Sep 2004
Posts: 388
A
AaronGiles Offline
Senior Member
Offline
Senior Member
A
Joined: Sep 2004
Posts: 388
As a quick hack have you tried using an AFUNC to hard-limit to the output?

AFUNC(LIMITER, 1, "max(min(A0, <rail_voltage>), 0)")
NET_C(LIMITER.A0, <opamp_output>)
NET_C(LIMITER.Q, <downstream_connections>)

It may not work (as I discovered) if there is feedback between multiple AFUNCs, as they will eventually force a super-small timestep, but for one-off cases it could be something to experiment with.

Re: Netlist: 280-ZZZAP sound problems [Re: AaronGiles] #117561 07/16/20 06:40 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
I tried your suggestion, Aaron, and it does work for clamping the output to following stages. cleaning up the glitchy sounds. So that is a potential workaround for now. Thanks for the tip.

In the long term, something more thorough is necessary, both because the out-of-range voltages will still feed back to the op-amp inputs and thus affect the op-amp circuit's own behavior, and because it is wasteful to include components like the voltage-limiting diodes within the op-amp model if they don't actually perform the function they're supposed to.

Last edited by Colin Howell; 07/16/20 06:52 AM. Reason: More thought-out response.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117562 07/17/20 02:41 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by Colin Howell
The problem is that in the netlist emulation, the output frequently swings far *beyond* rail-to-rail, producing voltages spikes up to hundreds of volts in magnitude, which is blatantly unphysical. It does this despite the fact that the op-amp model includes specifications which are supposed to limit how closely the output voltage can approach either power rail (power and ground, in this case). These specifications simply aren't working effectively.

The resulting extreme voltages propagate through the rest of the circuit, causing objectionable noise and probably convergence problems as well.


Without an example to test I can only give limited feedback. If you are observing spikes this is most likely due to the fact that your timestep is too big and the solver can't find a solution. The opamp type 3 model has clamping diodes and works in a all netlists I know. Aaron's tip may work but putting an AFUNC into an opamp feedback loop may have nasty side-effects and can cause ringing.

Please post an example here and I will have a look.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117566 07/17/20 07:49 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
OK, here's an example to look at. This netlist is for the noise generator for 280-ZZZAP, broken out to stand on its own. H4_2.OUT is the generator's output and is the notable terminal to log. I've included a comment showing how the range of spikes in opamp output declines with decreasing minimum timestep. To get the output range to remain reliably within (or nearly within) the opamp's actual output voltage range requires pushing the minimum timestep down to 10 ns, in the neighborhood of 100 MHz, even though the opamp is specified with a unity-gain frequency of only 2.5 MHz and a slew rate of 1 V/us.

I admit this is a difficult case to deal with. The opamp is deliberately configured to apply practically its full open-loop gain to the AC component of the input signal, producing a near-digital output that randomly flips between 4.5 V and 0 V.

Incidentally, when I run this with netlist, say for an emulated 10 seconds to look at the opamp noise waveform, I do get one or more NEWTON_LOOPS warnings, regardless of the timestep setting. But all of these warnings happens near the very beginning, while the noise generator is still filling its capacitors and is not yet able to generate substantial noise. I'm not getting any NEWTON_LOOPS warnings during the noise-generating part of the run, again regardless of timestep setting. So the warnings seem to have no relationship to the output voltage spikes.

(It would be helpful if such NEWTON_LOOPS warnings included an emulated-time timestamp; I had to deduce the time of the warning through repeated runs with different running times.)

Code
#include "netlist/devices/net_lib.h"

static NETLIST_START(test)

	SOLVER(Solver, 48000)
	PARAM(Solver.DYNAMIC_TS, 1)
	// Minimum dynamic timestep vs. voltage range of opamp output spikes:
	// 20833 ns (static at 48 kHz):	-600 V to +520 V
	// 10000 ns:			-350 V to +280 V
	// 1000 ns:			-30 V to +31 V
	// 100 ns:			-6 V to +9.5 V
	// 50 ns:			-2.5 V to +7.9 V
	// 20 ns:			-1 V to +5.3 V
	// 10 ns:			-0.06 V to +4.66 V
	PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-8)

	ANALOG_INPUT(I_V5, 5)
	ANALOG_INPUT(I_V12, 12)

	// Simple model of a 1N5239 9.1-volt Zener diode; according to
	// datasheets, this diode conducts 20 mA of current at 9.1 V reverse
	// bias.
	ZDIODE(ZD_1N5239, "D(BV=9.1 IBV=0.020 NBV=1)")

	// 24 kHz noise clock for the noise source, chosen to retain noise
	// frequencies as high as possible for 48 kHz sample rate.
	CLOCK(NCLK, 24000)
	NET_C(I_V5.Q, NCLK.VCC)
	NET_C(GND, NCLK.GND)

	// Based on the zener's current of around 25 microamps, its noise will
	// likely be in the range of tens of millivolts, as it needs to be for
	// the noise generation to work as intended.
	SYS_NOISE_MT_N(NOISE, 0.01)

	NET_C(NCLK.Q, NOISE.I)

	RES(RNOISE0, RES_K(100))
	CAP(CNOISE0, CAP_U(10))
	NET_C(CNOISE0.2, GND)

	NET_C(I_V12.Q, RNOISE0.1)
	NET_C(RNOISE0.2, CNOISE0.1, ZD_1N5239.K)

	LM3900(H4_2)

	RES(RNOISE1, RES_K(56))
	RES(RNOISE2, RES_K(47))
	RES(RNOISE3, RES_K(1))

	CAP(CNOISE, CAP_U(10))

	NET_C(CNOISE.1, RNOISE1.1, RNOISE2.1)
	NET_C(CNOISE.2, GND)
	NET_C(H4_2.MINUS, RNOISE1.2)
	NET_C(ZD_1N5239.A, NOISE.1)
	NET_C(H4_2.PLUS, NOISE.2)
	NET_C(H4_2.OUT, RNOISE2.2, RNOISE3.1)
	NET_C(RNOISE3.2, GND)

	NET_C(I_V5.Q, H4_2.VCC)
	NET_C(GND, H4_2.GND)

NETLIST_END()

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117567 07/18/20 10:05 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
10 mV noise seems extremely high. The following post has some measured values and also literature hints: https://groupdiy.com/index.php?topic=52037.msg662729#msg662729

Noise is in the 100nV range for zener diodes. This would also explain why there is a second amplifier stage. If I use 100nV the netlist behaves nicely.

Coming to the spikes again: If an opamp is used like in the netlist you provided every SPICE simulator out there will adjust it's timestep down to 10ns or even below to find a solution. LTSpice forums contain a lot of examples.

The "overshoot" and the clamping diodes only doing their work partially is most likely due to the fact that the relative criterion for convergence (RELTOL, default 1e-3) is met although in fact a stable state is not yet reached -> false positive. Reducing RELTOL to 1e-4 increases the necessary solver loops significantly and the limit of 300 is reached on nearly every step. We are reaching the borders of numerical stability. Netlist support long double and float128 types as well for academic applications. Performance vanishes.
All of this is an issue in all SPICE like applications I am aware of.



Last edited by couriersud; 07/18/20 10:19 AM.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117568 07/18/20 10:39 AM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Originally Posted by Colin Howell
(It would be helpful if such NEWTON_LOOPS warnings included an emulated-time timestamp; I had to deduce the time of the warning through repeated runs with different running times.)


Thanks for the proposal. Implemented.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117569 07/18/20 03:24 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Digging more into zener noise I need to correct my post above. The measurements in the are 100nV/sqrt(Hz) values, thus most likely from a spectrum analyzer. These need to be integrated over the frequency.

https://scholarsmine.mst.edu/cgi/viewcontent.cgi?article=4491&context=masters_theses

contains some real measurements for a 9V zener diode which is at 4mA current about 400uV noise: Using

  • the formula E^2 = 5e-20 * V^4 / I from "Low noise electronic design" which implies a 1 / sqrt(I) dependency of the noise amplitude
  • the measurements from the link above and a simple regression 1 / sqrt(I) ~ Vpp
  • 30uA reverse current through the diode ( (12-9) / 100k)


the noise amplitude results at about 5mV, thus in the order you calculated.

Which brings us back to the limits of solving multivariate differential equations in time. The UGF of 2.5M in LM3900 model 4 basically causes overshoots if the timestep is too small. My experiments showed that reducing the UGF to 10k due to the fact that the following stage is a low pass filter has no real implications on the result.
In this case you can increase the minimum timestep to 1e-6

But performance is still poor. I'd rather HLE this with a noise source followed by a AFUNC which compares the noise source output against a fixed value.

Code

#include "netlist/devices/net_lib.h"

static NETLIST_START(test)

	SOLVER(Solver, 48000)
	PARAM(Solver.DYNAMIC_TS, 1)
	// Minimum dynamic timestep vs. voltage range of opamp output spikes:
	// 20833 ns (static at 48 kHz):	-600 V to +520 V
	// 10000 ns:			-350 V to +280 V
	// 1000 ns:			-30 V to +31 V
	// 100 ns:			-6 V to +9.5 V
	// 50 ns:			-2.5 V to +7.9 V
	// 20 ns:			-1 V to +5.3 V
	// 10 ns:			-0.06 V to +4.66 V
	PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-6)

	ANALOG_INPUT(I_V5, 5)
	ANALOG_INPUT(I_V12, 12)

	// Simple model of a 1N5239 9.1-volt Zener diode; according to
	// datasheets, this diode conducts 20 mA of current at 9.1 V reverse
	// bias.
	ZDIODE(ZD_1N5239, "D(BV=9.1 IBV=0.020 NBV=1)")

	// 24 kHz noise clock for the noise source, chosen to retain noise
	// frequencies as high as possible for 48 kHz sample rate.
	CLOCK(NCLK, 24000)
	NET_C(I_V5.Q, NCLK.VCC)
	NET_C(GND, NCLK.GND)

	// Based on the zener's current of around 25 microamps, its noise will
	// likely be in the range of tens of millivolts, as it needs to be for
	// the noise generation to work as intended.
	SYS_NOISE_MT_N(NOISE, 5e-3)

	NET_C(NCLK.Q, NOISE.I)

	RES(RNOISE0, RES_K(100))
	CAP(CNOISE0, CAP_U(10))
	NET_C(CNOISE0.2, GND)

	NET_C(I_V12.Q, RNOISE0.1)
	NET_C(RNOISE0.2, CNOISE0.1, ZD_1N5239.K)

	LM3900(H4_2)
	PARAM(H4_2.A.MODEL, "OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=10000 SLEW=1M RI=10M RO=100 DAB=0.0015)")

	RES(RNOISE1, RES_K(56))
	RES(RNOISE2, RES_K(47))
	RES(RNOISE3, RES_K(1))

	CAP(CNOISE, CAP_U(10))

	NET_C(CNOISE.1, RNOISE1.1, RNOISE2.1)
	NET_C(CNOISE.2, GND)
	NET_C(H4_2.MINUS, RNOISE1.2)
	NET_C(ZD_1N5239.A, NOISE.1)
	NET_C(H4_2.PLUS, NOISE.2)
	NET_C(H4_2.OUT, RNOISE2.2, RNOISE3.1)
	NET_C(RNOISE3.2, GND)

	NET_C(I_V5.Q, H4_2.VCC)
	NET_C(GND, H4_2.GND)

	// Next stage
	
	LM3900(H4_1)
	CAP(C1, CAP_N(6.8))
	CAP(C2, CAP_P(220))
	CAP(C3, CAP_U(10))
	RES(R1, RES_K(10))
	RES(R2, RES_K(270))
	RES(R3, RES_K(820))
	RES(R4, RES_K(330))
	
	NET_C(GND, C1.2, H4_1.GND)
	NET_C(I_V5.Q, R3.1, H4_1.VCC)
	
	NET_C(H4_2.OUT, C3.1)
	NET_C(C3.2, R4.1)
	NET_C(R4.2, C1.1, R1.1, R2.2)
	NET_C(H4_1.OUT, R2.1, C2.1)
	NET_C(C2.2, R1.2, H4_1.MINUS)
	NET_C(R3.2, H4_1.PLUS)

NETLIST_END()

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117570 07/18/20 08:33 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by couriersud
Digging more into zener noise I need to correct my post above.

You wrote this while I was writing a rebuttal to the zener noise claim in that post, so I've altered my remarks to reply here. The timestep issues can be discussed separately.

Originally Posted by couriersud
The measurements in the are 100nV/sqrt(Hz) values, thus most likely from a spectrum analyzer. These need to be integrated over the frequency.

Also those measurements are for lower-voltage zeners, which have a different mechanism of noise generation that is less intense, and they are at higher levels of current. The noise we are talking about tends to decrease with current.

Originally Posted by couriersud
https://scholarsmine.mst.edu/cgi/viewcontent.cgi?article=4491&context=masters_theses

contains some real measurements for a 9V zener diode which is at 4mA current about 400uV noise: Using

  • the formula E^2 = 5e-20 * V^4 / I from "Low noise electronic design" which implies a 1 / sqrt(I) dependency of the noise amplitude
  • the measurements from the link above and a simple regression 1 / sqrt(I) ~ Vpp
  • 30uA reverse current through the diode ( (12-9) / 100k)


the noise amplitude results at about 5mV, thus in the order you calculated.

I appreciate the confirmation. Interesting way to derive a figure. I don't have Low-Noise Electronic Design, so I never found this formula. I remember coming across the paper you linked to, but I never gave it a good look, for reasons I don't recall—maybe by that point I had already found enough other sources and was getting tired of my never-ending, marginally productive studies of zener noise.

There are two different breakdown mechanisms found in zener diodes: the Zener effect for which they are named, and avalanche breakdown. For zeners with voltages of 5.6 V and below, the Zener effect dominates. Above that voltage, the avalanche effect becomes increasingly important, and by the time you reach 9.1 V, it dominates. Such "zeners" are really avalanche diodes and are much noisier than their lower-voltage cousins, especially when run at low currents. The amount of noise they generate increases as their current drops, up to a point, below which the noise drops with further reductions in current.

It's hard to find really good descriptions of this behavior, though this technical note from Vishay Semiconductors gives a decent intro and a nice plot of a typical avalanche diode waveform at microsecond timescales. One of the most informative discussions I found was in a 1997 thread in the USENET newsgroup sci.electronics.design, in postings titled "ZENER DIODE OSCILLATION", discussing the results of several participants' oscilloscope observations of zeners at low currents. (One of the participants was Winfield Hill, one of the two co-authors of The Art of Electronics, which gave the discussion a bit more authority.) Although the entire thread is quite long, with occasional derailings, it is nevertheless worth going over if you're interested in this subject. Here are some of the most informative postings of observations: here, here, here, here, here, here, here. This posting gives references to academic publications from the 1950s and 1960s which studied the dynamics of avalanche breakdown in detail.

I've found a few other more recent discussions of the subject by people who are interested in zener noise generation as a potential source of random bits for cryptography, but those tend to be more interested in the randomness of the noise than its magnitude. Wishlist: a detailed study on the use and performance of zener diodes for generating audio electronic noise, as in arcade machines, analog synthesizers, etc.

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117571 07/18/20 08:40 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by couriersud
I'd rather HLE this with a noise source followed by a AFUNC which compares the noise source output against a fixed value.

That ... makes a lot of sense. Thanks for the suggestion—I'll definitely try it!

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117587 07/23/20 06:45 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Just to bring people up to date, that suggestion worked like a charm, and the related changes have now been merged into master.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117619 08/03/20 02:57 AM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Originally Posted by Colin Howell
The sound seems higher in treble and lower in bass than what I hear in the few videos of real 280-ZZZAP machines I can find...

Remember this, from back at the end of May? Turns out the problem was that I had missed a diode in the internal netlist for the MC3340. Or rather, noted it and deliberately omitted it, thinking that it didn't make any difference in the sound. Well, that turned out to be very wrong. The engine sound is now much more "growly", sounding quite close to real machines.

Motorola's MC3340 chip schematics, while certainly helpful (without them full 280-ZZZAP sound would be nearly impossible to figure out) have also been sources of confusion. Late ones (1990s) have resistor values, early ones (1970s) don't. Late ones miss an internal connection that early ones include: a crossover gets a dot in the early ones and no dot in the late ones. And late ones have one internal diode while early ones have three. It turns out those two extra diodes matter. (It would have been less confusing if Motorola had left all diodes off the late schematics—at least you could say, "oh, they just left out their diodes". Leaving out some diodes and not others makes you think the omitted diodes are supposed to be irrelevant or something.)

Anyway, the fix has been made and incorporated in master.

Page 1 of 7 1 2 3 4 5 6 7

Who's Online Now
4 registered members (Cpt. Pugwash, Praxis, AJR, TeamE), 52 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
ShoutChat Box
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,792
Posts115,722
Members4,908
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3