Hi,
onlyonemac wrote:@SpyderTL: yes there is research being done (and possibly even a few synths implemented?) around the principle of using a basic tone and then modulating it to produce sound - if it was possible to change the amplitude of the PC speaker it might even be possible to generate speech that way, but it isn't possible to change the amplitude of the PC speaker unfortunately.
It's possible to change the amplitude of the PC speaker. The general technique is called "Pulse Width Modulation".
Imagine a high frequency square wave (maybe 110 KHz) with a 50% duty cycle (half the time "on" and half the time "off"). This is too fast for the speaker to cope with, so the speaker ends up half on and half off. By adjusting the duty cycle you adjust the position of the speaker.
Now imagine you've got a source of digitised sound with a 22 KHz sample rate and 8-bit samples. In this case your 110 KHz high frequency square wave does 5 "pulses" for each sample. If the sample is 255 you set the duty cycle to 100% for 5 high frequency pulses, if the sample is 128 you set the duty cycle to 50% for 5 high frequency pulses, etc.
Now imagine if you scale those 8-bit samples by some value. For example, you could halve the amplitude - if the sample is 255 you set the duty cycle to 50% for 5 high frequency pulses, if the sample is 128 you set the duty cycle to 25% for 5 high frequency pulses, etc.
Basically; you can get (mono, not necessarily awesome quality) digitised sound with volume control out of the PC speaker.
However; this will cost CPU time and take a lot of care.
To control the high frequency sound accurately you'd want to use both PIT channel 0 and PIT channel 2 in "one shot" mode ("mode 0 - interrupt on terminal count"). Within the IRQ handler for PIT channel 0; you set PIT channel 2's count to match the time until the rising edge of the pulse; and set PIT channel 0's count to generate an IRQ when you want the falling edge of the high frequency pulse. For 110 KHz this adds up to 110000 IRQs per second, and (assuming you're using "low byte only" mode) it'll cost of about 3 us per IRQ, or about 330 ms of time per second, or about a third of one CPU's time. Of course for 100% duty cycle and a 0% duty cycle you can optimise by setting both timer counts to cover the duration of 5 whole pulses at once, so that "a third of one CPU's time" is a slightly pessimistic estimate.
You also have to worry about "jitter" caused by anything that disables IRQs (possibly including other IRQ handlers), because this can cause audible distortion if it's bad enough.
Finally; some computers use a small traditional "moving coil" speaker and for these it shouldn't be too hard to get reasonable digitized sound playback because the speaker's diaphragm takes time to move; but some computers use smaller piezoelectric speakers that move much faster and for these you might not be able to get acceptable quality digitized sound playback using timers because the high frequency square wave needs to be higher frequency than the CPU, PIT and/or PIC chips can handle. In that case you'd probably need to skip the timers and dedicate an entire CPU to constantly pounding the speaker's on/off gate (which isn't necessarily insane if you're got a 4-core chip and want it bad enough).
Cheers,
Brendan