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