Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5544)
+++ ChangeLog	(revision 5546)
@@ -6,4 +6,5 @@
 	* Done more hardending work.
 	* Improved error handling (including on win32) (Closes: #235)
+	* Added small DTMF library.
 
 v. 1.0beta2 - Wed Jun 06 2012 19:56 CEST
Index: include/libroardsp/dtmf.h
===================================================================
--- include/libroardsp/dtmf.h	(revision 5546)
+++ include/libroardsp/dtmf.h	(revision 5546)
@@ -0,0 +1,50 @@
+//dtmf.h:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
+ *
+ *  This file is part of libroar 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.
+ *
+ *  libroar 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, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ *  NOTE for everyone want's to change something and send patches:
+ *  read README and HACKING! There a addition information on
+ *  the license of this document you need to read before you send
+ *  any patches.
+ *
+ *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
+ *  or libpulse*:
+ *  The libs libroaresd, libroararts and libroarpulse link this lib
+ *  and are therefore GPL. Because of this it may be illigal to use
+ *  them with any software that uses libesd, libartsc or libpulse*.
+ */
+
+#ifndef _LIBROARDSP_DTMF_H_
+#define _LIBROARDSP_DTMF_H_
+
+#include "libroardsp.h"
+
+#define ROAR_DTMF_OPTIONS_NONE 0
+
+ssize_t roar_dtmf_mus2samples(const int_least32_t t, const uint32_t rate);
+
+int roar_dtmf_break(int16_t * samples, const size_t len, const uint32_t rate, const int options);
+int roar_dtmf_tone (int16_t * samples, const size_t len, const uint32_t rate, const int options, const uint16_t c);
+
+#endif
+
+//ll
Index: include/libroardsp/libroardsp.h
===================================================================
--- include/libroardsp/libroardsp.h	(revision 5381)
+++ include/libroardsp/libroardsp.h	(revision 5546)
@@ -58,4 +58,5 @@
 #include "filters.h"
 #include "codecs.h"
+#include "dtmf.h"
 #include "transcode.h"
 #include "vio_transcode.h"
Index: libroardsp/Makefile
===================================================================
--- libroardsp/Makefile	(revision 5270)
+++ libroardsp/Makefile	(revision 5546)
@@ -5,5 +5,5 @@
 
 TARGETS=$(SLIB) libroardsp.a
-OBJS=libroardsp.o convert.o midside.o poly.o filter.o filterchain.o remove.o transcode.o vio_transcode.o rms.o fader.o mixer.o amp.o interleave.o channels.o resampler_poly3.o float.o
+OBJS=libroardsp.o convert.o midside.o poly.o filter.o filterchain.o remove.o transcode.o vio_transcode.o rms.o fader.o mixer.o amp.o interleave.o channels.o resampler_poly3.o float.o dtmf.o
 OLDROAR=midi.o
 FILTER=filter_lowp.o filter_highp.o filter_amp.o filter_quantify.o filter_add.o filter_clip.o filter_downmix.o filter_dcblock.o filter_swap.o filter_agc.o filter_speex_prep.o filter_responsecurve.o
Index: libroardsp/dtmf.c
===================================================================
--- libroardsp/dtmf.c	(revision 5546)
+++ libroardsp/dtmf.c	(revision 5546)
@@ -0,0 +1,136 @@
+//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
Index: roarclients/Makefile
===================================================================
--- roarclients/Makefile	(revision 5516)
+++ roarclients/Makefile	(revision 5546)
@@ -3,7 +3,7 @@
 TARGETS_IO=roarcat roarcatplay roarcatvio roarbidir roarmon roarmonhttp roarradio
 TARGETS_CTL=roarctl roarlight roarinterconnect roarclientpass
-TARGETS_DSP=roarfilt roarvumeter
+TARGETS_DSP=roarfilt roarvumeter roardtmf
 TARGETS_MISC=roarsockconnect roarphone roarshout
-TARGETS_M=roardtmf
+TARGETS_M=
 TARGETS_VIO=roarvio
 TARGETS_PLUGINS=roarpluginrunner roarpluginapplication
@@ -78,5 +78,5 @@
 	${CC} ${LDFLAGS} -o roarvumeter roarvumeter.o $(LIBS) $(LIBROARDSP) $(lib_m)
 roardtmf: roardtmf.o
-	${CC} ${LDFLAGS} -o roardtmf roardtmf.o $(LIBS) $(lib_m)
+	${CC} ${LDFLAGS} -o roardtmf roardtmf.o $(LIBS) $(LIBROARDSP)
 roarsockconnect: roarsockconnect.o
 	$L
Index: roarclients/roardtmf.c
===================================================================
--- roarclients/roardtmf.c	(revision 5545)
+++ roarclients/roardtmf.c	(revision 5546)
@@ -25,4 +25,5 @@
 
 #include <roaraudio.h>
+#include <libroardsp/libroardsp.h>
 
 #ifdef ROAR_HAVE_LIBM
@@ -30,35 +31,12 @@
 
 // in ms:
+#if 0
 #define ON_TIME  (180)
 #define OFF_TIME ( 80)
+#else
+#define ON_TIME  (180)
+#define OFF_TIME ( 80)
+#endif
 #define SUM_TIME (ON_TIME+OFF_TIME)
-
-struct tone {
- char c;
- float f0;
- float f1;
-} g_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}
-};
 
 void usage (void) {
@@ -74,55 +52,4 @@
 }
 
-int calc_break (int16_t * samples, size_t len, int rate, char c) {
- (void)rate, (void)c;
-// printf("calc_break(*): len=%zu\n", len);
- memset(samples, 0, len);
- return 0;
-}
-
-int calc_tone (int16_t * samples, size_t len, int rate, char c) {
- struct tone * ct = NULL;
- int i;
- float t;
- float t_inc = 1./rate;
- float t_max = ON_TIME / 1000.;
- float fc0, fc1;
-
-// printf("calc_tone(*): len=%zu\n", len);
-
-// printf("calc(*): t_inc=%f, t_max=%f\n", t_inc, t_max);
-
- if ( c >= 'a' )
-  c -= 'a' - 'A';
-
- for (i = 0; g_tones[i].c != 0; i++) {
-  if ( g_tones[i].c == c ) {
-   ct = &(g_tones[i]);
-   break;
-  }
- }
-
-// printf("calc(*): ct=%p\n", ct);
-
- if ( ct == NULL )
-  return -1;
-
- fc0 = 2 * M_PI * ct->f0;
- fc1 = 2 * M_PI * ct->f1;
-
-// printf("fc0=%f, fc1=%f\n", fc0, fc1);
-
- memset(samples, 0, len);
-
- for (i = 0, t = 0; t < t_max; t += t_inc, i++) {
-//  printf("i=%i, t=%f\n", i, t);
-  samples[i] = (sinf(fc0*t) + sinf(fc1*t))*8192.0;
- }
-
-// printf("i=%i\n", i);
-
- return 0;
-}
-
 int main (int argc, char * argv[]) {
  int    rate     = ROAR_RATE_DEFAULT;
@@ -134,4 +61,6 @@
  const char * tones = NULL;
  void * buf;
+ size_t len_break;
+ size_t len_tone;
  size_t samples;
  size_t len;
@@ -162,8 +91,10 @@
  }
 
- samples = SUM_TIME * rate / 1000;
+ len_break = roar_dtmf_mus2samples(OFF_TIME * 1000, rate);
+ len_tone  = roar_dtmf_mus2samples(ON_TIME  * 1000, rate);
+ samples = len_break + len_tone;
 
+ printf("samples=%llu\n", (long long unsigned int)samples);
 /*
- printf("samples=%llu\n", (long long unsigned int)samples);
  return 0;
 */
@@ -185,11 +116,12 @@
 
   if ( c == ' ' ) {
-   calc_break(buf, len, rate, c);
+   roar_dtmf_break(buf, len_tone, rate, ROAR_DTMF_OPTIONS_NONE);
   } else {
-   if ( calc_tone(buf, len, rate, c) == -1 ) {
+   if ( roar_dtmf_tone(buf, len_tone, rate, ROAR_DTMF_OPTIONS_NONE, c) == -1 ) {
     roar_mm_free(buf);
     return 5;
    }
   }
+  roar_dtmf_break(buf+len_tone*sizeof(int16_t), len_break, rate, ROAR_DTMF_OPTIONS_NONE);
   if ( roar_vs_write(vss, buf, len, &err) != (ssize_t)len ) {
    fprintf(stderr, "Error: can not write data: %s\n", roar_vs_strerr(err));
