[svn-commits] dvossel: branch dvossel/hd_confbridge r310046 - in /team/dvossel/hd_confbridg...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Mar 8 12:26:14 CST 2011


Author: dvossel
Date: Tue Mar  8 12:26:10 2011
New Revision: 310046

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=310046
Log:
Expand DSP code to handle slinear of any sample rate

Modified:
    team/dvossel/hd_confbridge/include/asterisk/dsp.h
    team/dvossel/hd_confbridge/main/dsp.c

Modified: team/dvossel/hd_confbridge/include/asterisk/dsp.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/dsp.h?view=diff&rev=310046&r1=310045&r2=310046
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/dsp.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/dsp.h Tue Mar  8 12:26:10 2011
@@ -66,7 +66,13 @@
 	THRESHOLD_MAX = 1,
 };
 
+/*! \brief Allocates a new dsp with a specific internal sample rate used
+ * during processing. */
+struct ast_dsp *ast_dsp_new_with_rate(unsigned int sample_rate);
+
+/*! \brief Allocates a new dsp, assumes 8khz for internal sample rate */
 struct ast_dsp *ast_dsp_new(void);
+
 void ast_dsp_free(struct ast_dsp *dsp);
 
 /*! \brief Set threshold value for silence */

Modified: team/dvossel/hd_confbridge/main/dsp.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/dsp.c?view=diff&rev=310046&r1=310045&r2=310046
==============================================================================
--- team/dvossel/hd_confbridge/main/dsp.c (original)
+++ team/dvossel/hd_confbridge/main/dsp.c Tue Mar  8 12:26:10 2011
@@ -192,15 +192,7 @@
 #define FAX_TONE_CED_DURATION	2600
 #define FAX_TONE_CED_DB		16
 
-#define SAMPLE_RATE		8000
-
-/* How many samples a frame has.  This constant is used when calculating
- * Goertzel block size for tone_detect.  It is only important if we want to
- * remove (squelch) the tone. In this case it is important to have block
- * size not to exceed size of voice frame.  Otherwise by the moment the tone
- * is detected it is too late to squelch it from previous frames.
- */
-#define SAMPLES_IN_FRAME	160
+#define DEFAULT_SAMPLE_RATE		8000
 
 /* MF goertzel size */
 #define MF_GSIZE		120
@@ -339,10 +331,10 @@
 	return (float)r.value * (float)(1 << r.power);
 }
 
-static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
+static inline void goertzel_init(goertzel_state_t *s, float freq, int samples, unsigned int sample_rate)
 {
 	s->v2 = s->v3 = s->chunky = 0.0;
-	s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
+	s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / sample_rate));
 	s->samples = samples;
 }
 
@@ -395,6 +387,7 @@
 	int display_inband_dtmf_warning;
 	float genergy;
 	int mute_fragments;
+	unsigned int sample_rate;
 	fragment_t mute_data[5];
 	digit_detect_state_t digit_state;
 	tone_detect_state_t cng_tone_state;
@@ -411,7 +404,7 @@
 	dsp->mute_data[dsp->mute_fragments++] = *fragment;
 }
 
-static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
+static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp, unsigned int sample_rate)
 {
 	int duration_samples;
 	float x;
@@ -420,16 +413,16 @@
 	s->freq = freq;
 
 	/* Desired tone duration in samples */
-	duration_samples = duration * SAMPLE_RATE / 1000;
+	duration_samples = duration * sample_rate / 1000;
 	/* We want to allow 10% deviation of tone duration */
 	duration_samples = duration_samples * 9 / 10;
 
 	/* If we want to remove tone, it is important to have block size not
 	   to exceed frame size. Otherwise by the moment tone is detected it is too late
- 	   to squelch it from previous frames */
-	s->block_size = SAMPLES_IN_FRAME;
-
-	periods_in_block = s->block_size * freq / SAMPLE_RATE;
+ 	   to squelch it from previous frames. Block size is 20ms at the given sample rate.*/
+	s->block_size = (20 * sample_rate) / 1000;
+
+	periods_in_block = s->block_size * freq / sample_rate;
 
 	/* Make sure we will have at least 5 periods at target frequency for analisys.
 	   This may make block larger than expected packet and will make squelching impossible
@@ -438,7 +431,7 @@
 		periods_in_block = 5;
 
 	/* Now calculate final block size. It will contain integer number of periods */
-	s->block_size = periods_in_block * SAMPLE_RATE / freq;
+	s->block_size = periods_in_block * sample_rate / freq;
 
 	/* tone_detect is currently only used to detect fax tones and we
 	   do not need suqlching the fax tones */
@@ -448,7 +441,7 @@
 	   and thus no tone will be detected in them */
 	s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
 
-	goertzel_init(&s->tone, freq, s->block_size);
+	goertzel_init(&s->tone, freq, s->block_size, sample_rate);
 
 	s->samples_pending = s->block_size;
 	s->hit_count = 0;
@@ -473,19 +466,19 @@
 
 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);
-	ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
-}
-
-static void ast_dtmf_detect_init (dtmf_detect_state_t *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);
+}
+
+static void ast_dtmf_detect_init (dtmf_detect_state_t *s, unsigned int sample_rate)
 {
 	int i;
 
 	s->lasthit = 0;
 	s->current_hit = 0;
 	for (i = 0;  i < 4;  i++) {
-		goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
-		goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
+		goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE, sample_rate);
+		goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE, sample_rate);
 		s->energy = 0.0;
 	}
 	s->current_sample = 0;
@@ -496,18 +489,18 @@
 	s->misses_to_end = DTMF_MISSES_TO_END;
 }
 
-static void ast_mf_detect_init (mf_detect_state_t *s)
+static void ast_mf_detect_init (mf_detect_state_t *s, unsigned int sample_rate)
 {
 	int i;
 	s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
 	for (i = 0;  i < 6;  i++) {
-		goertzel_init (&s->tone_out[i], mf_tones[i], 160);
+		goertzel_init (&s->tone_out[i], mf_tones[i], 160, sample_rate);
 	}
 	s->current_sample = 0;
 	s->current_hit = 0;
 }
 
-static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
+static void ast_digit_detect_init(digit_detect_state_t *s, int mf, unsigned int sample_rate)
 {
 	s->current_digits = 0;
 	s->detected_digits = 0;
@@ -515,9 +508,9 @@
 	s->digits[0] = '\0';
 
 	if (mf) {
-		ast_mf_detect_init(&s->td.mf);
+		ast_mf_detect_init(&s->td.mf, sample_rate);
 	} else {
-		ast_dtmf_detect_init(&s->td.dtmf);
+		ast_dtmf_detect_init(&s->td.dtmf, sample_rate);
 	}
 }
 
@@ -1106,7 +1099,7 @@
 		ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
 		return 0;
 	}
-	if (inf->subclass.format.id != AST_FORMAT_SLINEAR) {
+	if (!ast_format_is_slinear(&inf->subclass.format)) {
 		ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
 		return 0;
 	}
@@ -1129,7 +1122,7 @@
 	accum /= len;
 	if (accum < dsp->threshold) {
 		/* Silent */
-		dsp->totalsilence += len / 8;
+		dsp->totalsilence += len / (dsp->sample_rate / 1000);
 		if (dsp->totalnoise) {
 			/* Move and save history */
 			memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
@@ -1143,7 +1136,7 @@
 		res = 1;
 	} else {
 		/* Not silent */
-		dsp->totalnoise += len / 8;
+		dsp->totalnoise += len / (dsp->sample_rate / 1000);
 		if (dsp->totalsilence) {
 			int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
 			int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
@@ -1280,7 +1273,7 @@
 		ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
 		return 0;
 	}
-	if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
+	if (!ast_format_is_slinear(&f->subclass.format)) {
 		ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
 		return 0;
 	}
@@ -1298,7 +1291,7 @@
                ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
                return 0;
        }
-       if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
+       if (!ast_format_is_slinear(&f->subclass.format)) {
                ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
                return 0;
        }
@@ -1329,30 +1322,31 @@
 	odata = af->data.ptr;
 	len = af->datalen;
 	/* Make sure we have short data */
-	switch (af->subclass.format.id) {
-	case AST_FORMAT_SLINEAR:
+	if (ast_format_is_slinear(&af->subclass.format)) {
 		shortdata = af->data.ptr;
 		len = af->datalen / 2;
-		break;
-	case AST_FORMAT_ULAW:
-	case AST_FORMAT_TESTLAW:
-		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.format));
-		dsp->display_inband_dtmf_warning = 0;
-		return af;
+	} else {
+		switch (af->subclass.format.id) {
+		case AST_FORMAT_ULAW:
+		case AST_FORMAT_TESTLAW:
+			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.format));
+			dsp->display_inband_dtmf_warning = 0;
+			return af;
+		}
 	}
 
 	/* Initially we do not want to mute anything */
@@ -1413,7 +1407,7 @@
 				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;
+					event_len = dsp->digit_state.digitlen[0] * 1000 / dsp->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]));
@@ -1480,8 +1474,6 @@
 	}
 
 	switch (af->subclass.format.id) {
-	case AST_FORMAT_SLINEAR:
-		break;
 	case AST_FORMAT_ULAW:
 		for (x = 0; x < len; x++) {
 			odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
@@ -1516,7 +1508,7 @@
 	dsp->gsamps = 0;
 	for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
 		if (modes[dsp->progmode].freqs[x]) {
-			goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
+			goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size, dsp->sample_rate);
 			max = x + 1;
 		}
 	}
@@ -1524,7 +1516,7 @@
 	dsp->ringtimeout= 0;
 }
 
-struct ast_dsp *ast_dsp_new(void)
+static struct ast_dsp *__ast_dsp_new(unsigned int sample_rate)
 {
 	struct ast_dsp *dsp;
 	
@@ -1534,8 +1526,9 @@
 		dsp->busycount = DSP_HISTORY;
 		dsp->digitmode = DSP_DIGITMODE_DTMF;
 		dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
+		dsp->sample_rate = sample_rate;
 		/* Initialize digit detector */
-		ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
+		ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF, dsp->sample_rate);
 		dsp->display_inband_dtmf_warning = 1;
 		/* Initialize initial DSP progress detect parameters */
 		ast_dsp_prog_reset(dsp);
@@ -1543,6 +1536,16 @@
 		ast_fax_detect_init(dsp);
 	}
 	return dsp;
+}
+
+struct ast_dsp *ast_dsp_new(void)
+{
+	return __ast_dsp_new(DEFAULT_SAMPLE_RATE);
+}
+
+struct ast_dsp *ast_dsp_new_with_rate(unsigned int sample_rate)
+{
+	return __ast_dsp_new(sample_rate);
 }
 
 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
@@ -1632,7 +1635,7 @@
 	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);
+		ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF, dsp->sample_rate);
 	}
 	dsp->digitmode = digitmode;
 	return 0;




More information about the svn-commits mailing list