Go to the source code of this file.
Defines | |
| #define | DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
| #define | DSP_FEATURE_BUSY_DETECT (1 << 1) |
| #define | DSP_FEATURE_CALL_PROGRESS (1 << 2) |
| #define | DSP_FEATURE_DTMF_DETECT (1 << 3) |
| #define | DSP_DIGITMODE_DTMF 0 |
| #define | DSP_DIGITMODE_MF 1 |
| #define | DSP_DIGITMODE_NOQUELCH (1 << 8) |
| #define | DSP_DIGITMODE_MUTECONF (1 << 9) |
| #define | DSP_DIGITMODE_MUTEMAX (1 << 10) |
| #define | DSP_DIGITMODE_RELAXDTMF (1 << 11) |
Functions | |
| ast_dsp * | ast_dsp_new (void) |
| void | ast_dsp_free (struct ast_dsp *dsp) |
| void | ast_dsp_set_threshold (struct ast_dsp *dsp, int threshold) |
| void | ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences) |
| int | ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf) |
| ast_frame * | ast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf, int needlock) |
| int | ast_dsp_silence (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence) |
| int | ast_dsp_busydetect (struct ast_dsp *dsp) |
| int | ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f) |
| void | ast_dsp_reset (struct ast_dsp *dsp) |
| void | ast_dsp_digitreset (struct ast_dsp *dsp) |
| void | ast_dsp_set_features (struct ast_dsp *dsp, int features) |
| int | ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max) |
| int | ast_dsp_digitmode (struct ast_dsp *dsp, int digitmode) |
|
|
Definition at line 22 of file dsp.h. Referenced by ast_dsp_digitmode(). |
|
|
Definition at line 23 of file dsp.h. Referenced by ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_getdigits(), and ast_dsp_process(). |
|
|
Definition at line 26 of file dsp.h. Referenced by ast_dsp_digitmode(), and ast_dsp_process(). |
|
|
Definition at line 27 of file dsp.h. Referenced by ast_dsp_digitmode(), and ast_dsp_process(). |
|
|
|
|
|
|
|
|
Definition at line 18 of file dsp.h. Referenced by ast_dsp_process(). |
|
|
Definition at line 19 of file dsp.h. Referenced by ast_dsp_process(). |
|
|
Definition at line 20 of file dsp.h. Referenced by ast_dsp_process(). |
|
|
Definition at line 17 of file dsp.h. Referenced by ast_dsp_new(), and ast_dsp_process(). |
|
|
Referenced by ast_dsp_process(). |
|
||||||||||||
|
Definition at line 946 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.
00947 {
00948 if (inf->frametype != AST_FRAME_VOICE) {
00949 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00950 return 0;
00951 }
00952 if (inf->subclass != AST_FORMAT_SLINEAR) {
00953 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00954 return 0;
00955 }
00956 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
00957 }
|
|
||||||||||||
|
Definition at line 778 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.
00779 {
00780 short *s;
00781 int len;
00782 int ign=0;
00783 if (inf->frametype != AST_FRAME_VOICE) {
00784 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00785 return 0;
00786 }
00787 if (inf->subclass != AST_FORMAT_SLINEAR) {
00788 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00789 return 0;
00790 }
00791 s = inf->data;
00792 len = inf->datalen / 2;
00793 return __ast_dsp_digitdetect(dsp, s, len, &ign);
00794 }
|
|
||||||||||||
|
Definition at line 1422 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, and ast_dsp::td.
01423 {
01424 int new, old;
01425 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01426 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01427 if (old != new) {
01428 /* Must initialize structures if switching from MF to DTMF or vice-versa */
01429 if (new & DSP_DIGITMODE_MF)
01430 ast_mf_detect_init(&dsp->td.mf);
01431 else
01432 ast_dtmf_detect_init(&dsp->td.dtmf);
01433 }
01434 dsp->digitmode = digitmode;
01435 return 0;
01436 }
|
|
|
Definition at line 1377 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, ast_dsp::td, and ast_dsp::thinkdigit.
01378 {
01379 int i;
01380 dsp->thinkdigit = 0;
01381 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01382 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01383 dsp->td.mf.current_digits = 0;
01384 /* Reinitialise the detector for the next block */
01385 for (i = 0; i < 6; i++) {
01386 goertzel_reset(&dsp->td.mf.tone_out[i]);
01387 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01388 }
01389 dsp->td.mf.energy = 0.0;
01390 dsp->td.mf.current_sample = 0;
01391 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01392 } else {
01393 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01394 dsp->td.dtmf.current_digits = 0;
01395 /* Reinitialise the detector for the next block */
01396 for (i = 0; i < 4; i++) {
01397 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01398 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01399 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01400 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01401 }
01402 goertzel_reset (&dsp->td.dtmf.fax_tone);
01403 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01404 dsp->td.dtmf.energy = 0.0;
01405 dsp->td.dtmf.current_sample = 0;
01406 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01407 }
01408 }
|
|
|
Definition at line 1358 of file dsp.c. References free. Referenced by ast_app_getvoice().
01359 {
01360 free(dsp);
01361 }
|
|
||||||||||||||||
|
Definition at line 816 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, and ast_dsp::td.
00819 {
00820 if (dsp->digitmode & DSP_DIGITMODE_MF) {
00821 if (max > dsp->td.mf.current_digits)
00822 max = dsp->td.mf.current_digits;
00823 if (max > 0)
00824 {
00825 memcpy (buf, dsp->td.mf.digits, max);
00826 memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
00827 dsp->td.mf.current_digits -= max;
00828 }
00829 buf[max] = '\0';
00830 return max;
00831 } else {
00832 if (max > dsp->td.dtmf.current_digits)
00833 max = dsp->td.dtmf.current_digits;
00834 if (max > 0)
00835 {
00836 memcpy (buf, dsp->td.dtmf.digits, max);
00837 memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
00838 dsp->td.dtmf.current_digits -= max;
00839 }
00840 buf[max] = '\0';
00841 return max;
00842 }
00843 }
|
|
|
Definition at line 1330 of file dsp.c. References ast_dsp::busycount, DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::features, ast_dsp::freqs, HZ_1400, HZ_1800, HZ_350, HZ_440, HZ_480, HZ_620, HZ_950, malloc, ast_dsp::td, and ast_dsp::threshold. Referenced by ast_app_getvoice().
01331 {
01332 struct ast_dsp *dsp;
01333 dsp = malloc(sizeof(struct ast_dsp));
01334 if (dsp) {
01335 memset(dsp, 0, sizeof(struct ast_dsp));
01336 dsp->threshold = DEFAULT_THRESHOLD;
01337 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01338 dsp->busycount = DSP_HISTORY;
01339 /* Initialize goertzels */
01340 goertzel_init(&dsp->freqs[HZ_350], 350.0);
01341 goertzel_init(&dsp->freqs[HZ_440], 440.0);
01342 goertzel_init(&dsp->freqs[HZ_480], 480.0);
01343 goertzel_init(&dsp->freqs[HZ_620], 620.0);
01344 goertzel_init(&dsp->freqs[HZ_950], 950.0);
01345 goertzel_init(&dsp->freqs[HZ_1400], 1400.0);
01346 goertzel_init(&dsp->freqs[HZ_1800], 1800.0);
01347 /* Initialize DTMF detector */
01348 ast_dtmf_detect_init(&dsp->td.dtmf);
01349 }
01350 return dsp;
01351 }
|
|
||||||||||||||||||||
|
Definition at line 1139 of file dsp.c. References ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, ast_frame::datalen, ast_dsp::digitmode, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::f, ast_dsp::features, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.
01140 {
01141 int silence;
01142 int res;
01143 int digit;
01144 int x;
01145 unsigned short *shortdata;
01146 unsigned char *odata;
01147 int len;
01148 int writeback = 0;
01149
01150 #define FIX_INF(inf) do { \
01151 if (writeback) { \
01152 switch(inf->subclass) { \
01153 case AST_FORMAT_SLINEAR: \
01154 break; \
01155 case AST_FORMAT_ULAW: \
01156 for (x=0;x<len;x++) \
01157 odata[x] = AST_LIN2MU(shortdata[x]); \
01158 break; \
01159 case AST_FORMAT_ALAW: \
01160 for (x=0;x<len;x++) \
01161 odata[x] = AST_LIN2A(shortdata[x]); \
01162 break; \
01163 } \
01164 } \
01165 } while(0)
01166
01167 if (!af)
01168 return NULL;
01169 if (af->frametype != AST_FRAME_VOICE)
01170 return af;
01171 odata = af->data;
01172 len = af->datalen;
01173 /* Make sure we have short data */
01174 switch(af->subclass) {
01175 case AST_FORMAT_SLINEAR:
01176 shortdata = af->data;
01177 len = af->datalen / 2;
01178 break;
01179 case AST_FORMAT_ULAW:
01180 shortdata = alloca(af->datalen * 2);
01181 if (!shortdata) {
01182 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01183 return af;
01184 }
01185 for (x=0;x<len;x++)
01186 shortdata[x] = AST_MULAW(odata[x]);
01187 break;
01188 case AST_FORMAT_ALAW:
01189 shortdata = alloca(af->datalen * 2);
01190 if (!shortdata) {
01191 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01192 return af;
01193 }
01194 for (x=0;x<len;x++)
01195 shortdata[x] = AST_ALAW(odata[x]);
01196 break;
01197 default:
01198 ast_log(LOG_WARNING, "Unable to detect process %d frames\n", af->subclass);
01199 return af;
01200 }
01201 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01202 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01203 memset(&dsp->f, 0, sizeof(dsp->f));
01204 dsp->f.frametype = AST_FRAME_NULL;
01205 return &dsp->f;
01206 }
01207 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01208 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01209 memset(&dsp->f, 0, sizeof(dsp->f));
01210 dsp->f.frametype = AST_FRAME_CONTROL;
01211 dsp->f.subclass = AST_CONTROL_BUSY;
01212 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01213 return &dsp->f;
01214 }
01215 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01216 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01217 #if 0
01218 if (digit)
01219 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01220 #endif
01221 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01222 if (!dsp->thinkdigit) {
01223 if (digit) {
01224 /* Looks like we might have something. Request a conference mute for the moment */
01225 memset(&dsp->f, 0, sizeof(dsp->f));
01226 dsp->f.frametype = AST_FRAME_DTMF;
01227 dsp->f.subclass = 'm';
01228 dsp->thinkdigit = 'x';
01229 FIX_INF(af);
01230 if (chan)
01231 ast_queue_frame(chan, af, needlock);
01232 ast_frfree(af);
01233 return &dsp->f;
01234 }
01235 } else {
01236 if (digit) {
01237 /* Thought we saw one last time. Pretty sure we really have now */
01238 if (dsp->thinkdigit) {
01239 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01240 /* If we found a digit, and we're changing digits, go
01241 ahead and send this one, but DON'T stop confmute because
01242 we're detecting something else, too... */
01243 memset(&dsp->f, 0, sizeof(dsp->f));
01244 dsp->f.frametype = AST_FRAME_DTMF;
01245 dsp->f.subclass = dsp->thinkdigit;
01246 FIX_INF(af);
01247 if (chan)
01248 ast_queue_frame(chan, af, needlock);
01249 ast_frfree(af);
01250 }
01251 dsp->thinkdigit = digit;
01252 return &dsp->f;
01253 }
01254 dsp->thinkdigit = digit;
01255 } else {
01256 if (dsp->thinkdigit) {
01257 memset(&dsp->f, 0, sizeof(dsp->f));
01258 if (dsp->thinkdigit != 'x') {
01259 /* If we found a digit, send it now */
01260 dsp->f.frametype = AST_FRAME_DTMF;
01261 dsp->f.subclass = dsp->thinkdigit;
01262 dsp->thinkdigit = 0;
01263 } else {
01264 dsp->f.frametype = AST_FRAME_DTMF;
01265 dsp->f.subclass = 'u';
01266 dsp->thinkdigit = 0;
01267 }
01268 FIX_INF(af);
01269 if (chan)
01270 ast_queue_frame(chan, af, needlock);
01271 ast_frfree(af);
01272 return &dsp->f;
01273 }
01274 }
01275 }
01276 } else if (!digit) {
01277 /* Only check when there is *not* a hit... */
01278 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01279 if (dsp->td.mf.current_digits) {
01280 memset(&dsp->f, 0, sizeof(dsp->f));
01281 dsp->f.frametype = AST_FRAME_DTMF;
01282 dsp->f.subclass = dsp->td.mf.digits[0];
01283 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01284 dsp->td.mf.current_digits--;
01285 FIX_INF(af);
01286 if (chan)
01287 ast_queue_frame(chan, af, needlock);
01288 ast_frfree(af);
01289 return &dsp->f;
01290 }
01291 } else {
01292 if (dsp->td.dtmf.current_digits) {
01293 memset(&dsp->f, 0, sizeof(dsp->f));
01294 dsp->f.frametype = AST_FRAME_DTMF;
01295 dsp->f.subclass = dsp->td.dtmf.digits[0];
01296 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01297 dsp->td.dtmf.current_digits--;
01298 FIX_INF(af);
01299 if (chan)
01300 ast_queue_frame(chan, af, needlock);
01301 ast_frfree(af);
01302 return &dsp->f;
01303 }
01304 }
01305 }
01306 }
01307 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01308 res = __ast_dsp_call_progress(dsp, shortdata, len);
01309 memset(&dsp->f, 0, sizeof(dsp->f));
01310 dsp->f.frametype = AST_FRAME_CONTROL;
01311 if (res) {
01312 switch(res) {
01313 case AST_CONTROL_ANSWER:
01314 case AST_CONTROL_BUSY:
01315 case AST_CONTROL_RINGING:
01316 case AST_CONTROL_CONGESTION:
01317 dsp->f.subclass = res;
01318 if (chan)
01319 ast_queue_frame(chan, &dsp->f, needlock);
01320 break;
01321 default:
01322 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01323 }
01324 }
01325 }
01326 FIX_INF(af);
01327 return af;
01328 }
|
|
|
Definition at line 1410 of file dsp.c. References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.
01411 {
01412 int x;
01413 dsp->totalsilence = 0;
01414 dsp->gsamps = 0;
01415 for (x=0;x<4;x++)
01416 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01417 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01418 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01419
01420 }
|
|
||||||||||||
|
Definition at line 1368 of file dsp.c. References ast_dsp::busycount, and DSP_HISTORY.
01369 {
01370 if (cadences < 4)
01371 cadences = 4;
01372 if (cadences > DSP_HISTORY)
01373 cadences = DSP_HISTORY;
01374 dsp->busycount = cadences;
01375 }
|
|
||||||||||||
|
Definition at line 1353 of file dsp.c. References ast_dsp::features.
01354 {
01355 dsp->features = features;
01356 }
|
|
||||||||||||
|
Definition at line 1363 of file dsp.c. References ast_dsp::threshold.
01364 {
01365 dsp->threshold = threshold;
01366 }
|
|
||||||||||||||||
|
Definition at line 1121 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass. Referenced by ast_app_getvoice().
01122 {
01123 short *s;
01124 int len;
01125
01126 if (f->frametype != AST_FRAME_VOICE) {
01127 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01128 return 0;
01129 }
01130 if (f->subclass != AST_FORMAT_SLINEAR) {
01131 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01132 return 0;
01133 }
01134 s = f->data;
01135 len = f->datalen/2;
01136 return __ast_dsp_silence(dsp, s, len, totalsilence);
01137 }
|
1.3.4