Here's an even better way to think about this using complex numbers and roots of unit. Let w be a primitive 66'th root of unity: w^66=1, e.g., w=exp(2*pi*i/66). Then w^11 is a 6'th root of unity: (w^11)^6=1. And w^6 is an 11'th root of unity: (w^6)^11=1. Now consider a clock frequency of 1200*N Hz. At any point in time, the modem is transmitting nothing, it is transmitting a "1" bit, or it is transmitting a "0" bit. At any point in time, the current state of the transmitter is a complex number S, s.t. |S|=1. If the transmitter is transmitting either a "0" bit or a "1" bit, the state S of the transmitter is updated after every clock by multiplying S by another complex number. During the transmission of a full "1" bit, the state S is updated like so: S<-S*(w^6)^N=S*w^(6*N). During the transmission of a full "0" bit, the state S is updated like so: S<-S*(w^11)^N=S*w^(11*N). We can see that N=11 is a convenient choice, so that the clock frequency is 1200*11=13.2kHz. (Of course, we might also have N be some multiple of 11 and thereby gain some improvement in the quality of the generated sinusoids; details are left to the reader.) A "1" transmission will last 11 clock cycles, during which time we will output a complete sinusoid. In order to achieve this, after each clock during a "1" transmission, we update S: S<-S*(w^6)=S*exp(12*pi*i/66)=S*exp(2*pi*i/11). Similarly, a "0" transmission will also last 11 clock cycles, during which time we will output 1 5/6'ths of a sinusoid. In order to achieve this, after each clock during a "0" transmission, we update S: S<-S*(w^11)=S*exp(22*pi*i/66)=S*exp(2*pi*i/6). We can verify that after 11 clock cycles of a "1" transmission, S<-S*(w^6)^11=S*(w^66)=S, which is correct, since a single "1" bit always transmits one complete sinusoid cycle. But after 11 clock cycles of a "0" transmission, S<-S*(w^11)^11=S*w^121=S*w^55, which is correct, since a "0" transmission consists of 1+5/6's of a complete sinusoid cycle. We note that even if we initialize S=1, before starting to transmit a packet of bits, an unfortunate number of "0" bits will *not* return S to 1, so when we stop transmitting, we get a small glitch in the output. With floating point being almost ubiquitous in small CPU chips, these calculations may even be faster even than using a RAM table lookup. One thing to keep in mind: S should be *normalized* from time to time -- S<-S/|S| -- in order to preserve a constant waveform envelope. At 05:35 PM 1/15/2018, Henry Baker wrote:
The Bell 202 modem (1976) was the first digital modem in widespread use.
https://en.wikipedia.org/wiki/Bell_202_modem
It uses "audio frequency shift keying" with the two frequencies being 1200Hz ("1") and 2200Hz ("0"). It is still used to transmit Caller ID on wireline phones and by ham radio operators in the ham radio bands.
The choice of the frequencies 1200&2200 was a tiny bit unfortunate, because although a "1" consists of a single complete sinusoidal cycle, a "0" consists of *not quite* 2 complete cycles.
Here's the rub: when you transition from a 0->1 or from a 1->0, you want the waveform to be *continuous*. So this means that you're going to have to adjust the *phase* of the sinusoid that you generate when you make the transition; i.e., you can't simply start at zero for every bit, else these discontinuities will generate high frequency noise which will widen the overall bandwidth used by the modem.
Assuming that you're going to implement the "0" and the "1" by means of *tables* of *digital samples* of the appropriate sinusoids, how many tables do you need?