/* * Copyright (c) 2001 by Tsuyoshi Iguchi (zinnia@risky-safety.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id$ */ /* * gcc -o dtmf dtmf.c -lm * * usage: dtmf 117 > hoge.raw ; sox -t cdr hoge.raw hoge.wav * : sox -t cdr =(dtmf 117) hoge.wav (for zsh) */ #include #include const double tonelen = 0.2; const double brethlen = 0.1; const int samplerate = 44100; const int amp = 10; typedef struct { int h; /* dwarf, hobbit */ int l; /* leprechaun */ } tones; tones tone[17] = { {941, 1336}, /* 0 */ {697, 1209}, /* 1 */ {697, 1336}, /* 2 */ {697, 1477}, /* 3 */ {770, 1209}, /* 4 */ {770, 1336}, /* 5 */ {770, 1477}, /* 6 */ {852, 1209}, /* 7 */ {852, 1336}, /* 8 */ {852, 1477}, /* 9 */ {697, 1633}, /* A */ {770, 1633}, /* B */ {852, 1633}, /* C */ {941, 1633}, /* D */ {941, 1209}, /* * */ {941, 1447}, /* # */ {0, 0}, /* , */ }; double sine(double f, double t) { return sin(2.0 * M_PI * f * t); } int gettoneno(int c) { int d; if(isdigit(c)) return c - '0'; if(c == '*') return 14; if(c == '#') return 15; if(c == ',') return 16; d = tolower(c); if(d >= 'a' && d <= 'd') return d - 'a' + 10; return -1; } void dtmf(char* s) { char* p; int i, j; double t, v; char q[2]; for(p = s; *p; p++){ i = gettoneno(*p); if(i == -1) continue; for(t = 0; t < tonelen; t += 1.0 / samplerate){ v = amp * (sine(tone[i].h, t) + sine(tone[i].l, t)); j = (int)v; q[0] = j & 0xff; q[1] = (j >> 8) & 0xff; fwrite(q, 1, 2, stdout); fwrite(q, 1, 2, stdout); } q[0] = q[1] = 0; for(t = 0; t < brethlen; t += 1.0 / samplerate){ fwrite(q, 1, 2, stdout); fwrite(q, 1, 2, stdout); } } } int main(int argc, char* argv[]) { static char buf[0x100]; if(argc < 2){ while(fgets(buf, 0x100, stdin)){ dtmf(buf); } } else { dtmf(argv[1]); } return 0; }