dsp_process was enhanced to work with alaw and ulaw in addition to slin.
authorGregory Nietsky <gregory@distrotech.co.za>
Mon, 25 Jul 2011 14:07:01 +0000 (14:07 +0000)
committerGregory Nietsky <gregory@distrotech.co.za>
Mon, 25 Jul 2011 14:07:01 +0000 (14:07 +0000)
noticed that some functions could be refactored here it is.

Reported by: irroot
Tested by: irroot, mnicholson
Review: https://reviewboard.asterisk.org/r/1304/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@329432 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/dsp.h
main/dsp.c

index 78c9a74..f82f08a 100644 (file)
 #define DSP_FEATURE_CALL_PROGRESS      (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
 #define DSP_FEATURE_WAITDIALTONE       (1 << 20)               /*!< Enable dial tone detection */
 
 #define DSP_FEATURE_CALL_PROGRESS      (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
 #define DSP_FEATURE_WAITDIALTONE       (1 << 20)               /*!< Enable dial tone detection */
 
-#define DSP_FAXMODE_DETECT_CNG (1 << 0)
-#define DSP_FAXMODE_DETECT_CED (1 << 1)
-#define DSP_FAXMODE_DETECT_V21 (1 << 2)
+#define DSP_FAXMODE_DETECT_CNG         (1 << 0)
+#define DSP_FAXMODE_DETECT_CED         (1 << 1)
+#define DSP_FAXMODE_DETECT_V21         (1 << 2)
+#define DSP_FAXMODE_DETECT_SQUELCH     (1 << 3)
 #define DSP_FAXMODE_DETECT_ALL (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED | DSP_FAXMODE_DETECT_V21)
 
 #define DSP_TONE_STATE_SILENCE  0
 #define DSP_FAXMODE_DETECT_ALL (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED | DSP_FAXMODE_DETECT_V21)
 
 #define DSP_TONE_STATE_SILENCE  0
index da982d0..7ce4bf0 100644 (file)
@@ -527,6 +527,11 @@ static void ast_fax_detect_init(struct ast_dsp *s)
        ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB, s->sample_rate);
        ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB, s->sample_rate);
        ast_v21_detect_init(&s->v21_state, s->sample_rate);
        ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB, s->sample_rate);
        ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB, s->sample_rate);
        ast_v21_detect_init(&s->v21_state, s->sample_rate);
+       if (s->faxmode & DSP_FAXMODE_DETECT_SQUELCH) {
+               s->cng_tone_state.squelch = 1;
+               s->ced_tone_state.squelch = 1;
+       }
+
 }
 
 static void ast_dtmf_detect_init (dtmf_detect_state_t *s, unsigned int sample_rate)
 }
 
 static void ast_dtmf_detect_init (dtmf_detect_state_t *s, unsigned int sample_rate)
@@ -1449,58 +1454,65 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
        return res;
 }
 
        return res;
 }
 
-int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
+static int ast_dsp_silence_noise_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *total, int *frames_energy, int noise)
 {
        short *s;
        int len;
 {
        short *s;
        int len;
-       
+       int x;
+       unsigned char *odata;
+
+       if (!f) {
+               return 0;
+       }
+
        if (f->frametype != AST_FRAME_VOICE) {
                ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
                return 0;
        }
        if (!ast_format_is_slinear(&f->subclass.format)) {
        if (f->frametype != AST_FRAME_VOICE) {
                ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
                return 0;
        }
        if (!ast_format_is_slinear(&f->subclass.format)) {
-               ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
-               return 0;
+               odata = f->data.ptr;
+               len = f->datalen;
+               switch (f->subclass.format.id) {
+                       case AST_FORMAT_ULAW:
+                               s = alloca(len * 2);
+                               for (x = 0;x < len; x++) {
+                                       s[x] = AST_MULAW(odata[x]);
+                               }
+                               break;
+                       case AST_FORMAT_ALAW:
+                               s = alloca(len * 2);
+                               for (x = 0;x < len; x++) {
+                                       s[x] = AST_ALAW(odata[x]);
+                               }
+                               break;
+                       default:
+                               ast_log(LOG_WARNING, "Can only calculate silence on signed-linear, alaw or ulaw frames :(\n");
+                       return 0;
+               }
+       } else {
+               s = f->data.ptr;
+               len = f->datalen/2;
+       }
+       if (noise) {
+               return __ast_dsp_silence_noise(dsp, s, len, NULL, total, frames_energy);
+       } else {
+               return __ast_dsp_silence_noise(dsp, s, len, total, NULL, frames_energy);
        }
        }
-       s = f->data.ptr;
-       len = f->datalen/2;
-       return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL, NULL);
 }
 
 int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy)
 {
 }
 
 int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy)
 {
-       short *s;
-       int len;
+       return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, frames_energy, 0);
+}
 
 
-       if (f->frametype != AST_FRAME_VOICE) {
-               ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
-               return 0;
-       }
-       if (!ast_format_is_slinear(&f->subclass.format)) {
-               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, frames_energy);
+int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
+{
+       return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, NULL, 0);
 }
 
 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
 {
 }
 
 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
 {
-       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 (!ast_format_is_slinear(&f->subclass.format)) {
-               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, NULL);
+       return ast_dsp_silence_noise_with_energy(dsp, f, totalnoise, NULL, 1);
 }
 
 
 }
 
 
@@ -1858,9 +1870,9 @@ int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
 {
        if (dsp->faxmode != faxmode) {
 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
 {
        if (dsp->faxmode != faxmode) {
+               dsp->faxmode = faxmode;
                ast_fax_detect_init(dsp);
        }
                ast_fax_detect_init(dsp);
        }
-       dsp->faxmode = faxmode;
        return 0;
 }
 
        return 0;
 }