Thu Apr 28 2011 17:16:04

Asterisk developer's documentation


dsp.h File Reference

Convenient Signal Processing routines. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define DSP_DIGITMODE_DTMF   0
#define DSP_DIGITMODE_MF   1
#define DSP_DIGITMODE_MUTECONF   (1 << 9)
#define DSP_DIGITMODE_MUTEMAX   (1 << 10)
#define DSP_DIGITMODE_NOQUELCH   (1 << 8)
#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)
#define DSP_FAXMODE_DETECT_ALL   (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED)
#define DSP_FAXMODE_DETECT_CED   (1 << 1)
#define DSP_FAXMODE_DETECT_CNG   (1 << 0)
#define DSP_FEATURE_BUSY_DETECT   (1 << 1)
#define DSP_FEATURE_CALL_PROGRESS   (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
#define DSP_FEATURE_DIGIT_DETECT   (1 << 3)
#define DSP_FEATURE_FAX_DETECT   (1 << 4)
#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)
#define DSP_FEATURE_WAITDIALTONE   (1 << 20)
#define DSP_PROGRESS_BUSY   (1 << 18)
#define DSP_PROGRESS_CONGESTION   (1 << 19)
#define DSP_PROGRESS_RINGING   (1 << 17)
#define DSP_PROGRESS_TALK   (1 << 16)
#define DSP_TONE_STATE_BUSY   4
#define DSP_TONE_STATE_DIALTONE   2
#define DSP_TONE_STATE_HUNGUP   8
#define DSP_TONE_STATE_RINGING   1
#define DSP_TONE_STATE_SILENCE   0
#define DSP_TONE_STATE_SPECIAL1   5
#define DSP_TONE_STATE_SPECIAL2   6
#define DSP_TONE_STATE_SPECIAL3   7
#define DSP_TONE_STATE_TALKING   3

Enumerations

enum  threshold { THRESHOLD_SILENCE = 0, THRESHOLD_MAX = 1 }

Functions

int ast_dsp_busydetect (struct ast_dsp *dsp)
 Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called.
int ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf)
 Scans for progress indication in audio.
int ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f)
 Return non-zero if DTMF hit was found.
void ast_dsp_digitreset (struct ast_dsp *dsp)
 Reset DTMF detector.
void ast_dsp_frame_freed (struct ast_frame *fr)
 Hint that a frame from a dsp was freed.
void ast_dsp_free (struct ast_dsp *dsp)
int ast_dsp_get_tcount (struct ast_dsp *dsp)
 Get tcount (Threshold counter)
int ast_dsp_get_threshold_from_settings (enum threshold which)
 Get silence threshold from dsp.conf.
int ast_dsp_get_tstate (struct ast_dsp *dsp)
 Get tstate (Tone State)
int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
 Get pending DTMF/MF digits.
int ast_dsp_init (void)
 Load dsp settings from dsp.conf.
struct ast_dspast_dsp_new (void)
int ast_dsp_noise (struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
 Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.
struct ast_frameast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
 Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.
int ast_dsp_reload (void)
 Reloads dsp settings from dsp.conf.
void ast_dsp_reset (struct ast_dsp *dsp)
 Reset total silence count.
void ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences)
 Set number of required cadences for busy.
void ast_dsp_set_busy_pattern (struct ast_dsp *dsp, int tonelength, int quietlength)
 Set expected lengths of the busy tone.
int ast_dsp_set_call_progress_zone (struct ast_dsp *dsp, char *zone)
 Set zone for doing progress detection.
int ast_dsp_set_digitmode (struct ast_dsp *dsp, int digitmode)
 Set digit mode.
int ast_dsp_set_faxmode (struct ast_dsp *dsp, int faxmode)
 Set fax mode.
void ast_dsp_set_features (struct ast_dsp *dsp, int features)
 Select feature set.
void ast_dsp_set_threshold (struct ast_dsp *dsp, int threshold)
 Set threshold value for silence.
int ast_dsp_silence (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
 Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
int ast_dsp_was_muted (struct ast_dsp *dsp)
 Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio.

Detailed Description

Convenient Signal Processing routines.

Definition in file dsp.h.


Define Documentation

#define DSP_DIGITMODE_DTMF   0

Detect DTMF digits

Definition at line 31 of file dsp.h.

Referenced by ast_dsp_new(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), mkintf(), sip_new(), ss_thread(), and store_config().

#define DSP_DIGITMODE_MF   1

Detect MF digits

Definition at line 32 of file dsp.h.

Referenced by ast_dsp_digitreset(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), and ss_thread().

#define DSP_DIGITMODE_MUTECONF   (1 << 9)

Mute conference

Definition at line 35 of file dsp.h.

Referenced by ast_dsp_set_digitmode(), dahdi_setoption(), and store_config().

#define DSP_DIGITMODE_MUTEMAX   (1 << 10)

Delay audio by a frame to try to extra quelch

Definition at line 36 of file dsp.h.

Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().

#define DSP_DIGITMODE_NOQUELCH   (1 << 8)

Do not quelch DTMF from in-band

Definition at line 34 of file dsp.h.

Referenced by ast_dsp_process(), and mgcp_new().

#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)

"Radio" mode (relaxed DTMF)

Definition at line 37 of file dsp.h.

Referenced by ast_dsp_process(), dahdi_setoption(), process_dahdi(), sip_new(), and store_config().

#define DSP_FAXMODE_DETECT_ALL   (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED)

Definition at line 48 of file dsp.h.

#define DSP_FAXMODE_DETECT_CED   (1 << 1)

Definition at line 47 of file dsp.h.

Referenced by ast_dsp_process().

#define DSP_FAXMODE_DETECT_CNG   (1 << 0)

Definition at line 46 of file dsp.h.

Referenced by ast_dsp_new(), and ast_dsp_process().

#define DSP_FEATURE_BUSY_DETECT   (1 << 1)

Definition at line 27 of file dsp.h.

Referenced by ast_dsp_process(), and dahdi_new().

#define DSP_FEATURE_CALL_PROGRESS   (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)

Definition at line 43 of file dsp.h.

Referenced by __ast_dsp_call_progress(), ast_dsp_process(), and dahdi_new().

#define DSP_FEATURE_FAX_DETECT   (1 << 4)

Definition at line 29 of file dsp.h.

Referenced by ast_dsp_process(), dahdi_new(), misdn_set_opt_exec(), read_config(), and sip_new().

#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)

Definition at line 26 of file dsp.h.

Referenced by ast_dsp_new(), and ast_dsp_process().

#define DSP_FEATURE_WAITDIALTONE   (1 << 20)

Enable dial tone detection

Definition at line 44 of file dsp.h.

Referenced by ast_dsp_process(), dahdi_new(), and dahdi_read().

#define DSP_PROGRESS_BUSY   (1 << 18)

Enable busy tone detection

Definition at line 41 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_CONGESTION   (1 << 19)

Enable congestion tone detection

Definition at line 42 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_RINGING   (1 << 17)

Enable calling tone detection

Definition at line 40 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_TALK   (1 << 16)

Enable talk detection

Definition at line 39 of file dsp.h.

Referenced by __ast_dsp_call_progress(), and dahdi_new().

#define DSP_TONE_STATE_BUSY   4

Definition at line 54 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_DIALTONE   2

Definition at line 52 of file dsp.h.

Referenced by __ast_dsp_call_progress(), and dahdi_read().

#define DSP_TONE_STATE_HUNGUP   8

Definition at line 58 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_RINGING   1

Definition at line 51 of file dsp.h.

Referenced by __ast_dsp_call_progress(), and dahdi_read().

#define DSP_TONE_STATE_SILENCE   0

Definition at line 50 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL1   5

Definition at line 55 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL2   6

Definition at line 56 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL3   7

Definition at line 57 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_TALKING   3

Definition at line 53 of file dsp.h.

Referenced by __ast_dsp_call_progress().


Enumeration Type Documentation

enum threshold
Enumerator:
THRESHOLD_SILENCE 
THRESHOLD_MAX 

Definition at line 62 of file dsp.h.

               {
   /* Array offsets */
   THRESHOLD_SILENCE = 0,
   /* Always the last */
   THRESHOLD_MAX = 1,
};

Function Documentation

int ast_dsp_busydetect ( struct ast_dsp dsp)

Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called.

Definition at line 1187 of file dsp.c.

References ast_debug, BUSY_MAX, BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, and ast_dsp::historicsilence.

Referenced by ast_dsp_process().

{
   int res = 0, x;
#ifndef BUSYDETECT_TONEONLY
   int avgsilence = 0, hitsilence = 0;
#endif
   int avgtone = 0, hittone = 0;
   if (!dsp->busymaybe) {
      return res;
   }
   for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
#ifndef BUSYDETECT_TONEONLY
      avgsilence += dsp->historicsilence[x];
#endif
      avgtone += dsp->historicnoise[x];
   }
#ifndef BUSYDETECT_TONEONLY
   avgsilence /= dsp->busycount;
#endif
   avgtone /= dsp->busycount;
   for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
#ifndef BUSYDETECT_TONEONLY
      if (avgsilence > dsp->historicsilence[x]) {
         if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
            hitsilence++;
         }
      } else {
         if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
            hitsilence++;
         }
      }
#endif
      if (avgtone > dsp->historicnoise[x]) {
         if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
            hittone++;
         }
      } else {
         if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
            hittone++;
         }
      }
   }
#ifndef BUSYDETECT_TONEONLY
   if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
       (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
       (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
#else
   if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
#endif
#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
      if (avgtone > avgsilence) {
         if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
            res = 1;
         }
      } else {
         if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
            res = 1;
         }
      }
#else
      res = 1;
#endif
   }
   /* If we know the expected busy tone length, check we are in the range */
   if (res && (dsp->busy_tonelength > 0)) {
      if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
#ifdef BUSYDETECT_DEBUG
         ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
            avgtone, dsp->busy_tonelength);
#endif
         res = 0;
      }
   }
#ifndef BUSYDETECT_TONEONLY
   /* If we know the expected busy tone silent-period length, check we are in the range */
   if (res && (dsp->busy_quietlength > 0)) {
      if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
#ifdef BUSYDETECT_DEBUG
      ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
         avgsilence, dsp->busy_quietlength);
#endif
         res = 0;
      }
   }
#endif
#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
   if (res) {
      ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
   } else {
      ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
   }
#endif
   return res;
}
int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1111 of file dsp.c.

References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

{
   if (inf->frametype != AST_FRAME_VOICE) {
      ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
      return 0;
   }
   if (inf->subclass != AST_FORMAT_SLINEAR) {
      ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
      return 0;
   }
   return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
}
int ast_dsp_digitdetect ( struct ast_dsp dsp,
struct ast_frame f 
)

Return non-zero if DTMF hit was found.

void ast_dsp_frame_freed ( struct ast_frame fr)

Hint that a frame from a dsp was freed.

This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs because it is possible for the dsp to be freed while someone still holds a reference to the frame that is in that dsp. This has been known to happen when the dsp on a DAHDI channel detects a busy signal. The channel is hung up, and the application that read the frame to begin with still has a reference to the frame.

Returns:
nothing

Definition at line 1744 of file dsp.c.

References ast_clear_flag, ast_dsp_free(), AST_FRFLAG_FROM_DSP, ast_dsp::destroy, and f.

Referenced by __frame_free().

{
   struct ast_dsp *dsp;

   ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);

   dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));

   if (!dsp->destroy)
      return;
   
   ast_dsp_free(dsp);
}
void ast_dsp_free ( struct ast_dsp dsp)

Definition at line 1561 of file dsp.c.

References ast_free, AST_FRFLAG_FROM_DSP, ast_test_flag, ast_dsp::destroy, and ast_dsp::f.

Referenced by __ast_play_and_record(), __oh323_destroy(), ast_dsp_frame_freed(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), dahdi_hangup(), destroy_endpoint(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), record_exec(), sip_dtmfmode(), sip_hangup(), sip_rtp_read(), ss_thread(), and unload_module().

{
   if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
      /* If this flag is still set, that means that the dsp's destruction 
       * been torn down, while we still have a frame out there being used.
       * When ast_frfree() gets called on that frame, this ast_trans_pvt
       * will get destroyed, too. */

      dsp->destroy = 1;

      return;
   }
   ast_free(dsp);
}
int ast_dsp_get_tcount ( struct ast_dsp dsp)

Get tcount (Threshold counter)

Definition at line 1692 of file dsp.c.

References ast_dsp::tcount.

Referenced by dahdi_read().

{
   return dsp->tcount;
}
int ast_dsp_get_threshold_from_settings ( enum threshold  which)

Get silence threshold from dsp.conf.

Since:
1.6.1

Definition at line 1729 of file dsp.c.

Referenced by app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().

{
   return thresholds[which];
}
int ast_dsp_get_tstate ( struct ast_dsp dsp)

Get tstate (Tone State)

Definition at line 1687 of file dsp.c.

References ast_dsp::tstate.

Referenced by dahdi_read().

{
   return dsp->tstate;
}
int ast_dsp_getdigits ( struct ast_dsp dsp,
char *  buf,
int  max 
)

Get pending DTMF/MF digits.

int ast_dsp_init ( void  )

Load dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1734 of file dsp.c.

References _dsp_init().

Referenced by main().

{
   return _dsp_init(0);
}
int ast_dsp_noise ( struct ast_dsp dsp,
struct ast_frame f,
int *  totalnoise 
)

Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.

Since:
1.6.1

Definition at line 1300 of file dsp.c.

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, s, and ast_frame::subclass.

Referenced by do_waiting().

{
       short *s;
       int len;

       if (f->frametype != AST_FRAME_VOICE) {
               ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
               return 0;
       }
       if (f->subclass != AST_FORMAT_SLINEAR) {
               ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
               return 0;
       }
       s = f->data.ptr;
       len = f->datalen/2;
       return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
}
struct ast_frame* ast_dsp_process ( struct ast_channel chan,
struct ast_dsp dsp,
struct ast_frame inf 
) [read]

Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.

Definition at line 1319 of file dsp.c.

References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRFLAG_FROM_DSP, ast_frfree, ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, ast_dsp::cng_tone_state, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, digit_detect_state_t::digitlen, ast_dsp::digitmode, digit_detect_state_t::digits, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_MF, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, DSP_FEATURE_WAITDIALTONE, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame::frametype, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_frame::len, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_channel::name, ast_frame::ptr, SAMPLE_RATE, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().

Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), and usbradio_read().

{
   int silence;
   int res;
   int digit = 0, fax_digit = 0;
   int x;
   short *shortdata;
   unsigned char *odata;
   int len;
   struct ast_frame *outf = NULL;

   if (!af) {
      return NULL;
   }
   if (af->frametype != AST_FRAME_VOICE) {
      return af;
   }

   odata = af->data.ptr;
   len = af->datalen;
   /* Make sure we have short data */
   switch (af->subclass) {
   case AST_FORMAT_SLINEAR:
      shortdata = af->data.ptr;
      len = af->datalen / 2;
      break;
   case AST_FORMAT_ULAW:
      shortdata = alloca(af->datalen * 2);
      for (x = 0;x < len; x++) {
         shortdata[x] = AST_MULAW(odata[x]);
      }
      break;
   case AST_FORMAT_ALAW:
      shortdata = alloca(af->datalen * 2);
      for (x = 0; x < len; x++) {
         shortdata[x] = AST_ALAW(odata[x]);
      }
      break;
   default:
      /*Display warning only once. Otherwise you would get hundreds of warnings every second */
      if (dsp->display_inband_dtmf_warning)
         ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
      dsp->display_inband_dtmf_warning = 0;
      return af;
   }

   /* Initially we do not want to mute anything */
   dsp->mute_fragments = 0;

   /* Need to run the silence detection stuff for silence suppression and busy detection */
   if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
      res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
   }

   if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
      memset(&dsp->f, 0, sizeof(dsp->f));
      dsp->f.frametype = AST_FRAME_NULL;
      ast_frfree(af);
      ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
      return &dsp->f;
   }
   if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
      chan->_softhangup |= AST_SOFTHANGUP_DEV;
      memset(&dsp->f, 0, sizeof(dsp->f));
      dsp->f.frametype = AST_FRAME_CONTROL;
      dsp->f.subclass = AST_CONTROL_BUSY;
      ast_frfree(af);
      ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
      ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
      return &dsp->f;
   }

   if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
      if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
         fax_digit = 'f';
      }

      if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
         fax_digit = 'e';
      }
   }

   if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
      if (dsp->digitmode & DSP_DIGITMODE_MF)
         digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
      else
         digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));

      if (dsp->digit_state.current_digits) {
         int event = 0, event_len = 0;
         char event_digit = 0;

         if (!dsp->dtmf_began) {
            /* We have not reported DTMF_BEGIN for anything yet */

            if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
               event = AST_FRAME_DTMF_BEGIN;
               event_digit = dsp->digit_state.digits[0];
            }
            dsp->dtmf_began = 1;

         } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
            /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
            if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
               event = AST_FRAME_DTMF_END;
               event_digit = dsp->digit_state.digits[0];
               event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
            }
            memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
            memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
            dsp->digit_state.current_digits--;
            dsp->dtmf_began = 0;

            if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
               /* Reset Busy Detector as we have some confirmed activity */ 
               memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
               memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
               ast_debug(1, "DTMF Detected - Reset busydetector\n");
            }
         }

         if (event) {
            memset(&dsp->f, 0, sizeof(dsp->f));
            dsp->f.frametype = event;
            dsp->f.subclass = event_digit;
            dsp->f.len = event_len;
            outf = &dsp->f;
            goto done;
         }
      }
   }

   if (fax_digit) {
      /* Fax was detected - digit is either 'f' or 'e' */

      memset(&dsp->f, 0, sizeof(dsp->f));
      dsp->f.frametype = AST_FRAME_DTMF;
      dsp->f.subclass = fax_digit;
      outf = &dsp->f;
      goto done;
   }

   if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
      res = __ast_dsp_call_progress(dsp, shortdata, len);
      if (res) {
         switch (res) {
         case AST_CONTROL_ANSWER:
         case AST_CONTROL_BUSY:
         case AST_CONTROL_RINGING:
         case AST_CONTROL_CONGESTION:
         case AST_CONTROL_HANGUP:
            memset(&dsp->f, 0, sizeof(dsp->f));
            dsp->f.frametype = AST_FRAME_CONTROL;
            dsp->f.subclass = res;
            dsp->f.src = "dsp_progress";
            if (chan) 
               ast_queue_frame(chan, &dsp->f);
            break;
         default:
            ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
         }
      }
   } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
      res = __ast_dsp_call_progress(dsp, shortdata, len);
   }

done:
   /* Mute fragment of the frame */
   for (x = 0; x < dsp->mute_fragments; x++) {
      memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
   }

   switch (af->subclass) {
   case AST_FORMAT_SLINEAR:
      break;
   case AST_FORMAT_ULAW:
      for (x = 0; x < len; x++) {
         odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
      }
      break;
   case AST_FORMAT_ALAW:
      for (x = 0; x < len; x++) {
         odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
      }
      break;
   }

   if (outf) {
      if (chan) {
         ast_queue_frame(chan, af);
      }
      ast_frfree(af);
      ast_set_flag(outf, AST_FRFLAG_FROM_DSP);
      return outf;
   } else {
      return af;
   }
}
int ast_dsp_reload ( void  )

Reloads dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1739 of file dsp.c.

References _dsp_init().

{
   return _dsp_init(1);
}
void ast_dsp_reset ( struct ast_dsp dsp)

Reset total silence count.

Definition at line 1630 of file dsp.c.

References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::ringtimeout, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.

{
   int x;
   
   dsp->totalsilence = 0;
   dsp->gsamps = 0;
   for (x = 0; x < 4; x++) {
      dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
   }
   memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
   memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
   dsp->ringtimeout= 0;
}
void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1581 of file dsp.c.

References ast_dsp::busycount, cadences, and DSP_HISTORY.

Referenced by dahdi_new().

{
   if (cadences < 4) {
      cadences = 4;
   }
   if (cadences > DSP_HISTORY) {
      cadences = DSP_HISTORY;
   }
   dsp->busycount = cadences;
}
void ast_dsp_set_busy_pattern ( struct ast_dsp dsp,
int  tonelength,
int  quietlength 
)

Set expected lengths of the busy tone.

Definition at line 1592 of file dsp.c.

References ast_debug, ast_dsp::busy_quietlength, and ast_dsp::busy_tonelength.

Referenced by dahdi_new().

{
   dsp->busy_tonelength = tonelength;
   dsp->busy_quietlength = quietlength;
   ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
}
int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1668 of file dsp.c.

References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.

Referenced by dahdi_new().

{
   int x;
   
   for (x = 0; x < ARRAY_LEN(aliases); x++) {
      if (!strcasecmp(aliases[x].name, zone)) {
         dsp->progmode = aliases[x].mode;
         ast_dsp_prog_reset(dsp);
         return 0;
      }
   }
   return -1;
}
int ast_dsp_set_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Version:
1.6.1 renamed from ast_dsp_digitmode to ast_dsp_set_digitmode

Definition at line 1644 of file dsp.c.

References ast_digit_detect_init(), ast_dsp::digit_state, ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, and DSP_DIGITMODE_MUTEMAX.

Referenced by dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), mkintf(), sip_new(), ss_thread(), and store_config().

{
   int new;
   int old;
   
   old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
   new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
   if (old != new) {
      /* Must initialize structures if switching from MF to DTMF or vice-versa */
      ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
   }
   dsp->digitmode = digitmode;
   return 0;
}
int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1659 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

{
   if (dsp->faxmode != faxmode) {
      ast_fax_detect_init(dsp);
   }
   dsp->faxmode = faxmode;
   return 0;
}
void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)
void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Definition at line 1576 of file dsp.c.

References ast_dsp::threshold.

Referenced by __ast_play_and_record(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().

{
   dsp->threshold = threshold;
}
int ast_dsp_silence ( struct ast_dsp dsp,
struct ast_frame f,
int *  totalsilence 
)

Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.

Definition at line 1282 of file dsp.c.

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, s, and ast_frame::subclass.

Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().

{
   short *s;
   int len;
   
   if (f->frametype != AST_FRAME_VOICE) {
      ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
      return 0;
   }
   if (f->subclass != AST_FORMAT_SLINEAR) {
      ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
      return 0;
   }
   s = f->data.ptr;
   len = f->datalen/2;
   return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
}
int ast_dsp_was_muted ( struct ast_dsp dsp)

Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio.

Since:
1.6.1

Definition at line 1682 of file dsp.c.

References ast_dsp::mute_fragments.

Referenced by dahdi_read().

{
   return (dsp->mute_fragments > 0);
}