00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
#include <sys/types.h>
00032
#include <asterisk/frame.h>
00033
#include <asterisk/channel.h>
00034
#include <asterisk/channel_pvt.h>
00035
#include <asterisk/logger.h>
00036
#include <asterisk/dsp.h>
00037
#include <asterisk/ulaw.h>
00038
#include <asterisk/alaw.h>
00039
#include <stdlib.h>
00040
#include <unistd.h>
00041
#include <string.h>
00042
#include <math.h>
00043
#include <errno.h>
00044
#include <stdio.h>
00045
00046
00047 #define GSAMP_SIZE_NA 183
00048 #define GSAMP_SIZE_CR 188
00049
00050 #define PROG_MODE_NA 0
00051 #define PROG_MODE_CR 1
00052
00053
00054 #define HZ_350 0
00055 #define HZ_440 1
00056 #define HZ_480 2
00057 #define HZ_620 3
00058 #define HZ_950 4
00059 #define HZ_1400 5
00060 #define HZ_1800 6
00061
00062
00063 #define HZ_425 0
00064
00065
static struct progalias {
00066
char *name;
00067
int mode;
00068 } aliases[] = {
00069 {
"us",
PROG_MODE_NA },
00070 {
"ca",
PROG_MODE_NA },
00071 {
"cr",
PROG_MODE_CR },
00072 };
00073
00074
static struct progress {
00075
int size;
00076
int freqs[7];
00077 } modes[] = {
00078 {
GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } },
00079 {
GSAMP_SIZE_CR, { 425 } },
00080 };
00081
00082 #define DEFAULT_THRESHOLD 1024
00083
00084 #define BUSY_PERCENT 10
00085 #define BUSY_THRESHOLD 100
00086 #define BUSY_MIN 75
00087 #define BUSY_MAX 1100
00088
00089
00090 #define DSP_HISTORY 15
00091
00092
00093 #define FAX_DETECT
00094
00095 #define TONE_THRESH 10.0
00096 #define TONE_MIN_THRESH 1e8
00097 #define COUNT_THRESH 3
00098
00099 #define TONE_STATE_SILENCE 0
00100 #define TONE_STATE_RINGING 1
00101 #define TONE_STATE_DIALTONE 2
00102 #define TONE_STATE_TALKING 3
00103 #define TONE_STATE_BUSY 4
00104 #define TONE_STATE_SPECIAL1 5
00105 #define TONE_STATE_SPECIAL2 6
00106 #define TONE_STATE_SPECIAL3 7
00107
00108 #define MAX_DTMF_DIGITS 128
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define DTMF_THRESHOLD 8.0e7
00123 #define FAX_THRESHOLD 8.0e7
00124 #define FAX_2ND_HARMONIC 2.0
00125 #define DTMF_NORMAL_TWIST 6.3
00126
#ifdef RADIO_RELAX
00127
#define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)
00128
#else
00129 #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)
00130
#endif
00131 #define DTMF_RELATIVE_PEAK_ROW 6.3
00132 #define DTMF_RELATIVE_PEAK_COL 6.3
00133 #define DTMF_2ND_HARMONIC_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)
00134 #define DTMF_2ND_HARMONIC_COL 63.1
00135
#ifndef OLD_DSP_ROUTINES
00136 #define DTMF_TO_TOTAL_ENERGY 42.0
00137
#endif
00138
00139
#ifdef OLD_DSP_ROUTINES
00140
#define MF_THRESHOLD 8.0e7
00141
#define MF_NORMAL_TWIST 5.3
00142
#define MF_REVERSE_TWIST 4.0
00143
#define MF_RELATIVE_PEAK 5.3
00144
#define MF_2ND_HARMONIC 1.7
00145
#else
00146 #define BELL_MF_THRESHOLD 1.6e9
00147 #define BELL_MF_TWIST 4.0
00148 #define BELL_MF_RELATIVE_PEAK 12.6
00149
#endif
00150
00151 typedef struct {
00152 float v2;
00153 float v3;
00154 float fac;
00155
#ifndef OLD_DSP_ROUTINES
00156 int samples;
00157
#endif
00158
}
goertzel_state_t;
00159
00160 typedef struct
00161
{
00162
00163 goertzel_state_t row_out[4];
00164 goertzel_state_t col_out[4];
00165
#ifdef FAX_DETECT
00166 goertzel_state_t fax_tone;
00167
#endif
00168
#ifdef OLD_DSP_ROUTINES
00169
goertzel_state_t row_out2nd[4];
00170
goertzel_state_t col_out2nd[4];
00171
#ifdef FAX_DETECT
00172
goertzel_state_t fax_tone2nd;
00173
#endif
00174
int hit1;
00175
int hit2;
00176
int hit3;
00177
int hit4;
00178
#else
00179 int hits[3];
00180
#endif
00181 int mhit;
00182 float energy;
00183 int current_sample;
00184
00185 char digits[
MAX_DTMF_DIGITS + 1];
00186 int current_digits;
00187 int detected_digits;
00188 int lost_digits;
00189 int digit_hits[16];
00190
00191
00192
#ifdef FAX_DETECT
00193 int fax_hits;
00194
#endif
00195
}
dtmf_detect_state_t;
00196
00197 typedef struct
00198
{
00199 goertzel_state_t tone_out[6];
00200 int mhit;
00201
#ifdef OLD_DSP_ROUTINES
00202
int hit1;
00203
int hit2;
00204
int hit3;
00205
int hit4;
00206
goertzel_state_t tone_out2nd[6];
00207
float energy;
00208
#else
00209 int hits[5];
00210
#endif
00211
00212 int current_sample;
00213 char digits[
MAX_DTMF_DIGITS + 1];
00214 int current_digits;
00215 int detected_digits;
00216 int lost_digits;
00217
#ifdef FAX_DETECT
00218 int fax_hits;
00219
#endif
00220
}
mf_detect_state_t;
00221
00222
static float dtmf_row[] =
00223 {
00224 697.0, 770.0, 852.0, 941.0
00225 };
00226
static float dtmf_col[] =
00227 {
00228 1209.0, 1336.0, 1477.0, 1633.0
00229 };
00230
00231
static float mf_tones[] =
00232 {
00233 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00234 };
00235
00236
#ifdef FAX_DETECT
00237
static float fax_freq = 1100.0;
00238
#endif
00239
00240
static char dtmf_positions[] =
"123A" "456B" "789C" "*0#D";
00241
00242
#ifdef OLD_DSP_ROUTINES
00243
static char mf_hit[6][6] = {
00244 { 0,
'1',
'2',
'4',
'7',
'C' },
00245 {
'1', 0,
'3',
'5',
'8',
'A' },
00246 {
'2',
'3', 0,
'6',
'9',
'*' },
00247 {
'4',
'5',
'6', 0,
'0',
'B' },
00248 {
'7',
'8',
'9',
'0', 0,
'#' },
00249 {
'C',
'A',
'*',
'B',
'#', 0 },
00250 };
00251
#else
00252
static char bell_mf_positions[] =
"1247C-358A--69*---0B----#";
00253
#endif
00254
00255
static inline void goertzel_sample(
goertzel_state_t *s,
short sample)
00256 {
00257
float v1;
00258
float fsamp = sample;
00259 v1 =
s->v2;
00260
s->v2 =
s->v3;
00261
s->v3 =
s->fac *
s->v2 - v1 + fsamp;
00262 }
00263
00264
static inline void goertzel_update(
goertzel_state_t *s,
short *samps,
int count)
00265 {
00266
int i;
00267
for (i=0;i<count;i++)
00268 goertzel_sample(s, samps[i]);
00269 }
00270
00271
00272
static inline float goertzel_result(
goertzel_state_t *s)
00273 {
00274
return s->v3 *
s->v3 +
s->v2 *
s->v2 -
s->v2 *
s->v3 *
s->fac;
00275 }
00276
00277
static inline void goertzel_init(
goertzel_state_t *s,
float freq,
int samples)
00278 {
00279
s->v2 =
s->v3 = 0.0;
00280
s->fac = 2.0 * cos(2.0 * M_PI * (freq / 8000.0));
00281
#ifndef OLD_DSP_ROUTINES
00282
s->samples = samples;
00283
#endif
00284
}
00285
00286
static inline void goertzel_reset(
goertzel_state_t *s)
00287 {
00288
s->v2 =
s->v3 = 0.0;
00289 }
00290
00291 struct ast_dsp {
00292 struct ast_frame f;
00293 int threshold;
00294 int totalsilence;
00295 int totalnoise;
00296 int features;
00297 int busymaybe;
00298 int busycount;
00299 int historicnoise[
DSP_HISTORY];
00300 int historicsilence[
DSP_HISTORY];
00301 goertzel_state_t freqs[7];
00302 int freqcount;
00303 int gsamps;
00304 int gsamp_size;
00305 int progmode;
00306 int tstate;
00307 int tcount;
00308 int digitmode;
00309 int thinkdigit;
00310 float genergy;
00311
union {
00312 dtmf_detect_state_t dtmf;
00313 mf_detect_state_t mf;
00314 } td;
00315 };
00316
00317
static void ast_dtmf_detect_init (
dtmf_detect_state_t *s)
00318 {
00319
int i;
00320
00321
#ifdef OLD_DSP_ROUTINES
00322
s->hit1 =
00323
s->mhit =
00324
s->hit3 =
00325
s->hit4 =
00326
s->hit2 = 0;
00327
#else
00328
s->hits[0] =
s->hits[1] =
s->hits[2] = 0;
00329
#endif
00330
for (i = 0; i < 4; i++)
00331 {
00332
00333 goertzel_init (&
s->row_out[i], dtmf_row[i], 102);
00334 goertzel_init (&
s->col_out[i], dtmf_col[i], 102);
00335
#ifdef OLD_DSP_ROUTINES
00336
goertzel_init (&
s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
00337 goertzel_init (&
s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
00338
#endif
00339
s->energy = 0.0;
00340 }
00341
00342
#ifdef FAX_DETECT
00343
00344 goertzel_init (&
s->fax_tone, fax_freq, 102);
00345
00346
#ifdef OLD_DSP_ROUTINES
00347
00348 goertzel_init (&
s->fax_tone2nd, fax_freq * 2.0, 102);
00349
#endif
00350
#endif
00351
00352
s->current_sample = 0;
00353
s->detected_digits = 0;
00354
s->current_digits = 0;
00355 memset(&
s->digits, 0,
sizeof(
s->digits));
00356
s->lost_digits = 0;
00357
s->digits[0] =
'\0';
00358 }
00359
00360
static void ast_mf_detect_init (
mf_detect_state_t *s)
00361 {
00362
int i;
00363
00364
#ifdef OLD_DSP_ROUTINES
00365
s->hit1 =
00366
s->hit2 = 0;
00367
#else
00368
s->hits[0] =
s->hits[1] =
s->hits[2] =
s->hits[3] =
s->hits[4] = 0;
00369
#endif
00370
for (i = 0; i < 6; i++)
00371 {
00372
00373 goertzel_init (&
s->tone_out[i], mf_tones[i], 160);
00374
#ifdef OLD_DSP_ROUTINES
00375
goertzel_init (&
s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
00376
s->energy = 0.0;
00377
#endif
00378
00379 }
00380
00381
s->current_digits = 0;
00382 memset(&
s->digits, 0,
sizeof(
s->digits));
00383
s->current_sample = 0;
00384
s->detected_digits = 0;
00385
s->lost_digits = 0;
00386
s->digits[0] =
'\0';
00387
s->mhit = 0;
00388 }
00389
00390
static int dtmf_detect (
dtmf_detect_state_t *s,
00391 int16_t amp[],
00392
int samples,
00393
int digitmode,
int *writeback,
int faxdetect)
00394 {
00395
00396
float row_energy[4];
00397
float col_energy[4];
00398
#ifdef FAX_DETECT
00399
float fax_energy;
00400
#ifdef OLD_DSP_ROUTINES
00401
float fax_energy_2nd;
00402
#endif
00403
#endif
00404
float famp;
00405
float v1;
00406
int i;
00407
int j;
00408
int sample;
00409
int best_row;
00410
int best_col;
00411
int hit;
00412
int limit;
00413
00414 hit = 0;
00415
for (sample = 0; sample < samples; sample = limit)
00416 {
00417
00418
if ((samples - sample) >= (102 -
s->current_sample))
00419 limit = sample + (102 -
s->current_sample);
00420
else
00421 limit = samples;
00422
#if defined(USE_3DNOW)
00423
_dtmf_goertzel_update (
s->row_out, amp + sample, limit - sample);
00424 _dtmf_goertzel_update (
s->col_out, amp + sample, limit - sample);
00425
#ifdef OLD_DSP_ROUTINES
00426
_dtmf_goertzel_update (
s->row_out2nd, amp + sample, limit2 - sample);
00427 _dtmf_goertzel_update (
s->col_out2nd, amp + sample, limit2 - sample);
00428
#endif
00429
00430
#warning "Fax Support Broken"
00431
#else
00432
00433
00434
for (j = sample; j < limit; j++)
00435 {
00436 famp = amp[j];
00437
00438
s->energy += famp*famp;
00439
00440
00441
00442 v1 =
s->row_out[0].v2;
00443
s->row_out[0].v2 =
s->row_out[0].v3;
00444
s->row_out[0].v3 =
s->row_out[0].fac*
s->row_out[0].v2 - v1 + famp;
00445
00446 v1 =
s->col_out[0].v2;
00447
s->col_out[0].v2 =
s->col_out[0].v3;
00448
s->col_out[0].v3 =
s->col_out[0].fac*
s->col_out[0].v2 - v1 + famp;
00449
00450 v1 =
s->row_out[1].v2;
00451
s->row_out[1].v2 =
s->row_out[1].v3;
00452
s->row_out[1].v3 =
s->row_out[1].fac*
s->row_out[1].v2 - v1 + famp;
00453
00454 v1 =
s->col_out[1].v2;
00455
s->col_out[1].v2 =
s->col_out[1].v3;
00456
s->col_out[1].v3 =
s->col_out[1].fac*
s->col_out[1].v2 - v1 + famp;
00457
00458 v1 =
s->row_out[2].v2;
00459
s->row_out[2].v2 =
s->row_out[2].v3;
00460
s->row_out[2].v3 =
s->row_out[2].fac*
s->row_out[2].v2 - v1 + famp;
00461
00462 v1 =
s->col_out[2].v2;
00463
s->col_out[2].v2 =
s->col_out[2].v3;
00464
s->col_out[2].v3 =
s->col_out[2].fac*
s->col_out[2].v2 - v1 + famp;
00465
00466 v1 =
s->row_out[3].v2;
00467
s->row_out[3].v2 =
s->row_out[3].v3;
00468
s->row_out[3].v3 =
s->row_out[3].fac*
s->row_out[3].v2 - v1 + famp;
00469
00470 v1 =
s->col_out[3].v2;
00471
s->col_out[3].v2 =
s->col_out[3].v3;
00472
s->col_out[3].v3 =
s->col_out[3].fac*
s->col_out[3].v2 - v1 + famp;
00473
00474
#ifdef FAX_DETECT
00475
00476 v1 =
s->fax_tone.v2;
00477
s->fax_tone.v2 =
s->fax_tone.v3;
00478
s->fax_tone.v3 =
s->fax_tone.fac*
s->fax_tone.v2 - v1 + famp;
00479
#endif
00480
#ifdef OLD_DSP_ROUTINES
00481
v1 =
s->col_out2nd[0].v2;
00482
s->col_out2nd[0].v2 =
s->col_out2nd[0].v3;
00483
s->col_out2nd[0].v3 =
s->col_out2nd[0].fac*
s->col_out2nd[0].v2 - v1 + famp;
00484
00485 v1 =
s->row_out2nd[0].v2;
00486
s->row_out2nd[0].v2 =
s->row_out2nd[0].v3;
00487
s->row_out2nd[0].v3 =
s->row_out2nd[0].fac*
s->row_out2nd[0].v2 - v1 + famp;
00488
00489 v1 =
s->col_out2nd[1].v2;
00490
s->col_out2nd[1].v2 =
s->col_out2nd[1].v3;
00491
s->col_out2nd[1].v3 =
s->col_out2nd[1].fac*
s->col_out2nd[1].v2 - v1 + famp;
00492
00493 v1 =
s->row_out2nd[1].v2;
00494
s->row_out2nd[1].v2 =
s->row_out2nd[1].v3;
00495
s->row_out2nd[1].v3 =
s->row_out2nd[1].fac*
s->row_out2nd[1].v2 - v1 + famp;
00496
00497 v1 =
s->col_out2nd[2].v2;
00498
s->col_out2nd[2].v2 =
s->col_out2nd[2].v3;
00499
s->col_out2nd[2].v3 =
s->col_out2nd[2].fac*
s->col_out2nd[2].v2 - v1 + famp;
00500
00501 v1 =
s->row_out2nd[2].v2;
00502
s->row_out2nd[2].v2 =
s->row_out2nd[2].v3;
00503
s->row_out2nd[2].v3 =
s->row_out2nd[2].fac*
s->row_out2nd[2].v2 - v1 + famp;
00504
00505 v1 =
s->col_out2nd[3].v2;
00506
s->col_out2nd[3].v2 =
s->col_out2nd[3].v3;
00507
s->col_out2nd[3].v3 =
s->col_out2nd[3].fac*
s->col_out2nd[3].v2 - v1 + famp;
00508
00509 v1 =
s->row_out2nd[3].v2;
00510
s->row_out2nd[3].v2 =
s->row_out2nd[3].v3;
00511
s->row_out2nd[3].v3 =
s->row_out2nd[3].fac*
s->row_out2nd[3].v2 - v1 + famp;
00512
00513
00514
#ifdef FAX_DETECT
00515
00516 v1 =
s->fax_tone.v2;
00517
s->fax_tone2nd.v2 =
s->fax_tone2nd.v3;
00518
s->fax_tone2nd.v3 =
s->fax_tone2nd.fac*
s->fax_tone2nd.v2 - v1 + famp;
00519
#endif
00520
#endif
00521
}
00522
#endif
00523
s->current_sample += (limit - sample);
00524
if (
s->current_sample < 102) {
00525
if (hit && !((digitmode &
DSP_DIGITMODE_NOQUELCH))) {
00526
00527
00528
for (i=sample;i<limit;i++)
00529 amp[i] = 0;
00530 *writeback = 1;
00531 }
00532
continue;
00533 }
00534
00535
#ifdef FAX_DETECT
00536
00537 fax_energy = goertzel_result(&
s->fax_tone);
00538
#endif
00539
00540
00541
00542 row_energy[0] = goertzel_result (&
s->row_out[0]);
00543 col_energy[0] = goertzel_result (&
s->col_out[0]);
00544
00545
for (best_row = best_col = 0, i = 1; i < 4; i++)
00546 {
00547 row_energy[i] = goertzel_result (&
s->row_out[i]);
00548
if (row_energy[i] > row_energy[best_row])
00549 best_row = i;
00550 col_energy[i] = goertzel_result (&
s->col_out[i]);
00551
if (col_energy[i] > col_energy[best_col])
00552 best_col = i;
00553 }
00554 hit = 0;
00555
00556
if (row_energy[best_row] >=
DTMF_THRESHOLD
00557 &&
00558 col_energy[best_col] >=
DTMF_THRESHOLD
00559 &&
00560 col_energy[best_col] < row_energy[best_row]*
DTMF_REVERSE_TWIST
00561 &&
00562 col_energy[best_col]*
DTMF_NORMAL_TWIST > row_energy[best_row])
00563 {
00564
00565
for (i = 0; i < 4; i++)
00566 {
00567
if ((i != best_col && col_energy[i]*
DTMF_RELATIVE_PEAK_COL > col_energy[best_col])
00568 ||
00569 (i != best_row && row_energy[i]*
DTMF_RELATIVE_PEAK_ROW > row_energy[best_row]))
00570 {
00571
break;
00572 }
00573 }
00574
#ifdef OLD_DSP_ROUTINES
00575
00576
if (i >= 4
00577 &&
00578 (row_energy[best_row] + col_energy[best_col]) > 42.0*
s->energy
00579 &&
00580 goertzel_result (&
s->col_out2nd[best_col])*
DTMF_2ND_HARMONIC_COL < col_energy[best_col]
00581 &&
00582 goertzel_result (&
s->row_out2nd[best_row])*
DTMF_2ND_HARMONIC_ROW < row_energy[best_row])
00583
#else
00584
00585
if (i >= 4
00586 &&
00587 (row_energy[best_row] + col_energy[best_col]) >
DTMF_TO_TOTAL_ENERGY*
s->energy)
00588
#endif
00589
{
00590
00591 hit = dtmf_positions[(best_row << 2) + best_col];
00592
if (!(digitmode &
DSP_DIGITMODE_NOQUELCH)) {
00593
00594
for (i=sample;i<limit;i++)
00595 amp[i] = 0;
00596 *writeback = 1;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
#ifdef OLD_DSP_ROUTINES
00607
if (hit ==
s->hit3 &&
s->hit3 !=
s->hit2)
00608 {
00609
s->mhit = hit;
00610
s->digit_hits[(best_row << 2) + best_col]++;
00611
s->detected_digits++;
00612
if (
s->current_digits <
MAX_DTMF_DIGITS)
00613 {
00614
s->digits[
s->current_digits++] = hit;
00615
s->digits[
s->current_digits] =
'\0';
00616 }
00617
else
00618 {
00619
s->lost_digits++;
00620 }
00621 }
00622
#else
00623
if (hit ==
s->hits[2] && hit !=
s->hits[1] && hit !=
s->hits[0])
00624 {
00625
s->mhit = hit;
00626
s->digit_hits[(best_row << 2) + best_col]++;
00627
s->detected_digits++;
00628
if (
s->current_digits <
MAX_DTMF_DIGITS)
00629 {
00630
s->digits[
s->current_digits++] = hit;
00631
s->digits[
s->current_digits] =
'\0';
00632 }
00633
else
00634 {
00635
s->lost_digits++;
00636 }
00637 }
00638
#endif
00639
}
00640 }
00641
#ifdef FAX_DETECT
00642
if (!hit && (fax_energy >=
FAX_THRESHOLD) && (fax_energy >=
DTMF_TO_TOTAL_ENERGY*
s->energy) && (faxdetect)) {
00643
#if 0
00644
printf(
"Fax energy/Second Harmonic: %f\n", fax_energy);
00645
#endif
00646
00647 hit =
'f';
00648
s->fax_hits++;
00649 }
00650
else {
00651
if (
s->fax_hits > 5) {
00652 hit =
'f';
00653
s->mhit =
'f';
00654
s->detected_digits++;
00655
if (
s->current_digits <
MAX_DTMF_DIGITS)
00656 {
00657
s->digits[
s->current_digits++] = hit;
00658
s->digits[
s->current_digits] =
'\0';
00659 }
00660
else
00661 {
00662
s->lost_digits++;
00663 }
00664 }
00665
s->fax_hits = 0;
00666 }
00667
#endif
00668
#ifdef OLD_DSP_ROUTINES
00669
s->hit1 =
s->hit2;
00670
s->hit2 =
s->hit3;
00671
s->hit3 = hit;
00672
#else
00673
s->hits[0] =
s->hits[1];
00674
s->hits[1] =
s->hits[2];
00675
s->hits[2] = hit;
00676
#endif
00677
00678
for (i = 0; i < 4; i++)
00679 {
00680 goertzel_reset(&
s->row_out[i]);
00681 goertzel_reset(&
s->col_out[i]);
00682
#ifdef OLD_DSP_ROUTINES
00683
goertzel_reset(&
s->row_out2nd[i]);
00684 goertzel_reset(&
s->col_out2nd[i]);
00685
#endif
00686
}
00687
#ifdef FAX_DETECT
00688
goertzel_reset (&
s->fax_tone);
00689
#ifdef OLD_DSP_ROUTINES
00690
goertzel_reset (&
s->fax_tone2nd);
00691
#endif
00692
#endif
00693
s->energy = 0.0;
00694
s->current_sample = 0;
00695 }
00696
if ((!
s->mhit) || (
s->mhit != hit))
00697 {
00698
s->mhit = 0;
00699
return(0);
00700 }
00701
return (hit);
00702 }
00703
00704
00705
#ifdef OLD_DSP_ROUTINES
00706
#define MF_GSIZE 160
00707
#else
00708 #define MF_GSIZE 120
00709
#endif
00710
00711
static int mf_detect (
mf_detect_state_t *s,
00712 int16_t amp[],
00713
int samples,
00714
int digitmode,
int *writeback)
00715 {
00716
00717
#ifdef OLD_DSP_ROUTINES
00718
float tone_energy[6];
00719
int best1;
00720
int best2;
00721
float max;
00722
int sofarsogood;
00723
#else
00724
float energy[6];
00725
int best;
00726
int second_best;
00727
#endif
00728
float famp;
00729
float v1;
00730
int i;
00731
int j;
00732
int sample;
00733
int hit;
00734
int limit;
00735
00736 hit = 0;
00737
for (sample = 0; sample < samples; sample = limit)
00738 {
00739
00740
if ((samples - sample) >= (
MF_GSIZE -
s->current_sample))
00741 limit = sample + (
MF_GSIZE -
s->current_sample);
00742
else
00743 limit = samples;
00744
#if defined(USE_3DNOW)
00745
_dtmf_goertzel_update (
s->row_out, amp + sample, limit - sample);
00746 _dtmf_goertzel_update (
s->col_out, amp + sample, limit - sample);
00747
#ifdef OLD_DSP_ROUTINES
00748
_dtmf_goertzel_update (
s->row_out2nd, amp + sample, limit2 - sample);
00749 _dtmf_goertzel_update (
s->col_out2nd, amp + sample, limit2 - sample);
00750
#endif
00751
00752
#warning "Fax Support Broken"
00753
#else
00754
00755
00756
for (j = sample; j < limit; j++)
00757 {
00758 famp = amp[j];
00759
00760
#ifdef OLD_DSP_ROUTINES
00761
s->energy += famp*famp;
00762
#endif
00763
00764
00765
00766 v1 =
s->tone_out[0].v2;
00767
s->tone_out[0].v2 =
s->tone_out[0].v3;
00768
s->tone_out[0].v3 =
s->tone_out[0].fac*
s->tone_out[0].v2 - v1 + famp;
00769
00770 v1 =
s->tone_out[1].v2;
00771
s->tone_out[1].v2 =
s->tone_out[1].v3;
00772
s->tone_out[1].v3 =
s->tone_out[1].fac*
s->tone_out[1].v2 - v1 + famp;
00773
00774 v1 =
s->tone_out[2].v2;
00775
s->tone_out[2].v2 =
s->tone_out[2].v3;
00776
s->tone_out[2].v3 =
s->tone_out[2].fac*
s->tone_out[2].v2 - v1 + famp;
00777
00778 v1 =
s->tone_out[3].v2;
00779
s->tone_out[3].v2 =
s->tone_out[3].v3;
00780
s->tone_out[3].v3 =
s->tone_out[3].fac*
s->tone_out[3].v2 - v1 + famp;
00781
00782 v1 =
s->tone_out[4].v2;
00783
s->tone_out[4].v2 =
s->tone_out[4].v3;
00784
s->tone_out[4].v3 =
s->tone_out[4].fac*
s->tone_out[4].v2 - v1 + famp;
00785
00786 v1 =
s->tone_out[5].v2;
00787
s->tone_out[5].v2 =
s->tone_out[5].v3;
00788
s->tone_out[5].v3 =
s->tone_out[5].fac*
s->tone_out[5].v2 - v1 + famp;
00789
00790
#ifdef OLD_DSP_ROUTINES
00791
v1 =
s->tone_out2nd[0].v2;
00792
s->tone_out2nd[0].v2 =
s->tone_out2nd[0].v3;
00793
s->tone_out2nd[0].v3 =
s->tone_out2nd[0].fac*
s->tone_out2nd[0].v2 - v1 + famp;
00794
00795 v1 =
s->tone_out2nd[1].v2;
00796
s->tone_out2nd[1].v2 =
s->tone_out2nd[1].v3;
00797
s->tone_out2nd[1].v3 =
s->tone_out2nd[1].fac*
s->tone_out2nd[1].v2 - v1 + famp;
00798
00799 v1 =
s->tone_out2nd[2].v2;
00800
s->tone_out2nd[2].v2 =
s->tone_out2nd[2].v3;
00801
s->tone_out2nd[2].v3 =
s->tone_out2nd[2].fac*
s->tone_out2nd[2].v2 - v1 + famp;
00802
00803 v1 =
s->tone_out2nd[3].v2;
00804
s->tone_out2nd[3].v2 =
s->tone_out2nd[3].v3;
00805
s->tone_out2nd[3].v3 =
s->tone_out2nd[3].fac*
s->tone_out2nd[3].v2 - v1 + famp;
00806
00807 v1 =
s->tone_out2nd[4].v2;
00808
s->tone_out2nd[4].v2 =
s->tone_out2nd[4].v3;
00809
s->tone_out2nd[4].v3 =
s->tone_out2nd[4].fac*
s->tone_out2nd[2].v2 - v1 + famp;
00810
00811 v1 =
s->tone_out2nd[3].v2;
00812
s->tone_out2nd[5].v2 =
s->tone_out2nd[6].v3;
00813
s->tone_out2nd[5].v3 =
s->tone_out2nd[6].fac*
s->tone_out2nd[3].v2 - v1 + famp;
00814
#endif
00815
}
00816
#endif
00817
s->current_sample += (limit - sample);
00818
if (
s->current_sample <
MF_GSIZE) {
00819
if (hit && !((digitmode &
DSP_DIGITMODE_NOQUELCH))) {
00820
00821
00822
for (i=sample;i<limit;i++)
00823 amp[i] = 0;
00824 *writeback = 1;
00825 }
00826
continue;
00827 }
00828
00829
00830
#ifdef OLD_DSP_ROUTINES
00831
00832
00833
for (i=0;i<6;i++) {
00834 tone_energy[i] = goertzel_result(&
s->tone_out[i]);
00835 }
00836
00837 best1 = 0;
00838 max = tone_energy[0];
00839
for (i=1;i<6;i++) {
00840
if (tone_energy[i] > max) {
00841 max = tone_energy[i];
00842 best1 = i;
00843 }
00844 }
00845
00846
00847
if (best1) {
00848 max = tone_energy[0];
00849 best2 = 0;
00850 }
else {
00851 max = tone_energy[1];
00852 best2 = 1;
00853 }
00854
00855
for (i=0;i<6;i++) {
00856
if (i == best1)
continue;
00857
if (tone_energy[i] > max) {
00858 max = tone_energy[i];
00859 best2 = i;
00860 }
00861 }
00862
00863 hit = 0;
00864
if (best1 != best2) sofarsogood=1;
00865
else sofarsogood=0;
00866
00867
for (i=0;i<6;i++) {
00868
if (i == best1)
continue;
00869
if (i == best2)
continue;
00870
if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
00871 sofarsogood = 0;
00872
break;
00873 }
00874
if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
00875 sofarsogood = 0;
00876
break;
00877 }
00878 }
00879
00880
if (sofarsogood) {
00881
00882
if (goertzel_result(&
s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1])
00883 sofarsogood = 0;
00884
else if (goertzel_result(&
s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
00885 sofarsogood = 0;
00886 }
00887
if (sofarsogood) {
00888 hit = mf_hit[best1][best2];
00889
if (!(digitmode &
DSP_DIGITMODE_NOQUELCH)) {
00890
00891
for (i=sample;i<limit;i++)
00892 amp[i] = 0;
00893 *writeback = 1;
00894 }
00895
00896
if ((hit ==
s->hit3) && (
s->hit3 !=
s->hit2)) {
00897
s->mhit = hit;
00898
s->detected_digits++;
00899
if (
s->current_digits <
MAX_DTMF_DIGITS - 2) {
00900
s->digits[
s->current_digits++] = hit;
00901
s->digits[
s->current_digits] =
'\0';
00902 }
else {
00903
s->lost_digits++;
00904 }
00905 }
00906 }
00907
00908
s->hit1 =
s->hit2;
00909
s->hit2 =
s->hit3;
00910
s->hit3 = hit;
00911
00912
for (i = 0; i < 6; i++)
00913 {
00914 goertzel_reset(&
s->tone_out[i]);
00915 goertzel_reset(&
s->tone_out2nd[i]);
00916 }
00917
s->energy = 0.0;
00918
s->current_sample = 0;
00919 }
00920
#else
00921
00922
00923
00924
00925
00926
00927
00928 energy[0] = goertzel_result(&
s->tone_out[0]);
00929 energy[1] = goertzel_result(&
s->tone_out[1]);
00930
if (energy[0] > energy[1])
00931 {
00932 best = 0;
00933 second_best = 1;
00934 }
00935
else
00936 {
00937 best = 1;
00938 second_best = 0;
00939 }
00940
00941
for (i = 2; i < 6; i++)
00942 {
00943 energy[i] = goertzel_result(&
s->tone_out[i]);
00944
if (energy[i] >= energy[best])
00945 {
00946 second_best = best;
00947 best = i;
00948 }
00949
else if (energy[i] >= energy[second_best])
00950 {
00951 second_best = i;
00952 }
00953 }
00954
00955 hit = 0;
00956
if (energy[best] >=
BELL_MF_THRESHOLD
00957 &&
00958 energy[second_best] >=
BELL_MF_THRESHOLD
00959 &&
00960 energy[best] < energy[second_best]*
BELL_MF_TWIST
00961 &&
00962 energy[best]*
BELL_MF_TWIST > energy[second_best])
00963 {
00964
00965 hit = -1;
00966
for (i = 0; i < 6; i++)
00967 {
00968
if (i != best && i != second_best)
00969 {
00970
if (energy[i]*
BELL_MF_RELATIVE_PEAK >= energy[second_best])
00971 {
00972
00973 hit = 0;
00974
break;
00975 }
00976 }
00977 }
00978 }
00979
if (hit)
00980 {
00981
00982
if (second_best < best)
00983 {
00984 i = best;
00985 best = second_best;
00986 second_best = i;
00987 }
00988 best = best*5 + second_best - 1;
00989 hit = bell_mf_positions[best];
00990
00991
00992
00993
00994
00995
00996
if (hit ==
s->hits[4]
00997 &&
00998 hit ==
s->hits[3]
00999 &&
01000 ((hit !=
'*' && hit !=
s->hits[2] && hit !=
s->hits[1])
01001 ||
01002 (hit ==
'*' && hit ==
s->hits[2] && hit !=
s->hits[1] && hit !=
s->hits[0])))
01003 {
01004
s->detected_digits++;
01005
if (
s->current_digits <
MAX_DTMF_DIGITS)
01006 {
01007
s->digits[
s->current_digits++] = hit;
01008
s->digits[
s->current_digits] =
'\0';
01009 }
01010
else
01011 {
01012
s->lost_digits++;
01013 }
01014 }
01015 }
01016
else
01017 {
01018 hit = 0;
01019 }
01020
s->hits[0] =
s->hits[1];
01021
s->hits[1] =
s->hits[2];
01022
s->hits[2] =
s->hits[3];
01023
s->hits[3] =
s->hits[4];
01024
s->hits[4] = hit;
01025
01026
for (i = 0; i < 6; i++)
01027 goertzel_reset(&
s->tone_out[i]);
01028
s->current_sample = 0;
01029 }
01030
#endif
01031
if ((!
s->mhit) || (
s->mhit != hit))
01032 {
01033
s->mhit = 0;
01034
return(0);
01035 }
01036
return (hit);
01037 }
01038
01039
static int __ast_dsp_digitdetect(
struct ast_dsp *dsp,
short *s,
int len,
int *writeback)
01040 {
01041
int res;
01042
if (dsp->
digitmode &
DSP_DIGITMODE_MF)
01043 res = mf_detect(&dsp->
td.mf, s, len, dsp->
digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
01044
else
01045 res = dtmf_detect(&dsp->
td.dtmf, s, len, dsp->
digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->
features & DSP_FEATURE_FAX_DETECT);
01046
return res;
01047 }
01048
01049 int ast_dsp_digitdetect(
struct ast_dsp *dsp,
struct ast_frame *inf)
01050 {
01051
short *
s;
01052
int len;
01053
int ign=0;
01054
if (inf->
frametype !=
AST_FRAME_VOICE) {
01055
ast_log(
LOG_WARNING,
"Can't check call progress of non-voice frames\n");
01056
return 0;
01057 }
01058
if (inf->
subclass !=
AST_FORMAT_SLINEAR) {
01059
ast_log(
LOG_WARNING,
"Can only check call progress in signed-linear frames\n");
01060
return 0;
01061 }
01062
s = inf->
data;
01063 len = inf->
datalen / 2;
01064
return __ast_dsp_digitdetect(dsp,
s, len, &ign);
01065 }
01066
01067
static inline int pair_there(
float p1,
float p2,
float i1,
float i2,
float e)
01068 {
01069
01070
01071
if ((p1 <
TONE_MIN_THRESH) || (p2 <
TONE_MIN_THRESH))
01072
return 0;
01073
01074 i2 *=
TONE_THRESH;
01075 i1 *=
TONE_THRESH;
01076 e *=
TONE_THRESH;
01077
01078
if ((p1 < i1) || (p1 < i2) || (p1 < e))
01079
return 0;
01080
01081
if ((p2 < i1) || (p2 < i2) || (p2 < e))
01082
return 0;
01083
01084
return 1;
01085 }
01086
01087 int ast_dsp_getdigits (
struct ast_dsp *dsp,
01088
char *buf,
01089
int max)
01090 {
01091
if (dsp->
digitmode &
DSP_DIGITMODE_MF) {
01092
if (max > dsp->
td.mf.current_digits)
01093 max = dsp->
td.mf.current_digits;
01094
if (max > 0)
01095 {
01096 memcpy (buf, dsp->
td.mf.digits, max);
01097 memmove (dsp->
td.mf.digits, dsp->
td.mf.digits + max, dsp->
td.mf.current_digits - max);
01098 dsp->
td.mf.current_digits -= max;
01099 }
01100 buf[max] =
'\0';
01101
return max;
01102 }
else {
01103
if (max > dsp->
td.dtmf.current_digits)
01104 max = dsp->
td.dtmf.current_digits;
01105
if (max > 0)
01106 {
01107 memcpy (buf, dsp->
td.dtmf.digits, max);
01108 memmove (dsp->
td.dtmf.digits, dsp->
td.dtmf.digits + max, dsp->
td.dtmf.current_digits - max);
01109 dsp->
td.dtmf.current_digits -= max;
01110 }
01111 buf[max] =
'\0';
01112
return max;
01113 }
01114 }
01115
01116
static int __ast_dsp_call_progress(
struct ast_dsp *dsp,
short *s,
int len)
01117 {
01118
int x;
01119
int y;
01120
int pass;
01121
int newstate =
TONE_STATE_SILENCE;
01122
int res = 0;
01123
while(len) {
01124
01125 pass = len;
01126
if (pass > dsp->
gsamp_size - dsp->
gsamps)
01127 pass = dsp->
gsamp_size - dsp->
gsamps;
01128
for (x=0;x<pass;x++) {
01129
for (y=0;y<dsp->
freqcount;y++)
01130 goertzel_sample(&dsp->
freqs[y], s[x]);
01131 dsp->
genergy +=
s[x] *
s[x];
01132 }
01133
s += pass;
01134 dsp->
gsamps += pass;
01135 len -= pass;
01136
if (dsp->
gsamps == dsp->
gsamp_size) {
01137
float hz[7];
01138
for (y=0;y<7;y++)
01139 hz[y] = goertzel_result(&dsp->
freqs[y]);
01140
#if 0
01141
printf(
"Got whole dsp state: 350: %e, 440: %e, 480: %e, 620: %e, 950: %e, 1400: %e, 1800: %e, Energy: %e\n",
01142 hz_350, hz_440, hz_480, hz_620, hz_950, hz_1400, hz_1800, dsp->
genergy);
01143
#endif
01144
switch(dsp->
progmode) {
01145
case PROG_MODE_NA:
01146
if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->
genergy)) {
01147 newstate =
TONE_STATE_BUSY;
01148 }
else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->
genergy)) {
01149 newstate =
TONE_STATE_RINGING;
01150 }
else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->
genergy)) {
01151 newstate =
TONE_STATE_DIALTONE;
01152 }
else if (hz[
HZ_950] >
TONE_MIN_THRESH *
TONE_THRESH) {
01153 newstate =
TONE_STATE_SPECIAL1;
01154 }
else if (hz[
HZ_1400] >
TONE_MIN_THRESH *
TONE_THRESH) {
01155
if (dsp->
tstate ==
TONE_STATE_SPECIAL1)
01156 newstate =
TONE_STATE_SPECIAL2;
01157 }
else if (hz[
HZ_1800] >
TONE_MIN_THRESH *
TONE_THRESH) {
01158
if (dsp->
tstate ==
TONE_STATE_SPECIAL2)
01159 newstate =
TONE_STATE_SPECIAL3;
01160 }
else if (dsp->
genergy >
TONE_MIN_THRESH *
TONE_THRESH) {
01161 newstate =
TONE_STATE_TALKING;
01162 }
else
01163 newstate =
TONE_STATE_SILENCE;
01164
break;
01165
case PROG_MODE_CR:
01166
if (hz[
HZ_425] >
TONE_MIN_THRESH *
TONE_THRESH) {
01167 newstate =
TONE_STATE_RINGING;
01168 }
else if (dsp->
genergy >
TONE_MIN_THRESH *
TONE_THRESH) {
01169 newstate =
TONE_STATE_TALKING;
01170 }
else
01171 newstate =
TONE_STATE_SILENCE;
01172
break;
01173
default:
01174
ast_log(LOG_WARNING,
"Can't process in unknown prog mode '%d'\n", dsp->
progmode);
01175 }
01176
if (newstate == dsp->
tstate) {
01177 dsp->
tcount++;
01178
if (dsp->
tcount ==
COUNT_THRESH) {
01179
if (dsp->
tstate ==
TONE_STATE_BUSY) {
01180 res =
AST_CONTROL_BUSY;
01181 dsp->
features &= ~
DSP_FEATURE_CALL_PROGRESS;
01182 }
else if (dsp->
tstate ==
TONE_STATE_TALKING) {
01183 res =
AST_CONTROL_ANSWER;
01184 dsp->
features &= ~
DSP_FEATURE_CALL_PROGRESS;
01185 }
else if (dsp->
tstate ==
TONE_STATE_RINGING)
01186 res =
AST_CONTROL_RINGING;
01187
else if (dsp->
tstate ==
TONE_STATE_SPECIAL3) {
01188 res =
AST_CONTROL_CONGESTION;
01189 dsp->
features &= ~
DSP_FEATURE_CALL_PROGRESS;
01190 }
01191
01192 }
01193 }
else {
01194
#if 0
01195
printf(
"Newstate: %d\n", newstate);
01196
#endif
01197
dsp->
tstate = newstate;
01198 dsp->
tcount = 1;
01199 }
01200
01201
01202
for (x=0;x<7;x++)
01203 dsp->
freqs[x].
v2 = dsp->
freqs[x].
v3 = 0.0;
01204 dsp->
gsamps = 0;
01205 dsp->
genergy = 0.0;
01206 }
01207 }
01208
#if 0
01209
if (res)
01210 printf(
"Returning %d\n", res);
01211
#endif
01212
return res;
01213 }
01214
01215 int ast_dsp_call_progress(
struct ast_dsp *dsp,
struct ast_frame *inf)
01216 {
01217
if (inf->
frametype !=
AST_FRAME_VOICE) {
01218
ast_log(
LOG_WARNING,
"Can't check call progress of non-voice frames\n");
01219
return 0;
01220 }
01221
if (inf->
subclass !=
AST_FORMAT_SLINEAR) {
01222
ast_log(
LOG_WARNING,
"Can only check call progress in signed-linear frames\n");
01223
return 0;
01224 }
01225
return __ast_dsp_call_progress(dsp, inf->
data, inf->
datalen / 2);
01226 }
01227
01228
static int __ast_dsp_silence(
struct ast_dsp *dsp,
short *s,
int len,
int *totalsilence)
01229 {
01230
int accum;
01231
int x;
01232
int res = 0;
01233
01234 accum = 0;
01235
for (x=0;x<len; x++)
01236 accum += abs(s[x]);
01237 accum /= len;
01238
if (accum < dsp->
threshold) {
01239 dsp->
totalsilence += len/8;
01240
if (dsp->
totalnoise) {
01241
01242 memmove(dsp->
historicnoise + DSP_HISTORY - dsp->
busycount, dsp->
historicnoise + DSP_HISTORY - dsp->
busycount +1, dsp->
busycount*
sizeof(dsp->
historicnoise[0]));
01243 dsp->
historicnoise[
DSP_HISTORY - 1] = dsp->
totalnoise;
01244
01245
#if 0
01246
dsp->
busymaybe = 1;
01247
#endif
01248
}
01249 dsp->
totalnoise = 0;
01250 res = 1;
01251 }
else {
01252 dsp->
totalnoise += len/8;
01253
if (dsp->
totalsilence) {
01254
int silence1 = dsp->
historicsilence[
DSP_HISTORY - 1];
01255
int silence2 = dsp->
historicsilence[
DSP_HISTORY - 2];
01256
01257 memmove(dsp->
historicsilence + DSP_HISTORY - dsp->
busycount, dsp->
historicsilence + DSP_HISTORY - dsp->
busycount + 1, dsp->
busycount*
sizeof(dsp->
historicsilence[0]));
01258 dsp->
historicsilence[
DSP_HISTORY - 1] = dsp->
totalsilence;
01259
01260
if (silence1 < silence2) {
01261
if (silence1 + silence1/
BUSY_PERCENT >= silence2)
01262 dsp->
busymaybe = 1;
01263
else
01264 dsp->
busymaybe = 0;
01265 }
else {
01266
if (silence1 - silence1/
BUSY_PERCENT <= silence2)
01267 dsp->
busymaybe = 1;
01268
else
01269 dsp->
busymaybe = 0;
01270 }
01271
01272 }
01273 dsp->
totalsilence = 0;
01274 }
01275
if (totalsilence)
01276 *totalsilence = dsp->
totalsilence;
01277
return res;
01278 }
01279
#ifdef BUSYDETECT_MARTIN
01280
int ast_dsp_busydetect(
struct ast_dsp *dsp)
01281 {
01282
int res = 0, x;
01283
#ifndef BUSYDETECT_TONEONLY
01284
int avgsilence = 0, hitsilence = 0;
01285
#endif
01286
int avgtone = 0, hittone = 0;
01287
if (!dsp->
busymaybe)
01288
return res;
01289
for (x=
DSP_HISTORY - dsp->
busycount;x<
DSP_HISTORY;x++) {
01290
#ifndef BUSYDETECT_TONEONLY
01291
avgsilence += dsp->
historicsilence[x];
01292
#endif
01293
avgtone += dsp->
historicnoise[x];
01294 }
01295
#ifndef BUSYDETECT_TONEONLY
01296
avgsilence /= dsp->
busycount;
01297
#endif
01298
avgtone /= dsp->
busycount;
01299
for (x=
DSP_HISTORY - dsp->
busycount;x<
DSP_HISTORY;x++) {
01300
#ifndef BUSYDETECT_TONEONLY
01301
if (avgsilence > dsp->
historicsilence[x]) {
01302
if (avgsilence - (avgsilence /
BUSY_PERCENT) <= dsp->
historicsilence[x])
01303 hitsilence++;
01304 }
else {
01305
if (avgsilence + (avgsilence /
BUSY_PERCENT) >= dsp->
historicsilence[x])
01306 hitsilence++;
01307 }
01308
#endif
01309
if (avgtone > dsp->
historicnoise[x]) {
01310
if (avgtone - (avgtone /
BUSY_PERCENT) <= dsp->
historicsilence[x])
01311 hittone++;
01312 }
else {
01313
if (avgtone + (avgtone /
BUSY_PERCENT) >= dsp->
historicsilence[x])
01314 hittone++;
01315 }
01316 }
01317
#ifndef BUSYDETECT_TONEONLY
01318
if ((hittone >= dsp->
busycount - 1) && (hitsilence >= dsp->
busycount - 1) && (avgtone >=
BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >=
BUSY_MIN && avgsilence <=
BUSY_MAX)) {
01319
#else
01320
if ((hittone >= dsp->
busycount - 1) && (avgtone >=
BUSY_MIN && avgtone <=
BUSY_MAX)) {
01321
#endif
01322
#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01323
#ifdef BUSYDETECT_TONEONLY
01324
#error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01325
#endif
01326
if (avgtone > avgsilence) {
01327
if (avgtone - avgtone/(
BUSY_PERCENT*2) <= avgsilence)
01328 res = 1;
01329 }
else {
01330
if (avgtone + avgtone/(
BUSY_PERCENT*2) >= avgsilence)
01331 res = 1;
01332 }
01333
#else
01334
res = 1;
01335
#endif
01336
}
01337
#if 0
01338
if (res)
01339
ast_log(LOG_NOTICE,
"detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01340
#endif
01341
return res;
01342 }
01343
#endif
01344
01345
#ifdef BUSYDETECT
01346
int ast_dsp_busydetect(
struct ast_dsp *dsp)
01347 {
01348
int x;
01349
int res = 0;
01350
int max, min;
01351
01352
#if 0
01353
if (dsp->busy_hits > 5);
01354
return 0;
01355
#endif
01356
if (dsp->
busymaybe) {
01357
#if 0
01358
printf(
"Maybe busy!\n");
01359
#endif
01360
dsp->
busymaybe = 0;
01361 min = 9999;
01362 max = 0;
01363
for (x=
DSP_HISTORY - dsp->
busycount;x<
DSP_HISTORY;x++) {
01364
#if 0
01365
printf(
"Silence: %d, Noise: %d\n", dsp->
historicsilence[x], dsp->
historicnoise[x]);
01366
#endif
01367
if (dsp->
historicsilence[x] < min)
01368 min = dsp->
historicsilence[x];
01369
if (dsp->
historicnoise[x] < min)
01370 min = dsp->
historicnoise[x];
01371
if (dsp->
historicsilence[x] > max)
01372 max = dsp->
historicsilence[x];
01373
if (dsp->
historicnoise[x] > max)
01374 max = dsp->
historicnoise[x];
01375 }
01376
if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min >
BUSY_MIN)) {
01377
#if 0
01378
printf(
"Busy!\n");
01379
#endif
01380
res = 1;
01381 }
01382
#if 0
01383
printf(
"Min: %d, max: %d\n", min, max);
01384
#endif
01385
}
01386
return res;
01387 }
01388
#endif
01389
01390 int ast_dsp_silence(
struct ast_dsp *dsp,
struct ast_frame *f,
int *totalsilence)
01391 {
01392
short *
s;
01393
int len;
01394
01395
if (f->
frametype !=
AST_FRAME_VOICE) {
01396
ast_log(
LOG_WARNING,
"Can't calculate silence on a non-voice frame\n");
01397
return 0;
01398 }
01399
if (f->
subclass !=
AST_FORMAT_SLINEAR) {
01400
ast_log(
LOG_WARNING,
"Can only calculate silence on signed-linear frames :(\n");
01401
return 0;
01402 }
01403
s = f->
data;
01404 len = f->
datalen/2;
01405
return __ast_dsp_silence(dsp,
s, len, totalsilence);
01406 }
01407
01408 struct ast_frame *
ast_dsp_process(
struct ast_channel *chan,
struct ast_dsp *dsp,
struct ast_frame *af)
01409 {
01410
int silence;
01411
int res;
01412
int digit;
01413
int x;
01414
unsigned short *shortdata;
01415
unsigned char *odata;
01416
int len;
01417
int writeback = 0;
01418
01419
#define FIX_INF(inf) do { \
01420
if (writeback) { \
01421
switch(inf->subclass) { \
01422
case AST_FORMAT_SLINEAR: \
01423
break; \
01424
case AST_FORMAT_ULAW: \
01425
for (x=0;x<len;x++) \
01426
odata[x] = AST_LIN2MU(shortdata[x]); \
01427
break; \
01428
case AST_FORMAT_ALAW: \
01429
for (x=0;x<len;x++) \
01430
odata[x] = AST_LIN2A(shortdata[x]); \
01431
break; \
01432
} \
01433
} \
01434
} while(0)
01435
01436
if (!af)
01437
return NULL;
01438
if (af->
frametype !=
AST_FRAME_VOICE)
01439
return af;
01440 odata = af->
data;
01441 len = af->
datalen;
01442
01443
switch(af->
subclass) {
01444
case AST_FORMAT_SLINEAR:
01445 shortdata = af->
data;
01446 len = af->
datalen / 2;
01447
break;
01448
case AST_FORMAT_ULAW:
01449 shortdata = alloca(af->
datalen * 2);
01450
if (!shortdata) {
01451
ast_log(
LOG_WARNING,
"Unable to allocate stack space for data: %s\n", strerror(errno));
01452
return af;
01453 }
01454
for (x=0;x<len;x++)
01455 shortdata[x] =
AST_MULAW(odata[x]);
01456
break;
01457
case AST_FORMAT_ALAW:
01458 shortdata = alloca(af->
datalen * 2);
01459
if (!shortdata) {
01460
ast_log(
LOG_WARNING,
"Unable to allocate stack space for data: %s\n", strerror(errno));
01461
return af;
01462 }
01463
for (x=0;x<len;x++)
01464 shortdata[x] =
AST_ALAW(odata[x]);
01465
break;
01466
default:
01467
ast_log(
LOG_WARNING,
"Unable to process inband DTMF on %d frames\n", af->
subclass);
01468
return af;
01469 }
01470 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01471
if ((dsp->
features &
DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01472 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01473 dsp->
f.
frametype =
AST_FRAME_NULL;
01474
return &dsp->
f;
01475 }
01476
if ((dsp->
features &
DSP_FEATURE_BUSY_DETECT) &&
ast_dsp_busydetect(dsp)) {
01477 chan->
_softhangup |=
AST_SOFTHANGUP_DEV;
01478 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01479 dsp->
f.
frametype =
AST_FRAME_CONTROL;
01480 dsp->
f.
subclass =
AST_CONTROL_BUSY;
01481
ast_log(
LOG_DEBUG,
"Requesting Hangup because the busy tone was detected on channel %s\n", chan->
name);
01482
return &dsp->
f;
01483 }
01484
if ((dsp->
features &
DSP_FEATURE_DTMF_DETECT)) {
01485 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01486
#if 0
01487
if (digit)
01488 printf(
"Performing digit detection returned %d, digitmode is %d\n", digit, dsp->
digitmode);
01489
#endif
01490
if (dsp->
digitmode & (
DSP_DIGITMODE_MUTECONF |
DSP_DIGITMODE_MUTEMAX)) {
01491
if (!dsp->
thinkdigit) {
01492
if (digit) {
01493
01494 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01495 dsp->
f.
frametype =
AST_FRAME_DTMF;
01496 dsp->
f.
subclass =
'm';
01497 dsp->
thinkdigit =
'x';
01498
FIX_INF(af);
01499
if (chan)
01500
ast_queue_frame(chan, af);
01501
ast_frfree(af);
01502
return &dsp->
f;
01503 }
01504 }
else {
01505
if (digit) {
01506
01507
if (dsp->
thinkdigit) {
01508
if ((dsp->
thinkdigit !=
'x') && (dsp->
thinkdigit != digit)) {
01509
01510
01511
01512 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01513 dsp->
f.
frametype =
AST_FRAME_DTMF;
01514 dsp->
f.
subclass = dsp->
thinkdigit;
01515
FIX_INF(af);
01516
if (chan)
01517
ast_queue_frame(chan, af);
01518
ast_frfree(af);
01519 }
01520 dsp->
thinkdigit = digit;
01521
return &dsp->
f;
01522 }
01523 dsp->
thinkdigit = digit;
01524 }
else {
01525
if (dsp->
thinkdigit) {
01526 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01527
if (dsp->
thinkdigit !=
'x') {
01528
01529 dsp->
f.
frametype =
AST_FRAME_DTMF;
01530 dsp->
f.
subclass = dsp->
thinkdigit;
01531 dsp->
thinkdigit = 0;
01532 }
else {
01533 dsp->
f.
frametype =
AST_FRAME_DTMF;
01534 dsp->
f.
subclass =
'u';
01535 dsp->
thinkdigit = 0;
01536 }
01537
FIX_INF(af);
01538
if (chan)
01539
ast_queue_frame(chan, af);
01540
ast_frfree(af);
01541
return &dsp->
f;
01542 }
01543 }
01544 }
01545 }
else if (!digit) {
01546
01547
if (dsp->
digitmode &
DSP_DIGITMODE_MF) {
01548
if (dsp->
td.mf.current_digits) {
01549 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01550 dsp->
f.
frametype =
AST_FRAME_DTMF;
01551 dsp->
f.
subclass = dsp->
td.mf.digits[0];
01552 memmove(dsp->
td.mf.digits, dsp->
td.mf.digits + 1, dsp->
td.mf.current_digits);
01553 dsp->
td.mf.current_digits--;
01554
FIX_INF(af);
01555
if (chan)
01556
ast_queue_frame(chan, af);
01557
ast_frfree(af);
01558
return &dsp->
f;
01559 }
01560 }
else {
01561
if (dsp->
td.dtmf.current_digits) {
01562 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01563 dsp->
f.
frametype =
AST_FRAME_DTMF;
01564 dsp->
f.
subclass = dsp->
td.dtmf.digits[0];
01565 memmove(dsp->
td.dtmf.digits, dsp->
td.dtmf.digits + 1, dsp->
td.dtmf.current_digits);
01566 dsp->
td.dtmf.current_digits--;
01567
FIX_INF(af);
01568
if (chan)
01569
ast_queue_frame(chan, af);
01570
ast_frfree(af);
01571
return &dsp->
f;
01572 }
01573 }
01574 }
01575 }
01576
if ((dsp->
features &
DSP_FEATURE_CALL_PROGRESS)) {
01577 res = __ast_dsp_call_progress(dsp, shortdata, len);
01578 memset(&dsp->
f, 0,
sizeof(dsp->
f));
01579 dsp->
f.
frametype =
AST_FRAME_CONTROL;
01580
if (res) {
01581
switch(res) {
01582
case AST_CONTROL_ANSWER:
01583
case AST_CONTROL_BUSY:
01584
case AST_CONTROL_RINGING:
01585
case AST_CONTROL_CONGESTION:
01586 dsp->
f.
subclass = res;
01587
if (chan)
01588
ast_queue_frame(chan, &dsp->
f);
01589
break;
01590
default:
01591
ast_log(
LOG_WARNING,
"Don't know how to represent call progress message %d\n", res);
01592 }
01593 }
01594 }
01595
FIX_INF(af);
01596
return af;
01597 }
01598
01599
static void ast_dsp_prog_reset(
struct ast_dsp *dsp)
01600 {
01601
int max = 0;
01602
int x;
01603 dsp->
gsamp_size = modes[dsp->
progmode].size;
01604 dsp->
gsamps = 0;
01605
for (x=0;x<
sizeof(modes[dsp->
progmode].freqs) /
sizeof(modes[dsp->
progmode].freqs[0]);x++) {
01606
if (modes[dsp->
progmode].freqs[x]) {
01607 goertzel_init(&dsp->
freqs[x], (
float)modes[dsp->
progmode].freqs[x], dsp->
gsamp_size);
01608 max = x;
01609 }
01610 }
01611 dsp->
freqcount = max;
01612 }
01613
01614 struct ast_dsp *
ast_dsp_new(
void)
01615 {
01616
struct ast_dsp *dsp;
01617 dsp =
malloc(
sizeof(
struct ast_dsp));
01618
if (dsp) {
01619 memset(dsp, 0,
sizeof(
struct ast_dsp));
01620 dsp->
threshold =
DEFAULT_THRESHOLD;
01621 dsp->
features =
DSP_FEATURE_SILENCE_SUPPRESS;
01622 dsp->
busycount =
DSP_HISTORY;
01623
01624 ast_dtmf_detect_init(&dsp->
td.dtmf);
01625
01626 ast_dsp_prog_reset(dsp);
01627 }
01628
return dsp;
01629 }
01630
01631 void ast_dsp_set_features(
struct ast_dsp *dsp,
int features)
01632 {
01633 dsp->
features = features;
01634 }
01635
01636 void ast_dsp_free(
struct ast_dsp *dsp)
01637 {
01638
free(dsp);
01639 }
01640
01641 void ast_dsp_set_threshold(
struct ast_dsp *dsp,
int threshold)
01642 {
01643 dsp->
threshold = threshold;
01644 }
01645
01646 void ast_dsp_set_busy_count(
struct ast_dsp *dsp,
int cadences)
01647 {
01648
if (cadences < 4)
01649 cadences = 4;
01650
if (cadences >
DSP_HISTORY)
01651 cadences =
DSP_HISTORY;
01652 dsp->
busycount = cadences;
01653 }
01654
01655 void ast_dsp_digitreset(
struct ast_dsp *dsp)
01656 {
01657
int i;
01658 dsp->
thinkdigit = 0;
01659
if (dsp->
digitmode &
DSP_DIGITMODE_MF) {
01660 memset(dsp->
td.mf.digits, 0,
sizeof(dsp->
td.mf.digits));
01661 dsp->
td.mf.current_digits = 0;
01662
01663
for (i = 0; i < 6; i++) {
01664 goertzel_reset(&dsp->
td.mf.tone_out[i]);
01665
#ifdef OLD_DSP_ROUTINES
01666
goertzel_reset(&dsp->
td.mf.tone_out2nd[i]);
01667
#endif
01668
}
01669
#ifdef OLD_DSP_ROUTINES
01670
dsp->
td.mf.energy = 0.0;
01671 dsp->
td.mf.hit1 = dsp->
td.mf.hit2 = dsp->
td.mf.hit3 = dsp->
td.mf.hit4 = dsp->
td.mf.mhit = 0;
01672
#else
01673
dsp->
td.mf.hits[4] = dsp->
td.mf.hits[3] = dsp->
td.mf.hits[2] = dsp->
td.mf.hits[1] = dsp->
td.mf.hits[0] = dsp->
td.mf.mhit = 0;
01674
#endif
01675
dsp->
td.mf.current_sample = 0;
01676 }
else {
01677 memset(dsp->
td.dtmf.digits, 0,
sizeof(dsp->
td.dtmf.digits));
01678 dsp->
td.dtmf.current_digits = 0;
01679
01680
for (i = 0; i < 4; i++) {
01681 goertzel_reset(&dsp->
td.dtmf.row_out[i]);
01682 goertzel_reset(&dsp->
td.dtmf.col_out[i]);
01683
#ifdef OLD_DSP_ROUTINES
01684
goertzel_reset(&dsp->
td.dtmf.row_out2nd[i]);
01685 goertzel_reset(&dsp->
td.dtmf.col_out2nd[i]);
01686
#endif
01687
}
01688
#ifdef FAX_DETECT
01689
goertzel_reset (&dsp->
td.dtmf.fax_tone);
01690
#endif
01691
#ifdef OLD_DSP_ROUTINES
01692
#ifdef FAX_DETECT
01693
goertzel_reset (&dsp->
td.dtmf.fax_tone2nd);
01694
#endif
01695
dsp->
td.dtmf.hit1 = dsp->
td.dtmf.hit2 = dsp->
td.dtmf.hit3 = dsp->
td.dtmf.hit4 = dsp->
td.dtmf.mhit = 0;
01696
#else
01697
dsp->
td.dtmf.hits[2] = dsp->
td.dtmf.hits[1] = dsp->
td.dtmf.hits[0] = dsp->
td.dtmf.mhit = 0;
01698
#endif
01699
dsp->
td.dtmf.energy = 0.0;
01700 dsp->
td.dtmf.current_sample = 0;
01701 }
01702 }
01703
01704 void ast_dsp_reset(
struct ast_dsp *dsp)
01705 {
01706
int x;
01707 dsp->
totalsilence = 0;
01708 dsp->
gsamps = 0;
01709
for (x=0;x<4;x++)
01710 dsp->
freqs[x].
v2 = dsp->
freqs[x].
v3 = 0.0;
01711 memset(dsp->
historicsilence, 0,
sizeof(dsp->
historicsilence));
01712 memset(dsp->
historicnoise, 0,
sizeof(dsp->
historicnoise));
01713
01714 }
01715
01716 int ast_dsp_digitmode(
struct ast_dsp *dsp,
int digitmode)
01717 {
01718
int new, old;
01719 old = dsp->
digitmode & (
DSP_DIGITMODE_DTMF |
DSP_DIGITMODE_MF |
DSP_DIGITMODE_MUTECONF |
DSP_DIGITMODE_MUTEMAX);
01720
new = digitmode & (
DSP_DIGITMODE_DTMF |
DSP_DIGITMODE_MF |
DSP_DIGITMODE_MUTECONF |
DSP_DIGITMODE_MUTEMAX);
01721
if (old !=
new) {
01722
01723
if (
new &
DSP_DIGITMODE_MF)
01724 ast_mf_detect_init(&dsp->
td.mf);
01725
else
01726 ast_dtmf_detect_init(&dsp->
td.dtmf);
01727 }
01728 dsp->
digitmode = digitmode;
01729
return 0;
01730 }
01731
01732 int ast_dsp_set_call_progress_zone(
struct ast_dsp *dsp,
char *zone)
01733 {
01734
int x;
01735
for (x=0;x<
sizeof(aliases) /
sizeof(aliases[0]);x++) {
01736
if (!strcasecmp(aliases[x].name, zone)) {
01737 dsp->
progmode = aliases[x].mode;
01738 ast_dsp_prog_reset(dsp);
01739
return 0;
01740 }
01741 }
01742
return -1;
01743 }