/* Telphone Tones generator A.J. Fisher August 1995 C++ vsn AJF Dec. 1999 */ #include #include #include #include #include #define global #define unless(x) if(!(x)) #define until(x) while(!(x)) #define MAXSTR 512 #define SAMPLERATE 8000 #define SINEBITS 11 #define SINELEN (1 << SINEBITS) #define TWOPI (2.0 * M_PI) #define TWO32 4294967296.0 /* 2^32 */ typedef unsigned char uchar; typedef unsigned int uint; union word { word(char *sx) { s = sx; } word(int nx) { n = nx; } char *s; int n; }; static short expandtab[128]; /* entries 0 .. 32767 */ static char compresstab[32768]; /* entries 0 .. 127 */ static double sinetab[SINELEN]; static int header[8] = { 0x2e736e64, /* ".snd" magic number */ 32, /* length of hdr */ 0, /* *nominal* length of body, in samples */ 1, SAMPLERATE, 1, 0, 0, /* don't ask me what this means! */ }; extern "C" int atoi(char*); static void newhandler(), initaudio(), makeexpandtab(), makecompresstab(), makesinetab(); static void sendheader(), writeword(uint); static void senddtmf(char*), sendtone(int), sendwarble(double, double), sendfreqs(double, double, int, int); static void usage(), fail(char*, word = 0); inline int ifix(double x) { return (x >= 0.0) ? (int) (x+0.5) : (int) (x-0.5); } global void main() { set_new_handler(newhandler); logweb("teletones", ""); getentries(); initaudio(); if (isset("dial")) { char *s = getval("dial"); senddtmf(s); } else if (isset("tone")) { char *s = getval("tone"); sendtone(atoi(s)); } else usage(); exit(0); } static void newhandler() { fail("No room!"); } static void initaudio() { makeexpandtab(); makecompresstab(); makesinetab(); sendheader(); } static void makeexpandtab() { /* make mu-law expanding table */ for (int n = 0; n < 128; n++) { double x = (pow(256.0, (double) n / 127.0) - 1.0) / 255.0; /* result in range 0 .. 1 */ expandtab[n] = ifix(x * 32767.0); /* in range 0 .. 32767 */ } } static void makecompresstab() { /* make mu-law compressing table */ int i = 0, j = 0; while (i < 32768) { compresstab[i] = j; if (j < 127 && (expandtab[j+1] - i) < (i - expandtab[j])) j++; i++; } } static void makesinetab() { for (int k = 0; k < SINELEN; k++) { double th = TWOPI * (double) k / (double) SINELEN; sinetab[k] = sin(th); } } static void sendheader() { printf("Content-Type: audio/basic\n\n"); for (int i = 0; i < 8; i++) writeword(header[i]); } static void writeword(uint n) { #ifdef linux for (int i = 0; i < 4; i++) { putchar(n >> 24); n <<= 8; } #else for (int i = 0; i < 4; i++) { putchar(n & 0xff); n >>= 8; } #endif } static double rowtab[4] = { 697.0, 770.0, 852.0, 941.0 }; static double coltab[4] = { 1209.0, 1336.0, 1477.0, 1633.0 }; static void senddtmf(char *s) { int k = 0; until (s[k] == '\0') { char c = s[k++]; char *dstr = "123A456B789C*0#D"; char *p = strchr(dstr, c); unless (p == NULL) { uchar n = p - dstr; sendfreqs(rowtab[n >> 2], coltab[n & 3], 100, 1); /* tones for 100 ms */ sendfreqs(0.0, 0.0, 100, 1); /* silence for 100 ms */ } } } static void sendtone(int n) { switch (n) { default: usage(); case 0: /* BT */ { for (int i = 0; i < 14; i++) { sendfreqs(400.0, 400.0, 375, 1); sendfreqs(0.0, 0.0, 375, 1); } break; } case 1: /* EET */ { for (int i = 0; i < 7; i++) { sendfreqs(400.0, 400.0, 400, 0); /* quieter */ sendfreqs(0.0, 0.0, 350, 0); sendfreqs(400.0, 400.0, 225, 1); sendfreqs(0.0, 0.0, 525, 1); } break; } case 2: /* RT */ { for (int i = 0; i < 4; i++) { sendfreqs(400.0, 450.0, 400, 1); sendfreqs(0.0, 0.0, 200, 1); sendfreqs(400.0, 450.0, 400, 1); sendfreqs(0.0, 0.0, 2000, 1); } break; } case 3: /* NU */ { sendfreqs(400.0, 400.0, 10000, 1); break; } case 4: /* PT */ { for (int i = 0; i < 40; i++) { sendfreqs(400.0, 400.0, 125, 1); sendfreqs(0.0, 0.0, 125, 1); } break; } case 5: /* DT */ { sendfreqs(350.0, 450.0, 10000, 1); break; } case 6: /* Warble 1 */ { for (int i = 0; i < 4; i++) { sendwarble(1500.0, 1700.0); sendfreqs(0.0, 0.0, 200, 1); sendwarble(1500.0, 1700.0); sendfreqs(0.0, 0.0, 2000, 1); } break; } case 7: /* Warble 2 */ { for (int i = 0; i < 4; i++) { sendwarble(900.0, 1100.0); sendfreqs(0.0, 0.0, 200, 1); sendwarble(900.0, 1100.0); sendfreqs(0.0, 0.0, 2000, 1); } break; } } } static void sendwarble(double f1, double f2) { /* 400ms of warble */ for (int i = 0; i < 3; i++) { sendfreqs(f1, f1, 62, 1); sendfreqs(f2, f2, 63, 1); } sendfreqs(f1, f1, 25, 1); } static double amptab[2] = { 8191.75, 16383.5 }; inline int phinc(double f) { /* given frequency f, return corresponding phase increment */ return ifix(TWO32 * f / (double) SAMPLERATE); } inline double sine(uint ptr) { /* given 32-bit pointer ptr, return corresponding element from sine table */ return sinetab[ptr >> (32-SINEBITS)]; } static void sendfreqs(double f1, double f2, int ms, int ak) { double amp = amptab[ak]; int phinc1 = phinc(f1), phinc2 = phinc(f2); int ns = ms * (SAMPLERATE/1000); uint ptr1 = 0, ptr2 = 0; for (int n = 0; n < ns; n++) { double val = amp * (sine(ptr1) + sine(ptr2)); int ival = ifix(val); if (ival < -32768 || ival > 32767) fail("Bug! out of range: %08x", ival); putchar((ival >= 0) ? 255 - compresstab[ival] : 127 - compresstab[~ival]); ptr1 += phinc1; ptr2 += phinc2; } } static void usage() { fail("Usage error!"); } static void fail(char *msg, word p1) { discard_output(); /* in case we've sent audio/basic */ printf("Content-type: text/html\n\n"); printf("\n\n"); printf("

Error!

\n"); printf(msg, p1); putchar('\n'); exit(0); }
file: /Techref/uk/ac/york/cs/www-users/http/~fisher/telecom/tones/teletones.C, 5KB, , updated: 2000/4/4 12:33, local time: 2024/5/28 20:20,
TOP NEW HELP FIND: 
3.17.29.43:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://www.massmind.org/techref/uk/ac/york/cs/www-users/http/~fisher/telecom/tones/teletones.C"> uk ac york cs www-users http ~fisher telecom tones teletones</A>

Did you find what you needed?

 

Welcome to massmind.org!

 
Here is a great gift for computer geeks or widows:
The Backwoods Guide to Computer Lingo

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .