PC Speaker

From OSDev.wiki
Revision as of 12:12, 27 March 2008 by osdev>Lukem95 (→‎Sample Code: <-- Added some comments and info on emulators)
Jump to navigation Jump to search

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. It is important to note that the speaker will not instantly jump to the desired position. Rather it will move towards the desired position ("in" or "out") over a short period of time. This allows the speaker to produce actual beeps and whistles instead of just clicks.

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. See The Wikipedia article Pulse-width modulation.

Sample Code

This will work on real hardware, but may not on emulators. The code also changes the PIT frequency, so you will have to reset that when your done "beep"ing :)

//Play sound using built in speaker
static void play_sound(u32int nFrequence) {
	u32int Div;
	u8int tmp;

       //Set the PIT to the desired frequency
	Div = 1193180 / nFrequence;
	outb(0x43, 0xb6);
	outb(0x42, (u8int) (Div) );
	outb(0x42, (u8int) (Div >> 8));

       //And play the sound using the PC speaker
	tmp = inb(0x61);
 	if (tmp != (tmp | 3)) {
		outb(0x61, tmp | 3);
	}
}

//make is shutup
static void nosound() {
	u8int tmp = (inb(0x61) & 0xFC);
    
	outb(0x61, tmp);
}

//Make a beep
void beep() {
	 play_sound(1000);
	 timer_wait(10);
	 nosound();
        set_PIT(old_frequency);
}