Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

383 lines
8.5 KiB

  1. #include "precomp.h"
  2. #include "dtmf.h"
  3. #include <math.h>
  4. // has to be #defines, not const int's because our build environment
  5. // doesn't like the embedded structure stuff.
  6. #define DTMF_ROW1_FREQ 697
  7. #define DTMF_ROW2_FREQ 770
  8. #define DTMF_ROW3_FREQ 852
  9. #define DTMF_ROW4_FREQ 941
  10. #define DTMF_COL1_FREQ 1209
  11. #define DTMF_COL2_FREQ 1336
  12. #define DTMF_COL3_FREQ 1477
  13. #define DTMF_COL4_FREQ 1633
  14. // For "A", "B", "C", "D"
  15. // the length of all the tones are the same except for "zero"
  16. // Zero needs longer because it just barely survives G.723 compression
  17. const int DTMF_TONE_RAMP_MS = 60; // ramp up/down time
  18. const int DTMF_TONE_LENGTH_MS = 240; // includes ramp time!
  19. const int DTMF_SILENCE_LENGTH_MS = 240; // silence gap between tones
  20. const double DTMF_AMP_FREQ1 = 17000;
  21. const double DTMF_AMP_FREQ2 = 14000;
  22. struct DTMF_TONE
  23. {
  24. int freq1;
  25. int freq2;
  26. int nLengthMS; // length in milliseconds
  27. };
  28. const int DTMF_NUM_TONES = 16;
  29. const int DTMF_SILENCE = -1;
  30. DTMF_TONE DTMF_TONE_DEF_LIST[] =
  31. {
  32. {DTMF_ROW4_FREQ, DTMF_COL2_FREQ, DTMF_TONE_LENGTH_MS}, //0
  33. {DTMF_ROW1_FREQ, DTMF_COL1_FREQ, DTMF_TONE_LENGTH_MS}, //1
  34. {DTMF_ROW1_FREQ, DTMF_COL2_FREQ, DTMF_TONE_LENGTH_MS}, //2
  35. {DTMF_ROW1_FREQ, DTMF_COL3_FREQ, DTMF_TONE_LENGTH_MS}, //3
  36. {DTMF_ROW2_FREQ, DTMF_COL1_FREQ, DTMF_TONE_LENGTH_MS}, //4
  37. {DTMF_ROW2_FREQ, DTMF_COL2_FREQ, DTMF_TONE_LENGTH_MS}, //5
  38. {DTMF_ROW2_FREQ, DTMF_COL3_FREQ, DTMF_TONE_LENGTH_MS}, //6
  39. {DTMF_ROW3_FREQ, DTMF_COL1_FREQ, DTMF_TONE_LENGTH_MS}, //7
  40. {DTMF_ROW3_FREQ, DTMF_COL2_FREQ, DTMF_TONE_LENGTH_MS}, //8
  41. {DTMF_ROW3_FREQ, DTMF_COL3_FREQ, DTMF_TONE_LENGTH_MS}, //9
  42. {DTMF_ROW4_FREQ, DTMF_COL1_FREQ, DTMF_TONE_LENGTH_MS}, //STAR
  43. {DTMF_ROW4_FREQ, DTMF_COL3_FREQ, DTMF_TONE_LENGTH_MS}, //POUND
  44. {DTMF_ROW1_FREQ, DTMF_COL4_FREQ, DTMF_TONE_LENGTH_MS}, //A
  45. {DTMF_ROW2_FREQ, DTMF_COL4_FREQ, DTMF_TONE_LENGTH_MS}, //B
  46. {DTMF_ROW3_FREQ, DTMF_COL4_FREQ, DTMF_TONE_LENGTH_MS}, //C
  47. {DTMF_ROW4_FREQ, DTMF_COL4_FREQ, DTMF_TONE_LENGTH_MS}, //D
  48. };
  49. DTMFQueue::DTMFQueue() :
  50. m_aTones(NULL),
  51. m_bInitialized(false),
  52. m_nQueueHead(0),
  53. m_nQueueLength(0),
  54. m_hEvent(NULL)
  55. {
  56. InitializeCriticalSection(&m_cs);
  57. m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  58. }
  59. DTMFQueue::~DTMFQueue()
  60. {
  61. DeleteCriticalSection(&m_cs);
  62. ReleaseToneBank();
  63. CloseHandle(m_hEvent);
  64. }
  65. HRESULT DTMFQueue::Initialize(WAVEFORMATEX *pWaveFormat)
  66. {
  67. if (m_bInitialized)
  68. {
  69. ReleaseToneBank();
  70. }
  71. m_nQueueLength = 0;
  72. m_nQueueHead = 0;
  73. return GenerateTones(pWaveFormat);
  74. };
  75. HRESULT DTMFQueue::GenerateTones(WAVEFORMATEX *pWaveFormat)
  76. {
  77. int nIndex;
  78. int nToneLength; // tone length in bytes
  79. int nToneLengthMS; // tone length in millisecs
  80. ReleaseToneBank();
  81. m_WaveFormat = *pWaveFormat;
  82. DBG_SAVE_FILE_LINE
  83. m_aTones = new PBYTE[DTMF_NUM_TONES]; // array of 16 tones
  84. if (m_aTones == NULL)
  85. {
  86. return E_OUTOFMEMORY;
  87. }
  88. // allocate memory for each tone
  89. for (nIndex = 0; nIndex < DTMF_NUM_TONES; nIndex++)
  90. {
  91. nToneLengthMS = DTMF_TONE_DEF_LIST[nIndex].nLengthMS;
  92. nToneLength = (pWaveFormat->nSamplesPerSec) * (pWaveFormat->wBitsPerSample) / 8;
  93. nToneLength = (nToneLength * nToneLengthMS) / 1000;
  94. DBG_SAVE_FILE_LINE
  95. m_aTones[nIndex] = new BYTE[nToneLength];
  96. if (m_aTones[nIndex] == NULL)
  97. {
  98. return E_OUTOFMEMORY;
  99. }
  100. CreateDTMFTone(m_aTones[nIndex], nToneLength, nIndex);
  101. }
  102. m_bInitialized = true;
  103. return S_OK;
  104. }
  105. void DTMFQueue::CreateDTMFTone(BYTE *pTone, int nToneLength, int toneID)
  106. {
  107. ZeroMemory(pTone, nToneLength);
  108. AddSignal(pTone, DTMF_TONE_DEF_LIST[toneID].freq1, DTMF_AMP_FREQ1, nToneLength);
  109. AddSignal(pTone, DTMF_TONE_DEF_LIST[toneID].freq2, DTMF_AMP_FREQ2, nToneLength);
  110. }
  111. void DTMFQueue::AddSignal(BYTE *pTone, int nFrequency, double dAmp, int nLength)
  112. {
  113. double d;
  114. int nIndex;
  115. SHORT *aSamples = (SHORT*)pTone;
  116. SHORT shSample;
  117. BYTE nSample8;
  118. double dRampAmpInc, dRampAmp;
  119. int nRampSamples;
  120. const double PI = 3.1415926535897932384626433832795;
  121. nRampSamples = (m_WaveFormat.nSamplesPerSec * DTMF_TONE_RAMP_MS) / 1000;
  122. dRampAmpInc = 1.0 / nRampSamples;
  123. dRampAmp = 0.0;
  124. if (m_WaveFormat.wBitsPerSample == 16)
  125. {
  126. nLength = nLength / 2;
  127. for (nIndex = 0; nIndex < nLength; nIndex++)
  128. {
  129. // y = sin((x * 2 * PI * f)/SRATE)
  130. // d is a value between -1 and +1;
  131. d = sin((PI * (2.0 * (nIndex * nFrequency))) / m_WaveFormat.nSamplesPerSec);
  132. if (nIndex < nRampSamples)
  133. {
  134. dRampAmp = dRampAmpInc * nIndex;
  135. }
  136. else if ((nIndex+nRampSamples) >= nLength)
  137. {
  138. dRampAmp = dRampAmpInc * (nLength - nIndex - 1);
  139. }
  140. else
  141. {
  142. dRampAmp = 1.0;
  143. }
  144. shSample = (SHORT)(dAmp * d * dRampAmp);
  145. aSamples[nIndex] += shSample;
  146. }
  147. return;
  148. }
  149. // 8-bit samples have a center point of 128
  150. // must invert high order bit to compensate
  151. for (nIndex = 0; nIndex < nLength; nIndex++)
  152. {
  153. d = sin((PI * (2.0 * (nIndex * nFrequency))) / m_WaveFormat.nSamplesPerSec);
  154. if (nIndex < nRampSamples)
  155. {
  156. dRampAmp = dRampAmpInc * nIndex;
  157. }
  158. else if ((nIndex+nRampSamples) >= nLength)
  159. {
  160. dRampAmp = dRampAmpInc * (nLength - nIndex - 1);
  161. }
  162. else
  163. {
  164. dRampAmp = 1.0;
  165. }
  166. shSample = (SHORT)(dAmp * d * dRampAmp);
  167. shSample = (shSample >> 8) & 0x00ff;
  168. nSample8 = (BYTE)shSample;
  169. nSample8 = nSample8 ^ 0x80;
  170. pTone[nIndex] = nSample8;
  171. }
  172. return;
  173. };
  174. void DTMFQueue::ReleaseToneBank()
  175. {
  176. int nIndex;
  177. if (m_aTones)
  178. {
  179. for (nIndex = 0; nIndex < DTMF_NUM_TONES; nIndex++)
  180. {
  181. delete [] m_aTones[nIndex];
  182. }
  183. delete [] m_aTones;
  184. m_aTones = NULL;
  185. }
  186. m_bInitialized = false;
  187. }
  188. HRESULT DTMFQueue::AddDigitToQueue(int nDigit)
  189. {
  190. int nQueueIndex;
  191. int nToneLength, nToneLengthMS;
  192. int nSilenceLength;
  193. if (m_bInitialized == false)
  194. return E_FAIL;
  195. if ((nDigit < 0) || (nDigit >= DTMF_NUM_TONES))
  196. {
  197. return E_FAIL;
  198. }
  199. EnterCriticalSection(&m_cs);
  200. if (m_nQueueLength >= (DTMF_QUEUE_SIZE-1))
  201. {
  202. LeaveCriticalSection(&m_cs);
  203. return E_FAIL;
  204. }
  205. nToneLengthMS = DTMF_TONE_DEF_LIST[nDigit].nLengthMS;
  206. nToneLength = (m_WaveFormat.nSamplesPerSec) * (m_WaveFormat.wBitsPerSample) / 8;
  207. nSilenceLength = (nToneLength * DTMF_SILENCE_LENGTH_MS) / 1000;
  208. nToneLength = (nToneLength * nToneLengthMS) / 1000;
  209. // add silence to pad between tones. Also helps to "reset" the codec
  210. // to a good state
  211. nQueueIndex = (m_nQueueHead + m_nQueueLength) % DTMF_QUEUE_SIZE;
  212. m_aTxQueue[nQueueIndex].nBytesToCopy = nSilenceLength;
  213. m_aTxQueue[nQueueIndex].nToneID = DTMF_SILENCE;
  214. m_aTxQueue[nQueueIndex].nOffsetStart = 0;
  215. m_nQueueLength++;
  216. // add the tone to the read queue
  217. nQueueIndex = (m_nQueueHead + m_nQueueLength) % DTMF_QUEUE_SIZE;
  218. m_aTxQueue[nQueueIndex].nBytesToCopy = nToneLength;
  219. m_aTxQueue[nQueueIndex].nToneID = nDigit;
  220. m_aTxQueue[nQueueIndex].nOffsetStart = 0;
  221. m_nQueueLength++;
  222. LeaveCriticalSection(&m_cs);
  223. return S_OK;
  224. }
  225. HRESULT DTMFQueue::ReadFromQueue(BYTE *pBuffer, UINT uSize)
  226. {
  227. DTMF_TX_ELEMENT *pQueueElement;
  228. int nSilenceOffset;
  229. BYTE fillByte;
  230. if (m_bInitialized == false)
  231. return E_FAIL;
  232. if (m_WaveFormat.wBitsPerSample == 8)
  233. {
  234. fillByte = 0x80;
  235. }
  236. else
  237. {
  238. ASSERT((uSize % 2) == 0); // uSize must be even for 16-bit fills
  239. fillByte = 0;
  240. }
  241. EnterCriticalSection(&m_cs);
  242. if (m_nQueueLength <= 0)
  243. {
  244. LeaveCriticalSection(&m_cs);
  245. return E_FAIL;
  246. }
  247. pQueueElement = &m_aTxQueue[m_nQueueHead];
  248. if (pQueueElement->nBytesToCopy <= (int)uSize)
  249. {
  250. if (pQueueElement->nToneID == DTMF_SILENCE)
  251. {
  252. FillMemory(pBuffer, uSize, fillByte);
  253. }
  254. else
  255. {
  256. CopyMemory(pBuffer, pQueueElement->nOffsetStart + m_aTones[pQueueElement->nToneID], pQueueElement->nBytesToCopy);
  257. FillMemory(pBuffer+(pQueueElement->nBytesToCopy), uSize-(pQueueElement->nBytesToCopy), fillByte);
  258. }
  259. m_nQueueHead = (m_nQueueHead + 1) % DTMF_QUEUE_SIZE;
  260. m_nQueueLength--;
  261. }
  262. else
  263. {
  264. if (pQueueElement->nToneID == DTMF_SILENCE)
  265. {
  266. FillMemory(pBuffer, uSize, fillByte);
  267. }
  268. else
  269. {
  270. CopyMemory(pBuffer, pQueueElement->nOffsetStart + m_aTones[pQueueElement->nToneID], uSize);
  271. }
  272. pQueueElement->nBytesToCopy -= uSize;
  273. pQueueElement->nOffsetStart += uSize;
  274. }
  275. LeaveCriticalSection(&m_cs);
  276. return S_OK;
  277. }
  278. HRESULT DTMFQueue::ClearQueue()
  279. {
  280. if (m_bInitialized == false)
  281. return E_FAIL;
  282. EnterCriticalSection(&m_cs);
  283. m_nQueueHead = 0;
  284. m_nQueueLength = 0;
  285. LeaveCriticalSection(&m_cs);
  286. return S_OK;
  287. }