]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
sync
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 7 Nov 2007 21:16:38 +0000 (21:16 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 7 Nov 2007 21:16:38 +0000 (21:16 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6180 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/libteletone/src/libteletone_detect.c
libs/libteletone/src/libteletone_detect.h
libs/libteletone/src/libteletone_generate.c
libs/libteletone/src/libteletone_generate.h

index 14eb1688dad0b40d00c95748f2d72b91dd0b96d6..7a3bf0d406da59c576437301b37a4221b25407fe 100644 (file)
@@ -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_col[GRID_FACTOR];
 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.0f*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.0*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]/(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.0f*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 @@ void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *ma
                }
                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 @@ int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
        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 @@ int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
                                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 @@ int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
                        }
                }
 
-        /* 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 @@ int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                  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 @@ int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                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 @@ int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                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;
+               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;
+               /* 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] = (float)(teletone_goertzel_result (&dtmf_detect_state->col_out[i]));
-            if (col_energy[i] > col_energy[best_col]) {
-                best_col = 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 &&
+               }
+               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 @@ int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                                        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 @@ int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
                                           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:
index 9c18d4b5a16268fff3b82dda8d0ffe6cce7079e9..414bbf2b3505b160fdcf3a1501e79fc965e1b622 100644 (file)
@@ -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 @@ extern "C" {
        */
 
 #ifndef FALSE
-#define FALSE   0
+#define FALSE  0
 #ifndef TRUE
-#define TRUE    (!FALSE)
+#define TRUE   (!FALSE)
 #endif
 #endif
 
@@ -123,13 +123,13 @@ extern "C" {
         * 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 @@ extern "C" {
                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;
index b578c45d3889c7dfa98c55b768965883ba94aa3a..6b262252bb7dbae0a02ad7e91e884051d3db46a9 100644 (file)
@@ -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 @@ int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *m
 
        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 @@ int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *m
                        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;
index fc56405a1356e9637b7f4fadf56a3935912c1443..83fd3f00ef93868ab504bb85302682952979c529 100644 (file)
@@ -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 @@ extern "C" {
 #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 @@ extern float powf (float, float);
 
 #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 @@ typedef struct teletone_dds_state teletone_dds_state_t;
 
 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;
 }