Analog Simulation
Article by MiSTer core developer Jegor van Opdorp (SupraDeus/jopdorp)
Many old computers have analog parts, for example audio boards that have partly analog synthesis and old desktop computers with tape input.
Currently there is no convenient way to directly simulate electronic circuits, for example based in their spice netlists, in real time on the MiSTer. So to implement these type of circuits in fpga, you will have to come up with some kind of simulation of the behavior of the electronic circuit.
The Arcade-Battlezone core is an example of a core with analog sound synthesis.
A way to approach the problem:
- Find youtube video's of people playing the actual game, to get some idea of the sounds it has.
- Play the game in an emulator, paying extra attention to sounds that do not sound the same in the emulator as in the video of the actual machine.
-
Identify the digital and analog parts of the schematic.
- One thing to keep in mind is that the digital parts run at the system clock speed, or sometimes a separate clock source that is closer to the audible frequency spectrum, in Arcade Battlezone there is a 12khz input to a digital noise circuit, of which the output goes into and analog integrator circuit. This creates an axplosion sound. The implementation of this sound is listed at "inverting amplifier" below. The analog parts will be outputting at audio sample rate, i.e. 48khz
-
Implement all the digital parts, common digital components in sound systems are:
-
Identify analog circuits with isolated behavior, i.e. 1 input, 1 output. These can be individually implemented and tested.
-
Identify common, easily recognisable and implementable parts, such as:
-
low pass filters
This can be implemented using an iir low pass filter, you can find the parameters using this spreadsheetSome implementations of iir filters:
A simpler type:
-
inverting amplifiers
This is essentially a sign inversion of the sample, followed by a (fixed sign) multiplication.
-
non inverting amplifiers
This is just a (fixed sign) multiplication of the sample
-
differential amplifiers
-
inverting integrators
or
This is essentially a sign inversion of the sample, followed by a multiplication, with the result being stored in a reg.
The multiplication is run repeatedly, each audio clock cycle, Resulting in a "release/decay" type amplifier envelope.
An example of an implementation of this can be found here
-
other common opamp circuits
-
An additive mixer just adds up/averages two signals. If the resistance is higher for one signal than the other, this will result in a volume difference between them.
-
All the parts that are going to need more attention, make note of what these parts are an try to guess what they are for. Differentiators and integrators combined with 555 timers and noise inputs can be tricky.
- Implement the mixers
- Implement the filters
- Implement the difficult parts of the circuit:
- Implement the circuit in a simlator.
- Figure out what input goes into the circuit when the game gets played.
- Run the simulation with the correct input and save the output as a wav file
- Analyse the output by looking at it in a wave editor like audacity and listening to it.
- Is the input always the same? (not noise as input) Does the circuit always response in the same way? (not generating noise)
- Sample the output of the simulation
- Convert the sample into an array literal and trigger it as needed, usually the sample will just be triggered by a pulse in this case.
- If the analog circuit has noise as input or has variable inputs such as a number controlled frequency or speed you will need to:
- make a mathematical model of the analog circuit.
- implement the model in an easy to use programming language such as python
- compare the output of the mathematical model with the output of the circuit simulation using the same inputs. They have to be close, but not identical, but they should be identical to the hearing.
- rework your mathematical model to not have to use any dividers in real time, this is done in two steps
- by algebra
- by precalculating any left-over divisions into division lookup-tables
- you can also create other kind of lookup tables, for example a sine wave.
- implement the mathematical model in HDL
- verify the outputs of the HDL with a tesbench
- hook up the chip to the rest of our core!
Handy links:
Developer journeys of analog circuit implementations
Informational resources
- For finding the right values of a filter: https://www.micromodeler.com/dsp/
- Common operational amplifier uses, such as differentiators and integrators: https://en.wikipedia.org/wiki/Operational_amplifier_applications
- Explanation of how 555 timers work: https://www.electronics-tutorials.ws/waveforms/555_oscillator.html
- Spice programming https://www.allaboutcircuits.com/textbook/reference/chpt-7/fundamentals-spice-programming/
Code examples
- example of a noise-based sound python implementation in a notebook
- example of a piece of python code that generates a lookup table
- example of a common digital noise generator
- example of a sine-based sound that takes noise as input
- example of a script that can take the output of a spice simulation and generate a wav file from it
- example of a spice netlist for a noise based sound