1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * Extract DTMF signals from 16 bit PCM audio
10  *
11  * Originally written by Poul-Henning Kamp <phk@freebsd.org>
12  * Made into a C++ class by Roger Hardiman <roger@freebsd.org>, January 2002
13  *
14  * $Revision: 23725 $
15  * $Author: rjongbloed $
16  * $Date: 2009-10-28 22:11:42 -0500 (Wed, 28 Oct 2009) $
17  */
18 
19 #ifdef __GNUC__
20 #pragma implementation "dtmf.h"
21 #endif
22 
23 #include <ptlib.h>
24 #include <ptclib/dtmf.h>
25 
26 #if P_DTMF
27 
28 #include <math.h>
29 
30 /* Integer math scaling factor */
31 #define FSC (1<<12)
32 
33 /* This is the Q of the filter (pole radius) */
34 #define POLRAD .99
35 
36 #define P2 ((int)(POLRAD*POLRAD*FSC))
37 
PDTMFDecoder()38 PDTMFDecoder::PDTMFDecoder()
39   : sampleCount(0)
40   , tonesDetected(0)
41   , inputAmplitude(0)
42 {
43   // Initialise the class
44   int i;
45   for (i = 0; i < NumTones; i++)
46     y[i] = h[i] = k[i] = 0;
47 
48   for (i = 0; i < 256; i++)
49     key[i] = '?';
50 
51   /* We encode the tones in 8 bits, translate those to symbol */
52   key[0x11] = '1'; key[0x12] = '4'; key[0x14] = '7'; key[0x18] = '*';
53   key[0x21] = '2'; key[0x22] = '5'; key[0x24] = '8'; key[0x28] = '0';
54   key[0x41] = '3'; key[0x42] = '6'; key[0x44] = '9'; key[0x48] = '#';
55   key[0x81] = 'A'; key[0x82] = 'B'; key[0x84] = 'C'; key[0x88] = 'D';
56 
57   /* The frequencies we're trying to detect */
58   /* These are precalculated to save processing power */
59   /* static int dtmf[9] = {697, 770, 852, 941, 1209, 1336, 1477, 1633, 1100, 2100}; */
60   /* p1[tone] = (-cos(2 * 3.141592 * dtmf[tone] / 8000.0) * FSC) */
61   p1[0] = -3497; p1[1] = -3369; p1[2] = -3212; p1[3] = -3027;
62   p1[4] = -2384; p1[5] = -2040; p1[6] = -1635; p1[7] = -1164;
63   p1[8] = -2660; p1[9] = 321;
64 }
65 
Decode(const short * sampleData,PINDEX numSamples,unsigned mult,unsigned div)66 PString PDTMFDecoder::Decode(const short * sampleData, PINDEX numSamples, unsigned mult, unsigned div)
67 {
68 #if 0
69   {
70     static int fd = -1;
71     if (fd < 0) {
72       fd = ::_open("dtmf.pcm", _O_BINARY | _O_CREAT | O_RDWR, 0777);
73       PTRACE(1, "DTMF\tdebug file opened");
74     }
75     if (fd >= 0)
76       ::_write(fd, sampleData, numSamples*2);
77   }
78 #endif
79 
80   PString keyString;
81 
82   PINDEX pos;
83   for (pos = 0; pos < numSamples; pos++) {
84 
85     /* Read (and scale) the next 16 bit sample */
86     int x = (int)(mult * (*sampleData++)) / div;
87     x = x / (32768/FSC);
88 
89     /* Input amplitude */
90     if (x > 0)
91       inputAmplitude += (x - inputAmplitude) / 128;
92     else
93       inputAmplitude += (-x - inputAmplitude) / 128;
94 
95     /* For each tone */
96     int newTones = 0;
97     for (int tone = 0; tone < NumTones; tone++) {
98 
99       /* Turn the crank */
100       int c = (P2 * (x - k[tone])) / FSC;
101       int d = x + c;
102       int f = (p1[tone] * (d - h[tone])) / FSC;
103       int n = x - k[tone] - c;
104       k[tone] = h[tone] + f;
105       h[tone] = f + d;
106 
107       /* Detect and Average */
108       if (n > 0)
109         y[tone] += (n - y[tone]) / 64;
110       else
111         y[tone] += (-n - y[tone]) / 64;
112 
113       /* Threshold */
114       if (y[tone] > FSC/10 && y[tone] > inputAmplitude)
115         newTones |= 1 << tone;
116     }
117 
118     /* Hysteresis and noise supressor */
119     if (newTones != tonesDetected) {
120       sampleCount = 0;
121       tonesDetected = newTones;
122     }
123     else if (sampleCount++ == DetectSamples) {
124       if (tonesDetected < 256) {
125         if (key[tonesDetected] != '?') {
126           PTRACE(3,"DTMF\tDetected '" << key[tonesDetected] << "' in PCM-16 stream");
127           keyString += key[tonesDetected];
128         }
129       }
130       else {
131         char ch = 0;
132         if ((tonesDetected & 0x100) != 0)
133           ch = 'X';
134         else if ((tonesDetected & 0x200) != 0)
135           ch = 'Y';
136 
137         if (ch != 0) {
138           PTRACE(3,"DTMF\tDetected tone '" << ch << "' in PCM-16 stream");
139           keyString += ch;
140         }
141       }
142     }
143   }
144   return keyString;
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////////////////
148 
sine(int angle,int freq)149 static int sine(int angle, int freq)
150 {
151   static int const sinArray[2000] = {
152     0,0,1,2,3,3,4,5,6,7,7,8,9,10,10,11,12,13,14,14,15,16,17,18,18,19,20,21,21,22,
153     23,24,25,25,26,27,28,29,29,30,31,32,32,33,34,35,36,36,37,38,39,40,40,41,42,43,43,44,45,46,
154     47,47,48,49,50,51,51,52,53,54,54,55,56,57,58,58,59,60,61,62,62,63,64,65,65,66,67,68,69,69,
155     70,71,72,72,73,74,75,76,76,77,78,79,80,80,81,82,83,83,84,85,86,87,87,88,89,90,90,91,92,93,
156     94,94,95,96,97,98,98,99,100,101,101,102,103,104,105,105,106,107,108,108,109,110,111,112,112,113,114,115,115,116,
157     117,118,119,119,120,121,122,122,123,124,125,126,126,127,128,129,130,130,131,132,133,133,134,135,136,137,137,138,139,140,
158     140,141,142,143,144,144,145,146,147,147,148,149,150,151,151,152,153,154,154,155,156,157,157,158,159,160,161,161,162,163,
159     164,164,165,166,167,168,168,169,170,171,171,172,173,174,175,175,176,177,178,178,179,180,181,181,182,183,184,185,185,186,
160     187,188,188,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,201,202,202,203,204,205,205,206,207,208,208,209,
161     210,211,212,212,213,214,215,215,216,217,218,218,219,220,221,221,222,223,224,225,225,226,227,228,228,229,230,231,231,232,
162     233,234,234,235,236,237,238,238,239,240,241,241,242,243,244,244,245,246,247,247,248,249,250,250,251,252,253,254,254,255,
163     256,257,257,258,259,260,260,261,262,263,263,264,265,266,266,267,268,269,269,270,271,272,272,273,274,275,275,276,277,278,
164     278,279,280,281,282,282,283,284,285,285,286,287,288,288,289,290,291,291,292,293,294,294,295,296,297,297,298,299,300,300,
165     301,302,303,303,304,305,306,306,307,308,309,309,310,311,312,312,313,314,314,315,316,317,317,318,319,320,320,321,322,323,
166     323,324,325,326,326,327,328,329,329,330,331,332,332,333,334,335,335,336,337,337,338,339,340,340,341,342,343,343,344,345,
167     346,346,347,348,349,349,350,351,352,352,353,354,354,355,356,357,357,358,359,360,360,361,362,363,363,364,365,365,366,367,
168     368,368,369,370,371,371,372,373,373,374,375,376,376,377,378,379,379,380,381,381,382,383,384,384,385,386,387,387,388,389,
169     389,390,391,392,392,393,394,394,395,396,397,397,398,399,400,400,401,402,402,403,404,405,405,406,407,407,408,409,410,410,
170     411,412,412,413,414,415,415,416,417,417,418,419,420,420,421,422,422,423,424,425,425,426,427,427,428,429,430,430,431,432,
171     432,433,434,434,435,436,437,437,438,439,439,440,441,442,442,443,444,444,445,446,446,447,448,449,449,450,451,451,452,453,
172     453,454,455,456,456,457,458,458,459,460,460,461,462,463,463,464,465,465,466,467,467,468,469,470,470,471,472,472,473,474,
173     474,475,476,476,477,478,478,479,480,481,481,482,483,483,484,485,485,486,487,487,488,489,489,490,491,492,492,493,494,494,
174     495,496,496,497,498,498,499,500,500,501,502,502,503,504,504,505,506,507,507,508,509,509,510,511,511,512,513,513,514,515,
175     515,516,517,517,518,519,519,520,521,521,522,523,523,524,525,525,526,527,527,528,529,529,530,531,531,532,533,533,534,535,
176     535,536,537,537,538,539,539,540,541,541,542,543,543,544,545,545,546,547,547,548,549,549,550,550,551,552,552,553,554,554,
177     555,556,556,557,558,558,559,560,560,561,562,562,563,564,564,565,565,566,567,567,568,569,569,570,571,571,572,573,573,574,
178     575,575,576,576,577,578,578,579,580,580,581,582,582,583,583,584,585,585,586,587,587,588,589,589,590,590,591,592,592,593,
179     594,594,595,596,596,597,597,598,599,599,600,601,601,602,602,603,604,604,605,606,606,607,607,608,609,609,610,611,611,612,
180     612,613,614,614,615,616,616,617,617,618,619,619,620,620,621,622,622,623,624,624,625,625,626,627,627,628,628,629,630,630,
181     631,631,632,633,633,634,635,635,636,636,637,638,638,639,639,640,641,641,642,642,643,644,644,645,645,646,647,647,648,648,
182     649,650,650,651,651,652,653,653,654,654,655,655,656,657,657,658,658,659,660,660,661,661,662,663,663,664,664,665,666,666,
183     667,667,668,668,669,670,670,671,671,672,673,673,674,674,675,675,676,677,677,678,678,679,679,680,681,681,682,682,683,683,
184     684,685,685,686,686,687,687,688,689,689,690,690,691,691,692,693,693,694,694,695,695,696,697,697,698,698,699,699,700,700,
185     701,702,702,703,703,704,704,705,705,706,707,707,708,708,709,709,710,710,711,712,712,713,713,714,714,715,715,716,717,717,
186     718,718,719,719,720,720,721,721,722,723,723,724,724,725,725,726,726,727,727,728,728,729,730,730,731,731,732,732,733,733,
187     734,734,735,735,736,736,737,738,738,739,739,740,740,741,741,742,742,743,743,744,744,745,745,746,746,747,748,748,749,749,
188     750,750,751,751,752,752,753,753,754,754,755,755,756,756,757,757,758,758,759,759,760,760,761,761,762,762,763,763,764,764,
189     765,765,766,766,767,768,768,769,769,770,770,771,771,772,772,773,773,774,774,774,775,775,776,776,777,777,778,778,779,779,
190     780,780,781,781,782,782,783,783,784,784,785,785,786,786,787,787,788,788,789,789,790,790,791,791,792,792,793,793,793,794,
191     794,795,795,796,796,797,797,798,798,799,799,800,800,801,801,802,802,802,803,803,804,804,805,805,806,806,807,807,808,808,
192     809,809,809,810,810,811,811,812,812,813,813,814,814,814,815,815,816,816,817,817,818,818,819,819,819,820,820,821,821,822,
193     822,823,823,823,824,824,825,825,826,826,827,827,827,828,828,829,829,830,830,831,831,831,832,832,833,833,834,834,834,835,
194     835,836,836,837,837,837,838,838,839,839,840,840,840,841,841,842,842,843,843,843,844,844,845,845,846,846,846,847,847,848,
195     848,848,849,849,850,850,850,851,851,852,852,853,853,853,854,854,855,855,855,856,856,857,857,857,858,858,859,859,859,860,
196     860,861,861,861,862,862,863,863,863,864,864,865,865,865,866,866,867,867,867,868,868,869,869,869,870,870,870,871,871,872,
197     872,872,873,873,874,874,874,875,875,875,876,876,877,877,877,878,878,878,879,879,880,880,880,881,881,881,882,882,883,883,
198     883,884,884,884,885,885,885,886,886,887,887,887,888,888,888,889,889,889,890,890,891,891,891,892,892,892,893,893,893,894,
199     894,894,895,895,895,896,896,896,897,897,898,898,898,899,899,899,900,900,900,901,901,901,902,902,902,903,903,903,904,904,
200     904,905,905,905,906,906,906,907,907,907,908,908,908,909,909,909,910,910,910,911,911,911,912,912,912,913,913,913,913,914,
201     914,914,915,915,915,916,916,916,917,917,917,918,918,918,918,919,919,919,920,920,920,921,921,921,922,922,922,922,923,923,
202     923,924,924,924,925,925,925,925,926,926,926,927,927,927,928,928,928,928,929,929,929,930,930,930,930,931,931,931,932,932,
203     932,932,933,933,933,934,934,934,934,935,935,935,935,936,936,936,937,937,937,937,938,938,938,939,939,939,939,940,940,940,
204     940,941,941,941,941,942,942,942,942,943,943,943,944,944,944,944,945,945,945,945,946,946,946,946,947,947,947,947,948,948,
205     948,948,949,949,949,949,950,950,950,950,951,951,951,951,952,952,952,952,952,953,953,953,953,954,954,954,954,955,955,955,
206     955,956,956,956,956,956,957,957,957,957,958,958,958,958,958,959,959,959,959,960,960,960,960,960,961,961,961,961,962,962,
207     962,962,962,963,963,963,963,963,964,964,964,964,964,965,965,965,965,965,966,966,966,966,967,967,967,967,967,967,968,968,
208     968,968,968,969,969,969,969,969,970,970,970,970,970,971,971,971,971,971,972,972,972,972,972,972,973,973,973,973,973,973,
209     974,974,974,974,974,975,975,975,975,975,975,976,976,976,976,976,976,977,977,977,977,977,977,978,978,978,978,978,978,979,
210     979,979,979,979,979,980,980,980,980,980,980,980,981,981,981,981,981,981,981,982,982,982,982,982,982,983,983,983,983,983,
211     983,983,984,984,984,984,984,984,984,984,985,985,985,985,985,985,985,986,986,986,986,986,986,986,986,987,987,987,987,987,
212     987,987,987,988,988,988,988,988,988,988,988,989,989,989,989,989,989,989,989,989,990,990,990,990,990,990,990,990,990,990,
213     991,991,991,991,991,991,991,991,991,992,992,992,992,992,992,992,992,992,992,992,993,993,993,993,993,993,993,993,993,993,
214     993,994,994,994,994,994,994,994,994,994,994,994,994,995,995,995,995,995,995,995,995,995,995,995,995,995,995,996,996,996,
215     996,996,996,996,996,996,996,996,996,996,996,996,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,
216     998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,999,999,999,999,999,999,
217     999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,
218     999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999
219   };
220   static int const sinArraySize = sizeof(sinArray)/sizeof(sinArray[0]);
221 
222   int adjustedAngle = (int)(angle*sinArraySize*4LL/freq);
223   int quadrant = adjustedAngle / sinArraySize;
224   int offset   = adjustedAngle % sinArraySize;
225 
226   switch (quadrant) {
227     case 0:
228       return sinArray[offset];
229     case 1:
230       return sinArray[sinArraySize-1-offset];
231     case 2:
232       return -sinArray[offset];
233     default:
234       return -sinArray[sinArraySize-1-offset];
235   }
236 }
237 
238 
239 ////////////////////////////////////////////////////////////////////////
240 
241 
PTones(unsigned volume,unsigned sampleRate)242 PTones::PTones(unsigned volume, unsigned sampleRate)
243   : m_sampleRate(sampleRate)
244   , m_masterVolume(volume)
245 {
246   Construct();
247 }
248 
249 
PTones(const PString & descriptor,unsigned volume,unsigned sampleRate)250 PTones::PTones(const PString & descriptor, unsigned volume, unsigned sampleRate)
251   : m_sampleRate(sampleRate)
252   , m_masterVolume(volume)
253 {
254   Construct();
255 
256   if (!Generate(descriptor)) {
257     PTRACE(1,"DTMF\tCannot encode tone \"" << descriptor << '"');
258   }
259 }
260 
261 
Construct()262 void PTones::Construct()
263 {
264   m_lastOperation = 0;
265   m_lastFrequency1 = 0;
266   m_lastFrequency2 = 0;
267   m_angle1 = 0;
268   m_angle2 = 0;
269 
270   if (m_sampleRate < 8000)
271     m_sampleRate = 8000;
272   else if (m_sampleRate > 96000)
273     m_sampleRate = 96000;
274 
275   m_maxFrequency = m_sampleRate/4;
276 
277   if (m_masterVolume < 1)
278     m_masterVolume = 1;
279   else if (m_masterVolume > 100)
280     m_masterVolume = 100;
281 }
282 
283 
Generate(const PString & descriptor)284 bool PTones::Generate(const PString & descriptor)
285 {
286   PStringArray toneChunks = descriptor.Tokenise('/');
287   if (toneChunks.IsEmpty())
288     return false;
289 
290   for (PINDEX chunk = 0; chunk < toneChunks.GetSize(); chunk++) {
291     // split frequency and cadence
292     PINDEX pos = toneChunks[chunk].Find(':');
293     if (pos == P_MAX_INDEX)
294       return false;
295 
296     PString frequencyStr = toneChunks[chunk].Left(pos).Trim();
297     PString cadenceStr = toneChunks[chunk].Mid(pos+1).Trim();
298 
299     if (cadenceStr.IsEmpty())
300       return false;
301 
302     // Do we have a volume?
303     unsigned volume = 100;
304     if ((pos = frequencyStr.Find('%')) != P_MAX_INDEX) {
305         volume = frequencyStr.Left(pos).AsUnsigned();
306         if (volume < 1 || volume > 100)
307           return false;
308         frequencyStr.Delete(0, pos+1);
309     }
310 
311     if (frequencyStr.IsEmpty())
312       return false;
313 
314     // Parse the frequencies
315     unsigned frequency1, frequency2;
316     char operation;
317     if ((pos =  frequencyStr.FindOneOf("+-x")) != P_MAX_INDEX) {
318       frequency1 = frequencyStr.Left(pos).AsUnsigned();
319       frequency2 = frequencyStr.Mid(pos+1).AsUnsigned();
320       operation = frequencyStr[pos];
321     }
322     else {
323       frequency1 = frequency2 = frequencyStr.AsUnsigned();
324       operation = '-';
325     }
326 
327     // Parse the cadence
328     double duration = cadenceStr.AsReal();
329 
330     // First one
331     if (!Generate(operation, frequency1, frequency2, (unsigned)(duration*1000), volume))
332       return false;
333 
334     char originalOperation = operation;
335     operation = ' ';
336 
337     pos = 0;
338     while ((pos = cadenceStr.Find('-', pos)) != P_MAX_INDEX) {
339       duration = cadenceStr.Mid(++pos).AsReal();
340       if (duration < 0 || duration > 60)
341         return false;
342 
343       if (!Generate(operation, frequency1, frequency2, (unsigned)(duration*1000), volume))
344         return false;
345 
346       // Alternate between the tone and silence
347       operation = operation == ' ' ? originalOperation : ' ';
348     }
349   }
350 
351   return true;
352 }
353 
354 
Generate(char operation,unsigned frequency1,unsigned frequency2,unsigned milliseconds,unsigned volume)355 bool PTones::Generate(char operation, unsigned frequency1, unsigned frequency2, unsigned milliseconds, unsigned volume)
356 {
357   if (m_lastOperation  != operation  ||
358       m_lastFrequency1 != frequency1 ||
359       m_lastFrequency2 != frequency2) {
360     m_lastOperation  = operation;
361     m_lastFrequency1 = frequency1;
362     m_lastFrequency2 = frequency2;
363 
364     m_angle1 = 0;
365     m_angle2 = 0;
366   }
367 
368   switch (operation) {
369     case '+':
370       return Juxtapose(frequency1, frequency2, milliseconds, volume);
371 
372     case 'x':
373       return Modulate(frequency1, frequency2, milliseconds, volume);
374 
375     case '-':
376       return PureTone(frequency1, milliseconds, volume);
377 
378     case ' ':
379       return Silence(milliseconds);
380   }
381 
382   return false;
383 }
384 
385 
Juxtapose(unsigned frequency1,unsigned frequency2,unsigned milliseconds,unsigned volume)386 bool PTones::Juxtapose(unsigned frequency1, unsigned frequency2, unsigned milliseconds, unsigned volume)
387 {
388   if (frequency1 < MinFrequency || frequency1 > m_maxFrequency ||
389       frequency2 < MinFrequency || frequency2 > m_maxFrequency)
390     return false;
391 
392   // TODO this gived 8000 samples for 100 ms !!!
393   //unsigned samples = CalcSamples(milliseconds, frequency1, frequency2);
394   unsigned samples = milliseconds * m_sampleRate / 1000;
395   while (samples-- > 0) {
396     int a1 = sine(m_angle1, m_sampleRate);
397     int a2 = sine(m_angle2, m_sampleRate);
398 
399     AddSample((a1 + a2) / 2, volume);
400 
401     m_angle1 += frequency1;
402     if (m_angle1 >= (int)m_sampleRate)
403       m_angle1 -= m_sampleRate;
404 
405     m_angle2 += frequency2;
406     if (m_angle2 >= (int)m_sampleRate)
407       m_angle2 -= m_sampleRate;
408   }
409   return true;
410 }
411 
412 
Modulate(unsigned frequency1,unsigned modulator,unsigned milliseconds,unsigned volume)413 bool PTones::Modulate(unsigned frequency1, unsigned modulator, unsigned milliseconds, unsigned volume)
414 {
415   if (frequency1 > m_maxFrequency || frequency1 > m_maxFrequency || modulator < MinModulation || modulator >= frequency1/2)
416     return false;
417 
418   unsigned samples = CalcSamples(milliseconds, frequency1, modulator);
419 
420   while (samples-- > 0) {
421     int a1 = sine(m_angle1, m_sampleRate);   // -999 to 999
422     int a2 = sine(m_angle2, m_sampleRate);   // -999 to 999
423 
424     AddSample((a1 * (a2 + SineScale)) / SineScale / 2, volume);
425 
426     m_angle1 += frequency1;
427     if (m_angle1 >= (int)m_sampleRate)
428       m_angle1 -= m_sampleRate;
429 
430     m_angle2 += modulator;
431     if (m_angle2 >= (int)m_sampleRate)
432       m_angle2 -= m_sampleRate;
433   }
434   return true;
435 }
436 
437 static unsigned char tone_2100[320] = {
438 	0x00, 0x00, 0xF4, 0x3F, 0xF7, 0xF5, 0xA0, 0xC1, 0xD2, 0x13, 0x44, 0x3B, 0xE1, 0xE2, 0x4E, 0xC9,
439 	0xB5, 0x25, 0xC8, 0x30, 0xA3, 0xD2, 0x56, 0xD6, 0xE6, 0x33, 0x84, 0x21, 0xD7, 0xC6, 0x74, 0xE7,
440 	0x03, 0x3D, 0xF9, 0x0E, 0xA4, 0xC0, 0xF8, 0xFA, 0x27, 0x40, 0xF7, 0xFA, 0xA4, 0xC0, 0xFA, 0x0E,
441 	0x02, 0x3D, 0x74, 0xE7, 0xD7, 0xC6, 0x84, 0x21, 0xE6, 0x33, 0x57, 0xD6, 0xA4, 0xD2, 0xC8, 0x30,
442 	0xB4, 0x25, 0x4D, 0xC9, 0xE1, 0xE2, 0x45, 0x3B, 0xD3, 0x13, 0x9F, 0xC1, 0xF7, 0xF5, 0xF4, 0x3F,
443 	0x01, 0x00, 0x0D, 0xC0, 0x09, 0x0A, 0x60, 0x3E, 0x2D, 0xEC, 0xBB, 0xC4, 0x20, 0x1D, 0xB3, 0x36,
444 	0x4B, 0xDA, 0x38, 0xCF, 0x5C, 0x2D, 0xAA, 0x29, 0x19, 0xCC, 0x7C, 0xDE, 0x28, 0x39, 0x8C, 0x18,
445 	0xFE, 0xC2, 0x06, 0xF1, 0x5C, 0x3F, 0x08, 0x05, 0xDA, 0xBF, 0x08, 0x05, 0x5D, 0x3F, 0x07, 0xF1,
446 	0xFE, 0xC2, 0x8C, 0x18, 0x29, 0x39, 0x7C, 0xDE, 0x1A, 0xCC, 0xAA, 0x29, 0x5C, 0x2D, 0x38, 0xCF,
447 	0x4C, 0xDA, 0xB3, 0x36, 0x20, 0x1D, 0xBC, 0xC4, 0x2D, 0xEC, 0x62, 0x3E, 0x09, 0x0A, 0x0D, 0xC0,
448 	0x01, 0x00, 0xF4, 0x3F, 0xF7, 0xF5, 0x9F, 0xC1, 0xD2, 0x13, 0x45, 0x3B, 0xE0, 0xE2, 0x4D, 0xC9,
449 	0xB4, 0x25, 0xC7, 0x30, 0xA3, 0xD2, 0x56, 0xD6, 0xE6, 0x33, 0x85, 0x21, 0xD8, 0xC6, 0x74, 0xE7,
450 	0x03, 0x3D, 0xFA, 0x0E, 0xA4, 0xC0, 0xF8, 0xFA, 0x26, 0x40, 0xF7, 0xFA, 0xA3, 0xC0, 0xFA, 0x0E,
451 	0x03, 0x3D, 0x73, 0xE7, 0xD8, 0xC6, 0x85, 0x21, 0xE6, 0x33, 0x57, 0xD6, 0xA3, 0xD2, 0xC7, 0x30,
452 	0xB5, 0x25, 0x4E, 0xC9, 0xE0, 0xE2, 0x44, 0x3B, 0xD3, 0x13, 0x9F, 0xC1, 0xF7, 0xF5, 0xF3, 0x3F,
453 	0x00, 0x00, 0x0D, 0xC0, 0x0A, 0x0A, 0x61, 0x3E, 0x2D, 0xEC, 0xBC, 0xC4, 0x1F, 0x1D, 0xB2, 0x36,
454 	0x4B, 0xDA, 0x38, 0xCF, 0x5C, 0x2D, 0xA9, 0x29, 0x1A, 0xCC, 0x7B, 0xDE, 0x29, 0x39, 0x8D, 0x18,
455 	0xFD, 0xC2, 0x07, 0xF1, 0x5C, 0x3F, 0x08, 0x05, 0xDA, 0xBF, 0x08, 0x05, 0x5B, 0x3F, 0x07, 0xF1,
456 	0xFE, 0xC2, 0x8D, 0x18, 0x28, 0x39, 0x7B, 0xDE, 0x19, 0xCC, 0xA9, 0x29, 0x5D, 0x2D, 0x38, 0xCF,
457 	0x4B, 0xDA, 0xB2, 0x36, 0x1F, 0x1D, 0xBB, 0xC4, 0x2D, 0xEC, 0x61, 0x3E, 0x09, 0x0A, 0x0C, 0xC0
458 };
459 
460 
PureTone(unsigned frequency1,unsigned milliseconds,unsigned volume)461 bool PTones::PureTone(unsigned frequency1, unsigned milliseconds, unsigned volume)
462 {
463   if (frequency1 == 2100) {
464     int samples = milliseconds * 8;
465     short * tone = (short *)tone_2100;
466     unsigned int toneLen  = sizeof(tone_2100) / 2;
467     PINDEX length;
468     for (length = 0; length < samples; ++length) {
469       PINDEX length = GetSize();
470       SetSize(length + 1);
471       short sample = tone[length % toneLen];
472       //sample *= volume;
473       //sample *= masterVolume;
474       //sample /= SineScale*100*100/SHRT_MAX;
475       SetAt(length, (short)sample);
476     }
477     return true;
478   }
479 
480   if (frequency1 < MinFrequency || frequency1 > m_maxFrequency)
481     return false;
482 
483   unsigned samples = CalcSamples(milliseconds, frequency1);
484   while (samples-- > 0) {
485     AddSample(sine(m_angle1, m_sampleRate), volume);
486 
487     m_angle1 += frequency1;
488     if (m_angle1 >= (int)m_sampleRate)
489       m_angle1 -= m_sampleRate;
490   }
491   return true;
492 }
493 
494 
Silence(unsigned milliseconds)495 bool PTones::Silence(unsigned milliseconds)
496 {
497   unsigned samples = milliseconds * m_sampleRate/1000;
498   while (samples-- > 0)
499     AddSample(0, 0);
500   return true;
501 }
502 
503 
CalcSamples(unsigned ms,unsigned f1,unsigned f2)504 unsigned PTones::CalcSamples(unsigned ms, unsigned f1, unsigned f2)
505 {
506   // firstly, find the minimum time to repeat the waveform
507   unsigned v1 = 1;
508   unsigned v2 = 1;
509 
510   if (f2 > 0)
511   {
512       while (v1*f2 != v2*f1) {
513         if (v1*f2 < v2*f1)
514           v1++;
515         else
516           v2++;
517       }
518   }
519 
520   // v1 repetitions of f1 == v2 repetitions of f2
521   //cout << v1 << " cycles of " << f1 << "hz = " << v2 << " samples of " << f2 << "hz" << endl;
522 
523   // now find the number of times we need to repeat this to match the sampling rate
524   unsigned n1 = 1;
525   unsigned n2 = 1;
526   while (n1*m_sampleRate*v1 != n2*f1) {
527     if (n1*m_sampleRate*v1 < n2*f1)
528       n1++;
529     else
530       n2++;
531   }
532 
533   // v1 repetitions of t == v2 repetitions sample frequency
534   //cout << n1*v1 << " cycles at " << f1 << "hz = "
535   //     << n1*v2 << " cycles at " << f2 << "hz = "
536   //     << n2    << " samples at " << m_sampleRate << "hz" << endl;
537 
538   // Make sure we round up the number of milliseconds to even multiple of cycles
539   return ms == 0 ? n2 : ((ms * m_sampleRate/1000 + n2 - 1)/n2*n2);
540 }
541 
542 
AddSample(int sample,unsigned volume)543 void PTones::AddSample(int sample, unsigned volume)
544 {
545   // Sample added is value from -1000 to 1000, rescale to short range -32767 to +32767
546   PINDEX length = GetSize();
547   SetSize(length + 1);
548   sample *= volume;
549   sample *= m_masterVolume;
550   sample /= SineScale*100*100/SHRT_MAX;
551   SetAt(length, (short)sample);
552 }
553 
554 
555 ////////////////////////////////////////////////////////////////////////
556 
PDTMFEncoder(const char * dtmf,unsigned milliseconds)557 PDTMFEncoder::PDTMFEncoder(const char * dtmf, unsigned milliseconds) :
558    PTones()
559 {
560   AddTone(dtmf, milliseconds);
561 }
562 
PDTMFEncoder(char digit,unsigned milliseconds)563 PDTMFEncoder::PDTMFEncoder(char digit, unsigned milliseconds) :
564    PTones()
565 {
566   AddTone(digit, milliseconds);
567 }
568 
AddTone(const char * str,unsigned milliseconds)569 void PDTMFEncoder::AddTone(const char * str, unsigned milliseconds)
570 {
571   if (str == NULL)
572       return;
573 
574   while (*str != '\0')
575     AddTone(*str++, milliseconds);
576 }
577 
578 
AddTone(char digit,unsigned milliseconds)579 void PDTMFEncoder::AddTone(char digit, unsigned milliseconds)
580 {
581   // DTMF frequencies as per http://www.commlinx.com.au/DTMF_frequencies.htm
582 
583   static struct {
584     char code;
585     char operation;
586     unsigned frequency1;
587     unsigned frequency2;
588   } const dtmfData[] = {
589     { '0', '+', 941,1336 },
590     { '1', '+', 697,1209 },
591     { '2', '+', 697,1336 },
592     { '3', '+', 697,1477 },
593     { '4', '+', 770,1209 },
594     { '5', '+', 770,1336 },
595     { '6', '+', 770,1477 },
596     { '7', '+', 852,1209 },
597     { '8', '+', 852,1336 },
598     { '9', '+', 852,1477 },
599     { '*', '+', 941,1209 },
600     { '#', '+', 941,1477 },
601     { 'A', '+', 697,1633 },
602     { 'B', '+', 770,1633 },
603     { 'C', '+', 852,1633 },
604     { 'D', '+', 941,1633 },
605     { 'a', '+', 697,1633 },
606     { 'b', '+', 770,1633 },
607     { 'c', '+', 852,1633 },
608     { 'd', '+', 941,1633 },
609     { 'X', '-', 1100     }, // CNG  1100 hz - sent by originating fax machine after dialing
610     { 'x', '-', 1100     }, // CNG
611     { 'Y', '-', 2100     }, // CED  2100 hz - sent by terminating fax machine after answer to disable echo cancellers
612     { 'y', '-', 2100     }  // CED
613   };
614 
615   for (PINDEX i = 0; i < PARRAYSIZE(dtmfData); i++) {
616     if (dtmfData[i].code == digit) {
617       Generate(dtmfData[i].operation, dtmfData[i].frequency1, dtmfData[i].frequency2, milliseconds);
618       break;
619     }
620   }
621 }
622 
623 
AddTone(double f1,double f2,unsigned milliseconds)624 void PDTMFEncoder::AddTone(double f1, double f2, unsigned milliseconds)
625 {
626   if (f1 > 0 && f1 < m_maxFrequency && f2 > 0 && f2 < m_maxFrequency){
627     Generate('+', (unsigned)f1, (unsigned)f2, milliseconds);
628   } else {
629     PAssertAlways(PInvalidParameter);
630   }
631 }
632 
633 
DtmfChar(PINDEX i)634 char PDTMFEncoder::DtmfChar(PINDEX i)
635 {
636   PAssert(i < 16, "Only 16 dtmf symbols. Index too large");
637 
638   static char dtmfSymbols[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','*','#' };
639   return dtmfSymbols[i];
640 }
641 
642 
643 #endif // P_DTMF
644 
645 ////////////////////////////////////////////////////////////////////////////
646