I had a VIC-20 growing up, but the difficulty of bootstrapping pre-internet meant I never really did anything all that interesting on it. Someone recently posted their flashcart for same to HackADay and then I started looking at this stuff again.
I'd forgotten—or maybe just been too young to know—just how minimal the whole thing was. A simple tilemap-based display, with a pixel clock of either NTSC colorburst×8÷7 (aspect ratio 3:2), or PAL colorburst (aspect ratio 5:3); interleaved with a CPU that ran at exactly 1/4 of that. Each nametable (using this term just for NES comparison) entry is 12 bits wide (vs 10), specifying 8 bits of tile, 3 bits of foreground color, and 1 bit specifying whether to interpret the tile as 1bpp or 2bpp and twice as wide, with three colors that are shared across the entire screen. The source palette is extremely limited, and several are out of gamut (The ones that the C64's VIC-2 replaced with greys).
The audio channels appear to be three square waves, plus one 16-bit LFSR, all of which have a seven bit divisor, and each of which have a different master clock: CPU/32, CPU/64, CPU/128, and CPU/256 respectively. All four voices share the same linear volume control, but the analog output path clips asymmetrically on anything more than about 1/3-1/2 of full scale.
In doing, I stumbled onto this thread on chipmusic where it's pointed out that the VIC20's output sound stage isn't a simple 50% square wave, but rather a eight bit shift register, with its output connected through a NOR gate to its input. When you disable the sound, you don't actually stop anything; instead you start clocking in 0s. When you enable the sound, you instead start clocking in NOT(eight bits ago). Viznut's writeup of his discovery pointed out that of the 256 different possible values, all but 16 are actually rotated forms of others. (e.g. the square wave, "0", is the same as "1", "3", "7", … "192" and "128").
I was curious about what these waveforms sounded like, so I entered them into schism tracker, and then threw Octave's FFT at them. And I noticed that, of the 16, there were four more duplicates. Because, for chip samples, forwards in time sounds the same as backwards in time.
I finally ended up with the following table ("code" means "the value in viznut's writeup treated as big-endian binary and printed as decimal"):
The first thing I noticed was that the sums of the magnitudes of the harmonics fell into three distinct groups. And then I noticed that the individual overtones tended to bounce around in the same pattern. For the group of four patterns that all have a maximum-amplitude harmonic, the other three harmonics were all same-valued.
I was specifically looking for sequences one could use in making a typical forment sweep sound (or maybe "the 'acid music' sound"). It turns out that of the extremely restricted set of sounds, the patterns above suggest rearranging the sequences in a 4x3 matrix:
At the most broadband of sequences (4/8/18/20) I have a lot of difficulty noticing the difference between the sound of the patterns: the not-quite-7dB variation from loudest to quietest isn't obvious to me.
This would suggest sequences of the form of narrowband→broadband→narrowband again would sound good and also provide a significant number of different tone colors, e.g. 0,2,4,8,12,24, and it does seem to be mostly true, except for the waveform "44", which has a problematically quiet fundamental in comparison to any of its neighbors.
None of these advanced waveforms help with the extremely restrictive tuning: for that, the only option is some kind of dithering between adjacent values at super-infrasonic rates.
Anyway, maybe this'll be useful to someone.
I'd forgotten—or maybe just been too young to know—just how minimal the whole thing was. A simple tilemap-based display, with a pixel clock of either NTSC colorburst×8÷7 (aspect ratio 3:2), or PAL colorburst (aspect ratio 5:3); interleaved with a CPU that ran at exactly 1/4 of that. Each nametable (using this term just for NES comparison) entry is 12 bits wide (vs 10), specifying 8 bits of tile, 3 bits of foreground color, and 1 bit specifying whether to interpret the tile as 1bpp or 2bpp and twice as wide, with three colors that are shared across the entire screen. The source palette is extremely limited, and several are out of gamut (The ones that the C64's VIC-2 replaced with greys).
The audio channels appear to be three square waves, plus one 16-bit LFSR, all of which have a seven bit divisor, and each of which have a different master clock: CPU/32, CPU/64, CPU/128, and CPU/256 respectively. All four voices share the same linear volume control, but the analog output path clips asymmetrically on anything more than about 1/3-1/2 of full scale.
In doing, I stumbled onto this thread on chipmusic where it's pointed out that the VIC20's output sound stage isn't a simple 50% square wave, but rather a eight bit shift register, with its output connected through a NOR gate to its input. When you disable the sound, you don't actually stop anything; instead you start clocking in 0s. When you enable the sound, you instead start clocking in NOT(eight bits ago). Viznut's writeup of his discovery pointed out that of the 256 different possible values, all but 16 are actually rotated forms of others. (e.g. the square wave, "0", is the same as "1", "3", "7", … "192" and "128").
I was curious about what these waveforms sounded like, so I entered them into schism tracker, and then threw Octave's FFT at them. And I noticed that, of the 16, there were four more duplicates. Because, for chip samples, forwards in time sounds the same as backwards in time.
I finally ended up with the following table ("code" means "the value in viznut's writeup treated as big-endian binary and printed as decimal"):
Code:
code waveform-------- dB 1x dB 3x dB 5x dB 7x
0 0000000011111111 0 -9.09 -12.59 -14.03
24 0001100011100111 -12.59 0 -14.03 -9.09
36 0010010011011011 -9.09 -14.03 0 -12.59
42 0010101011010101 -14.03 -12.59 -9.09 0
2 0000001011111101 -1.43 -21.68 -7.66 -4.94
12 0000110011110011 -7.66 -1.43 -4.94 -21.68
44 0010110011010011 -21.68 -4.94 -1.43 -7.66
10 0000101011110101 -4.94 -7.66 -21.68 -1.43
4 0000010011111011 -2.98 -6.53 -4.12 -9.76 (aka 6)
8 0000100011110111 -4.12 -2.98 -9.76 -6.53 (aka 14)
18 0001001011101101 -6.53 -9.76 -2.98 -4.12 (aka 22)
20 0001010011101011 -9.76 -4.12 -6.53 -2.98 (aka 26)
0 0000000011111111 0 -9.09 -12.59 -14.03
24 0001100011100111 -12.59 0 -14.03 -9.09
36 0010010011011011 -9.09 -14.03 0 -12.59
42 0010101011010101 -14.03 -12.59 -9.09 0
2 0000001011111101 -1.43 -21.68 -7.66 -4.94
12 0000110011110011 -7.66 -1.43 -4.94 -21.68
44 0010110011010011 -21.68 -4.94 -1.43 -7.66
10 0000101011110101 -4.94 -7.66 -21.68 -1.43
4 0000010011111011 -2.98 -6.53 -4.12 -9.76 (aka 6)
8 0000100011110111 -4.12 -2.98 -9.76 -6.53 (aka 14)
18 0001001011101101 -6.53 -9.76 -2.98 -4.12 (aka 22)
20 0001010011101011 -9.76 -4.12 -6.53 -2.98 (aka 26)
The first thing I noticed was that the sums of the magnitudes of the harmonics fell into three distinct groups. And then I noticed that the individual overtones tended to bounce around in the same pattern. For the group of four patterns that all have a maximum-amplitude harmonic, the other three harmonics were all same-valued.
I was specifically looking for sequences one could use in making a typical forment sweep sound (or maybe "the 'acid music' sound"). It turns out that of the extremely restricted set of sounds, the patterns above suggest rearranging the sequences in a 4x3 matrix:
Code:
1st 3rd 5th 7th harmonic
0 - 24 - 36 - 42 ↑ more narrowband
2 - 12 - 44 - 10
4 - 8 - 18 - 20 ↓ more broadband
0 - 24 - 36 - 42 ↑ more narrowband
2 - 12 - 44 - 10
4 - 8 - 18 - 20 ↓ more broadband
At the most broadband of sequences (4/8/18/20) I have a lot of difficulty noticing the difference between the sound of the patterns: the not-quite-7dB variation from loudest to quietest isn't obvious to me.
This would suggest sequences of the form of narrowband→broadband→narrowband again would sound good and also provide a significant number of different tone colors, e.g. 0,2,4,8,12,24, and it does seem to be mostly true, except for the waveform "44", which has a problematically quiet fundamental in comparison to any of its neighbors.
None of these advanced waveforms help with the extremely restrictive tuning: for that, the only option is some kind of dithering between adjacent values at super-infrasonic rates.
Anyway, maybe this'll be useful to someone.