Table of Contents

Simulating Analog Audio Cicuits

This article describes an extension to ngspice that provides a libsndfile voltage source and the possibility to write ngspice's output in audio-file format.

Ngspice is a mixed-level/mixed-signal circuit simulator, based on Berkeley Spice3F5 and developed openly as ngspice sourceforge project. (see SPICE)

Libsndfile is a C library for reading and writing files containing sampled sound; released in source code format under the GNU Lesser General Public License.

Spicy Sound

The idea is simple: use a schematic as audio-effect.

When compared to traditional digital audio effects, performing a full analog circuit simulation breaks a fly on the wheel. However todays computing power allows to do so almost in real-time! But don't get your hopes up too soon.. even if passing 10 seconds 48kHz audio though a simulated RC bandpass takes 11.2 seconds on a 1.6Ghz pentium, it's far far away..

Nevertheless being able to process arbitrary audio-samples with SPICE provides off-line sound processing and (re-)engineering features for analog audio circuits.

In this exercise the audio-input represents a linear sound-controlled voltage-source in the schematic and the audio-sink can be any node in the schematic's netlist.

Preparation / Source Code

Though spice is rather flexibly importing/exporting data, adding native sound I/O functionality greatly improves performance, simplifies prototyping and shortens turnaround time at the cost of (re-)compiling ngspice 1).

The patch applies to the ngspice-rework17 source code release and does not modify exiting functionality of ngspice . It just adds new features, and also works with the current CVS version of ngspice.

Apart from ngspice' build-dependencies, you need the libsndfile-dev package to compile it:

cd /tmp
wget http://downloads.sourceforge.net/ngspice/ng-spice-rework-17.tar.gz
wget http://gareus.org/_media/oss/spicesound/ng-spice-rework-17-snd-v3.2.diff
tar xzf ng-spice-rework-17.tar.gz
cd ng-spice-rework-17
patch -p1 < ../ng-spice-rework-17-snd-v3.2.diff
./autogen.sh
mkdir build && cd build
../configure && make
sudo make install


UPDATE: Hannu Vuolasaho rebased the patch to spice-0.23. The patch and information is available on http://sourceforge.net/tracker/?func=detail&aid=3408334&group_id=38962&atid=423917

Syntax

See the chapter Voltage and Current Sources in the spice3 user manual for general information.

Audio Source

The snd patched spice knows a new type of Independent voltage source extending the syntax of

VXXXXXXX N+ N- <<DC> DC/TRAN VALUE> <AC <ACMAG <ACPHASE>>>
+       <DISTOF1 <F1MAG <F1PHASE>>> <DISTOF2 <F2MAG <F2PHASE>>>

with the time-dependent value:

Syntax:

FILE(FILENAME) 
SND (ID V_OFFSET V_MULT T_OFF CHANNEL OVERSAMPLING

Examples:

V_V2 10 0 dc 0.0 file /tmp/stay.wav snd 0 0 0.2 0 0 1
VLEFT 2 0 file(/TmP/tEst.wAv) snd 1 0 0.2 5.0 0 64
VRIGHT 13 2 snd(1 0.0 1.0 5.0 1 64)

Description

N+ and N- are the positive and negative nodes, and the new parameters are

If unspecified spice uses default TSTEP and TSTOP for transient analysis, which should match the sampling rate of the audio file times the oversampling factor. - unless you know what you're doing: choose the same oversampling-factor for input and output. Read more about synchronization in the next section.

Sink

Converting spice's output into a sound file is done with a standard print command. sndprint behaves just like print with the difference that it does not write text to screen but the same values into a audio file instead. each sndprint argument gets written as a channel in the file. The global parameters (filename, samplerate) can be changed for each sndprintf.

Syntax:

.PRINT PRTYPE OV1 [ OV2 ... OV8 ]
.SNDPARAM FILENAME [ SAMPLERATE [FORMAT [V_OFF [V_MULT] [OVERSAMPLING] ] ] ]
.SNDPRINT PRTYPE OV1 [ OV2 ... OV8 ]  

Examples:

.sndparam /tmp/spice-1.wav 48000 wav16 3.0 0.0 64
.sndprint tran v(10) v(9)
.sndparam /tmp/spice-2.wav 48000 wav24
.sndprint tran v(10)

Description

sndparam affects all following .sndprint lines. If not specified the defaults values are used: .sndparam spice.wav 48000 -1 0.0 1.0 64.

The output range of sndprint is [-1..1] - values are clipped. Each printed parameter will be written to a separate audio-channel; fi. sndprint v(2) writes a mono file from the voltage of net 2; sndprint v(2) v(4) produces a stereo file. - The sndparam conversion parameters are set per file and apply for all channels to be written.

Further Information

Synchronization

Spice allows to specify a maximum time-step, which should be set to the audio-sample rate. The step-size is not guaranteed and sometimes smaller than the specified value, which makes synchronization a non trivial problem.

Unlike the txt2snd tool, the internal sndprint does not add missing samples. sndprint only drops excess samples and does not perform any resampling or interpolation; thus sndprint should only be used when simulating at audio-samplerate or even shorter interval which should best be at an integer multiple of the samplerate.

simulating 5 seconds at 1/48000Hz:

.tran 2.0833333333333e-05 5.0 0 2.0833333333333e-05

when using oversampling, the time step needs to be adjusted accordingly!

.tran 3.25520833e-07 3.0 0 3.25520833e-07

Note: the simulation time-step must be smaller than the 1sec/(sndprint_samplerate*sndprint_oversampling).

Examples

simple audio test

V_V2 1 0 file /tmp/test.wav snd 0 0 1.0 0 0
R_R1 1 0 1M

.sndparam /tmp/test-spice.wav 48000 wav24 1.0 0.0
.sndprint tran  v(1)
.tran 2.08333e-05 2.0 0 2.08333e-05
.op
.END

Save this file as sndtst.cir copy any audio-file (longer than 2 seconds) to /tmp/test.wav. Launch the simulation: spice -b sndtst.cir will generate /tmp/test-spice.wav - this example simply copies the first two secods of audio from the channel of the audio-file into a 24bit 48kHz mono wav file.

more examples.

Developer Notes

This patch is rather a quick experiment; already very useful though. There are some open-ends, that will be fixed after testing and receiving feedback on the patch: Most notably are verifying the command arguments; checking for libsndfile in configure.in; and printing nice warnings/statistics for missing/skipped audio-samples.

Other addons that could come in handy, would be implementing different algorithms of converting the sound into a spice-value and back (eg. logarithmic scale, linear resampling, current source) though I dare say that can be done with ngSPICE functions already. - Before settling on the sndprint command I considered using a resistor or inductance based model for a “speaker” that could be wired into the schematic and write the sound to file during the simulation. sndprint is more flexible.

References

1) earlier versions of the patch include a simple tool to convert spice .print text to sound. - see txt2snd