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.

Page 1 of 7 1 2 3 4 5 6 7

Who's Online Now
2 registered members (Dorando, 1 invisible), 67 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,792
Posts115,722
Members4,908
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3