PC Speaker: Difference between revisions

2,442 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
(Comment grammatical error: 'is' -> 'it')
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(13 intermediate revisions by 10 users not shown)
Line 1:
The PC Speaker is the most primitive sound device available on PC compatible systems. It is characterized by the distinctive "beeps" and "squeaks" that it can be made to produce, and is therefore sometimes referred to as the "PC Beeper" or the "PC Squeaker".
 
== The Raw Hardware ==
 
The speaker itself has two possible positions, "in" and "out". This position can be set through bit 1 of port 0x61 on the [[Keyboard Controller]]. If this bit is set (=1), the speaker will move to the "out" position, if it is cleared (=0) then the speaker will move to the "in" position. ItMoving isin importantand toout noterepeatedly thatproduces theaudible speakertones willif notthe instantlyspeed jumpof torepetition (the desiredfrequency) position.is Ratherwithin itthe willrange movethe towardsspeaker can reproduce and the desiredhuman positionear can hear. Also, a single movement ("in" or "out") overmakes a shortclick periodsound ofbecause it's so timefast. ThisThus, allowsa thefrequency speakerwhich is too low to producebe actualheard beepsas anda whistlestone insteadmay ofbe justheard clicksas a rattle or buzz. (In fact, any frequency produced by this system also produces higher frequencies; look up "square wave harmonics" if you're interested.)
 
== Modes of Operation ==
 
=== Through the Programmable Interval Timer (PIT) ===
 
The PC Speaker can be connected directly to the output of timer number 2 on the [[Programmable Interval Timer]] by setting bit 0 of port 0x61 (=1). In this mode, when the timer goes "high" (=1) the speaker will move to the "out" position. Likewise, when the timer goes "low" (=0) the speaker will move to the "in" position. By changing the frequency at which timer 2 "ticks", the PC Speaker can be made to output sound of the same frequency.
This mode is very popular because it is easy to program and because it is asynchronous from the rest of the computer's operation, meaning that it takes very little CPU time.
It should also be noted that this is the "official" way to program the PC Speaker and, if a sound card is present, should be the only way that the PC Speaker is programmed.
 
=== Pulse Width Modulation ===
In the absence of a real sound card, the PC Speaker can be used to output low quality digital sound. As stated earlier, the speaker itself has only two possible positions, "in" and "out". More positions are needed though in order to play digital sound. Typically, 256 positions (8 bits) are considered adequate to play comprehensible audio. One popular method used by many early PC games to overcome this limitation is called pulse-width modulation. This technique uses the physical properties of the speaker to allow it to output the (relatively) complex sounds that exist in 8-bit audio.
In the absence of a real sound card, the PC Speaker can be used to output low quality digital sound.
See The Wikipedia article [http://en.wikipedia.org/wiki/Pulse-width_modulation Pulse-width modulation.]
 
==== How It Works ====
= Sample Code =
The PC Speaker takes approximately 60 millionths of a second to change positions. This means that if the position of the speaker is changed from "in" to "out" and then changed back in less than 60 microseconds, the speaker did not have enough time to fully reach the "out" position. By precisely adjusting the amount of time that the speaker is left "out", the speaker's position can be set to anywhere between "in" and "out", allowing the speaker to form more complex sounds.
 
==== Setting It Up ====
This will work on real hardware, but may not on emulators. The code also changes the PIT timer 2 frequency, so you will have to reset that when your done "beep"ing :)
You should first have the PIT interrupt you each time the speaker's position needs to be changed. To play standard audio, the CPU needs to be interrupted 44100 times every second. The easiest way to do this is to (re)program timer zero (0) to interrupt you at 44100Hz.
 
You also need a way to actually change the speaker's position. This could be done simply through bit 1 of port 0x61, but this option is too slow to be practical. Instead, it is best to (re)program timer 2 to properly set the position of the speaker for you while you wait for the next interrupt (or do other, more useful things with any spare CPU time).
//Play sound using built in speaker
 
static void play_sound(u32int nFrequence) {
==== Playing the Audio ====
u32int Div;
When the PIT interrupts you, you need to program PIT timer 2 so that it puts the PC Speaker in the "out" position for a fraction of 60 microseconds. For 8-bit audio, the number of microseconds can be calculated like this:
u8int tmp;
 
<syntaxhighlight lang="C">
microseconds = (sample * 60) / 255;
</syntaxhighlight>
 
== Sample Code ==
This will work on real hardware, butand mayin notQEMU onif emulatorsit started with <code>-audiodev pa,id=speaker -machine pcspk-audiodev=speaker</code>. The code also changes the PIT timer 2 frequency, so you will have to reset that when youryou're done "beep"ing :)
<syntaxhighlight lang="c">
//Play sound using built -in speaker
static void play_sound(u32intuint32_t nFrequence) {
u32intuint32_t Div;
u8intuint8_t tmp;
//Set the PIT to the desired frequency
Div = 1193180 / nFrequence;
outb(0x43, 0xb6);
outb(0x42, (u8intuint8_t) (Div) );
outb(0x42, (u8intuint8_t) (Div >> 8));
//And play the sound using the PC speaker
Line 39 ⟶ 52:
}
//make it shutupshut up
static void nosound() {
u8intuint8_t tmp = (inb(0x61) & 0xFC);
outb(0x61, tmp);
Line 53 ⟶ 66:
//set_PIT_2(old_frequency);
}
</syntaxhighlight>
 
== See Also ==
 
=== External links ===
 
See The Wikipedia article* [http://en.wikipedia.org/wiki/Pulse-width_modulation PulseWikipedia on pulse-width modulation.]
 
=== Forum Threads ===
 
* [http://forum.osdev.org/viewtopic.php?f=13&t=17293 Sample PC speaker code]
 
[[Category:Sound]]