summaryrefslogtreecommitdiff
path: root/gendigits.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-06-08 16:13:48 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-06-08 16:13:48 +0000
commita2bbaa084edb6a669880368fc63c1cf62b5c4f42 (patch)
treedf9f944cf945fb546be284d54c00ac8c583d64d7 /gendigits.c
parentd0f5c4c6d5c4ac688a88b4369e8c8501eab78127 (diff)
Version 0.1.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@6 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'gendigits.c')
-rwxr-xr-xgendigits.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/gendigits.c b/gendigits.c
new file mode 100755
index 0000000..d1847cb
--- /dev/null
+++ b/gendigits.c
@@ -0,0 +1,172 @@
+/* Generate a header file for a particular
+ single or double frequency */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#define CLIP 32635
+#define BIAS 0x84
+
+/* Dial frequency tables */
+typedef struct
+{
+char chr; /* character representation */
+float f1; /* first freq */
+float f2; /* second freq */
+} ZAP_DIAL;
+
+ZAP_DIAL dtmf_dial[] = {
+{ '1',697.0,1209.0 },
+{ '4',770.0,1209.0 },
+{ '7',852.0,1209.0 },
+{ '*',941.0,1209.0 },
+{ '2',697.0,1336.0 },
+{ '5',770.0,1336.0 },
+{ '8',852.0,1336.0 },
+{ '0',941.0,1336.0 },
+{ '3',697.0,1477.0 },
+{ '6',770.0,1477.0 },
+{ '9',852.0,1477.0 },
+{ '#',941.0,1477.0 },
+{ 'A',697.0,1633.0 },
+{ 'B',770.0,1633.0 },
+{ 'C',852.0,1633.0 },
+{ 'D',941.0,1633.0 },
+{ 0,0,0 }
+} ;
+
+ZAP_DIAL mf_dial[] = {
+{ '1',700.0,900.0 },
+{ '2',700.0,1100.0 },
+{ '3',900.0,1100.0 },
+{ '4',700.0,1300.0 },
+{ '5',900.0,1300.0 },
+{ '6',1100.0,1300.0 },
+{ '7',700.0,1500.0 },
+{ '8',900.0,1500.0 },
+{ '9',1100.0,1500.0 },
+{ '0',1300.0,1500.0 },
+{ '*',1100.0,1700.0 }, /* KP */
+{ '#',1500.0,1700.0 }, /* ST */
+{ 'A',900.0,1700.0 }, /* ST' */
+{ 'B',1300.0,1700.0}, /* ST'' */
+{ 'C',700.0,1700.0}, /* ST''' */
+{ 0,0,0 }
+} ;
+
+static float loudness=8192.0;
+
+unsigned char
+linear2ulaw(sample)
+short sample; {
+ static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+ int sign, exponent, mantissa;
+ unsigned char ulawbyte;
+
+ /* Get the sample into sign-magnitude. */
+ sign = (sample >> 8) & 0x80; /* set aside the sign */
+ if (sign != 0) sample = -sample; /* get magnitude */
+ if (sample > CLIP) sample = CLIP; /* clip the magnitude */
+
+ /* Convert from 16 bit linear to ulaw. */
+ sample = sample + BIAS;
+ exponent = exp_lut[(sample >> 7) & 0xFF];
+ mantissa = (sample >> (exponent + 3)) & 0x0F;
+ ulawbyte = ~(sign | (exponent << 4) | mantissa);
+#ifdef ZEROTRAP
+ if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
+#endif
+
+ return(ulawbyte);
+}
+
+static int calc_samples(int freq)
+{
+ int x, samples;
+ /* Calculate the number of samples at 8000hz sampling
+ we need to have this wave form */
+ samples = 8000;
+ /* Take out common 2's up to six times */
+ for (x=0;x<6;x++)
+ if (!(freq % 2)) {
+ freq /= 2;
+ samples /= 2;
+ }
+ /* Take out common 5's (up to three times */
+ for (x=0;x<3;x++)
+ if (!(freq % 5)) {
+ freq /= 5;
+ samples /=5;
+ }
+ /* No more common factors. */
+ return samples;
+}
+
+int process(FILE *f, char *label, ZAP_DIAL z[])
+{
+ char c;
+ int x, samples, samples1, samples2;
+ float val;
+ while(z->chr) {
+ c = z->chr;
+ if (c == '*')
+ c = 's';
+ if (c == '#')
+ c = 'p';
+ samples1 = calc_samples((int)z->f1);
+ samples2 = calc_samples((int)z->f2);
+ samples = samples1;
+ while(samples % samples2)
+ samples += samples1;
+ printf("Need %d samples for %s_%c\n", samples, label, c);
+ fprintf(f, "static unsigned char %s_%c[%d] = {\n\t", label, c, samples);
+ for (x=0;x<samples;x++) {
+ val = loudness * sin((z->f1 * 2.0 * M_PI * x)/8000.0);
+ val += loudness * sin((z->f2 * 2.0 * M_PI * x)/8000.0);
+ fprintf(f, "%3d, ", linear2ulaw((int)val));
+ if (!((x+1) % 15))
+ fprintf(f, "\n\t");
+ }
+ if (x % 15)
+ fprintf(f, "\n");
+ fprintf(f, "};\n\n");
+ z++;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *f;
+
+ if ((f = fopen("tones.h", "w"))) {
+ fprintf(f, "/* DTMF and MF tones used by the Tormenta Driver, in static tables.\n"
+ " Generated automatically from gendigits. Do not edit by hand. */\n");
+ process(f, "dtmf", dtmf_dial);
+ process(f, "mfv1", mf_dial);
+ fprintf(f, "/* END tones.h */\n");
+ fclose(f);
+ } else {
+ fprintf(stderr, "Unable to open tones.h for writing\n");
+ return 1;
+ }
+
+ return 0;
+}