386BSD provided a MD function sysbeep. This took two arguments (pitch and period). Pitch was jammed into the PIT's divisor directly (which means the argument was expected to sound a tone at '1193182 / pitch' Hz). FreeBSD inherited this interface. In commit e46598588587 (svn 177642, Mar 26 2008), phk changed this function to take a tone to sound in hz. He converted all in-tree instances of 1193182 / hz to just hz (and kept the few misguided folks that passed hz directly unchanged -- this was part of what motivated the change). He converted the places where we pre-computed the 8254 divisor from being pitch to 1193182 / pitch (since that converts the divisor to the frequency and the interfaces that were exposed to userland exposed it in these units in places, continuing the tradition inherited from SCO System V/386 Unix in spots). In 2009, Ed Shouten was contracted by the FreeBSD Foundation to write / finish newcons. This work was done in perforce and was imported into subversion in user/ed/newcons in revision 199072 (https://svnweb.freebsd.org/base?view=revision&revision=199072) which was later imported into FreeBSD by ray@ (Aleksandr Rybalko). From that earliest import into svn import to this date, we ring the bell with: sysbeep(1193182 / VT_BELLPITCH, VT_BELLDURATION); where VT_BELLPITCH was defined to be 800. This results in a bell frequency of 1491Hz, more or less today. This is similar to the frequency that syscons and pcvt used (1493Hz and 1500Hz respectively). This in turn was inherited from 386BSD, it seems, which used the hard coded value 0x31b which is 795 -> 1500Hz. This '800' was intended to be the bell tone (eg 800Hz) and this interface was one that wasn't converted. The most common terminal prior to the rise of PCs was the VT100, which had an approximately 800Hz bell. Ed Shouten has confirmed that the original intent was 800Hz and changing this was overlooked after the change to -current was made. This restors that original intent and makes the bell less obnoxious in the process.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
It looks like this bug was inherited from sc(4)
See R10:e46598588587b4897f6604489364f83fffd4d033, although it looks like that just preserved an existing bug
--- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -3613,7 +3613,7 @@ sc_bell(scr_stat *scp, int pitch, int duration) } else if (duration != 0 && pitch != 0) { if (scp != scp->sc->cur_scp) pitch *= 2; - sysbeep(pitch, duration); + sysbeep(1193182 / pitch, duration); } }
This code is right: the bell has always been obnoxious. Further research shows this was intended. 800 was never the frequency, but was always the divisor.
I think you got it backward. I think it was always meant to be the frequency, hence the name of the constant, but whoever first implemented it got the math wrong and didn't realize, either because they had a tin ear or because they attributed the unpleasantness to the poor quality of PC speakers. And regardless, I agree that 1491 Hz is grating, and that alone is reason enough to change it if we want to.
(As an aside, I have tried to find out what frequency the original VT220 beeped at and not had much luck so far, but I have contacted someone whom I believe may have a working unit.)
This dates back to syscons, which got it from pcvt. pcvt uses 1193182 / 1493 for its routines (which program the pit directly, so this results in 1491Hz being selected: the value is 799). In 2.1 it does 'sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);' where sysbeep writes the first argument direclty into the PIT (so it really is 1493Hz) But there's something interesting below...
(As an aside, I have tried to find out what frequency the original VT220 beeped at and not had much luck so far, but I have contacted someone whom I believe may have a working unit.)
I was looking for a VT100 or VT220 beep frequency. The VT220 uses the LK201 to beep. The LK201 has an 8051 running at 7.373MHz in it that drives one of the pins through an inverter to a PNP amplifier transistor to a speaker tied to +12V. As far as I know, we don't have the ROM dumps for the program that's inside the 8051. I do have an LK201 that I could connect a scope to the speaker when it beeps, though my home gear is kinda cheap and limited. I've not run across a beep frequency for this that was documented.
The closest I could find was in the VT100 technical manual (EK-VT100-TM-003) that says in section 4.4.3 Keyboard Status Byte on page 4-31 (page 82 in the PDF):
"The eighth bit, if sent only once, causes the keyboard speaker to click. ... If the bit is sent approximately two hundred times in a row, for about a quarter second, it sounds a bell. "
which if I'm doing the math right would mean '200 0->1' transitions in .25s -> 800Hz, approximately.
And then later in section 4.4.7 Bell it walks us through how the circuit works concluding "allowing the circuit to produce an 800 hertz tone." including the schematic on page 4-41 (page 92 in the PDF) "Figure 4-4-9 Bell Circuit".
Source: http://bitsavers.org/pdf/dec/terminal/vt100/EK-VT100-TM-003_VT100_Technical_Manual_Jul82.pdf
So now I'm less sure.
So the bell in X was 1493Hz (the code quoted was for the ring bell ioctl)
For a normal ^G that was output, it used 1500Hz:
case 0x07: /* BEL */ if(svsp->bell_on) sysbeep(PCVT_SYSBEEPF/1500, hz/4); break;
Looking at the history here: sysbeep used to take a PIT divisor (so the 1193182 / freq_in_hz was right). This changed in 2008 (but would first appear in FreeBSD 8). vt was merged in 2013 just before FreeBSD 10, but could have started before this change.
So after saying a lot where I didn't believe DES, I've convinced myself that the vt code was written knowing sysbeep took the old value, not the new value. I'll write to ray@.
sys/dev/vt/vt_core.c | ||
---|---|---|
123–124 | I'll likely drop this bit, though. |
obsolete hardware, long standing PIT/timer hilarity and reverse engineering frequencies from documentation. i love it.