
Hollywood in 3 MB: How DCS Raised the Bar for Pinball Sound
Williams' DCS sound system squeezed recorded audio into limited ROM space. This post decodes real DCS sound in your browser, working through the format (frequency bands, quantisation, Huffman codes, reconstruction) using demos. Was near limitless sound actually good for pinball?

Nick C
Pinball fans will recognise that distinctive logo that cycled past on the DMD while the game blinked away, trying to tempt a punter into parting with some change. Attract mode was prime real estate for an operator’s 1990s machine, so Williams was clearly proud enough of this mysterious DCS (Digital Compression System) to give it a slot.
Williams used it in its Williams and Bally branded pinball machines from 1993 to 1998. Before DCS, sound teams were limited to whatever the sound synthesis chip and sample playback hardware on the board could do. DCS could play back any recorded waveform, so for the first time any sound could go into a pinball machine with reasonable fidelity. Of course, any technological change comes with consequences, both good and bad, and I’ll throw my opinions in the ring at the end of the article (skip there now if you’re not so interested in the function of the tech). First though, let’s analyse exactly how the system worked.
Press Play. That’s data straight from the Scared Stiff sound ROM. It’s decoded live in your browser with the same arithmetic used on the sound board inside the machine, so the result matches the original. The image that builds up as it plays is a spectrogram (a map of which frequencies are sounding at each moment), drawn directly from those decoded ~7 kB.
DCS is a transform codec. Rather than storing the shape of the sound wave, it stores the frequencies that make up the sound, and spends its storage on the parts a listener is most likely to notice. MP3 rests on the same principle, but the two were developed separately (and DCS is simpler and easier to explain in a single blog post).
Scared Stiff wasn’t the first game to use DCS sound, but it did use the most common version of the format and Halloween is just around the corner at the time of writing. This voice sample also has clearly identifiable features in a spectrogram representation, which make the interactive widgets further down this page easier to understand.
The memory budget
Before DCS, Williams machines made their music and most of their sound effects with a Yamaha FM synthesiser chip. The composers typed their notes into text macros that were assembled into songs, and the results include some of the best-loved soundtracks in pinball, such as Black Knight 2000, Diner and White Water. Rich Karstens, who helped build the system, said it produced “some of the finest arcade music ever produced”, and Matt Booty thought the way its music responded to the gameplay was only matched recently by modern game audio tools like FMOD and Wwise1.
Speech was the weak spot. It was stored with CVSD (discussed in our Gorgar blog post), which lost the high frequencies that consonants like S, F and T depend on. The sound team’s inside joke was a line in Road Kings that came out as “Bite the Road Kings” instead of “Fight”. To work around it, they carried a disk of clean T, P, K, S, Sh and F sounds and spliced them into the recordings by hand1.
By the early 1990s Williams decided to encode audio and speech as recordings rather than the split between synthesised sounds and recorded speech. At 16 bits and 31.25 kHz, sound uses 62,500 bytes per second. Budget limited the sound ROM to about 3 MB, enough for 50.3 s at full rate2. Most Williams games had 10 to 15 minutes of sound that does not repeat. Memory had become far cheaper since Gorgar’s day, from $6,704 per MB in 1979 to $30 per MB in 19933, but not cheap enough. For example, Scared Stiff (1996) has 647.4 s of sound. Uncompressed it would fill 39 MB, $1,158 of memory at 1993 prices, when the company was willing to spend an extra $20 to $40 per game on better sound1.
DCS fits sounds into ~13 times less space. CVSD gets similar or better compression ratios, but the audio quality suffers more. The difference in the DCS era was the availability of more sophisticated compute for the decoding step allowing for a higher-fidelity compression scheme. The DCS board decodes its sound with an Analog Devices ADSP-2105, a digital signal processor (DSP), running at 40 MHz and executing over 10 million instructions per second2.
DCS started with Matt Booty and Robin Seaver, then head of audio at Williams. Booty built the proof of concept from an Akai sampler with 32 MB of memory, wired to a prototype pinball machine through a PC that turned the game’s sound commands into MIDI1. QSound, a Canadian company, wrote the first compression software, which Rich Karstens and Will Morrell then improved. Ed Keenan wrote the DSP code, and Booty wrote the software that prepared the sound team’s recordings for the ROMs. The first DCS machines, Indiana Jones: The Pinball Adventure, Star Trek: The Next Generation and Judge Dredd, all came out in 1993. Twilight Zone was meant to be one of them, but the board was not ready, so its sounds were reworked for the older board: a Yamaha synthesiser for music and CVSD for speech4.
The MPEG standard that defines MP3 was published the same year5, but DCS owes nothing to it. Williams compared its system with Sony’s MiniDisc and Philips’ Digital Compact Cassette, the new digital audio formats of the day2. MP3 is far more complex than DCS, with more stages and more ways of adapting to each sound, so although the two were published at a similar time, the first portable MP3 player didn’t go on sale until March 19986.
Time and frequency
A sound can be described in two ways: as the shape of its wave over time, or as the set of frequencies it contains. A PCM recording describes it the first way. It is a list of samples, the height of the wave measured at regular intervals, 31,250 times a second in DCS. This is the time domain. The second description lists the sinusoids that add up to the same sound, with the amplitude of each. This is the frequency domain, and the list is called a spectrum. The Fourier transform converts the first description into the second, and the inverse Fourier transform converts it back. Lossy audio formats, which discard detail to save space, mostly store the spectrum. MP3 does, and so does DCS.
Each sinusoid in a spectrum needs two numbers: its amplitude, which is its size, and its phase, which is where its peaks fall in time. The convenient way to store both is as two coefficients: how much of a cosine wave, and how much of a sine wave, at that frequency. Added together, the two make a single wave of the same frequency, and changing the balance between them changes the phase.
The demonstration below is an additive synthesiser: it builds a sound by adding sinusoids together. It has five frequencies, 244 Hz and its multiples up to 1,221 Hz, each with a fader for amplitude and a knob for phase, and the waveform above them is one DCS frame of 256 samples. Press Play and the sound follows the controls as you move them. The Square and Sawtooth buttons set the controls to build those waveforms. The final stage of a DCS decoder does the same job with 128 sinusoids at once.
You may notice that changing the phase changes the shape of the wave but barely changes how it sounds. For a steady sound made of well-separated harmonics like these, the ear is largely insensitive to their relative phase. Phase only moves the peaks: where the harmonics peak together the wave reaches higher, but its overall power stays the same.
DCS still has to get phase right, because the sound is rebuilt one frame at a time, and a sinusoid only carries on smoothly from one frame into the next if its phase in each frame picks up where the last one left off. With the wrong phase, the joins between frames would break and be audible as distortion. This phase discontinuity is why you might notice a crunching sound when you adjust the phase knobs while the sound is playing (you can use some code tricks to get rid of it, but I left it in for demonstration).
The ROM stores a sort of spectrogram
DCS divides the sound into frames of 256 samples, 8.192 ms each. Each frame is stored as its spectrum: 128 equally spaced frequencies from 0 to 15.5 kHz, each with a cosine and a sine coefficient. Consecutive frames overlap by 16 samples, for reasons covered later, so a new frame begins every 240 samples (or 130.2 times a second).
A sequence of spectra concatenated over time is a spectrogram. The one below shows this sound’s 208 frames, drawn from the coefficients as they come out of the ROM data, before the decoder turns them back into samples. Time runs from left to right, frequency from bottom to top, and a brighter pixel means a larger magnitude. It only goes up to 7.7 kHz because nothing above that was encoded for this particular sample. Drag across it, or use the slider, to see the frequency energy in a single frame.
DCS groups the frequencies into 16 bands and decides how much storage each band gets. A band is a slice of the spectrum, and all the coefficients inside it are coded with the same settings. The bands are narrowest at the bottom, where hearing is best at resolving nearby frequencies7. Bands 0 and 1 are each 488 Hz wide, together covering everything up to 854 Hz. Bands 2 to 14 are each 977 Hz wide, and band 15 at the top covers 13.7 to 15.5 kHz (when it’s used). Every stream begins with a 16-byte header, one byte per band, and the header can end early with a marker byte. Any band after the marker is not stored.
None of Scared Stiff’s 427 sounds uses all 16 bands. 242 of them stop after band 6, 82 stop after band 8 like this one, 98 stop after band 10, and 5 stop after band 12, at 11.6 kHz. The 31.25 kHz sample rate could carry frequencies up to 15.625 kHz, but the encoder chose not to spend storage on them. This is the kind of trade-off the sound team would have to make to get all of the sounds into the game that they wanted, while fitting into the number of ROM chips allocated for the job.
Each header byte also carries a half-density flag. When it is set, the band keeps only the cosine coefficient for each of its frequencies, and the sine coefficient is taken as zero. Every frequency in the band is still there, but its phase is lost, because a cosine on its own can only start at a peak or a trough. That halves the cost of the band. Losing the phase introduces discontinuities between frames, which result in distortion, but distortion from these high bands is far less offensive than distortion coming from the low frequency bands. This sound uses it on bands 7 and 8, from about 5.9 to 7.7 kHz.
Switch bands on and off below and listen to the result.
Quantisation
Most of the saving comes from storing each coefficient with as few bits as possible. Storing a value with fewer bits means rounding it to one of fewer possible levels. This is quantisation, and it is where DCS, like MP3, throws information away, which is what makes it lossy. The rounding error is heard as noise, so the encoder’s task is to round coarsely where the noise will not be noticed and finely where it will.
Each band has a scale factor, which sets the size of its rounding steps, and the coefficients in the band are stored as whole numbers of those steps. The scale factor is stored as a 6-bit code on a logarithmic scale. Each step up the code makes the rounding step about 1.5 dB larger, and four steps double it (6 dB). All of Scared Stiff’s sounds are what Roberts calls Type 1 streams, in which each frame can adjust those codes as it goes7. The next section goes into how those adjustments work.
The encoder ran on a PC with no time limit, and its settings could be tuned for each sound2. Williams gave average rates of 50 to 70 kbps for music and effects, and 20 to 40 kbps for speech. This sound is stored at 35.8 kbps. Uncompressed, it would be 500 kbps.
The demonstration below is a much cruder encoder. It rounds every coefficient in each frame to the number of bits chosen, and the rate shown is what storing every coefficient at that fixed width would cost.
At 3 bits per coefficient the crude encoder needs 43.4 kbps, more than the ROM version’s 35.8 kbps, and it still sounds worse. DCS does better by choosing the number of bits band by band and frame by frame, spending them where the noise would be noticed, and by packing the results with Huffman codes. This is not an entirely fair comparison as I’m re encoding a decoded sound here, but it makes the general point.
Dynamic quantisation
Every frame in the ROM has two parts, a frame header that describes the coding, followed by the coefficients themselves. The amount of data stored in coefficients is represented by a variable width box in the figure below, because the coding resolution is defined by the header. The frame header itself is simply one of 16 values, but even this tiny 4-bit number is compressed, so the header is shown as variable length too.
This is per band, so every frame in time has a representation as follows.
The 16 settings form a ladder of windows. Setting 0 is digital silence, setting 1 is the lowest intensity window, just above the noise floor, and setting 15 is roughly 90 dB higher intensity. Each setting pairs a coefficient bit depth with a gain scale factor. The gain sets the size of one quantisation step, i.e. the smallest detail the band can keep, while the bit depth determines how many steps a coefficient can count before clipping. Each extra bit doubles the count, adding about 6 dB of dynamic range. Humans perceive sound intensity logarithmically (as with most of our senses, we are sensitive to small changes of small sensations, but need large differences to notice changes we perceive in response to more intense physical stimuli). Settings higher up the ladder take advantage of this by scaling up the gain step size for bands representing more energy. Instead of allocating extra bits to high-intensity signals, DCS simply widens the quantization steps, maintaining a wide dynamic range while keeping the bitrate low.
If DCS wrote each band’s 4-bit heading explicitly every frame, a 9-band sound would require 36 bits of header per frame. At 130.2 frames per second, that consumes 4.7 kbps, which would be a significant chunk of this sound’s 35.8 kbps.
A frame lasts only 7.68 ms, and real sounds change far more slowly than that. A vocal formant shifts, or a cymbal decays across dozens of frames. Large jumps only occur on sudden transients like a snare hit or consonant. Therefore, the vast majority of sound (when viewed statistically across time) can be encoded as small changes. DCS exploits these acoustic properties by storing setting changes relative to the previous frame (deltas) rather than raw setting numbers. These 31 possible delta values (from −15 to +15) are packed using a single, global Huffman table. In a Huffman code, common values get short codewords and rare values get long ones. It’s the same general idea as Morse code giving E, the most common letter in English, a single dot. A delta of zero is encoded as a single bit 1, and it accounts for 55.3% of all encoded deltas in Scared Stiff’s audio data. A step down is 00, a step up is 011, and the rare big jumps take up to 23 bits. When none of the 9 bands change, the whole frame header is just 9 bits instead of 36.
To read the coefficients, the decoder looks each band’s setting up in a table that gives the band’s bit depth and gain. Setting 0 means silence, and nothing is stored for the band. At bit depths 1 to 6, the values go through Huffman tables of their own to squeeze out extra space, because values near zero occur most often. Only the top few settings store plain signed numbers, at 7 or 8 bits.
Each row in the table below is one band. It shows the codeword from the ROM, the change it encodes, and the band’s setting, scale code and bit depth before and after. Drag your finger or mouse through the timeline to see the codes and their translated meanings for each frame.
Drag the slider to a quiet frame, or one where the upper bands fall silent in the spectrogram, and watch the encoding change with it: the settings step down, silent bands drop to 0 bits and the frame gets smaller.
Rebuilding the waveform
To play a frame, the decoder turns its spectrum back into samples and joins it smoothly to the frame before. The conversion is the inverse Fourier transform: the additive synthesiser from earlier in this article, with 128 sinusoids instead of five. The DSP computes it with a Fast Fourier Transform (FFT), a method that needs far fewer multiplications than adding up 128 waves sample by sample, and that is what makes decoding in real time possible on a 1990s chip.
The result is 256 samples, but only 240 are played before the next frame begins. The last 16 samples of each frame fade out while the first 16 of the next frame fade in. This crossfade hides the join between frames. It uses 16 fixed coefficients built into the decoder, and it is not quite a plain crossfade. The encoder has already scaled these 16 samples at each end of the frame with its own window, so the decoder’s weights have to undo that scaling as well as blend the two frames, bringing every sample back to its original level7. That is why the fade-in starts at 0.0096 but rises slightly above 1, to 1.034, before settling at 1.0015.
Because every sound is built from frames, a music loop had to begin and end on a frame boundary. Matt Booty wrote an audio editor for the composers that understood frames and could preview loops1.
Switch the crossfade off below and listen. The plot zooms in on the join where switching it off makes the biggest difference, with the 16 overlapping samples shaded.
Tracks
The game board doesn’t request sounds directly. When something happens in the game, it sends the sound board a number, which the sound board uses to look up a track: a short program, in DCS’s own instruction set, that starts streams, waits, loops and sets the levels of its six channels. The channel is set inside the sound ROM, not by the game: each track’s header names its channel, so a new track on a busy channel replaces whatever was playing there7. A stream is one compressed sound, like the one used throughout this article. Scared Stiff has 404 tracks and 427 streams, and waits are counted in frames.
Each channel runs its own track, so several tracks play at once. The game’s music is one of them, playing on channel 0. The sound used throughout this article is played by a different track, $03F4, on channel 3. As well as starting the stream on its own channel, track $03F4 reaches across to channel 0: it turns the music down as the sound starts and brings it back up as the sound ends, without the music track having to know anything about it7. The player at the top of this page plays the stream on its own, so none of that is heard here. This is track $03F4 as listed by DCS Explorer:
SetMixingLevel(level 115); // set this channel's volume
SetMixingLevel(channel 0, decrease 30); // turn the music down
Play(stream $2EC9DC); // play the sound
Wait(138); // wait 138 frames
SetMixingLevel(channel 0, increase 30, steps 70); // start raising the music
Wait(71); // wait 71 more frames
End; // end of trackThe two waits add up to 209 frames, 1,605.12 ms, one frame longer than the sound’s 208. Turning the music down under a foreground sound is called ducking. Matt Booty lists ducking among the controls he and Ed Keenan added to DCS to get back what the older Yamaha synthesiser board could do1.
Williams mixed the channels, and applied level changes such as this one, in the frequency domain, before the inverse transform2. Adding the spectra of six channels together gives the spectrum of the mix, so the DSP needs only one inverse transform per frame for all six channels, rather than one per channel.
Was it any good?
The big win was freedom. Composers could record music with whatever tools they wanted in the studio, rather than composing and arranging for whatever synthesis chip was in the game. Speech callouts sounded noticeably more intelligible than they did with CVSD, and booming orchestral scores and film-accurate sound effects became a possibility. However, with great power comes great responsibility. There’s a fascinating video from Pinball EXPO 2026 featuring Roger Sharpe and Pat Lawlor discussing licensing in the pinball industry (thanks to Martin Ayub of Pinball News who works tirelessly to bring us the content). Roger realised with DCS that, oh wow, now we can have real film scores. This is very much a double-edged sword. Potentially awesome sound experience, but also a licensing obstacle course. You now have the composers, various rights owners, and even musicians who performed the audio you want to include to contend with.
My personal take on this is that these kinds of technological advances force a much greater investment in production to meet the standards rightfully expected by consumers. High-fidelity anything imposes a massively high bar of expectation on that creative vector. For example, take cabinet art of classic games: a limited colour palette applied with stencils and a simple design can look striking and classy. Now with ultra high fidelity printing processes, the artwork needs to match that level of fidelity or it simply falls over and is, completely justifiably, ridiculed. Exactly the same thing is true for video displays. Cutesy alphanumeric cup stirring animations on Diner make me smile, but usher in the DMD era and my expectations go up exponentially. The manufacturers of the DMD era evidently understood this and produced legendary dot art and animations to fully leverage this advancement. However, DCS is more analogous to the transition from DMD to LCD displays. All of a sudden it’s possible to display absolutely anything audibly or visually. In adopting those technologies, you just set (my) expectation level to Hollywood. A video display with static images and dramatic Ken Burns effects was cool in the DMD era, but feels decidedly chintzy in the LCD era. DCS was a more subtle change to your average arcade punter. As pinball fans, we throw terms around like SS, DMD, and LCD as synonyms for the eras of games. It’s less common for people to talk about the Yamaha vs DCS eras. However, all of this points in the same direction of giving designers near limitless possibility. DCS was simply the first technology to burden the sound teams with that responsibility. With each previous era of games there was technological limitation allowing designers to creatively push that technology to the absolute limits in an effort to dazzle the consumers. Conversely, it is pretty much impossible to push audio-visual technology to its limits today and so a chasm develops between consumer expectation and what is possible in the small world of pinball. The money to begin to attempt that with original content is in video games and not the pinball sideshow.
To throw even more contentious spice in at the end of a long technical article, I could make the argument that encoding synth heavy soundtracks using DCS actually made the experience worse. Flexibility came at the expense of character. For synth-heavy soundtracks, nothing in DCS’s compressed sample-playback could match the raw, crystalline bite of the classic Yamaha YM2151 coupled with its companion YM3012 DAC. It is built on the same family of 4-operator FM chips that powered legendary synths like the Yamaha DX100 (famously used by Aphex Twin among a long list of others). If the composer could work within the constraints of the older system, then the music sounded huge. The synthesis hardware is being driven directly by software instructions as the game runs, and I like to think of it as the digital equivalent of a live performance rather than simple playback*.
To hear an example of this, put some headphones on and listen to the wedgehead podcast episode 97 (well, listen to all their podcasts, they are awesome) featuring the music of Chris Granner. At 28 minutes in you can hear the DCS coded synth heavy music of Indy 500. It’s an awesome soundtrack (absolutely no shade on the genius work of Granner) but it’s got that FM synth vibe, and all that DCS adds to the experience is quantisation noise and bandwidth limitation. Compare that to the synth chip examples back earlier in the episode, and well, make your own minds up. You can argue the recording level is different on the podcast, and yes there’s compression from the web codecs too, blah blah, but go decode some soundtracks using PinMAME or whatever on your local machine and A/B them if you need more convincing. Flame me.
My take-home message from this section is that due to technological advances, designing an original-theme pinball machine today that meets the expectations of the general public may be a more difficult task than it has ever been in the entire history of pinball. Modern production tools are incredible, but so is modern consumer appetite for production standards.
* I actually listened to episode 96 of the Wedgehead podcast in my car the other day (I’m catching up on them all in reverse order), and they were making the same live performance analogy, so my point isn’t an original take, but to me it was while in the flow of writing.
The evolution of DCS
DCS’s stream format went through three versions, which Roberts labels by the year each appeared7:
- 1993a (1993): Indiana Jones: The Pinball Adventure, Judge Dredd
- 1993b (1993): Star Trek: The Next Generation
- 1994 (1994 to 1998): every other DCS pinball machine, including Scared Stiff, Theatre of Magic, Attack from Mars, Medieval Madness, Monster Bash and Cactus Canyon
The two Pinball 2000 machines of 1999, Revenge From Mars and Star Wars Episode I, used a later version of DCS that Roberts’ reference does not cover.
DCS also provided the sound for many of Midway’s arcade video games, starting with Mortal Kombat II in 19932. In the arcade it went further: the version first used in War Gods loaded its sound banks from a hard drive instead of ROM, and streamed its music from the drive as uncompressed stereo1. In Rich Karstens’ words, “With the extreme dropping of price on storage they soon became essentially relics of the past.”
Thanks to Michael Roberts, whose DCS Audio Format Technical Reference and DCS Explorer made this post possible. The decoder on this page is a port of DCS Explorer's native decoder, and the statistics for Scared Stiff come from running the native decoder over the game's sound ROMs.
The post is closely related to audio codec work I was involved with in the past, and so I had a lot of fun making it. It started out by getting my hands dirty making small scripts to try to get to grips with how DCS worked under the hood compared to modern audio codecs (based off Michael’s incredible documentation and code linked above) and then it wasn’t a huge leap (thanks orange butthole of doom) to port these over to versions that run in the browser in an effort to make this work more accessible to a wider audience.
Williams Electronics Games registered the mark as “DCS SOUND SYSTEM” (registration no. 1929182, serial 74496689). It was filed on 4 March 1994 and registered on 24 October 1995, covering electrical circuitry in amusement game machines for reproducing music, speech and sound effects from digitally stored information. Its status is “Cancelled – Section 8”, dated 27 July 2002. The Scared Stiff sound and its track program are a single short extract, used here for education and historical reference. They remain the property of their rights holders. To request change or removal, get in touch.
Footnotes
Chris Granner, Rich Karstens and Matt Booty, DCS history, collected on GitHub. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
Williams Electronics Games, Ask Uncle Willy #3: The DCS Sound System, 7 July 1995, archived by Planetary Pinball. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
John C. McCallum’s memory price data, via Stanford DAM, Memory Prices: a 64 KB S-100 memory kit at $419 on 2 October 1979, and a 1 MB SIMM at $30 from June to September 1993. Both are retail prices for RAM. ↩
Wikipedia, Digital Compression System, citing Ken Horowitz, From Pinballs to Pixels: An Arcade History of Williams-Bally-Midway (McFarland, 2023), p. 294. ↩
ISO/IEC 11172-3:1993, the MPEG-1 audio standard, which defines Layer III (MP3). ↩
The Register, Ten years old: the world’s first MP3 player, 10 March 2008, on Saehan’s MPMan F10, launched at CeBIT in March 1998. ↩
Michael J Roberts, DCS Audio Format Technical Reference (2023), part of the DCS Explorer project. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
Share this post
Like this post? Share it with your friends!