VIC-20 audio output - DC offsets and clipping
Moderator: Moderators
VIC-20 audio output - DC offsets and clipping
I've been doing some more investigations into the VIC-20 audio output recently, initially focusing on the noise generator but later returning to the subject of DC offsets and clipping.
There are four audio generators summed together and amplified at adjustable gain by a 4 bit volume control to produce the audio output in a VIC-20. While one of these may be operated at full volume (level 15) without distortion, operating all four at full volume will produce clipping distortion. The distortion is asymmetric, occurring on the high side of the waveform when measured at the audio output but not on the low side.
One subject of interest is what volume level can be used with all three tone generators and the noise generator without causing distortion. This may vary between VIC to VIC but broadly speaking a setting of 7 or 8 generally produces no distortion or very little distortion depending on the machine. Because 7 is 0111 in binary and 8 is 1000, the difference between these two settings relies on the magnitude of all four bits and so it is the most susceptible to error. One of my VICs has almost no difference between 7 and 8, producing undistorted sound on both. The VIC in eslapion's video posted on the following post is undistorted at volume 7 and starting to distort at volume 8.
http://ploguechipsounds.blogspot.com/20 ... pping.html
A good test is to play a chorused three oscillator note and listen for periodic distortion as the squares constructively interfere. At times there will be no distortion, when the tone generators are out of phase with each other, other times there will be distortion depending upon the volume level. Example POKEs for this are as follows.
POKE 36878, (from 0 to 15)
POKE 36874, 255-32 (Sets the bass tone generator to period 32, equivalent to 128 on the soprano generator)
POKE 36875, 255-63 (Sets the alto tone generator to 63, equivalent to 126 on soprano)
POKE 36876, 255-127 (Sets the soprano tone generator to 127)
When the VIC is reset, the tone generators are silenced and output 0, which corresponds to the minimum offset. However, the noise generator, which is also silenced, outputs 1 from reset state. Since the distortion occurs on the 1 side of the waveform, when you determine the maximum volume level for three tone oscillators without clipping from the reset state, you are in fact determining the maximum level for all three tone oscillators plus noise.
When the noise generator is turned on and then off again, the state it outputs is sometimes 0 and sometimes 1. When outputting 0, a higher maximum level for three tone oscillators is possible without distortion, and a higher level for two oscillators is also possible. On my VIC it is possible to play two tone generators at volume 15 without distortion, when the noise generator is stopped and outputting 0. When it is outputting 1, the maximum level for two tone generators is 10.
When the noise generator is stopped and outputting 1, that level 1 is equivalent to the highs when it is started and outputting noise. However, the level when it is stopped and outputting 0 is not equivalent to the lows when outputting noise. The voltage for the 0 state when stopped is somewhere between the low and high on states, not quite half way but biased slightly towards the low side.
The same turns out to be true for the tone generators as well. These are always in the 0 state when stopped, but that 0 state level is not the same as the lows of the square waveforms but somewhere between the low and high points, near the mid point but slightly towards the low side.
The effect is to remove most of the DC offset when a tone generator is turned on and off, thus VIC tone generators do not emit loud clicks when they are switched on or off, unlike some other square wave based tone generators.
When the noise generator stops on output state 0, the same is true, but there is a click when it stops on output state 1, and there will be another one when it starts again. This can be seen on an oscilloscope.
Greater understanding of the noise generator may provide the ability to control which state it stops in, as well as the ability to control which of several noise polynomial sequences it produces. In many VIC games and demos the noise generator can be heard changing in timbre from time to time, varying from a very pitchless 'white' noise to a sound with a strong bias toward one frequency, sounding a bit like white noise going through an analogue filter at high resonance.
This is more noticeable when the cutoff frequency of the filter in the audio output stage has been moved from 1.6kHz to 16kHz, as in my earlier post.
http://rga24.blogspot.com/2008/09/vic-2 ... ation.html
There are four audio generators summed together and amplified at adjustable gain by a 4 bit volume control to produce the audio output in a VIC-20. While one of these may be operated at full volume (level 15) without distortion, operating all four at full volume will produce clipping distortion. The distortion is asymmetric, occurring on the high side of the waveform when measured at the audio output but not on the low side.
One subject of interest is what volume level can be used with all three tone generators and the noise generator without causing distortion. This may vary between VIC to VIC but broadly speaking a setting of 7 or 8 generally produces no distortion or very little distortion depending on the machine. Because 7 is 0111 in binary and 8 is 1000, the difference between these two settings relies on the magnitude of all four bits and so it is the most susceptible to error. One of my VICs has almost no difference between 7 and 8, producing undistorted sound on both. The VIC in eslapion's video posted on the following post is undistorted at volume 7 and starting to distort at volume 8.
http://ploguechipsounds.blogspot.com/20 ... pping.html
A good test is to play a chorused three oscillator note and listen for periodic distortion as the squares constructively interfere. At times there will be no distortion, when the tone generators are out of phase with each other, other times there will be distortion depending upon the volume level. Example POKEs for this are as follows.
POKE 36878, (from 0 to 15)
POKE 36874, 255-32 (Sets the bass tone generator to period 32, equivalent to 128 on the soprano generator)
POKE 36875, 255-63 (Sets the alto tone generator to 63, equivalent to 126 on soprano)
POKE 36876, 255-127 (Sets the soprano tone generator to 127)
When the VIC is reset, the tone generators are silenced and output 0, which corresponds to the minimum offset. However, the noise generator, which is also silenced, outputs 1 from reset state. Since the distortion occurs on the 1 side of the waveform, when you determine the maximum volume level for three tone oscillators without clipping from the reset state, you are in fact determining the maximum level for all three tone oscillators plus noise.
When the noise generator is turned on and then off again, the state it outputs is sometimes 0 and sometimes 1. When outputting 0, a higher maximum level for three tone oscillators is possible without distortion, and a higher level for two oscillators is also possible. On my VIC it is possible to play two tone generators at volume 15 without distortion, when the noise generator is stopped and outputting 0. When it is outputting 1, the maximum level for two tone generators is 10.
When the noise generator is stopped and outputting 1, that level 1 is equivalent to the highs when it is started and outputting noise. However, the level when it is stopped and outputting 0 is not equivalent to the lows when outputting noise. The voltage for the 0 state when stopped is somewhere between the low and high on states, not quite half way but biased slightly towards the low side.
The same turns out to be true for the tone generators as well. These are always in the 0 state when stopped, but that 0 state level is not the same as the lows of the square waveforms but somewhere between the low and high points, near the mid point but slightly towards the low side.
The effect is to remove most of the DC offset when a tone generator is turned on and off, thus VIC tone generators do not emit loud clicks when they are switched on or off, unlike some other square wave based tone generators.
When the noise generator stops on output state 0, the same is true, but there is a click when it stops on output state 1, and there will be another one when it starts again. This can be seen on an oscilloscope.
Greater understanding of the noise generator may provide the ability to control which state it stops in, as well as the ability to control which of several noise polynomial sequences it produces. In many VIC games and demos the noise generator can be heard changing in timbre from time to time, varying from a very pitchless 'white' noise to a sound with a strong bias toward one frequency, sounding a bit like white noise going through an analogue filter at high resonance.
This is more noticeable when the cutoff frequency of the filter in the audio output stage has been moved from 1.6kHz to 16kHz, as in my earlier post.
http://rga24.blogspot.com/2008/09/vic-2 ... ation.html
That post was saying the noise generator either outputs 0 or 1 when the gate bit is off; unlike the tone generators it does not always return to 0. In fact it starts up in the 1 state, unlike the tone generators.tlr wrote:Interesting read!
The noise generator timbre changing is one of the really unknown bits of the VIC.
What you are saying is that the noise generator does not run when the gate bit is off?
It appears that the noise generator does not run when the gate bit is off, but what is also interesting is that the noise generator can go into different states depending on precisely when it is turned off.
I have written a program which demonstrates different VIC noise waveforms using this feature. You give it a number and the program executes a short machine code routine which switches the noise generator on and off in certain ways.
At any point after that, you may turn the noise generator back on and get the same particular noise waveform for that number. It can be turned on at any frequency and the frequency may be changed after that without changing which waveform the noise generator is producing.
Evidently the act of turning the noise generator off is what puts it into a new state; an arbitrary length of time may then pass until it is turned back on. It depends where in the noise polynomial cycle it is when it is turned off.
The program works by first putting the noise generator into a defined state using a series of on and off pulses of fixed width, which I have observed always puts it into the same waveform, then applying the pulse of user definable width.
-
- The Most Noble Order of Denial
- Posts: 343
- Joined: Fri May 01, 2009 4:44 pm
If you look in the VICE at the VIC file, I think it has the random noise pattern exactly as the vic generates it. At least from my vague memory of the comments.tlr wrote:Even more interesting!
Controlling the noise...
Maybe I should resume work on ultraplayer2.
If we would know the RNG structure it could be easily emulated in xvic.
From my rather detailed knowledge of the vice code base, the noise generator is not accurate.matsondawson wrote:If you look in the VICE at the VIC file, I think it has the random noise pattern exactly as the vic generates it. At least from my vague memory of the comments.tlr wrote:If we would know the RNG structure it could be easily emulated in xvic.
The reason that the noise generator is not accurate is because no one managed to understand it fully yet.
The rest is very accurate though, except for probably the "middle" levels rga24 mentions.
Re: VIC-20 audio output - DC offsets and clipping
Interesting thread! I'm trying to fix the FPGA implementation of the VIC-20 which currently does not emulate the DC offset.
If my understanding is correct this is what happens in pseudo-C code:
Is that a good approximation?
EDIT:
If my understanding is correct this is what happens in pseudo-C code:
Code: Select all
int half = volume * 40 / 100;
int last_noise = /* half or max */;
int level =
(reg_36874 & 128 == 0 ? half : volume * value_36874) +
(reg_36875 & 128 == 0 ? half : volume * value_36875) +
(reg_36876 & 128 == 0 ? half : volume * value_36876) +
(reg_36877 & 128 == 0 ? last_noise : volume * value_36877);
EDIT:
@rga24 can I have it?"I have written a program which demonstrates different VIC noise waveforms using this feature."
Re: VIC-20 audio output - DC offsets and clipping
Regarding the internals of the noise generator, I did a little of research browsing the source code of the various emulators:
1) VICE implements it as a wave table (sampled from a real VIC I guess)
2) FPGA-arcade mentions "I am fairly sure it is a LFSR of length 18 or 19, however I have not found the taps which reproduce the waveform of a real device."
but what's interesting is 3) MAME/MESS as it mentions a certain document by Asger Alstrup Nielsen:
I wonder if there's a way to check it against a real machine. Any ideas?
1) VICE implements it as a wave table (sampled from a real VIC I guess)
2) FPGA-arcade mentions "I am fairly sure it is a LFSR of length 18 or 19, however I have not found the taps which reproduce the waveform of a real device."
but what's interesting is 3) MAME/MESS as it mentions a certain document by Asger Alstrup Nielsen:
Code: Select all
* noise channel
* based on a document by diku0748@diku.dk (Asger Alstrup Nielsen)
*
* 23 bit shift register
* initial value (0x7ffff8)
* after shift bit 0 is set to bit 22 xor bit 17
* dac sample bit22 bit20 bit16 bit13 bit11 bit7 bit4 bit2(lsb)
- eslapion
- ultimate expander
- Posts: 5458
- Joined: Fri Jun 23, 2006 7:50 pm
- Location: Canada
- Occupation: 8bit addict
Re: VIC-20 audio output - DC offsets and clipping
I find it encouraging some people suddenly find interest in this aspect of the VIC-20's audio output.
Be normal.
Re: VIC-20 audio output - DC offsets and clipping
can you point me to some other threads where the sound generation is discussed in detail? I remember years ago a discussion about changing the waveform of the square wave with some trickery. But I can't locate it...
I'm running the VIC-20 FPGA and the sound is quite inaccurate, I would like to improve it, at least at the VICE level.
I'm running the VIC-20 FPGA and the sound is quite inaccurate, I would like to improve it, at least at the VICE level.
Re: VIC-20 audio output - DC offsets and clipping
Hi nippur72, search for
„Digital audio boosting examples„ here on Denial.
„Digital audio boosting examples„ here on Denial.
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
-._/classes instead of masses\_.-
Re: VIC-20 audio output - DC offsets and clipping
@Noizer thanks! Found a very interesting document by Viznut/pwp, with a model of the sound generators.
Re: VIC-20 audio output - DC offsets and clipping
This document is no longer available. Please could you upload it Nippur72?
Vic20-Ian
The best things in life are Vic-20
Upgrade all new gadgets and mobiles to 3583 Bytes Free today! Ready
The best things in life are Vic-20
Upgrade all new gadgets and mobiles to 3583 Bytes Free today! Ready
Re: VIC-20 audio output - DC offsets and clipping
Thank you Simon.srowe wrote: ↑Sun Jul 18, 2021 9:17 am This one?
https://github.com/LeifBloomquist/VICMI ... eforms.txt
Vic20-Ian
The best things in life are Vic-20
Upgrade all new gadgets and mobiles to 3583 Bytes Free today! Ready
The best things in life are Vic-20
Upgrade all new gadgets and mobiles to 3583 Bytes Free today! Ready