summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgendigits.c172
-rwxr-xr-xtonezone.c412
-rwxr-xr-xtonezone.h79
-rwxr-xr-xzonedata.c40
4 files changed, 703 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;
+}
diff --git a/tonezone.c b/tonezone.c
new file mode 100755
index 0000000..e601de9
--- /dev/null
+++ b/tonezone.c
@@ -0,0 +1,412 @@
+/*
+ * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * Working with the "Tormenta ISA" Card
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under thet erms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Primary Author: Mark Spencer <markster@linux-support.net>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include "tonezone.h"
+
+#define DEFAULT_ZT_DEV "/dev/zap/ctl"
+
+#define MAX_SIZE 16384
+#define CLIP 32635
+#define BIAS 0x84
+
+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;
+}
+
+
+
+struct tone_zone *tone_zone_find(char *country)
+{
+ struct tone_zone *z;
+ z = builtin_zones;
+ while(z->zone > -1) {
+ if (!strcasecmp(country, z->country))
+ return z;
+ z++;
+ }
+ return NULL;
+}
+
+struct tone_zone *tone_zone_find_by_num(int id)
+{
+ struct tone_zone *z;
+ z = builtin_zones;
+ while(z->zone > -1) {
+ if (z->zone == id)
+ return z;
+ z++;
+ }
+ return NULL;
+}
+
+static int build_tone(char *data, int size, struct tone_zone_sound *t, int *count)
+{
+ char *dup, *s;
+ struct zt_tone_def *td=NULL;
+ int firstnobang = -1;
+ int freq1, freq2, time;
+ int samples, samples1, samples2;
+ int x;
+ int used = 0;
+ float val;
+ dup = strdup(t->data);
+ s = strtok(dup, ",");
+ while(s && strlen(s)) {
+ /* Handle optional ! which signifies don't start here*/
+ if (s[0] == '!')
+ s++;
+ else if (firstnobang < 0) {
+#if 0
+ printf("First no bang: %s\n", s);
+#endif
+ firstnobang = *count;
+ }
+ if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) {
+ /* f1+f2/time format */
+#if 0
+ printf("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time);
+#endif
+ } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) {
+#if 0
+ printf("f1+f2 format: %d, %d\n", freq1, freq2);
+#endif
+ time = 0;
+ } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) {
+#if 0
+ printf("f1/time format: %d, %d\n", freq1, time);
+#endif
+ freq2 = 0;
+ } else if (sscanf(s, "%d", &freq1) == 1) {
+#if 0
+ printf("f1 format: %d\n", freq1);
+#endif
+ firstnobang = *count;
+ freq2 = 0;
+ time = 0;
+ } else {
+ fprintf(stderr, "tone component '%s' of '%s' is a syntax error\n", s,t->data);
+ return -1;
+ }
+ if (freq1)
+ samples1 = calc_samples(freq1);
+ else
+ samples1 = 40;
+ if (freq2)
+ samples2 = calc_samples(freq2);
+ else
+ samples2 = 0;
+ samples = samples1;
+ if (freq2) {
+ while(samples % samples2)
+ samples += samples1;
+ }
+#if 0
+ printf("Using %d samples for %d and %d\n", samples, freq1, freq2);
+#endif
+ if (size < samples + sizeof(struct zt_tone_def)) {
+ fprintf(stderr, "Not enough space for samples\n");
+ return -1;
+ }
+ td = (struct zt_tone_def *)data;
+ data += (sizeof(struct zt_tone_def) + samples);
+ used += (sizeof(struct zt_tone_def) + samples);
+ size -= (sizeof(struct zt_tone_def) + samples);
+ td->size = samples;
+ td->tone = t->toneid;
+ if (time) {
+ /* We should move to the next tone */
+ td->next = *count + 1;
+ td->samples = time * 8;
+ } else {
+ /* Stay with us */
+ td->next = *count;
+ td->samples = samples;
+ }
+ for (x=0;x<samples;x++) {
+ val = 0.0;
+ if (freq1)
+ val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
+ if (freq2)
+ val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
+ td->data[x] = linear2ulaw((int)val);
+ }
+ (*count)++;
+ s = strtok(NULL, ",");
+ }
+ if (td && time) {
+ /* If we don't end on a solid tone, return */
+ td->next = firstnobang;
+ }
+ return used;
+}
+
+char *tone_zone_tone_name(int id)
+{
+ static char tmp[80];
+ switch(id) {
+ case ZT_TONE_DIALTONE:
+ return "Dialtone";
+ case ZT_TONE_BUSY:
+ return "Busy";
+ case ZT_TONE_RINGTONE:
+ return "Ringtone";
+ case ZT_TONE_CONGESTION:
+ return "Congestion";
+ case ZT_TONE_CALLWAIT:
+ return "Call Waiting";
+ case ZT_TONE_DIALRECALL:
+ return "Dial Recall";
+ case ZT_TONE_RECORDTONE:
+ return "Record Tone";
+ case ZT_TONE_CUST1:
+ return "Custom 1";
+ case ZT_TONE_CUST2:
+ return "Custom 2";
+ case ZT_TONE_INFO:
+ return "Special Information";
+ default:
+ snprintf(tmp, sizeof(tmp), "Unknown tone %d", id);
+ return tmp;
+ }
+}
+
+#ifdef TONEZONE_DRIVER
+static void dump_tone_zone(void *data)
+{
+ struct zt_tone_def_header *z;
+ struct zt_tone_def *td;
+ int x;
+ int len=0;
+ z = data;
+ data += sizeof(*z);
+ printf("Header: %d tones, %d bytes of data, zone %d (%s)\n",
+ z->count, z->size, z->zone, z->name);
+ for (x=0;x < z->count; x++) {
+ td = data;
+ printf("Tone Fragment %d: %d bytes, %s tone, next is %d, %d samples total\n",
+ x, td->size, tone_name(td->tone), td->next, td->samples);
+ data += sizeof(*td);
+ data += td->size;
+ len += td->size;
+ }
+ printf("Total measured bytes of data: %d\n", len);
+}
+#endif
+
+int tone_zone_register_zone(int fd, struct tone_zone *z)
+{
+ char buf[MAX_SIZE];
+ int res;
+ int count=0;
+ int x;
+ int used = 0;
+ int iopenedit = 0;
+ int space = MAX_SIZE;
+ char *ptr = buf;
+ struct zt_tone_def_header *h;
+ if (fd < 0) {
+ fd = open(DEFAULT_ZT_DEV, O_RDWR);
+ iopenedit=1;
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_ZT_DEV);
+ return -1;
+ }
+ }
+ h = (struct zt_tone_def_header *)ptr;
+ ptr += sizeof(struct zt_tone_def_header);
+ space -= sizeof(struct zt_tone_def_header);
+ used += sizeof(struct zt_tone_def_header);
+ /*
+ * Fill in ring cadence
+ */
+ for (x=0;x<ZT_MAX_CADENCE;x++)
+ h->ringcadence[x] = z->ringcadence[x];
+ /* Put in an appropriate method for a kernel ioctl */
+ for (x=0;x<ZT_TONE_MAX;x++) {
+ if (strlen(z->tones[x].data)) {
+ /* It's a real tone */
+#if 0
+ printf("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data);
+#endif
+ res = build_tone(ptr, space, &z->tones[x], &count);
+ if (res < 0) {
+ fprintf(stderr, "Tone not built.\n");
+ if (iopenedit)
+ close(fd);
+ return -1;
+ }
+ ptr += res;
+ used += res;
+ space -= res;
+ }
+ }
+ h->count = count;
+ h->size = used - sizeof(struct zt_tone_def_header) - count * sizeof(struct zt_tone_def);
+ h->zone = z->zone;
+ strncpy(h->name, z->description, sizeof(h->name));
+ x = z->zone;
+ ioctl(fd, ZT_FREEZONE, &x);
+ res = ioctl(fd, ZT_LOADZONE, h);
+ if (res)
+ fprintf(stderr, "ioctl(ZT_LOADZONE) failed: %s\n", strerror(errno));
+ if (iopenedit)
+ close(fd);
+ return res;
+}
+
+int tone_zone_register(int fd, char *country)
+{
+ struct tone_zone *z;
+ z = tone_zone_find(country);
+ if (z) {
+ return tone_zone_register_zone(-1, z);
+ } else {
+ return -1;
+ }
+}
+
+
+
+int tone_zone_set_zone(int fd, char *country)
+{
+ int res=-1;
+ struct tone_zone *z;
+ if (fd > -1) {
+ z = tone_zone_find(country);
+ if (z)
+ res = ioctl(fd, ZT_SETTONEZONE, &z->zone);
+ if ((res < 0) && (errno == ENODATA)) {
+ tone_zone_register_zone(fd, z);
+ res = ioctl(fd, ZT_SETTONEZONE, &z->zone);
+ }
+ }
+ return res;
+}
+
+int tone_zone_get_zone(int fd)
+{
+ int x=-1;
+ if (fd > -1) {
+ ioctl(fd, ZT_GETTONEZONE, &x);
+ return x;
+ }
+ return -1;
+}
+
+int tone_zone_play_tone(int fd, int tone)
+{
+ struct tone_zone *z;
+ int res = -1;
+ int zone;
+#if 0
+ fprintf(stderr, "Playing tone %d (%s) on %d\n", tone, tone_zone_tone_name(tone), fd);
+#endif
+ if (fd > -1) {
+ res = ioctl(fd, ZT_SENDTONE, &tone);
+ if ((res < 0) && (errno == ENODATA)) {
+ ioctl(fd, ZT_GETTONEZONE, &zone);
+ z = tone_zone_find_by_num(zone);
+ if (z) {
+ res = tone_zone_register_zone(fd, z);
+ /* Recall the zone */
+ ioctl(fd, ZT_SETTONEZONE, &zone);
+ if (res < 0) {
+ fprintf(stderr, "Failed to register zone '%s': %s\n", z->description, strerror(errno));
+ } else {
+ res = ioctl(fd, ZT_SENDTONE, &tone);
+ }
+ } else
+ fprintf(stderr, "Don't know anything about zone %d\n", zone);
+ }
+ }
+ return res;
+}
diff --git a/tonezone.h b/tonezone.h
new file mode 100755
index 0000000..cc3a248
--- /dev/null
+++ b/tonezone.h
@@ -0,0 +1,79 @@
+/*
+ * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * Working with the "Tormenta ISA" Card
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Primary Author: Mark Spencer <markster@linux-support.net>
+ *
+ */
+
+#ifndef _TONEZONE_H
+#define _TONEZONE_H
+#ifdef BUILDING_TONEZONE
+#include "zaptel.h"
+#else
+#include <linux/zaptel.h>
+#endif
+
+struct tone_zone_sound {
+ int toneid;
+ char data[256]; /* Actual zone description */
+ /* Description is a series of tones of the format:
+ [!]freq1[+freq2][/time] separated by commas. There
+ are no spaces. The sequence is repeated back to the
+ first tone description not preceeded by !. time is
+ specified in milliseconds */
+};
+
+struct tone_zone {
+ int zone; /* Zone number */
+ char country[10]; /* Country code */
+ char description[40]; /* Description */
+ int ringcadence[ZT_MAX_CADENCE]; /* Ring cadence */
+ struct tone_zone_sound tones[ZT_TONE_MAX];
+};
+
+extern struct tone_zone builtin_zones[];
+
+/* Register a given two-letter tone zone if we can */
+extern int tone_zone_register(int fd, char *country);
+
+/* Register a given two-letter tone zone if we can */
+extern int tone_zone_register_zone(int fd, struct tone_zone *z);
+
+/* Retrieve a raw tone zone structure */
+extern struct tone_zone *tone_zone_find(char *country);
+
+/* Retrieve a raw tone zone structure by id instead of country*/
+extern struct tone_zone *tone_zone_find_by_num(int id);
+
+/* Retrieve a string name for a given tone id */
+extern char *tone_zone_tone_name(int id);
+
+/* Set a given file descriptor into a given country -- USE THIS
+ INTERFACE INSTEAD OF THE IOCTL ITSELF. Auto-loads tone
+ zone if necessary */
+extern int tone_zone_set_zone(int fd, char *country);
+
+/* Get the current tone zone */
+extern int tone_zone_get_zone(int fd);
+
+/* Play a given tone, loading tone zone automatically
+ if necessary */
+extern int tone_zone_play_tone(int fd, int toneid);
+
+#endif
diff --git a/zonedata.c b/zonedata.c
new file mode 100755
index 0000000..84104f0
--- /dev/null
+++ b/zonedata.c
@@ -0,0 +1,40 @@
+/*
+ * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * Working with the "Tormenta ISA" Card
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under thet erms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Primary Author: Mark Spencer <markster@linux-support.net>
+ *
+ * This information from ITU E.180 Supplement 2.
+ */
+#include "tonezone.h"
+
+struct tone_zone builtin_zones[] =
+{
+ { 0, "us", "United States / North America", { 2000, 4000 },
+ {
+ { ZT_TONE_DIALTONE, "350+440" },
+ { ZT_TONE_BUSY, "480+620/500,0/500" },
+ { ZT_TONE_RINGTONE, "440+480/2000,0/4000" },
+ { ZT_TONE_CONGESTION, "480+620/250,0/250" },
+ { ZT_TONE_CALLWAIT, "440/300,0/10000" },
+ { ZT_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" },
+ { ZT_TONE_RECORDTONE, "1400/500,0/15000" },
+ { ZT_TONE_INFO, "!950/330,!1400/330,!1800/330,0" } }
+ },
+ { -1 }
+};