//dtmf.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "libroardsp.h" ssize_t roar_dtmf_mus2samples(const int_least32_t t, const uint32_t rate) { int64_t ret = t; if ( t < 0 || rate == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ret *= (int64_t)rate; ret /= (int64_t)1000000; return ret; } int roar_dtmf_break(int16_t * samples, const size_t len, const uint32_t rate, const int options) { (void)rate, (void)options; ROAR_DBG("roar_dtmf_break(samples=%p, len=%llu, rate=%lu, options=%i) = ?", samples, (long long unsigned int)len, (long unsigned int)rate, options); if ( samples == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(samples, 0, len*sizeof(int16_t)); return 0; } static const struct tone { const uint16_t c; const float f0; const float f1; } _roardsp_tones[] = { {'1', 697, 1209}, {'2', 697, 1336}, {'3', 697, 1477}, {'A', 697, 1633}, {'4', 770, 1209}, {'5', 770, 1336}, {'6', 770, 1477}, {'B', 770, 1633}, {'7', 852, 1209}, {'8', 852, 1336}, {'9', 852, 1477}, {'C', 852, 1633}, {'*', 941, 1209}, {'0', 941, 1336}, {'#', 941, 1477}, {'D', 941, 1633}, {0, -1, -1} }; static const struct tone * __lookup_tone(const int options, uint16_t c) { size_t i; (void)options; if ( c >= 'a' ) c -= 'a' - 'A'; for (i = 0; _roardsp_tones[i].c != 0; i++) { if ( _roardsp_tones[i].c == c ) { return &(_roardsp_tones[i]); } } roar_err_set(ROAR_ERROR_NOENT); return NULL; } int roar_dtmf_tone (int16_t * samples, const size_t len, const uint32_t rate, const int options, const uint16_t c) { const struct tone * ct = NULL; size_t i; float t; float t_inc = 1./rate; float fc0, fc1; ROAR_DBG("roar_dtmf_tone(samples=%p, len=%llu, rate=%lu, options=%i, c=%i) = ?", samples, (long long unsigned int)len, (long unsigned int)rate, options, (int)c); if ( samples == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } ct = __lookup_tone(options, c); if ( ct == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } fc0 = 2. * M_PI * ct->f0; fc1 = 2. * M_PI * ct->f1; // memset(samples, 0, len); for (i = 0, t = 0.; i < len; t += t_inc, i++) { samples[i] = (sinf(fc0*t) + sinf(fc1*t))*8192.0; } return 0; } //ll