FreeSWITCH API Documentation  1.7.0
Data Structures | Macros | Typedefs | Functions | Variables
libteletone_generate.h File Reference

Tone Generation Routines. More...

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#include <libteletone.h>
+ Include dependency graph for libteletone_generate.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  teletone_dds_state
 
struct  teletone_generation_session
 An abstraction to store a tone generation session. More...
 

Macros

#define TELETONE_VOL_DB_MAX   0
 
#define TELETONE_VOL_DB_MIN   -63
 
#define MAX_PHASE_TONES   4
 
#define SINE_TABLE_MAX   128
 
#define SINE_TABLE_LEN   (SINE_TABLE_MAX - 1)
 
#define MAX_PHASE_ACCUMULATOR   0x10000 * 0x10000
 
#define DBM0_MAX_POWER   (3.14f + 3.02f)
 

Typedefs

typedef struct teletone_dds_state teletone_dds_state_t
 
typedef int16_t teletone_audio_t
 
typedef int(* tone_handler )(struct teletone_generation_session *ts, teletone_tone_map_t *map)
 
typedef struct
teletone_generation_session 
teletone_generation_session_t
 

Functions

float powf (float, float)
 
static __inline__ int32_t teletone_dds_phase_rate (teletone_process_t tone, uint32_t rate)
 
static __inline__ int16_t teletone_dds_state_modulate_sample (teletone_dds_state_t *dds, uint32_t pindex)
 
static __inline__ void teletone_dds_state_set_tx_level (teletone_dds_state_t *dds, float tx_level)
 
static __inline__ void teletone_dds_state_reset_accum (teletone_dds_state_t *dds)
 
static __inline__ int teletone_dds_state_set_tone (teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex)
 
int teletone_set_tone (teletone_generation_session_t *ts, int index,...)
 Assign a set of tones to a tone_session indexed by a paticular index/character. More...
 
int teletone_set_map (teletone_tone_map_t *map,...)
 Assign a set of tones to a single tone map. More...
 
int teletone_init_session (teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
 Initilize a tone generation session. More...
 
int teletone_destroy_session (teletone_generation_session_t *ts)
 Free the buffer allocated by a tone generation session. More...
 
int teletone_mux_tones (teletone_generation_session_t *ts, teletone_tone_map_t *map)
 Execute a single tone generation instruction. More...
 
int teletone_run (teletone_generation_session_t *ts, const char *cmd)
 Execute a tone generation script and call callbacks after each instruction. More...
 

Variables

int16_t TELETONE_SINES [SINE_TABLE_MAX]
 

Detailed Description

Tone Generation Routines.

This module is responsible for tone generation specifics

Definition in file libteletone_generate.h.

Macro Definition Documentation

#define DBM0_MAX_POWER   (3.14f + 3.02f)

Definition at line 147 of file libteletone_generate.h.

Referenced by teletone_dds_state_set_tx_level().

#define MAX_PHASE_ACCUMULATOR   0x10000 * 0x10000

Definition at line 144 of file libteletone_generate.h.

Referenced by teletone_dds_phase_rate().

#define MAX_PHASE_TONES   4
#define SINE_TABLE_LEN   (SINE_TABLE_MAX - 1)

Definition at line 143 of file libteletone_generate.h.

Referenced by teletone_dds_state_modulate_sample().

#define SINE_TABLE_MAX   128

Definition at line 142 of file libteletone_generate.h.

Referenced by teletone_dds_state_modulate_sample().

#define TELETONE_VOL_DB_MAX   0

Definition at line 130 of file libteletone_generate.h.

#define TELETONE_VOL_DB_MIN   -63

Definition at line 131 of file libteletone_generate.h.

Referenced by teletone_mux_tones(), and teletone_run().

Typedef Documentation

typedef int16_t teletone_audio_t

Definition at line 208 of file libteletone_generate.h.

Definition at line 140 of file libteletone_generate.h.

Definition at line 257 of file libteletone_generate.h.

typedef int(* tone_handler)(struct teletone_generation_session *ts, teletone_tone_map_t *map)

Definition at line 210 of file libteletone_generate.h.

Function Documentation

float powf ( float  ,
float   
)
static __inline__ int32_t teletone_dds_phase_rate ( teletone_process_t  tone,
uint32_t  rate 
)
static

Definition at line 151 of file libteletone_generate.h.

References MAX_PHASE_ACCUMULATOR.

Referenced by teletone_dds_state_set_tone().

152 {
153  return (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate);
154 }
#define MAX_PHASE_ACCUMULATOR
static __inline__ int16_t teletone_dds_state_modulate_sample ( teletone_dds_state_t dds,
uint32_t  pindex 
)
static

Definition at line 156 of file libteletone_generate.h.

References MAX_PHASE_TONES, teletone_dds_state::phase_accumulator, teletone_dds_state::phase_rate, teletone_dds_state::scale_factor, SINE_TABLE_LEN, SINE_TABLE_MAX, and TELETONE_SINES.

Referenced by teletone_mux_tones().

157 {
158  int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN;
159  int16_t sample;
160 
161  if (pindex >= MAX_PHASE_TONES) {
162  pindex = 0;
163  }
164 
165  if (bitmask & SINE_TABLE_MAX) {
166  sine_index = SINE_TABLE_LEN - sine_index;
167  }
168 
169  sample = TELETONE_SINES[sine_index];
170 
171  if (bitmask & (SINE_TABLE_MAX * 2)) {
172  sample *= -1;
173  }
174 
175  dds->phase_accumulator += dds->phase_rate[pindex];
176  return (int16_t) (sample * dds->scale_factor >> 15);
177 }
uint32_t phase_rate[MAX_PHASE_TONES]
#define SINE_TABLE_LEN
#define MAX_PHASE_TONES
int16_t TELETONE_SINES[SINE_TABLE_MAX]
#define SINE_TABLE_MAX
static __inline__ void teletone_dds_state_reset_accum ( teletone_dds_state_t dds)
static

Definition at line 185 of file libteletone_generate.h.

References teletone_dds_state::phase_accumulator.

186 {
187  dds->phase_accumulator = 0;
188 }
static __inline__ int teletone_dds_state_set_tone ( teletone_dds_state_t dds,
teletone_process_t  tone,
uint32_t  rate,
uint32_t  pindex 
)
static

Definition at line 190 of file libteletone_generate.h.

References MAX_PHASE_TONES, teletone_dds_state::phase_rate, and teletone_dds_phase_rate().

Referenced by teletone_mux_tones().

191 {
192  if (pindex < MAX_PHASE_TONES) {
193  dds->phase_rate[pindex] = teletone_dds_phase_rate(tone, rate);
194  return 0;
195  }
196 
197  return -1;
198 }
uint32_t phase_rate[MAX_PHASE_TONES]
static __inline__ int32_t teletone_dds_phase_rate(teletone_process_t tone, uint32_t rate)
#define MAX_PHASE_TONES
static __inline__ void teletone_dds_state_set_tx_level ( teletone_dds_state_t dds,
float  tx_level 
)
static

Definition at line 179 of file libteletone_generate.h.

References DBM0_MAX_POWER, powf(), teletone_dds_state::scale_factor, and teletone_dds_state::tx_level.

Referenced by teletone_mux_tones().

180 {
181  dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f));
182  dds->tx_level = tx_level;
183 }
#define DBM0_MAX_POWER
teletone_process_t tx_level
float powf(float, float)
int teletone_destroy_session ( teletone_generation_session_t ts)

Free the buffer allocated by a tone generation session.

Parameters
tsthe tone generation session to destroy
Returns
0

Definition at line 177 of file libteletone_generate.c.

Referenced by inband_dtmf_generate_callback(), main(), setup_ringback(), switch_ivr_gentones(), switch_ivr_originate(), and switch_ivr_wait_for_answer().

178 {
179  if (ts->buffer) {
180  free(ts->buffer);
181  ts->buffer = NULL;
182  ts->samples = 0;
183  }
184  return 0;
185 }
int teletone_init_session ( teletone_generation_session_t ts,
int  buflen,
tone_handler  handler,
void *  user_data 
)

Initilize a tone generation session.

Parameters
tsthe tone generation session to initilize
buflenthe size of the buffer(in samples) to dynamically allocate
handlera callback function to execute when a tone generation instruction is complete
user_dataoptional user data to send
Returns
0

Definition at line 134 of file libteletone_generate.c.

References buflen, memset(), and teletone_set_tone().

Referenced by inband_dtmf_generate_callback(), main(), setup_ringback(), switch_ivr_gentones(), and switch_ivr_wait_for_answer().

135 {
136  memset(ts, 0, sizeof(*ts));
137  ts->rate = 8000;
138  ts->channels = 1;
139  ts->duration = 2000;
140  ts->wait = 500;
141  ts->tmp_duration = -1;
142  ts->tmp_wait = -1;
143  ts->handler = handler;
144  ts->user_data = user_data;
145  ts->volume = -7;
146  ts->decay_step = 0;
147  ts->decay_factor = 1;
148  if (buflen) {
149  if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
150  return -1;
151  }
152  ts->datalen = buflen;
153  } else {
154  ts->dynamic = 1024;
155  }
156  /* Add Standard DTMF Tones */
157  teletone_set_tone(ts, '1', 697.0, 1209.0, 0.0);
158  teletone_set_tone(ts, '2', 697.0, 1336.0, 0.0);
159  teletone_set_tone(ts, '3', 697.0, 1477.0, 0.0);
160  teletone_set_tone(ts, 'A', 697.0, 1633.0, 0.0);
161  teletone_set_tone(ts, '4', 770.0, 1209.0, 0.0);
162  teletone_set_tone(ts, '5', 770.0, 1336.0, 0.0);
163  teletone_set_tone(ts, '6', 770.0, 1477.0, 0.0);
164  teletone_set_tone(ts, 'B', 770.0, 1633.0, 0.0);
165  teletone_set_tone(ts, '7', 859.0, 1209.0, 0.0);
166  teletone_set_tone(ts, '8', 859.0, 1336.0, 0.0);
167  teletone_set_tone(ts, '9', 859.0, 1477.0, 0.0);
168  teletone_set_tone(ts, 'C', 859.0, 1633.0, 0.0);
169  teletone_set_tone(ts, '*', 941.0, 1209.0, 0.0);
170  teletone_set_tone(ts, '0', 941.0, 1336.0, 0.0);
171  teletone_set_tone(ts, '#', 941.0, 1477.0, 0.0);
172  teletone_set_tone(ts, 'D', 941.0, 1633.0, 0.0);
173 
174  return 0;
175 }
int teletone_set_tone(teletone_generation_session_t *ts, int index,...)
Assign a set of tones to a tone_session indexed by a paticular index/character.
switch_byte_t switch_byte_t uint32_t buflen
int16_t teletone_audio_t
memset(buf, 0, buflen)
int teletone_mux_tones ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)

Execute a single tone generation instruction.

Parameters
tsthe tone generation session to consult for parameters
mapthe tone mapping to use for the frequencies
Returns
0

Definition at line 206 of file libteletone_generate.c.

References ensure_buffer(), memset(), teletone_dds_state_modulate_sample(), teletone_dds_state_set_tone(), teletone_dds_state_set_tx_level(), TELETONE_MAX_TONES, and TELETONE_VOL_DB_MIN.

Referenced by teletone_dtmf_generate_handler(), and teletone_handler().

207 {
208  /*teletone_process_t period = (1.0 / ts->rate) / ts->channels;*/
209  int i, c;
210  int freqlen = 0;
212  //int decay = 0;
213  int duration;
214  int wait = 0;
215  int32_t sample;
216  int32_t dc = 0;
217  float vol = ts->volume;
218  ts->samples = 0;
219  memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES);
220  duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration;
221  wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait;
222 
223  if (map->freqs[0] > 0) {
224  for (freqlen = 0; freqlen < TELETONE_MAX_TONES && map->freqs[freqlen]; freqlen++) {
225  teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0);
226  teletone_dds_state_set_tx_level(&tones[freqlen], vol);
227  }
228 
229  if (ts->channels > 1) {
230  duration *= ts->channels;
231  }
232 
233  if (ts->dynamic) {
234  if (ensure_buffer(ts, duration)) {
235  return -1;
236  }
237  }
238 
239  for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) {
240  if (ts->decay_direction && ++dc >= ts->decay_step) {
241  float nvol = vol + ts->decay_direction * ts->decay_factor;
242  int j;
243 
244  if (nvol <= TELETONE_VOL_DB_MAX && nvol >= TELETONE_VOL_DB_MIN) {
245  vol = nvol;
246  for (j = 0; j < TELETONE_MAX_TONES && map->freqs[j]; j++) {
247  teletone_dds_state_set_tx_level(&tones[j], vol);
248  }
249  dc = 0;
250  }
251  }
252 
253  sample = 128;
254 
255  for (i = 0; i < freqlen; i++) {
256  int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0);
257  sample += s;
258  }
259  sample /= freqlen;
260  ts->buffer[ts->samples] = (teletone_audio_t)sample;
261 
262  for (c = 1; c < ts->channels; c++) {
263  ts->buffer[ts->samples+1] = ts->buffer[ts->samples];
264  ts->samples++;
265  }
266 
267  }
268  }
269  if (ts->dynamic) {
270  if (ensure_buffer(ts, wait)) {
271  return -1;
272  }
273  }
274  for (c = 0; c < ts->channels; c++) {
275  for (i = 0; i < wait && ts->samples < ts->datalen; i++) {
276  ts->buffer[ts->samples++] = 0;
277  }
278  }
279 
280  if (ts->debug && ts->debug_stream) {
281  if (map->freqs[0] <= 0) {
282  fprintf(ts->debug_stream, "wait %d (%dms)\n", wait, wait / (ts->rate / 1000));
283  } else {
284  fprintf(ts->debug_stream, "Generate: (");
285 
286  for (i = 0; i < TELETONE_MAX_TONES && map->freqs[i]; i++) {
287  fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]);
288  }
289 
290  fprintf(ts->debug_stream,
291  ") [volume %0.2fdB; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %0.2fdB; decay_step %d(%dms); wrote %d bytes]\n",
292  ts->volume,
293  duration,
294  duration / (ts->rate / 1000),
295  ts->channels,
296  ts->channels == 1 ? "" : "s",
297  wait,
298  wait / (ts->rate / 1000),
299  ts->decay_factor,
300  ts->decay_step,
301  ts->decay_step / (ts->rate / 1000),
302  ts->samples * 2);
303  }
304  }
305  return ts->samples / ts->channels;
306 }
static __inline__ int16_t teletone_dds_state_modulate_sample(teletone_dds_state_t *dds, uint32_t pindex)
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
static __inline__ int teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex)
#define TELETONE_VOL_DB_MIN
static __inline__ void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level)
teletone_process_t freqs[TELETONE_MAX_TONES]
Definition: libteletone.h:95
static int ensure_buffer(teletone_generation_session_t *ts, int need)
int16_t teletone_audio_t
memset(buf, 0, buflen)
int teletone_run ( teletone_generation_session_t ts,
const char *  cmd 
)

Execute a tone generation script and call callbacks after each instruction.

Parameters
tsthe tone generation session to execute on
cmdthe script to execute
Returns
0

Definition at line 321 of file libteletone_generate.c.

References cur, teletone_tone_map_t::freqs, memset(), my_strdup(), TELETONE_MAX_TONES, TELETONE_TONE_RANGE, and TELETONE_VOL_DB_MIN.

Referenced by inband_dtmf_generate_callback(), main(), setup_ringback(), switch_ivr_gentones(), and switch_ivr_wait_for_answer().

322 {
323  char *data = NULL, *cur = NULL, *end = NULL;
324  int LOOPING = 0;
325 
326  if (!cmd) {
327  return -1;
328  }
329 
330  do {
331  if (!(data = my_strdup(cmd))) {
332  return -1;
333  }
334 
335  cur = data;
336 
337  while (*cur) {
338  if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
339  cur++;
340  continue;
341  }
342 
343  if ((end = strchr(cur, ';')) != 0) {
344  *end++ = '\0';
345  }
346 
347  if (*(cur + 1) == '=') {
348  switch(*cur) {
349  case 'c':
350  ts->channels = atoi(cur + 2);
351  break;
352  case 'r':
353  ts->rate = atoi(cur + 2);
354  break;
355  case 'd':
356  ts->duration = atoi(cur + 2) * (ts->rate / 1000);
357  break;
358  case 'v':
359  {
360  float vol = (float)atof(cur + 2);
361  if (vol <= TELETONE_VOL_DB_MAX && vol >= TELETONE_VOL_DB_MIN) {
362  ts->volume = vol;
363  }
364  }
365  break;
366  case '>':
367  ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
368  ts->decay_direction = -1;
369  break;
370  case '<':
371  ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
372  ts->decay_direction = 1;
373  break;
374  case '+':
375  ts->decay_factor = (float)atof(cur + 2);
376  break;
377  case 'w':
378  ts->wait = atoi(cur + 2) * (ts->rate / 1000);
379  break;
380  case 'l':
381  ts->loops = atoi(cur + 2);
382  break;
383  case 'L':
384  if (!LOOPING) {
385  int L;
386  if ((L = atoi(cur + 2)) > 0) {
387  ts->LOOPS = L;
388  LOOPING++;
389  }
390  }
391  break;
392  }
393  } else {
394  while (*cur) {
395  char *p = NULL, *e = NULL;
396  teletone_tone_map_t mymap, *mapp = NULL;
397 
398  if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
399  cur++;
400  continue;
401  }
402 
403  ts->tmp_duration = -1;
404  ts->tmp_wait = -1;
405 
406  memset(&mymap, 0, sizeof(mymap));
407 
408  if (*(cur + 1) == '(') {
409  p = cur + 2;
410  if (*cur) {
411  char *next;
412  int i = 0;
413  if ((e = strchr(p, ')')) != 0) {
414  *e++ = '\0';
415  }
416  do {
417 #if (_MSC_VER == 1600)
418  if (!p) {
419  break;
420  }
421 #endif
422  if ((next = strchr(p, ',')) != 0) {
423  *next++ = '\0';
424  }
425  if (i == 0) {
426  ts->tmp_duration = atoi(p) * (ts->rate / 1000);
427  i++;
428  } else if (i == 1) {
429  ts->tmp_wait = atoi(p) * (ts->rate / 1000);
430  i++;
431  } else {
432  mymap.freqs[i++ - 2] = atof(p);
433  }
434  p = next;
435 
436  } while (next && (i-2) < TELETONE_MAX_TONES);
437  if (i > 2 && *cur == '%') {
438  mapp = &mymap;
439  } else if ((i != 2 || *cur == '%')) {
440  if (ts->debug && ts->debug_stream) {
441  fprintf(ts->debug_stream, "Syntax Error!\n");
442  }
443  goto bottom;
444  }
445  }
446  }
447 
448  if (*cur && !mapp) {
449  if (*cur > 0 && *cur < TELETONE_TONE_RANGE) {
450  mapp = &ts->TONES[(int)*cur];
451  } else if (ts->debug && ts->debug_stream) {
452  fprintf(ts->debug_stream, "Map [%c] Out Of Range!\n", *cur);
453  }
454  }
455 
456  if (mapp) {
457  if (mapp->freqs[0]) {
458  if (ts->handler) {
459  do {
460  ts->handler(ts, mapp);
461  if (ts->loops > 0) {
462  ts->loops--;
463  }
464  } while (ts->loops);
465  }
466  } else if (ts->debug && ts->debug_stream) {
467  fprintf(ts->debug_stream, "Ignoring Empty Map [%c]!\n", *cur);
468  }
469  }
470 
471  if (e) {
472  cur = e;
473  } else {
474  cur++;
475  }
476  }
477  }
478 
479  if (end) {
480  cur = end;
481  } else if (*cur){
482  cur++;
483  }
484  }
485  bottom:
486  free(data);
487  data = NULL;
488 
489  if (ts->LOOPS > 0) {
490  ts->LOOPS--;
491  }
492 
493  } while (ts->LOOPS);
494 
495  return 0;
496 }
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
An abstraction to store a tone mapping.
Definition: libteletone.h:93
static char * my_strdup(const char *s)
pack cur
teletone_tone_map_t TONES[TELETONE_TONE_RANGE]
#define TELETONE_VOL_DB_MIN
teletone_process_t freqs[TELETONE_MAX_TONES]
Definition: libteletone.h:95
#define TELETONE_TONE_RANGE
Definition: libteletone.h:82
memset(buf, 0, buflen)
int teletone_set_map ( teletone_tone_map_t map,
  ... 
)

Assign a set of tones to a single tone map.

Parameters
mapthe map to assign the tones to
...up to TELETONE_MAX_TONES frequencies terminated by 0.0
Returns
0

Definition at line 118 of file libteletone_generate.c.

References TELETONE_MAX_TONES.

119 {
120  va_list ap;
121  int i = 0;
122  teletone_process_t x = 0;
123 
124  va_start(ap, map);
125  while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) {
126  map->freqs[i++] = x;
127  }
128  va_end(ap);
129 
130  return (i > TELETONE_MAX_TONES) ? -1 : 0;
131 
132 }
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
double teletone_process_t
Definition: libteletone.h:84
teletone_process_t freqs[TELETONE_MAX_TONES]
Definition: libteletone.h:95
int teletone_set_tone ( teletone_generation_session_t ts,
int  index,
  ... 
)

Assign a set of tones to a tone_session indexed by a paticular index/character.

Parameters
tsthe tone generation session
indexthe index to map the tone to
...up to TELETONE_MAX_TONES frequencies terminated by 0.0
Returns
0

Definition at line 102 of file libteletone_generate.c.

References TELETONE_MAX_TONES.

Referenced by teletone_init_session().

103 {
104  va_list ap;
105  int i = 0;
106  teletone_process_t x = 0;
107 
108  va_start(ap, index);
109  while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) {
110  ts->TONES[index].freqs[i++] = x;
111  }
112  va_end(ap);
113 
114  return (i > TELETONE_MAX_TONES) ? -1 : 0;
115 
116 }
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
double teletone_process_t
Definition: libteletone.h:84
teletone_tone_map_t TONES[TELETONE_TONE_RANGE]
teletone_process_t freqs[TELETONE_MAX_TONES]
Definition: libteletone.h:95

Variable Documentation

int16_t TELETONE_SINES[SINE_TABLE_MAX]

Definition at line 82 of file libteletone_generate.c.

Referenced by teletone_dds_state_modulate_sample().