Previous Thread
Next Thread
Print Thread
Page 1 of 5 1 2 3 4 5
Netlist: 280-ZZZAP sound problems #117139 04/11/20 09:58 PM
Joined: Jun 2003
Posts: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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,145
Vas Crabb Online Content
Very Senior Member
Online Content
Very Senior Member
Joined: Feb 2004
Posts: 2,145
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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,842
J
Just Desserts Offline
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,842
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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,499
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,499
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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,145
Vas Crabb Online Content
Very Senior Member
Online Content
Very Senior Member
Joined: Feb 2004
Posts: 2,145
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 387
A
AaronGiles Offline
Senior Member
Offline
Senior Member
A
Joined: Sep 2004
Posts: 387
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 387
A
AaronGiles Offline
Senior Member
Offline
Senior Member
A
Joined: Sep 2004
Posts: 387
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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,610
H
Haze Offline
Very Senior Member
Offline
Very Senior Member
H
Joined: May 2004
Posts: 1,610
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,499
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,499
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 498
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 498
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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,499
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,499
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,499
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,499
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: 48
C
Colin Howell Offline OP
Member
OP Offline
Member
C
Joined: Jun 2003
Posts: 48
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.

Page 1 of 5 1 2 3 4 5

Who's Online Now
4 registered members (R. Belmont, Olivier Galibert, robcfg, Duke), 63 guests, and 3 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,775
Posts115,464
Members4,899
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3