[Freeswitch-svn] [commit] r6180 - freeswitch/trunk/libs/libteletone/src
Freeswitch SVN
anthm at freeswitch.org
Wed Nov 7 16:16:38 EST 2007
Author: anthm
Date: Wed Nov 7 16:16:38 2007
New Revision: 6180
Modified:
freeswitch/trunk/libs/libteletone/src/libteletone_detect.c
freeswitch/trunk/libs/libteletone/src/libteletone_detect.h
freeswitch/trunk/libs/libteletone/src/libteletone_generate.c
freeswitch/trunk/libs/libteletone/src/libteletone_generate.h
Log:
sync
Modified: freeswitch/trunk/libs/libteletone/src/libteletone_detect.c
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_detect.c (original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_detect.c Wed Nov 7 16:16:38 2007
@@ -54,7 +54,7 @@
* Exception:
* The author hereby grants the use of this source code under the
* following license if and only if the source code is distributed
- * as part of the openzap library. Any use or distribution of this
+ * as part of the openzap library. Any use or distribution of this
* source code outside the scope of the openzap library will nullify the
* following license and reinact the MPL 1.1 as stated above.
*
@@ -80,7 +80,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -106,64 +106,64 @@
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
static teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR];
-static float dtmf_row[] = {697.0f, 770.0f, 852.0f, 941.0f};
+static float dtmf_row[] = {697.0f, 770.0f, 852.0f, 941.0f};
static float dtmf_col[] = {1209.0f, 1336.0f, 1477.0f, 1633.0f};
static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc) {
- goertzel_state->v2 = goertzel_state->v3 = 0.0;
- goertzel_state->fac = tdesc->fac;
+ goertzel_state->v2 = goertzel_state->v3 = 0.0;
+ goertzel_state->fac = tdesc->fac;
}
void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
int16_t sample_buffer[],
int samples)
{
- int i;
- float v1;
-
- for (i = 0; i < samples; i++) {
- v1 = goertzel_state->v2;
- goertzel_state->v2 = goertzel_state->v3;
- goertzel_state->v3 = (float)(goertzel_state->fac*goertzel_state->v2 - v1 + sample_buffer[i]);
- }
+ int i;
+ float v1;
+
+ for (i = 0; i < samples; i++) {
+ v1 = goertzel_state->v2;
+ goertzel_state->v2 = goertzel_state->v3;
+ goertzel_state->v3 = (float)(goertzel_state->fac*goertzel_state->v2 - v1 + sample_buffer[i]);
+ }
}
-#define teletone_goertzel_result(gs) ((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac)
+#define teletone_goertzel_result(gs) (float)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac))
void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate)
{
- int i;
- float theta;
+ int i;
+ float theta;
+
+ dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
- dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
+ for (i = 0; i < GRID_FACTOR; i++) {
+ theta = (float)(M_TWO_PI*(dtmf_row[i]/(float)sample_rate));
+ dtmf_detect_row[i].fac = (float)(2.0*cos(theta));
- for (i = 0; i < GRID_FACTOR; i++) {
- theta = (float)(M_TWO_PI*(dtmf_row[i]/(float)sample_rate));
- dtmf_detect_row[i].fac = (float)(2.0f*cos(theta));
-
- theta = (float)(M_TWO_PI*(dtmf_col[i]/(float)sample_rate));
- dtmf_detect_col[i].fac = (float)(2.0f*cos(theta));
-
- theta = (float)(M_TWO_PI*(dtmf_row[i]*2.0/(float)sample_rate));
- dtmf_detect_row_2nd[i].fac = (float)(2.0f*cos(theta));
-
- theta = (float)(M_TWO_PI*(dtmf_col[i]*2.0/(float)sample_rate));
- dtmf_detect_col_2nd[i].fac = (float)(2.0f*cos(theta));
-
+ theta = (float)(M_TWO_PI*(dtmf_col[i]/(float)sample_rate));
+ dtmf_detect_col[i].fac = (float)(2.0*cos(theta));
+
+ theta = (float)(M_TWO_PI*(dtmf_row[i]*2.0/(float)sample_rate));
+ dtmf_detect_row_2nd[i].fac = (float)(2.0*cos(theta));
+
+ theta = (float)(M_TWO_PI*(dtmf_col[i]*2.0/(float)sample_rate));
+ dtmf_detect_col_2nd[i].fac = (float)(2.0*cos(theta));
+
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
- goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
- goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
- goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
+ goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
+ goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
+ goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
dtmf_detect_state->energy = 0.0;
- }
- dtmf_detect_state->current_sample = 0;
- dtmf_detect_state->detected_digits = 0;
- dtmf_detect_state->lost_digits = 0;
- dtmf_detect_state->digits[0] = '\0';
- dtmf_detect_state->mhit = 0;
+ }
+ dtmf_detect_state->current_sample = 0;
+ dtmf_detect_state->detected_digits = 0;
+ dtmf_detect_state->lost_digits = 0;
+ dtmf_detect_state->digits[0] = '\0';
+ dtmf_detect_state->mhit = 0;
}
void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
@@ -197,7 +197,7 @@
}
mt->tone_count++;
theta = (float)(M_TWO_PI*(map->freqs[x]/(float)mt->sample_rate));
- mt->tdd[x].fac = (float)(2.0f * cos(theta));
+ mt->tdd[x].fac = (float)(2.0 * cos(theta));
goertzel_init (&mt->gs[x], &mt->tdd[x]);
goertzel_init (&mt->gs2[x], &mt->tdd[x]);
}
@@ -213,17 +213,17 @@
float eng_sum = 0, eng_all[TELETONE_MAX_TONES];
int gtest = 0, see_hit = 0;
- for (sample = 0; sample < samples; sample = limit) {
+ for (sample = 0; sample < samples; sample = limit) {
mt->total_samples++;
- if ((samples - sample) >= (mt->min_samples - mt->current_sample)) {
- limit = sample + (mt->min_samples - mt->current_sample);
+ if ((samples - sample) >= (mt->min_samples - mt->current_sample)) {
+ limit = sample + (mt->min_samples - mt->current_sample);
} else {
- limit = samples;
+ limit = samples;
}
- for (j = sample; j < limit; j++) {
- famp = sample_buffer[j];
+ for (j = sample; j < limit; j++) {
+ famp = sample_buffer[j];
mt->energy += famp*famp;
@@ -231,16 +231,16 @@
v1 = mt->gs[x].v2;
mt->gs[x].v2 = mt->gs[x].v3;
mt->gs[x].v3 = (float)(mt->gs[x].fac * mt->gs[x].v2 - v1 + famp);
-
+
v1 = mt->gs2[x].v2;
mt->gs2[x].v2 = mt->gs2[x].v3;
mt->gs2[x].v3 = (float)(mt->gs2[x].fac*mt->gs2[x].v2 - v1 + famp);
}
}
- mt->current_sample += (limit - sample);
- if (mt->current_sample < mt->min_samples) {
- continue;
+ mt->current_sample += (limit - sample);
+ if (mt->current_sample < mt->min_samples) {
+ continue;
}
eng_sum = 0;
@@ -277,15 +277,15 @@
}
}
- /* Reinitialise the detector for the next block */
+ /* Reinitialise the detector for the next block */
for(x = 0; x < mt->tone_count; x++) {
goertzel_init (&mt->gs[x], &mt->tdd[x]);
goertzel_init (&mt->gs2[x], &mt->tdd[x]);
}
mt->energy = 0.0;
- mt->current_sample = 0;
- }
+ mt->current_sample = 0;
+ }
return see_hit;
}
@@ -295,30 +295,30 @@
int16_t sample_buffer[],
int samples)
{
- float row_energy[GRID_FACTOR];
- float col_energy[GRID_FACTOR];
- float famp;
- float v1;
- int i;
- int j;
- int sample;
- int best_row;
- int best_col;
- char hit;
- int limit;
-
- hit = 0;
- for (sample = 0; sample < samples; sample = limit) {
- /* BLOCK_LEN is optimised to meet the DTMF specs. */
- if ((samples - sample) >= (BLOCK_LEN - dtmf_detect_state->current_sample)) {
- limit = sample + (BLOCK_LEN - dtmf_detect_state->current_sample);
+ float row_energy[GRID_FACTOR];
+ float col_energy[GRID_FACTOR];
+ float famp;
+ float v1;
+ int i;
+ int j;
+ int sample;
+ int best_row;
+ int best_col;
+ char hit;
+ int limit;
+
+ hit = 0;
+ for (sample = 0; sample < samples; sample = limit) {
+ /* BLOCK_LEN is optimised to meet the DTMF specs. */
+ if ((samples - sample) >= (BLOCK_LEN - dtmf_detect_state->current_sample)) {
+ limit = sample + (BLOCK_LEN - dtmf_detect_state->current_sample);
} else {
- limit = samples;
+ limit = samples;
}
- for (j = sample; j < limit; j++) {
+ for (j = sample; j < limit; j++) {
int x = 0;
- famp = sample_buffer[j];
+ famp = sample_buffer[j];
dtmf_detect_state->energy += famp*famp;
@@ -326,7 +326,7 @@
v1 = dtmf_detect_state->row_out[x].v2;
dtmf_detect_state->row_out[x].v2 = dtmf_detect_state->row_out[x].v3;
dtmf_detect_state->row_out[x].v3 = (float)(dtmf_detect_state->row_out[x].fac*dtmf_detect_state->row_out[x].v2 - v1 + famp);
-
+
v1 = dtmf_detect_state->col_out[x].v2;
dtmf_detect_state->col_out[x].v2 = dtmf_detect_state->col_out[x].v3;
dtmf_detect_state->col_out[x].v3 = (float)(dtmf_detect_state->col_out[x].fac*dtmf_detect_state->col_out[x].v2 - v1 + famp);
@@ -334,59 +334,59 @@
v1 = dtmf_detect_state->col_out2nd[x].v2;
dtmf_detect_state->col_out2nd[x].v2 = dtmf_detect_state->col_out2nd[x].v3;
dtmf_detect_state->col_out2nd[x].v3 = (float)(dtmf_detect_state->col_out2nd[x].fac*dtmf_detect_state->col_out2nd[x].v2 - v1 + famp);
-
+
v1 = dtmf_detect_state->row_out2nd[x].v2;
dtmf_detect_state->row_out2nd[x].v2 = dtmf_detect_state->row_out2nd[x].v3;
dtmf_detect_state->row_out2nd[x].v3 = (float)(dtmf_detect_state->row_out2nd[x].fac*dtmf_detect_state->row_out2nd[x].v2 - v1 + famp);
}
- }
+ }
- dtmf_detect_state->current_sample += (limit - sample);
- if (dtmf_detect_state->current_sample < BLOCK_LEN) {
- continue;
- }
- /* We are at the end of a DTMF detection block */
- /* Find the peak row and the peak column */
- row_energy[0] = (float)(teletone_goertzel_result (&dtmf_detect_state->row_out[0]));
- col_energy[0] = (float)(teletone_goertzel_result (&dtmf_detect_state->col_out[0]));
-
- for (best_row = best_col = 0, i = 1; i < GRID_FACTOR; i++) {
- row_energy[i] = (float)(teletone_goertzel_result (&dtmf_detect_state->row_out[i]));
- if (row_energy[i] > row_energy[best_row]) {
- best_row = i;
- }
- col_energy[i] = (float)(teletone_goertzel_result (&dtmf_detect_state->col_out[i]));
- if (col_energy[i] > col_energy[best_col]) {
- best_col = i;
- }
- }
- hit = 0;
- /* Basic signal level test and the twist test */
- if (row_energy[best_row] >= DTMF_THRESHOLD &&
+ dtmf_detect_state->current_sample += (limit - sample);
+ if (dtmf_detect_state->current_sample < BLOCK_LEN) {
+ continue;
+ }
+ /* We are at the end of a DTMF detection block */
+ /* Find the peak row and the peak column */
+ row_energy[0] = teletone_goertzel_result (&dtmf_detect_state->row_out[0]);
+ col_energy[0] = teletone_goertzel_result (&dtmf_detect_state->col_out[0]);
+
+ for (best_row = best_col = 0, i = 1; i < GRID_FACTOR; i++) {
+ row_energy[i] = teletone_goertzel_result (&dtmf_detect_state->row_out[i]);
+ if (row_energy[i] > row_energy[best_row]) {
+ best_row = i;
+ }
+ col_energy[i] = teletone_goertzel_result (&dtmf_detect_state->col_out[i]);
+ if (col_energy[i] > col_energy[best_col]) {
+ best_col = i;
+ }
+ }
+ hit = 0;
+ /* Basic signal level test and the twist test */
+ if (row_energy[best_row] >= DTMF_THRESHOLD &&
col_energy[best_col] >= DTMF_THRESHOLD &&
- col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
- col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
- /* Relative peak test */
- for (i = 0; i < GRID_FACTOR; i++) {
- if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
- (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
- break;
- }
- }
- /* ... and second harmonic test */
- if (i >= GRID_FACTOR && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy &&
- teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] &&
- teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
- hit = dtmf_positions[(best_row << 2) + best_col];
- /* Look for two successive similar results */
- /* The logic in the next test is:
- We need two successive identical clean detects, with
+ col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
+ col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
+ /* Relative peak test */
+ for (i = 0; i < GRID_FACTOR; i++) {
+ if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
+ (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
+ break;
+ }
+ }
+ /* ... and second harmonic test */
+ if (i >= GRID_FACTOR && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy &&
+ teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] &&
+ teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
+ hit = dtmf_positions[(best_row << 2) + best_col];
+ /* Look for two successive similar results */
+ /* The logic in the next test is:
+ We need two successive identical clean detects, with
something different preceeding it. This can work with
back to back differing digits. More importantly, it
can work with nasty phones that give a very wobbly start
to a digit. */
- if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
+ if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
dtmf_detect_state->mhit = hit;
dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
dtmf_detect_state->detected_digits++;
@@ -399,26 +399,26 @@
dtmf_detect_state->lost_digits++;
}
}
- }
- }
- dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
- dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
- dtmf_detect_state->hit3 = hit;
- /* Reinitialise the detector for the next block */
- for (i = 0; i < GRID_FACTOR; i++) {
- goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
- goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
- goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
- goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
- }
+ }
+ }
+ dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
+ dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
+ dtmf_detect_state->hit3 = hit;
+ /* Reinitialise the detector for the next block */
+ for (i = 0; i < GRID_FACTOR; i++) {
+ goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
+ goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
+ goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
+ goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
+ }
dtmf_detect_state->energy = 0.0;
- dtmf_detect_state->current_sample = 0;
- }
- if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
+ dtmf_detect_state->current_sample = 0;
+ }
+ if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
dtmf_detect_state->mhit = 0;
return(0);
- }
- return (hit);
+ }
+ return (hit);
}
@@ -426,16 +426,16 @@
char *buf,
int max)
{
- if (max > dtmf_detect_state->current_digits) {
- max = dtmf_detect_state->current_digits;
+ if (max > dtmf_detect_state->current_digits) {
+ max = dtmf_detect_state->current_digits;
+ }
+ if (max > 0) {
+ memcpy (buf, dtmf_detect_state->digits, max);
+ memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
+ dtmf_detect_state->current_digits -= max;
}
- if (max > 0) {
- memcpy (buf, dtmf_detect_state->digits, max);
- memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
- dtmf_detect_state->current_digits -= max;
- }
- buf[max] = '\0';
- return max;
+ buf[max] = '\0';
+ return max;
}
/* For Emacs:
Modified: freeswitch/trunk/libs/libteletone/src/libteletone_detect.h
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_detect.h (original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_detect.h Wed Nov 7 16:16:38 2007
@@ -54,7 +54,7 @@
* Exception:
* The author hereby grants the use of this source code under the
* following license if and only if the source code is distributed
- * as part of the openzap library. Any use or distribution of this
+ * as part of the openzap library. Any use or distribution of this
* source code outside the scope of the openzap library will nullify the
* following license and reinact the MPL 1.1 as stated above.
*
@@ -80,7 +80,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -105,9 +105,9 @@
*/
#ifndef FALSE
-#define FALSE 0
+#define FALSE 0
#ifndef TRUE
-#define TRUE (!FALSE)
+#define TRUE (!FALSE)
#endif
#endif
@@ -123,13 +123,13 @@
* Frequency tolerance +- 1.5% will detect, +-3.5% will reject
*/
-#define DTMF_THRESHOLD 8.0e7
-#define DTMF_NORMAL_TWIST 6.3 /* 8dB */
-#define DTMF_REVERSE_TWIST 2.5 /* 4dB */
-#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
-#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
-#define DTMF_2ND_HARMONIC_ROW 2.5 /* 4dB */
-#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
+#define DTMF_THRESHOLD 8.0e7
+#define DTMF_NORMAL_TWIST 6.3 /* 8dB */
+#define DTMF_REVERSE_TWIST 2.5 /* 4dB */
+#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
+#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
+#define DTMF_2ND_HARMONIC_ROW 2.5 /* 4dB */
+#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
#define GRID_FACTOR 4
#define BLOCK_LEN 102
#define M_TWO_PI 2.0*M_PI
@@ -154,7 +154,7 @@
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
float energy;
-
+
int current_sample;
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
int current_digits;
Modified: freeswitch/trunk/libs/libteletone/src/libteletone_generate.c
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_generate.c (original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_generate.c Wed Nov 7 16:16:38 2007
@@ -33,7 +33,7 @@
* Exception:
* The author hereby grants the use of this source code under the
* following license if and only if the source code is distributed
- * as part of the openzap library. Any use or distribution of this
+ * as part of the openzap library. Any use or distribution of this
* source code outside the scope of the openzap library will nullify the
* following license and reinact the MPL 1.1 as stated above.
*
@@ -59,7 +59,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -219,7 +219,8 @@
if (map->freqs[0] > 0) {
for (freqlen = 0; map->freqs[freqlen] && freqlen < TELETONE_MAX_TONES; freqlen++) {
- teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, vol);
+ teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0);
+ teletone_dds_state_set_tx_level(&tones[freqlen], vol);
}
if (ts->channels > 1) {
@@ -249,7 +250,7 @@
sample = 128;
for (i = 0; i < freqlen; i++) {
- int32_t s = teletone_dds_modulate_sample(&tones[i]);
+ int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0);
sample += s;
}
sample /= freqlen;
Modified: freeswitch/trunk/libs/libteletone/src/libteletone_generate.h
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_generate.h (original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_generate.h Wed Nov 7 16:16:38 2007
@@ -33,7 +33,7 @@
* Exception:
* The author hereby grants the use of this source code under the
* following license if and only if the source code is distributed
- * as part of the openzap library. Any use or distribution of this
+ * as part of the openzap library. Any use or distribution of this
* source code outside the scope of the openzap library will nullify the
* following license and reinact the MPL 1.1 as stated above.
*
@@ -59,7 +59,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -80,8 +80,9 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
-#undef inline
-#define inline __inline
+#ifndef __inline__
+#define __inline__ __inline
+#endif
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
@@ -111,12 +112,12 @@
#define TELETONE_VOL_DB_MAX 0
#define TELETONE_VOL_DB_MIN -63
+#define MAX_PHASE_TONES 4
struct teletone_dds_state {
- uint32_t phase_rate;
+ uint32_t phase_rate[MAX_PHASE_TONES];
uint32_t scale_factor;
uint32_t phase_accumulator;
- int16_t sample;
teletone_process_t tx_level;
};
typedef struct teletone_dds_state teletone_dds_state_t;
@@ -130,42 +131,53 @@
extern int16_t TELETONE_SINES[SINE_TABLE_MAX];
-static inline int16_t teletone_dds_modulate_sample(teletone_dds_state_t *dds)
+static __inline__ int32_t teletone_dds_phase_rate(teletone_process_t tone, uint32_t rate)
{
- int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN;
+ return (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate);
+}
+
+static __inline__ int16_t teletone_dds_state_modulate_sample(teletone_dds_state_t *dds, uint32_t pindex)
+{
+ int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN;
int16_t sample;
- if (bitmask & SINE_TABLE_MAX) {
- sine_index = SINE_TABLE_LEN - sine_index;
+ if (pindex >= MAX_PHASE_TONES) {
+ pindex = 0;
+ }
+
+ if (bitmask & SINE_TABLE_MAX) {
+ sine_index = SINE_TABLE_LEN - sine_index;
}
- sample = TELETONE_SINES[sine_index];
+ sample = TELETONE_SINES[sine_index];
- if (bitmask & (SINE_TABLE_MAX * 2)) {
+ if (bitmask & (SINE_TABLE_MAX * 2)) {
sample *= -1;
}
- dds->phase_accumulator += dds->phase_rate;
-
- return (int16_t) (sample * dds->scale_factor >> 15);
+ dds->phase_accumulator += dds->phase_rate[pindex];
+ return (int16_t) (sample * dds->scale_factor >> 15);
}
-static inline void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level)
+static __inline__ void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level)
{
dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f));
+ dds->tx_level = tx_level;
}
-static inline void teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, float tx_level)
+static __inline__ void teletone_dds_state_reset_accum(teletone_dds_state_t *dds)
{
dds->phase_accumulator = 0;
- dds->phase_rate = (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate);
-
+}
- if (dds->tx_level != tx_level || !dds->scale_factor) {
- teletone_dds_state_set_tx_level(dds, tx_level);
+static __inline__ int teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex)
+{
+ if (pindex < MAX_PHASE_TONES) {
+ dds->phase_rate[pindex] = teletone_dds_phase_rate(tone, rate);
+ return 0;
}
- dds->tx_level = tx_level;
+ return -1;
}
More information about the Freeswitch-svn
mailing list