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