source: roaraudio/libroardsp/dtmf.c @ 5547:3f5d08ba722e

Last change on this file since 5547:3f5d08ba722e was 5547:3f5d08ba722e, checked in by phi, 12 years ago

added an extended DTMF mode

File size: 5.9 KB
Line 
1//dtmf.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
5 *
6 *  This file is part of libroardsp a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroardsp is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "libroardsp.h"
26
27ssize_t roar_dtmf_mus2samples(const int_least32_t t, const uint32_t rate) {
28 int64_t ret = t;
29
30 if ( t < 0 || rate == 0 ) {
31  roar_err_set(ROAR_ERROR_INVAL);
32  return -1;
33 }
34
35 ret *= (int64_t)rate;
36 ret /= (int64_t)1000000;
37
38 return ret;
39}
40
41int roar_dtmf_break(int16_t * samples, const size_t len, const uint32_t rate, const int options) {
42 (void)rate, (void)options;
43
44 ROAR_DBG("roar_dtmf_break(samples=%p, len=%llu, rate=%lu, options=%i) = ?", samples, (long long unsigned int)len, (long unsigned int)rate, options);
45
46 if ( samples == NULL ) {
47  roar_err_set(ROAR_ERROR_FAULT);
48  return -1;
49 }
50
51 memset(samples, 0, len*sizeof(int16_t));
52
53 return 0;
54}
55
56#define _FQL0 697
57#define _FQL1 770
58#define _FQL2 852
59#define _FQL3 941
60#define _FQH0 1209
61#define _FQH1 1336
62#define _FQH2 1477
63#define _FQH3 1633
64
65#define _FRL0 571
66#define _FRL1 631
67#define _FRL2 _FQL0
68#define _FRL3 _FQL1
69#define _FRL4 _FQL2
70#define _FRL5 _FQL3
71#define _FRL6 1040
72#define _FRH0 _FQH0
73#define _FRH1 _FQH1
74#define _FRH2 _FQH2
75#define _FRH3 _FQH3
76#define _FRH4 1805
77#define _FRH5 1995
78#define _FRH6 2205
79
80static const struct tone {
81 const uint16_t c;
82 const float f0;
83 const float f1;
84} _roardsp_tones[] = {
85 {ROAR_DTMF_CHAR_DTMF('1'), _FQL0, _FQH0},
86 {ROAR_DTMF_CHAR_DTMF('2'), _FQL0, _FQH1},
87 {ROAR_DTMF_CHAR_DTMF('3'), _FQL0, _FQH2},
88 {ROAR_DTMF_CHAR_DTMF('A'), _FQL0, _FQH3},
89
90 {ROAR_DTMF_CHAR_DTMF('4'), _FQL1, _FQH0},
91 {ROAR_DTMF_CHAR_DTMF('5'), _FQL1, _FQH1},
92 {ROAR_DTMF_CHAR_DTMF('6'), _FQL1, _FQH2},
93 {ROAR_DTMF_CHAR_DTMF('B'), _FQL1, _FQH3},
94
95 {ROAR_DTMF_CHAR_DTMF('7'), _FQL2, _FQH0},
96 {ROAR_DTMF_CHAR_DTMF('8'), _FQL2, _FQH1},
97 {ROAR_DTMF_CHAR_DTMF('9'), _FQL2, _FQH2},
98 {ROAR_DTMF_CHAR_DTMF('C'), _FQL2, _FQH3},
99
100 {ROAR_DTMF_CHAR_DTMF('*'), _FQL3, _FQH0},
101 {ROAR_DTMF_CHAR_DTMF('0'), _FQL3, _FQH1},
102 {ROAR_DTMF_CHAR_DTMF('#'), _FQL3, _FQH2},
103 {ROAR_DTMF_CHAR_DTMF('D'), _FQL3, _FQH3},
104
105
106 {ROAR_DTMF_CHAR_NOOP,   _FRL0, _FRH0},
107 {ROAR_DTMF_CHAR_ESCAPE, _FRL0, _FRH1},
108
109 {ROAR_DTMF_CHAR_ROAR('"'), _FRL0, _FRH2},
110 {ROAR_DTMF_CHAR_ROAR(' '), _FRL0, _FRH3},
111 {ROAR_DTMF_CHAR_ROAR('F'), _FRL0, _FRH4},
112 {ROAR_DTMF_CHAR_ROAR('M'), _FRL0, _FRH5},
113 {ROAR_DTMF_CHAR_ROAR('T'), _FRL0, _FRH6},
114 {ROAR_DTMF_CHAR_ROAR('.'), _FRL1, _FRH0},
115 {ROAR_DTMF_CHAR_ROAR('?'), _FRL1, _FRH1},
116 {ROAR_DTMF_CHAR_ROAR('!'), _FRL1, _FRH2},
117 {ROAR_DTMF_CHAR_ROAR(','), _FRL1, _FRH3},
118 {ROAR_DTMF_CHAR_ROAR('G'), _FRL1, _FRH4},
119 {ROAR_DTMF_CHAR_ROAR('N'), _FRL1, _FRH5},
120 {ROAR_DTMF_CHAR_ROAR('U'), _FRL1, _FRH6},
121 {ROAR_DTMF_CHAR_ROAR('1'), _FRL2, _FRH0},
122 {ROAR_DTMF_CHAR_ROAR('2'), _FRL2, _FRH1},
123 {ROAR_DTMF_CHAR_ROAR('3'), _FRL2, _FRH2},
124 {ROAR_DTMF_CHAR_ROAR('A'), _FRL2, _FRH3},
125 {ROAR_DTMF_CHAR_ROAR('H'), _FRL2, _FRH4},
126 {ROAR_DTMF_CHAR_ROAR('O'), _FRL2, _FRH5},
127 {ROAR_DTMF_CHAR_ROAR('V'), _FRL2, _FRH6},
128 {ROAR_DTMF_CHAR_ROAR('4'), _FRL3, _FRH0},
129 {ROAR_DTMF_CHAR_ROAR('5'), _FRL3, _FRH1},
130 {ROAR_DTMF_CHAR_ROAR('6'), _FRL3, _FRH2},
131 {ROAR_DTMF_CHAR_ROAR('B'), _FRL3, _FRH3},
132 {ROAR_DTMF_CHAR_ROAR('I'), _FRL3, _FRH4},
133 {ROAR_DTMF_CHAR_ROAR('P'), _FRL3, _FRH5},
134 {ROAR_DTMF_CHAR_ROAR('W'), _FRL3, _FRH6},
135 {ROAR_DTMF_CHAR_ROAR('7'), _FRL4, _FRH0},
136 {ROAR_DTMF_CHAR_ROAR('8'), _FRL4, _FRH1},
137 {ROAR_DTMF_CHAR_ROAR('9'), _FRL4, _FRH2},
138 {ROAR_DTMF_CHAR_ROAR('C'), _FRL4, _FRH3},
139 {ROAR_DTMF_CHAR_ROAR('J'), _FRL4, _FRH4},
140 {ROAR_DTMF_CHAR_ROAR('Q'), _FRL4, _FRH5},
141 {ROAR_DTMF_CHAR_ROAR('X'), _FRL4, _FRH6},
142 {ROAR_DTMF_CHAR_ROAR('*'), _FRL5, _FRH0},
143 {ROAR_DTMF_CHAR_ROAR('0'), _FRL5, _FRH1},
144 {ROAR_DTMF_CHAR_ROAR('#'), _FRL5, _FRH2},
145 {ROAR_DTMF_CHAR_ROAR('D'), _FRL5, _FRH3},
146 {ROAR_DTMF_CHAR_ROAR('K'), _FRL5, _FRH4},
147 {ROAR_DTMF_CHAR_ROAR('R'), _FRL5, _FRH5},
148 {ROAR_DTMF_CHAR_ROAR('Y'), _FRL5, _FRH6},
149 {ROAR_DTMF_CHAR_ROAR('@'), _FRL6, _FRH0},
150 {ROAR_DTMF_CHAR_ROAR('+'), _FRL6, _FRH1},
151 {ROAR_DTMF_CHAR_ROAR('-'), _FRL6, _FRH2},
152 {ROAR_DTMF_CHAR_ROAR('E'), _FRL6, _FRH3},
153 {ROAR_DTMF_CHAR_ROAR('L'), _FRL6, _FRH4},
154 {ROAR_DTMF_CHAR_ROAR('S'), _FRL6, _FRH5},
155 {ROAR_DTMF_CHAR_ROAR('Z'), _FRL6, _FRH6},
156
157 {0, -1, -1}
158};
159
160static const struct tone * __lookup_tone(const int options, uint16_t c) {
161 size_t i;
162
163 (void)options;
164
165 if ( c >= 'a' )
166  c -= 'a' - 'A';
167
168 for (i = 0; _roardsp_tones[i].c != 0; i++) {
169  if ( _roardsp_tones[i].c == c ) {
170   return &(_roardsp_tones[i]);
171  }
172 }
173
174 roar_err_set(ROAR_ERROR_NOENT);
175 return NULL;
176}
177
178int roar_dtmf_tone (int16_t * samples, const size_t len, const uint32_t rate, const int options, const uint16_t c) {
179 const struct tone * ct = NULL;
180 size_t i;
181 float t;
182 float t_inc = 1./rate;
183 float fc0, fc1;
184
185 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);
186
187 if ( samples == NULL ) {
188  roar_err_set(ROAR_ERROR_FAULT);
189  return -1;
190 }
191
192 ct = __lookup_tone(options, c);
193
194 if ( ct == NULL ) {
195  roar_err_set(ROAR_ERROR_NOENT);
196  return -1;
197 }
198
199 fc0 = 2. * M_PI * ct->f0;
200 fc1 = 2. * M_PI * ct->f1;
201
202// memset(samples, 0, len);
203
204 for (i = 0, t = 0.; i < len; t += t_inc, i++) {
205  samples[i] = (sinf(fc0*t) + sinf(fc1*t))*8192.0;
206 }
207
208 return 0;
209}
210
211
212//ll
Note: See TracBrowser for help on using the repository browser.