[Freeswitch-svn] [commit] r5276 - freeswitch/trunk/libs/libteletone/src

Freeswitch SVN anthm at freeswitch.org
Wed Jun 6 19:28:01 EDT 2007


Author: anthm
Date: Wed Jun  6 19:28:00 2007
New Revision: 5276

Modified:
   freeswitch/trunk/libs/libteletone/src/libteletone_detect.c
   freeswitch/trunk/libs/libteletone/src/libteletone_detect.h
   freeswitch/trunk/libs/libteletone/src/libteletone_generate.c
   freeswitch/trunk/libs/libteletone/src/libteletone_generate.h

Log:
update teletone see wiki for syntax changes in TTML

Modified: freeswitch/trunk/libs/libteletone/src/libteletone_detect.c
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_detect.c	(original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_detect.c	Wed Jun  6 19:28:00 2007
@@ -90,7 +90,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <math.h>
+#include <libteletone_detect.h>
+
 #ifndef _MSC_VER
 #include <stdint.h>
 #endif
@@ -98,7 +99,7 @@
 #include <stdio.h>
 #include <time.h>
 #include <fcntl.h>
-#include <libteletone_detect.h>
+
 
 static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
 static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
@@ -208,8 +209,8 @@
 }
 
 int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
-					   int16_t sample_buffer[],
-					   int samples)
+								int16_t sample_buffer[],
+								int samples)
 {
 	int sample, limit, j, x = 0;
 	teletone_process_t v1, famp;
@@ -295,8 +296,8 @@
 
 
 int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
-                 int16_t sample_buffer[],
-                 int samples)
+						  int16_t sample_buffer[],
+						  int samples)
 {
     teletone_process_t row_energy[GRID_FACTOR];
     teletone_process_t col_energy[GRID_FACTOR];
@@ -426,8 +427,8 @@
 
 
 int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-              char *buf,
-              int max)
+					   char *buf,
+					   int max)
 {
     if (max > dtmf_detect_state->current_digits) {
         max = dtmf_detect_state->current_digits;

Modified: freeswitch/trunk/libs/libteletone/src/libteletone_detect.h
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_detect.h	(original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_detect.h	Wed Jun  6 19:28:00 2007
@@ -98,11 +98,11 @@
 #endif
 #include <libteletone.h>
 
-/*! \file libteletone_detect.h
-    \brief Tone Detection Routines
+	/*! \file libteletone_detect.h
+	  \brief Tone Detection Routines
 
-	This module is responsible for tone detection specifics
-*/
+	  This module is responsible for tone detection specifics
+	*/
 
 #ifndef FALSE
 #define FALSE   0
@@ -111,17 +111,17 @@
 #endif
 #endif
 
-/* Basic DTMF specs:
- *
- * Minimum tone on = 40ms
- * Minimum tone off = 50ms
- * Maximum digit rate = 10 per second
- * Normal twist <= 8dB accepted
- * Reverse twist <= 4dB accepted
- * S/N >= 15dB will detect OK
- * Attenuation <= 26dB will detect OK
- * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
- */
+	/* Basic DTMF specs:
+	 *
+	 * Minimum tone on = 40ms
+	 * Minimum tone off = 50ms
+	 * Maximum digit rate = 10 per second
+	 * Normal twist <= 8dB accepted
+	 * Reverse twist <= 4dB accepted
+	 * S/N >= 15dB will detect OK
+	 * Attenuation <= 26dB will detect OK
+	 * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
+	 */
 
 #define DTMF_THRESHOLD              8.0e7
 #define DTMF_NORMAL_TWIST           6.3     /* 8dB */
@@ -134,131 +134,131 @@
 #define BLOCK_LEN 102
 #define M_TWO_PI 2.0*M_PI
 
-/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
-typedef struct {
-	teletone_process_t v2;
-	teletone_process_t v3;
-	teletone_process_t fac;
-} teletone_goertzel_state_t;
+	/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
+	typedef struct {
+		teletone_process_t v2;
+		teletone_process_t v3;
+		teletone_process_t fac;
+	} teletone_goertzel_state_t;
 	
-/*! \brief A container for a DTMF detection state.*/
-typedef struct {
-    int hit1;
-    int hit2;
-    int hit3;
-    int hit4;
-    int mhit;
-
-    teletone_goertzel_state_t row_out[GRID_FACTOR];
-    teletone_goertzel_state_t col_out[GRID_FACTOR];
-    teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
-    teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
-    teletone_process_t energy;
+	/*! \brief A container for a DTMF detection state.*/
+	typedef struct {
+		int hit1;
+		int hit2;
+		int hit3;
+		int hit4;
+		int mhit;
+
+		teletone_goertzel_state_t row_out[GRID_FACTOR];
+		teletone_goertzel_state_t col_out[GRID_FACTOR];
+		teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
+		teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
+		teletone_process_t energy;
     
-    int current_sample;
-    char digits[TELETONE_MAX_DTMF_DIGITS + 1];
-    int current_digits;
-    int detected_digits;
-    int lost_digits;
-    int digit_hits[16];
-} teletone_dtmf_detect_state_t;
-
-/*! \brief An abstraction to store the coefficient of a tone frequency */
-typedef struct {
-    teletone_process_t fac;
-} teletone_detection_descriptor_t;
-
-/*! \brief A container for a single multi-tone detection 
-TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present
-in a multi-tone representation.
-*/
-typedef struct {
-	int sample_rate;
-
-	teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES];
-	teletone_goertzel_state_t gs[TELETONE_MAX_TONES];
-	teletone_goertzel_state_t gs2[TELETONE_MAX_TONES];
-	int tone_count;
+		int current_sample;
+		char digits[TELETONE_MAX_DTMF_DIGITS + 1];
+		int current_digits;
+		int detected_digits;
+		int lost_digits;
+		int digit_hits[16];
+	} teletone_dtmf_detect_state_t;
+
+	/*! \brief An abstraction to store the coefficient of a tone frequency */
+	typedef struct {
+		teletone_process_t fac;
+	} teletone_detection_descriptor_t;
+
+	/*! \brief A container for a single multi-tone detection 
+	  TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present
+	  in a multi-tone representation.
+	*/
+	typedef struct {
+		int sample_rate;
+
+		teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES];
+		teletone_goertzel_state_t gs[TELETONE_MAX_TONES];
+		teletone_goertzel_state_t gs2[TELETONE_MAX_TONES];
+		int tone_count;
 
-	teletone_process_t energy;
-	int current_sample;
+		teletone_process_t energy;
+		int current_sample;
 	
-	int min_samples;
-	int total_samples;
+		int min_samples;
+		int total_samples;
 
-	int positives;
-	int negatives;
-	int hits;
-
-	int positive_factor;
-	int negative_factor;
-	int hit_factor;
-
-} teletone_multi_tone_t;
-
-
-/*! 
-  \brief Initilize a multi-frequency tone detector
-  \param mt the multi-frequency tone descriptor
-  \param map a representation of the multi-frequency tone
-*/
-void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map);
-
-/*! 
-  \brief Check a sample buffer for the presence of the mulit-frequency tone described by mt
-  \param mt the multi-frequency tone descriptor
-  \param sample_buffer an array aof 16 bit signed linear samples
-  \param samples the number of samples present in sample_buffer
-  \return true when the tone was detected or false when it is not
-*/
-int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
-								int16_t sample_buffer[],
-								int samples);
-
-/*! 
-  \brief Initilize a DTMF detection state object
-  \param dtmf_detect_state the DTMF detection state to initilize
-  \param sample_rate the desired sample rate
-*/
-void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate);
-
-/*! 
-  \brief Check a sample buffer for the presence of DTMF digits
-  \param dtmf_detect_state the detection state object to check
-  \param sample_buffer an array aof 16 bit signed linear samples
-  \param samples the number of samples present in sample_buffer
-  \return true when DTMF was detected or false when it is not
-*/
-int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
-						  int16_t sample_buffer[],
-						  int samples);
-/*! 
-  \brief retrieve any collected digits into a string buffer
-  \param dtmf_detect_state the detection state object to check
-  \param buf the string buffer to write to
-  \param max the maximum length of buf
-  \return the number of characters written to buf
-*/
-int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
-					   char *buf,
-					   int max);
-
-/*! 
-  \brief Step through the Goertzel Algorithm for each sample in a buffer
-  \param goertzel_state the goertzel state to step the samples through
-  \param sample_buffer an array aof 16 bit signed linear samples
-  \param samples the number of samples present in sample_buffer
-*/
-void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
+		int positives;
+		int negatives;
+		int hits;
+
+		int positive_factor;
+		int negative_factor;
+		int hit_factor;
+
+	} teletone_multi_tone_t;
+
+
+	/*! 
+	  \brief Initilize a multi-frequency tone detector
+	  \param mt the multi-frequency tone descriptor
+	  \param map a representation of the multi-frequency tone
+	*/
+	void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map);
+
+	/*! 
+	  \brief Check a sample buffer for the presence of the mulit-frequency tone described by mt
+	  \param mt the multi-frequency tone descriptor
+	  \param sample_buffer an array aof 16 bit signed linear samples
+	  \param samples the number of samples present in sample_buffer
+	  \return true when the tone was detected or false when it is not
+	*/
+	int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
+									int16_t sample_buffer[],
+									int samples);
+
+	/*! 
+	  \brief Initilize a DTMF detection state object
+	  \param dtmf_detect_state the DTMF detection state to initilize
+	  \param sample_rate the desired sample rate
+	*/
+	void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate);
+
+	/*! 
+	  \brief Check a sample buffer for the presence of DTMF digits
+	  \param dtmf_detect_state the detection state object to check
+	  \param sample_buffer an array aof 16 bit signed linear samples
+	  \param samples the number of samples present in sample_buffer
+	  \return true when DTMF was detected or false when it is not
+	*/
+	int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
 							  int16_t sample_buffer[],
 							  int samples);
-
-/*! 
-  \brief Compute the result of the last applied step of the Goertzel Algorithm
-  \param goertzel_state the goertzel state to retrieve from
-  \return the computed value for consideration in furthur audio tests
-*/
-teletone_process_t teletone_goertzel_result (teletone_goertzel_state_t *goertzel_state);
+	/*! 
+	  \brief retrieve any collected digits into a string buffer
+	  \param dtmf_detect_state the detection state object to check
+	  \param buf the string buffer to write to
+	  \param max the maximum length of buf
+	  \return the number of characters written to buf
+	*/
+	int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
+						   char *buf,
+						   int max);
+
+	/*! 
+	  \brief Step through the Goertzel Algorithm for each sample in a buffer
+	  \param goertzel_state the goertzel state to step the samples through
+	  \param sample_buffer an array aof 16 bit signed linear samples
+	  \param samples the number of samples present in sample_buffer
+	*/
+	void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
+								  int16_t sample_buffer[],
+								  int samples);
+
+	/*! 
+	  \brief Compute the result of the last applied step of the Goertzel Algorithm
+	  \param goertzel_state the goertzel state to retrieve from
+	  \return the computed value for consideration in furthur audio tests
+	*/
+	teletone_process_t teletone_goertzel_result (teletone_goertzel_state_t *goertzel_state);
 
 
 

Modified: freeswitch/trunk/libs/libteletone/src/libteletone_generate.c
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_generate.c	(original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_generate.c	Wed Jun  6 19:28:00 2007
@@ -70,6 +70,7 @@
  */
 
 #include <libteletone.h>
+
 #define SMAX 32767
 #define SMIN -32768
 #define normalize_to_16bit(n) if (n > SMAX) n = SMAX; else if (n < SMIN) n = SMIN;
@@ -78,6 +79,25 @@
 #pragma warning(disable:4706)
 #endif
 
+int16_t TELETONE_SINES[SINE_TABLE_MAX] = {
+	0x00c9, 0x025b, 0x03ed, 0x057f, 0x0711, 0x08a2, 0x0a33, 0x0bc4,
+	0x0d54, 0x0ee4, 0x1073, 0x1201, 0x138f, 0x151c, 0x16a8, 0x1833,
+	0x19be, 0x1b47, 0x1cd0, 0x1e57, 0x1fdd, 0x2162, 0x22e5, 0x2467,
+	0x25e8, 0x2768, 0x28e5, 0x2a62, 0x2bdc, 0x2d55, 0x2ecc, 0x3042,
+	0x31b5, 0x3327, 0x3497, 0x3604, 0x3770, 0x38d9, 0x3a40, 0x3ba5,
+	0x3d08, 0x3e68, 0x3fc6, 0x4121, 0x427a, 0x43d1, 0x4524, 0x4675,
+	0x47c4, 0x490f, 0x4a58, 0x4b9e, 0x4ce1, 0x4e21, 0x4f5e, 0x5098,
+	0x51cf, 0x5303, 0x5433, 0x5560, 0x568a, 0x57b1, 0x58d4, 0x59f4,
+	0x5b10, 0x5c29, 0x5d3e, 0x5e50, 0x5f5e, 0x6068, 0x616f, 0x6272,
+	0x6371, 0x646c, 0x6564, 0x6657, 0x6747, 0x6832, 0x691a, 0x69fd,
+	0x6add, 0x6bb8, 0x6c8f, 0x6d62, 0x6e31, 0x6efb, 0x6fc2, 0x7083,
+	0x7141, 0x71fa, 0x72af, 0x735f, 0x740b, 0x74b3, 0x7556, 0x75f4,
+	0x768e, 0x7723, 0x77b4, 0x7840, 0x78c8, 0x794a, 0x79c9, 0x7a42,
+	0x7ab7, 0x7b27, 0x7b92, 0x7bf9, 0x7c5a, 0x7cb7, 0x7d0f, 0x7d63,
+	0x7db1, 0x7dfb, 0x7e3f, 0x7e7f, 0x7eba, 0x7ef0, 0x7f22, 0x7f4e,
+	0x7f75, 0x7f98, 0x7fb5, 0x7fce, 0x7fe2, 0x7ff1, 0x7ffa, 0x7fff
+};
+
 
 int teletone_set_tone(teletone_generation_session_t *ts, int index, ...)
 {
@@ -122,8 +142,9 @@
 	ts->tmp_wait = -1;
 	ts->handler = handler;
 	ts->user_data = user_data;
-	ts->volume = 1500;
+	ts->volume = -7;
 	ts->decay_step = 0;
+	ts->decay_factor = 1;
 	if (buflen) {
 		if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
 			return -1;
@@ -181,34 +202,24 @@
 
 int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
 {
-	teletone_process_t period = (1.0 / ts->rate) / ts->channels;
+	/*teletone_process_t period = (1.0 / ts->rate) / ts->channels;*/
 	int i, c;
 	int freqlen = 0;
-	teletone_process_t tones[TELETONE_MAX_TONES];
-	int decay = 0;
+	teletone_dds_state_t tones[TELETONE_MAX_TONES];
+	//int decay = 0;
 	int duration;
 	int wait = 0;
-	teletone_process_t sample;
-	
+	int32_t sample;
+	int32_t dc = 0;
+	float vol = ts->volume;
 	ts->samples = 0;
-
+	memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES);
 	duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration;
 	wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait;
 
 	if (map->freqs[0] > 0) {
-		if (ts->decay_step) {
-			if (ts->decay_factor) {
-				decay = (duration - (duration / ts->decay_factor));
-			} else {
-				decay = 0;
-			}
-		}
-		if (ts->volume < 0) {
-			ts->volume = 0;
-		}
-	
 		for (freqlen = 0; map->freqs[freqlen] && freqlen < TELETONE_MAX_TONES; freqlen++) {
-			tones[freqlen] = (teletone_process_t) map->freqs[freqlen] * (2 * M_PI);
+			teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, vol);
 		}
 	
 		if (ts->channels > 1) {
@@ -220,17 +231,28 @@
 				return -1;
 			}
 		}
+
 		for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) {
-			if (ts->decay_step && !(ts->samples % ts->decay_step) && ts->volume > 0 && ts->samples > decay) {
-				ts->volume += ts->decay_direction;
+			if (ts->decay_direction && ++dc >= ts->decay_step) {
+				float nvol = vol + ts->decay_direction * ts->decay_factor;
+				int j;
+
+				if (nvol <= TELETONE_VOL_DB_MAX && nvol >= TELETONE_VOL_DB_MIN) {
+					vol = nvol;
+					for (j = 0; map->freqs[j] && j < TELETONE_MAX_TONES; j++) {					
+						teletone_dds_state_set_tx_level(&tones[j], vol);
+					}
+					dc = 0;
+				}
 			}
 
-			sample = (teletone_process_t) 128;
+			sample = 128;
 
 			for (i = 0; i < freqlen; i++) {
-				sample += ((teletone_process_t) 2 * (ts->volume > 0 ? ts->volume : 1) * cos(tones[i] * ts->samples * period));
+				int32_t s = teletone_dds_modulate_sample(&tones[i]);
+				sample += s;
 			}
-			normalize_to_16bit(sample);
+			sample /= freqlen;
 			ts->buffer[ts->samples] = (teletone_audio_t)sample;
 			
 			for (c = 1; c < ts->channels; c++) {
@@ -261,7 +283,8 @@
 				fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]);
 			}
 			 
-			fprintf(ts->debug_stream, ") [volume %d; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %d; decay_step %d; wrote %d bytes]\n",
+			fprintf(ts->debug_stream, 
+					") [volume %0.2fDb; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %0.2f; decay_step %d(%dms); wrote %d bytes]\n",
 					ts->volume,
 					duration,
 					duration / (ts->rate / 1000), 
@@ -271,6 +294,7 @@
 					wait / (ts->rate / 1000),
 					ts->decay_factor,
 					ts->decay_step,
+					ts->decay_step / (ts->rate / 1000),					
 					ts->samples * 2);
 		}
 	}	
@@ -330,18 +354,23 @@
 					ts->duration = atoi(cur + 2) * (ts->rate / 1000);
 					break;
 				case 'v':
-					ts->volume = atoi(cur + 2);
+					{
+						float vol = atof(cur + 2);
+						if (vol <= TELETONE_VOL_DB_MAX && vol >= TELETONE_VOL_DB_MIN) {
+							ts->volume = vol;
+						}
+					}
 					break;
 				case '>':
-					ts->decay_factor = atoi(cur + 2);
+					ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
 					ts->decay_direction = -1;
 					break;
 				case '<':
-					ts->decay_factor = atoi(cur + 2);
+					ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
 					ts->decay_direction = 1;
 					break;
 				case '+':
-					ts->decay_step = atoi(cur + 2);
+					ts->decay_factor = atof(cur + 2);
 					break;
 				case 'w':
 					ts->wait = atoi(cur + 2) * (ts->rate / 1000);

Modified: freeswitch/trunk/libs/libteletone/src/libteletone_generate.h
==============================================================================
--- freeswitch/trunk/libs/libteletone/src/libteletone_generate.h	(original)
+++ freeswitch/trunk/libs/libteletone/src/libteletone_generate.h	Wed Jun  6 19:28:00 2007
@@ -72,13 +72,30 @@
 #define LIBTELETONE_GENERATE_H
 #ifdef __cplusplus
 extern "C" {
+#ifdef _doh
+}
+#endif
 #endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <math.h>
+#if !defined(powf)
+extern float powf (float, float);
+#endif
+#include <string.h>
+#include <errno.h>
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <math.h>
 #ifndef _MSC_VER
 #include <unistd.h>
+#include <stdint.h>
 #endif
 #include <fcntl.h>
 #include <sys/types.h>
@@ -87,12 +104,71 @@
 #include <stdarg.h>
 #include <libteletone.h>
 
+#define TELETONE_VOL_DB_MAX 0
+#define TELETONE_VOL_DB_MIN -63
+
+struct teletone_dds_state {
+	uint32_t phase_rate;
+	uint32_t scale_factor;
+	uint32_t phase_accumulator;
+	int16_t sample;
+	float tx_level;
+};
+typedef struct teletone_dds_state teletone_dds_state_t;
+
+#define SINE_TABLE_MAX 128
+#define SINE_TABLE_LEN (SINE_TABLE_MAX - 1)
+#define MAX_PHASE_ACCUMULATOR 0x10000 * 0x10000
+/* 3.14 == the max power on ulaw (alaw is 3.17) */
+/* 3.02 represents twice the power */
+#define DBM0_MAX_POWER (3.14f + 3.02f)
+
+extern int16_t TELETONE_SINES[SINE_TABLE_MAX];
+
+static __inline__ int16_t teletone_dds_modulate_sample(teletone_dds_state_t *dds)
+{
+    int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN;
+	int16_t sample;
+
+    if (bitmask & SINE_TABLE_MAX) {
+        sine_index = SINE_TABLE_LEN - sine_index;
+	}
+
+    sample = TELETONE_SINES[sine_index];
+	
+    if (bitmask & (SINE_TABLE_MAX * 2)) {
+		sample *= -1;
+	}
+
+	dds->phase_accumulator += dds->phase_rate;
+
+    return (int16_t) (sample * dds->scale_factor >> 15);
+}
+
+static __inline__ void teletone_dds_state_set_tone(teletone_dds_state_t *dds, float tone, uint32_t rate, float tx_level)
+{
+	dds->phase_accumulator = 0;
+	dds->phase_rate = (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate);
+
+
+	if (dds->tx_level != tx_level || !dds->scale_factor) {
+		dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f));
+	}
+	
+	dds->tx_level = tx_level;
+}
+
+static __inline__ void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level)
+{
+	dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f));
+}
+
 
 
 /*! \file libteletone_generate.h
-    \brief Tone Generation Routines
+  \brief Tone Generation Routines
 
-	This module is responsible for tone generation specifics
+  This module is responsible for tone generation specifics
 */
 
 typedef int16_t teletone_audio_t;
@@ -120,13 +196,13 @@
 	/*! Number of loops to repeat the entire set of instructions*/
 	int LOOPS;
 	/*! Number to mutiply total samples by to determine when to begin ascent or decent e.g. 0=beginning 4=(last 25%) */
-	int decay_factor;
+	float decay_factor;
 	/*! Direction to perform volume increase/decrease 1/-1*/
 	int decay_direction;
 	/*! Number of samples between increase/decrease of volume */
 	int decay_step;
 	/*! Volume factor of the tone */
-	int volume;
+	float volume;
 	/*! Debug on/off */
 	int debug;
 	/*! FILE stream to write debug data to */



More information about the Freeswitch-svn mailing list