[asterisk-commits] dvossel: branch dvossel/hd_confbridge r310046 - in /team/dvossel/hd_confbridg...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list