linux/drivers/isdn/hardware/eicon/capidtmf.c
<<
>>
Prefs
   1
   2/*
   3 *
   4  Copyright (c) Eicon Networks, 2002.
   5 *
   6  This source file is supplied for the use with
   7  Eicon Networks range of DIVA Server Adapters.
   8 *
   9  Eicon File Revision :    2.1
  10 *
  11  This program is free software; you can redistribute it and/or modify
  12  it under the terms of the GNU General Public License as published by
  13  the Free Software Foundation; either version 2, or (at your option)
  14  any later version.
  15 *
  16  This program is distributed in the hope that it will be useful,
  17  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  18  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19  See the GNU General Public License for more details.
  20 *
  21  You should have received a copy of the GNU General Public License
  22  along with this program; if not, write to the Free Software
  23  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 */
  26
  27#include "platform.h"
  28
  29
  30  
  31  
  32
  33
  34
  35
  36
  37#include "capidtmf.h"
  38
  39/* #define TRACE_ */
  40
  41#define FILE_ "CAPIDTMF.C"
  42
  43/*---------------------------------------------------------------------------*/
  44
  45
  46#define trace(a)
  47
  48
  49
  50/*---------------------------------------------------------------------------*/
  51
  52static short capidtmf_expand_table_alaw[0x0100] =
  53{
  54   -5504,   5504,   -344,    344, -22016,  22016,  -1376,   1376,
  55   -2752,   2752,    -88,     88, -11008,  11008,   -688,    688,
  56   -7552,   7552,   -472,    472, -30208,  30208,  -1888,   1888,
  57   -3776,   3776,   -216,    216, -15104,  15104,   -944,    944,
  58   -4480,   4480,   -280,    280, -17920,  17920,  -1120,   1120,
  59   -2240,   2240,    -24,     24,  -8960,   8960,   -560,    560,
  60   -6528,   6528,   -408,    408, -26112,  26112,  -1632,   1632,
  61   -3264,   3264,   -152,    152, -13056,  13056,   -816,    816,
  62   -6016,   6016,   -376,    376, -24064,  24064,  -1504,   1504,
  63   -3008,   3008,   -120,    120, -12032,  12032,   -752,    752,
  64   -8064,   8064,   -504,    504, -32256,  32256,  -2016,   2016,
  65   -4032,   4032,   -248,    248, -16128,  16128,  -1008,   1008,
  66   -4992,   4992,   -312,    312, -19968,  19968,  -1248,   1248,
  67   -2496,   2496,    -56,     56,  -9984,   9984,   -624,    624,
  68   -7040,   7040,   -440,    440, -28160,  28160,  -1760,   1760,
  69   -3520,   3520,   -184,    184, -14080,  14080,   -880,    880,
  70   -5248,   5248,   -328,    328, -20992,  20992,  -1312,   1312,
  71   -2624,   2624,    -72,     72, -10496,  10496,   -656,    656,
  72   -7296,   7296,   -456,    456, -29184,  29184,  -1824,   1824,
  73   -3648,   3648,   -200,    200, -14592,  14592,   -912,    912,
  74   -4224,   4224,   -264,    264, -16896,  16896,  -1056,   1056,
  75   -2112,   2112,     -8,      8,  -8448,   8448,   -528,    528,
  76   -6272,   6272,   -392,    392, -25088,  25088,  -1568,   1568,
  77   -3136,   3136,   -136,    136, -12544,  12544,   -784,    784,
  78   -5760,   5760,   -360,    360, -23040,  23040,  -1440,   1440,
  79   -2880,   2880,   -104,    104, -11520,  11520,   -720,    720,
  80   -7808,   7808,   -488,    488, -31232,  31232,  -1952,   1952,
  81   -3904,   3904,   -232,    232, -15616,  15616,   -976,    976,
  82   -4736,   4736,   -296,    296, -18944,  18944,  -1184,   1184,
  83   -2368,   2368,    -40,     40,  -9472,   9472,   -592,    592,
  84   -6784,   6784,   -424,    424, -27136,  27136,  -1696,   1696,
  85   -3392,   3392,   -168,    168, -13568,  13568,   -848,    848
  86};
  87
  88static short capidtmf_expand_table_ulaw[0x0100] =
  89{
  90  -32124,  32124,  -1884,   1884,  -7932,   7932,   -372,    372,
  91  -15996,  15996,   -876,    876,  -3900,   3900,   -120,    120,
  92  -23932,  23932,  -1372,   1372,  -5884,   5884,   -244,    244,
  93  -11900,  11900,   -620,    620,  -2876,   2876,    -56,     56,
  94  -28028,  28028,  -1628,   1628,  -6908,   6908,   -308,    308,
  95  -13948,  13948,   -748,    748,  -3388,   3388,    -88,     88,
  96  -19836,  19836,  -1116,   1116,  -4860,   4860,   -180,    180,
  97   -9852,   9852,   -492,    492,  -2364,   2364,    -24,     24,
  98  -30076,  30076,  -1756,   1756,  -7420,   7420,   -340,    340,
  99  -14972,  14972,   -812,    812,  -3644,   3644,   -104,    104,
 100  -21884,  21884,  -1244,   1244,  -5372,   5372,   -212,    212,
 101  -10876,  10876,   -556,    556,  -2620,   2620,    -40,     40,
 102  -25980,  25980,  -1500,   1500,  -6396,   6396,   -276,    276,
 103  -12924,  12924,   -684,    684,  -3132,   3132,    -72,     72,
 104  -17788,  17788,   -988,    988,  -4348,   4348,   -148,    148,
 105   -8828,   8828,   -428,    428,  -2108,   2108,     -8,      8,
 106  -31100,  31100,  -1820,   1820,  -7676,   7676,   -356,    356,
 107  -15484,  15484,   -844,    844,  -3772,   3772,   -112,    112,
 108  -22908,  22908,  -1308,   1308,  -5628,   5628,   -228,    228,
 109  -11388,  11388,   -588,    588,  -2748,   2748,    -48,     48,
 110  -27004,  27004,  -1564,   1564,  -6652,   6652,   -292,    292,
 111  -13436,  13436,   -716,    716,  -3260,   3260,    -80,     80,
 112  -18812,  18812,  -1052,   1052,  -4604,   4604,   -164,    164,
 113   -9340,   9340,   -460,    460,  -2236,   2236,    -16,     16,
 114  -29052,  29052,  -1692,   1692,  -7164,   7164,   -324,    324,
 115  -14460,  14460,   -780,    780,  -3516,   3516,    -96,     96,
 116  -20860,  20860,  -1180,   1180,  -5116,   5116,   -196,    196,
 117  -10364,  10364,   -524,    524,  -2492,   2492,    -32,     32,
 118  -24956,  24956,  -1436,   1436,  -6140,   6140,   -260,    260,
 119  -12412,  12412,   -652,    652,  -3004,   3004,    -64,     64,
 120  -16764,  16764,   -924,    924,  -4092,   4092,   -132,    132,
 121   -8316,   8316,   -396,    396,  -1980,   1980,      0,      0
 122};
 123
 124
 125/*---------------------------------------------------------------------------*/
 126
 127static short capidtmf_recv_window_function[CAPIDTMF_RECV_ACCUMULATE_CYCLES] =
 128{
 129    -500L,   -999L,  -1499L,  -1998L,  -2496L,  -2994L,  -3491L,  -3988L,
 130   -4483L,  -4978L,  -5471L,  -5963L,  -6454L,  -6943L,  -7431L,  -7917L,
 131   -8401L,  -8883L,  -9363L,  -9840L, -10316L, -10789L, -11259L, -11727L,
 132  -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L,
 133  -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L,
 134  -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L,
 135  -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L,
 136  -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L,
 137  -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L,
 138  -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L,
 139  -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L,
 140  -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L,
 141  -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L,
 142  -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L,
 143  -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L,
 144  -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L,
 145  -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L,
 146  -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L,
 147  -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L,
 148  -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L,
 149  -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L,
 150  -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L,
 151  -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L,
 152  -10316L,  -9840L,  -9363L,  -8883L,  -8401L,  -7917L,  -7431L,  -6943L,
 153   -6454L,  -5963L,  -5471L,  -4978L,  -4483L,  -3988L,  -3491L,  -2994L,
 154   -2496L,  -1998L,  -1499L,   -999L,   -500L, 
 155};
 156
 157static byte capidtmf_leading_zeroes_table[0x100] =
 158{
 159  8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
 160  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 161  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 162  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 163  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 164  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 165  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 166  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 167  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 168  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 169  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 170  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 171  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 172  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 173  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 174  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 175};
 176
 177#define capidtmf_byte_leading_zeroes(b)  (capidtmf_leading_zeroes_table[(BYTE)(b)])
 178#define capidtmf_word_leading_zeroes(w)  (((w) & 0xff00) ? capidtmf_leading_zeroes_table[(w) >> 8] : 8 + capidtmf_leading_zeroes_table[(w)])
 179#define capidtmf_dword_leading_zeroes(d)  (((d) & 0xffff0000L) ?    (((d) & 0xff000000L) ? capidtmf_leading_zeroes_table[(d) >> 24] : 8 + capidtmf_leading_zeroes_table[(d) >> 16]) :    (((d) & 0xff00) ? 16 + capidtmf_leading_zeroes_table[(d) >> 8] : 24 + capidtmf_leading_zeroes_table[(d)]))
 180
 181
 182/*---------------------------------------------------------------------------*/
 183
 184
 185static void capidtmf_goertzel_loop (long *buffer, long *coeffs, short *sample, long count)
 186{
 187  int i, j;
 188  long c, d, q0, q1, q2;
 189
 190  for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++)
 191  {
 192    q1 = buffer[i];
 193    q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
 194    d = coeffs[i] >> 1;
 195    c = d << 1;
 196    if (c >= 0)
 197    {
 198      for (j = 0; j < count; j++)
 199      {
 200        q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15);
 201        q2 = q1;
 202        q1 = q0;
 203      }
 204    }
 205    else
 206    {
 207      c = -c;
 208      d = -d;
 209      for (j = 0; j < count; j++)
 210      {
 211        q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15));
 212        q2 = q1;
 213        q1 = q0;
 214      }
 215    }
 216    buffer[i] = q1;
 217    buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
 218  }
 219  q1 = buffer[i];
 220  q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
 221  c = (coeffs[i] >> 1) << 1;
 222  if (c >= 0)
 223  {
 224    for (j = 0; j < count; j++)
 225    {
 226      q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15);
 227      q2 = q1;
 228      q1 = q0;
 229      c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
 230    }
 231  }
 232  else
 233  {
 234    c = -c;
 235    for (j = 0; j < count; j++)
 236    {
 237      q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15));
 238      q2 = q1;
 239      q1 = q0;
 240      c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
 241    }
 242  }
 243  coeffs[i] = c;
 244  buffer[i] = q1;
 245  buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
 246}
 247
 248
 249static void capidtmf_goertzel_result (long *buffer, long *coeffs)
 250{
 251  int i;
 252  long d, e, q1, q2, lo, mid, hi;
 253  dword k;
 254
 255  for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
 256  {
 257    q1 = buffer[i];
 258    q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
 259    d = coeffs[i] >> 1;
 260    if (d >= 0)
 261      d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15);
 262    else
 263      d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15);
 264    e = (q2 >= 0) ? q2 : -q2;
 265    if (d >= 0)
 266    {
 267      k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
 268      lo = k & 0xffff;
 269      mid = k >> 16;
 270      k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
 271      mid += k & 0xffff;
 272      hi = k >> 16;
 273      k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
 274      mid += k & 0xffff;
 275      hi += k >> 16;
 276      hi += ((dword)(d >> 16)) * ((dword)(e >> 16));
 277    }
 278    else
 279    {
 280      d = -d;
 281      k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
 282      lo = -((long)(k & 0xffff));
 283      mid = -((long)(k >> 16));
 284      k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
 285      mid -= k & 0xffff;
 286      hi = -((long)(k >> 16));
 287      k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
 288      mid -= k & 0xffff;
 289      hi -= k >> 16;
 290      hi -= ((dword)(d >> 16)) * ((dword)(e >> 16));
 291    }
 292    if (q2 < 0)
 293    {
 294      lo = -lo;
 295      mid = -mid;
 296      hi = -hi;
 297    }
 298    d = (q1 >= 0) ? q1 : -q1;
 299    k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
 300    lo += k & 0xffff;
 301    mid += k >> 16;
 302    k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
 303    mid += (k & 0xffff) << 1;
 304    hi += (k >> 16) << 1;
 305    hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
 306    d = (q2 >= 0) ? q2 : -q2;
 307    k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
 308    lo += k & 0xffff;
 309    mid += k >> 16;
 310    k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
 311    mid += (k & 0xffff) << 1;
 312    hi += (k >> 16) << 1;
 313    hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
 314    mid += lo >> 16;
 315    hi += mid >> 16;
 316    buffer[i] = (lo & 0xffff) | (mid << 16);
 317    buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi;
 318  }
 319}
 320
 321
 322/*---------------------------------------------------------------------------*/
 323
 324#define CAPIDTMF_RECV_GUARD_SNR_INDEX_697     0
 325#define CAPIDTMF_RECV_GUARD_SNR_INDEX_770     1
 326#define CAPIDTMF_RECV_GUARD_SNR_INDEX_852     2
 327#define CAPIDTMF_RECV_GUARD_SNR_INDEX_941     3
 328#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1209    4
 329#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1336    5
 330#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1477    6
 331#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1633    7
 332#define CAPIDTMF_RECV_GUARD_SNR_INDEX_635     8
 333#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1010    9
 334#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1140    10
 335#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1272    11
 336#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1405    12
 337#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1555    13
 338#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1715    14
 339#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1875    15
 340
 341#define CAPIDTMF_RECV_GUARD_SNR_DONTCARE      0xc000
 342#define CAPIDTMF_RECV_NO_DIGIT                0xff
 343#define CAPIDTMF_RECV_TIME_GRANULARITY        (CAPIDTMF_RECV_ACCUMULATE_CYCLES + 1)
 344
 345#define CAPIDTMF_RECV_INDICATION_DIGIT        0x0001
 346
 347static long capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 348{
 349  0xda97L * 2,  /* 697 Hz (Low group 697 Hz) */
 350  0xd299L * 2,  /* 770 Hz (Low group 770 Hz) */
 351  0xc8cbL * 2,  /* 852 Hz (Low group 852 Hz) */
 352  0xbd36L * 2,  /* 941 Hz (Low group 941 Hz) */
 353  0x9501L * 2,  /* 1209 Hz (High group 1209 Hz) */
 354  0x7f89L * 2,  /* 1336 Hz (High group 1336 Hz) */
 355  0x6639L * 2,  /* 1477 Hz (High group 1477 Hz) */
 356  0x48c6L * 2,  /* 1633 Hz (High group 1633 Hz) */
 357  0xe14cL * 2,  /* 630 Hz (Lower guard of low group 631 Hz) */
 358  0xb2e0L * 2,  /* 1015 Hz (Upper guard of low group 1039 Hz) */
 359  0xa1a0L * 2,  /* 1130 Hz (Lower guard of high group 1140 Hz) */
 360  0x8a87L * 2,  /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */
 361  0x7353L * 2,  /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */
 362  0x583bL * 2,  /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */
 363  0x37d8L * 2,  /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */
 364  0x0000L * 2   /* 100-630 Hz (fundamentals) */
 365};
 366
 367
 368static word capidtmf_recv_guard_snr_low_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 369{
 370  14,                                    /* Low group peak versus 697 Hz */
 371  14,                                    /* Low group peak versus 770 Hz */
 372  16,                                    /* Low group peak versus 852 Hz */
 373  16,                                    /* Low group peak versus 941 Hz */
 374  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1209 Hz */
 375  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1336 Hz */
 376  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1477 Hz */
 377  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1633 Hz */
 378  14,                                    /* Low group peak versus 635 Hz */
 379  16,                                    /* Low group peak versus 1010 Hz */
 380  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1140 Hz */
 381  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1272 Hz */
 382  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8,  /* Low group peak versus 1405 Hz */
 383  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1555 Hz */
 384  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1715 Hz */
 385  12                                     /* Low group peak versus 100-630 Hz */
 386};
 387
 388
 389static word capidtmf_recv_guard_snr_high_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 390{
 391  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 697 Hz */
 392  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 770 Hz */
 393  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 852 Hz */
 394  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 941 Hz */
 395  20,                                    /* High group peak versus 1209 Hz */
 396  20,                                    /* High group peak versus 1336 Hz */
 397  20,                                    /* High group peak versus 1477 Hz */
 398  20,                                    /* High group peak versus 1633 Hz */
 399  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 635 Hz */
 400  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 1010 Hz */
 401  16,                                    /* High group peak versus 1140 Hz */
 402  4,                                     /* High group peak versus 1272 Hz */
 403  6,                                     /* High group peak versus 1405 Hz */
 404  8,                                     /* High group peak versus 1555 Hz */
 405  16,                                    /* High group peak versus 1715 Hz */
 406  12                                     /* High group peak versus 100-630 Hz */
 407};
 408
 409
 410/*---------------------------------------------------------------------------*/
 411
 412static void capidtmf_recv_init (t_capidtmf_state   *p_state)
 413{
 414  p_state->recv.min_gap_duration = 1;
 415  p_state->recv.min_digit_duration = 1;
 416
 417  p_state->recv.cycle_counter = 0;
 418  p_state->recv.current_digit_on_time = 0;
 419  p_state->recv.current_digit_off_time = 0;
 420  p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
 421
 422  p_state->recv.digit_write_pos = 0;
 423  p_state->recv.digit_read_pos = 0;
 424  p_state->recv.indication_state = 0;
 425  p_state->recv.indication_state_ack = 0;
 426  p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE;
 427}
 428
 429
 430void capidtmf_recv_enable (t_capidtmf_state   *p_state, word min_digit_duration, word min_gap_duration)
 431{
 432  p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT;
 433  p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) +
 434    ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
 435  if (p_state->recv.min_digit_duration <= 1)
 436    p_state->recv.min_digit_duration = 1;
 437  else
 438    (p_state->recv.min_digit_duration)--;
 439  p_state->recv.min_gap_duration =
 440    (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
 441  if (p_state->recv.min_gap_duration <= 1)
 442    p_state->recv.min_gap_duration = 1;
 443  else
 444    (p_state->recv.min_gap_duration)--;
 445  p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
 446}
 447
 448
 449void capidtmf_recv_disable (t_capidtmf_state   *p_state)
 450{
 451  p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
 452  if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE)
 453    capidtmf_recv_init (p_state);
 454  else
 455  {
 456    p_state->recv.cycle_counter = 0;
 457    p_state->recv.current_digit_on_time = 0;
 458    p_state->recv.current_digit_off_time = 0;
 459    p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
 460  }
 461}
 462
 463
 464word capidtmf_recv_indication (t_capidtmf_state   *p_state, byte *buffer)
 465{
 466  word i, j, k, flags;
 467
 468  flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack;
 469  p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT;
 470  if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos)
 471  {
 472    i = 0;
 473    k = p_state->recv.digit_write_pos;
 474    j = p_state->recv.digit_read_pos;
 475    do
 476    {
 477      buffer[i++] = p_state->recv.digit_buffer[j];
 478      j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1;
 479    } while (j != k);
 480    p_state->recv.digit_read_pos = k;
 481    return (i);
 482  }
 483  p_state->recv.indication_state_ack ^= flags;
 484  return (0);
 485}
 486
 487
 488#define CAPIDTMF_RECV_WINDOWED_SAMPLES  32
 489
 490void capidtmf_recv_block (t_capidtmf_state   *p_state, byte   *buffer, word length)
 491{
 492  byte result_digit;
 493  word sample_number, cycle_counter, n, i;
 494  word low_peak, high_peak;
 495  dword lo, hi;
 496  byte   *p;
 497  short *q;
 498  byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
 499    short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES];
 500
 501
 502  if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE)
 503  {
 504    cycle_counter = p_state->recv.cycle_counter;
 505    sample_number = 0;
 506    while (sample_number < length)
 507    {
 508      if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES)
 509      {
 510        if (cycle_counter == 0)
 511        {
 512          for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
 513          {
 514            p_state->recv.goertzel_buffer[0][i] = 0;
 515            p_state->recv.goertzel_buffer[1][i] = 0;
 516          }
 517        }
 518        n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter;
 519        if (n > length - sample_number)
 520          n = length - sample_number;
 521        if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES)
 522          n = CAPIDTMF_RECV_WINDOWED_SAMPLES;
 523        p = buffer + sample_number;
 524        q = capidtmf_recv_window_function + cycle_counter;
 525        if (p_state->ulaw)
 526        {
 527          for (i = 0; i < n; i++)
 528          {
 529            windowed_sample_buffer[i] =
 530              (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15);
 531          }
 532        }
 533        else
 534        {
 535          for (i = 0; i < n; i++)
 536          {
 537            windowed_sample_buffer[i] =
 538              (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15);
 539          }
 540        }
 541        capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET;
 542        capidtmf_goertzel_loop (p_state->recv.goertzel_buffer[0],
 543          capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n);
 544        cycle_counter += n;
 545        sample_number += n;
 546      }
 547      else
 548      {
 549        capidtmf_goertzel_result (p_state->recv.goertzel_buffer[0],
 550          capidtmf_recv_goertzel_coef_table);
 551        for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
 552        {
 553          lo = (dword)(p_state->recv.goertzel_buffer[0][i]);
 554          hi = (dword)(p_state->recv.goertzel_buffer[1][i]);
 555          if (hi != 0)
 556          {
 557            n = capidtmf_dword_leading_zeroes (hi);
 558            hi = (hi << n) | (lo >> (32 - n));
 559          }
 560          else
 561          {
 562            n = capidtmf_dword_leading_zeroes (lo);
 563            hi = lo << n;
 564            n += 32;
 565          }
 566          n = 195 - 3 * n;
 567          if (hi >= 0xcb300000L)
 568            n += 2;
 569          else if (hi >= 0xa1450000L)
 570            n++;
 571          goertzel_result_buffer[i] = (byte) n;
 572        }
 573        low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT;
 574        result_digit = CAPIDTMF_RECV_NO_DIGIT;
 575        for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++)
 576        {
 577          if (goertzel_result_buffer[i] > low_peak)
 578          {
 579            low_peak = goertzel_result_buffer[i];
 580            result_digit = (byte) i;
 581          }
 582        }
 583        high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT;
 584        n = CAPIDTMF_RECV_NO_DIGIT;
 585        for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++)
 586        {
 587          if (goertzel_result_buffer[i] > high_peak)
 588          {
 589            high_peak = goertzel_result_buffer[i];
 590            n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2;
 591          }
 592        }
 593        result_digit |= (byte) n;
 594        if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak)
 595          result_digit = CAPIDTMF_RECV_NO_DIGIT;
 596        if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak)
 597          result_digit = CAPIDTMF_RECV_NO_DIGIT;
 598        n = 0;
 599        for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
 600        {
 601          if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0)
 602           || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0))
 603          {
 604            n++;
 605          }
 606        }
 607        if (n != 2)
 608          result_digit = CAPIDTMF_RECV_NO_DIGIT;
 609
 610        if (result_digit == CAPIDTMF_RECV_NO_DIGIT)
 611        {
 612          if (p_state->recv.current_digit_on_time != 0)
 613          {
 614            if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration)
 615            {
 616              p_state->recv.current_digit_on_time = 0;
 617              p_state->recv.current_digit_off_time = 0;
 618            }
 619          }
 620          else
 621          {
 622            if (p_state->recv.current_digit_off_time != 0)
 623              (p_state->recv.current_digit_off_time)--;
 624          }
 625        }
 626        else
 627        {
 628          if ((p_state->recv.current_digit_on_time == 0)
 629           && (p_state->recv.current_digit_off_time != 0))
 630          {
 631            (p_state->recv.current_digit_off_time)--;
 632          }
 633          else
 634          {
 635            n = p_state->recv.current_digit_off_time;
 636            if ((p_state->recv.current_digit_on_time != 0)
 637             && (result_digit != p_state->recv.current_digit_value))
 638            {
 639              p_state->recv.current_digit_on_time = 0;
 640              n = 0;
 641            }
 642            p_state->recv.current_digit_value = result_digit;
 643            p_state->recv.current_digit_off_time = 0;
 644            if (p_state->recv.current_digit_on_time != 0xffff)
 645            {
 646              p_state->recv.current_digit_on_time += n + 1;
 647              if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration)
 648              {
 649                p_state->recv.current_digit_on_time = 0xffff;
 650                i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ?
 651                  0 : p_state->recv.digit_write_pos + 1;
 652                if (i == p_state->recv.digit_read_pos)
 653                {
 654                  trace (dprintf ("%s,%d: Receive digit overrun",
 655                    (char   *)(FILE_), __LINE__));
 656                }
 657                else
 658                {
 659                  p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit;
 660                  p_state->recv.digit_write_pos = i;
 661                  p_state->recv.indication_state =
 662                    (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) |
 663                    (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT);
 664                }
 665              }
 666            }
 667          }
 668        }
 669        cycle_counter = 0;
 670        sample_number++;
 671      }
 672    }
 673    p_state->recv.cycle_counter = cycle_counter;
 674  }
 675}
 676
 677
 678void capidtmf_init (t_capidtmf_state   *p_state, byte ulaw)
 679{
 680  p_state->ulaw = ulaw;
 681  capidtmf_recv_init (p_state);
 682}
 683
 684
 685/*---------------------------------------------------------------------------*/
 686