dtmf.c File Reference
`#include <stdlib.h>`
`#include <inttypes.h>`
`#include "floating_fudge.h"`
`#include <memory.h>`
`#include <string.h>`
`#include <limits.h>`
`#include "spandsp/telephony.h"`
`#include "spandsp/logging.h"`
`#include "spandsp/fast_convert.h"`
`#include "spandsp/queue.h"`
`#include "spandsp/complex.h"`
`#include "spandsp/dds.h"`
`#include "spandsp/tone_detect.h"`
`#include "spandsp/tone_generate.h"`
`#include "spandsp/super_tone_rx.h"`
`#include "spandsp/dtmf.h"`
`#include "spandsp/private/logging.h"`
`#include "spandsp/private/queue.h"`
`#include "spandsp/private/tone_generate.h"`
`#include "spandsp/private/dtmf.h"`

## Macros

#define | DEFAULT_DTMF_TX_LEVEL -10
#define | DEFAULT_DTMF_TX_ON_TIME 50
#define | DEFAULT_DTMF_TX_OFF_TIME 55
#define | DTMF_THRESHOLD 171032462.0f /* -42dBm0 [((DTMF_SAMPLES_PER_BLOCK*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2 => 171032462.0] */
#define | DTMF_NORMAL_TWIST 6.309f /* 8dB [10^(8/10) => 6.309] */
#define | DTMF_REVERSE_TWIST 2.512f /* 4dB */
#define | DTMF_RELATIVE_PEAK_ROW 6.309f /* 8dB */
#define | DTMF_RELATIVE_PEAK_COL 6.309f /* 8dB */
#define | DTMF_TO_TOTAL_ENERGY 83.868f /* -0.85dB [DTMF_SAMPLES_PER_BLOCK*10^(-0.85/10.0)] */
#define | DTMF_POWER_OFFSET 110.395f /* 10*log(32768.0*32768.0*DTMF_SAMPLES_PER_BLOCK) */
#define | DTMF_SAMPLES_PER_BLOCK 102

## Functions

int | dtmf_rx (dtmf_rx_state_t *s, const int16_t amp[], int samples)
| Process a block of received DTMF audio samples.
int | dtmf_rx_fillin (dtmf_rx_state_t *s, int samples)
| Fake processing of a missing block of received DTMF audio samples.
int | dtmf_rx_status (dtmf_rx_state_t *s)
| Get the status of DTMF detection during processing of the last audio chunk.
size_t | dtmf_rx_get (dtmf_rx_state_t *s, char *buf, int max)
| Get a string of digits from a DTMF receiver's output buffer.
void | dtmf_rx_set_realtime_callback (dtmf_rx_state_t *s, tone_report_func_t callback, void *user_data)
| Set a realtime callback for a DTMF receiver context.
void | dtmf_rx_parms (dtmf_rx_state_t *s, int filter_dialtone, int twist, int reverse_twist, int threshold)
| Adjust a DTMF receiver context.
logging_state_t * | dtmf_rx_get_logging_state (dtmf_rx_state_t *s)
| Get the logging context associated with a DTMF receiver context.
dtmf_rx_state_t * | dtmf_rx_init (dtmf_rx_state_t *s, digits_rx_callback_t callback, void *user_data)
| Initialise a DTMF receiver context.
int | dtmf_rx_release (dtmf_rx_state_t *s)
| Release a DTMF receiver context.
int | dtmf_rx_free (dtmf_rx_state_t *s)
| Free a DTMF receiver context.
int | dtmf_tx (dtmf_tx_state_t *s, int16_t amp[], int max_samples)
| Generate a buffer of DTMF tones.
int | dtmf_tx_put (dtmf_tx_state_t *s, const char *digits, int len)
| Put a string of digits in a DTMF generator's input buffer.
void | dtmf_tx_set_level (dtmf_tx_state_t *s, int level, int twist)
| Change the transmit level for a DTMF tone generator context.
void | dtmf_tx_set_timing (dtmf_tx_state_t *s, int on_time, int off_time)
| Change the transmit on and off time for a DTMF tone generator context.
dtmf_tx_state_t * | dtmf_tx_init (dtmf_tx_state_t *s)
| Initialise a DTMF tone generator context.
int | dtmf_tx_release (dtmf_tx_state_t *s)
| Release a DTMF tone generator context.
int | dtmf_tx_free (dtmf_tx_state_t *s)
| Free a DTMF tone generator context.

## Function Documentation

## dtmf_rx()

int dtmf_rx | ( | dtmf_rx_state_t * | s,
|  | const int16_t | amp[],
|  | int | samples )

Process a block of received DTMF audio samples.

Process a block of received DTMF audio samples.

Parameters

  s | The DTMF receiver context.
  amp | The audio sample buffer.
  samples | The number of samples in the buffer.

Returns
  The number of samples unprocessed.

References dtmf_rx_state_s::col_out, dtmf_rx_state_s::current_digits, dtmf_rx_state_s::current_sample, dtmf_rx_state_s::digits, dtmf_rx_state_s::digits_callback, dtmf_rx_state_s::digits_callback_data, dtmf_rx_state_s::duration, dtmf_rx_state_s::energy, dtmf_rx_state_s::filter_dialtone, dtmf_rx_state_s::in_digit, dtmf_rx_state_s::last_hit, dtmf_rx_state_s::logging, dtmf_rx_state_s::lost_digits, dtmf_rx_state_s::normal_twist, dtmf_rx_state_s::realtime_callback, dtmf_rx_state_s::realtime_callback_data, dtmf_rx_state_s::reverse_twist, dtmf_rx_state_s::row_out, span_log(), span_log_test(), dtmf_rx_state_s::threshold, dtmf_rx_state_s::z350, and dtmf_rx_state_s::z440.

Referenced by adsi_rx().

## dtmf_rx_fillin()

int dtmf_rx_fillin | ( | dtmf_rx_state_t * | s,
|  | int | samples )

Fake processing of a missing block of received DTMF audio samples.

Fake processing of a missing block of received DTMF audio samples. (e.g due to packet loss).

Parameters

  s | The DTMF receiver context.
  len | The number of samples to fake.

Returns
  The number of samples unprocessed.

References dtmf_rx_state_s::col_out, dtmf_rx_state_s::current_sample, dtmf_rx_state_s::energy, and dtmf_rx_state_s::row_out.

## dtmf_rx_free()

int dtmf_rx_free | ( | dtmf_rx_state_t * | s | ) |

Free a DTMF receiver context.

Parameters

  s | The DTMF receiver context.

Returns
  0 for OK, else -1.

## dtmf_rx_get()

size_t dtmf_rx_get | ( | dtmf_rx_state_t * | s,
|  | char * | digits,
|  | int | max )

Get a string of digits from a DTMF receiver's output buffer.

Parameters

  s | The DTMF receiver context.
  digits | The buffer for the received digits.
  max | The maximum number of digits to be returned,

Returns
  The number of digits actually returned.

References dtmf_rx_state_s::current_digits, and dtmf_rx_state_s::digits.

## dtmf_rx_get_logging_state()

logging_state_t * dtmf_rx_get_logging_state | ( | dtmf_rx_state_t * | s | ) |

Get the logging context associated with a DTMF receiver context.

Parameters

  s | The DTMF receiver context.

Returns
  A pointer to the logging context

References dtmf_rx_state_s::logging.

## dtmf_rx_init()

dtmf_rx_state_t * dtmf_rx_init | ( | dtmf_rx_state_t * | s,
|  | digits_rx_callback_t | callback,
|  | void * | user_data )

Initialise a DTMF receiver context.

Parameters

  s | The DTMF receiver context.
  callback | An optional callback routine, used to report received digits. If no callback routine is set, digits may be collected, using the dtmf_rx_get() function.
  user_data | An opaque pointer which is associated with the context, and supplied in callbacks.

Returns
  A pointer to the DTMF receiver context.

References dtmf_rx_state_s::col_out, dtmf_rx_state_s::current_digits, dtmf_rx_state_s::current_sample, dtmf_rx_state_s::digits, dtmf_rx_state_s::digits_callback, dtmf_rx_state_s::digits_callback_data, dtmf_rx_state_s::energy, dtmf_rx_state_s::filter_dialtone, dtmf_rx_state_s::in_digit, dtmf_rx_state_s::last_hit, dtmf_rx_state_s::logging, dtmf_rx_state_s::lost_digits, dtmf_rx_state_s::normal_twist, dtmf_rx_state_s::realtime_callback, dtmf_rx_state_s::realtime_callback_data, dtmf_rx_state_s::reverse_twist, dtmf_rx_state_s::row_out, and dtmf_rx_state_s::threshold.

Referenced by adsi_rx_init(), and v18_init().

## dtmf_rx_parms()

void dtmf_rx_parms | ( | dtmf_rx_state_t * | s,
|  | int | filter_dialtone,
|  | int | twist,
|  | int | reverse_twist,
|  | int | threshold )

Adjust a DTMF receiver context.

Parameters

  s | The DTMF receiver context.
  filter_dialtone | TRUE to enable filtering of dialtone, FALSE to disable, < 0 to leave unchanged.
  twist | Acceptable twist, in dB. < 0 to leave unchanged.
  reverse_twist | Acceptable reverse twist, in dB. < 0 to leave unchanged.
  threshold | The minimum acceptable tone level for detection, in dBm0. <= -99 to leave unchanged.

References dtmf_rx_state_s::filter_dialtone, dtmf_rx_state_s::normal_twist, dtmf_rx_state_s::reverse_twist, dtmf_rx_state_s::threshold, dtmf_rx_state_s::z350, and dtmf_rx_state_s::z440.

## dtmf_rx_release()

int dtmf_rx_release | ( | dtmf_rx_state_t * | s | ) |

Release a DTMF receiver context.

Parameters

  s | The DTMF receiver context.

Returns
  0 for OK, else -1.

## dtmf_rx_set_realtime_callback()

void dtmf_rx_set_realtime_callback | ( | dtmf_rx_state_t * | s,
|  | tone_report_func_t | callback,
|  | void * | user_data )

Set a realtime callback for a DTMF receiver context.

Set a optional realtime callback for a DTMF receiver context. This function is called immediately a confirmed state change occurs in the received DTMF. It is called with the ASCII value for a DTMF tone pair, or zero to indicate no tone is being received.

Parameters

  s | The DTMF receiver context.
  callback | Callback routine used to report the start and end of digits.
  user_data | An opaque pointer which is associated with the context, and supplied in callbacks.

References dtmf_rx_state_s::duration, dtmf_rx_state_s::realtime_callback, and dtmf_rx_state_s::realtime_callback_data.

## dtmf_rx_status()

int dtmf_rx_status | ( | dtmf_rx_state_t * | s | ) |

Get the status of DTMF detection during processing of the last audio chunk.

Get the status of DTMF detection during processing of the last audio chunk.

Parameters

  s | The DTMF receiver context.

Returns
  The current digit status. Either 'x' for a "maybe" condition, or the digit being detected.

References dtmf_rx_state_s::in_digit, and dtmf_rx_state_s::last_hit.

## dtmf_tx()

int dtmf_tx | ( | dtmf_tx_state_t * | s,
|  | int16_t | amp[],
|  | int | max_samples )

Generate a buffer of DTMF tones.

Parameters

  s | The DTMF generator context.
  amp | The buffer for the generated signal.
  max_samples | The required number of generated samples.

Returns
  The number of samples actually generated. This may be less than max_samples if the input buffer empties.

References queue_read_byte().

Referenced by adsi_tx().

## dtmf_tx_free()

int dtmf_tx_free | ( | dtmf_tx_state_t * | s | ) |

Free a DTMF tone generator context.

Parameters

  s | The DTMF tone generator context.

Returns
  0 for OK, else -1.

## dtmf_tx_init()

dtmf_tx_state_t * dtmf_tx_init | ( | dtmf_tx_state_t * | s | ) |

Initialise a DTMF tone generator context.

Parameters

  s | The DTMF generator context.

Returns
  A pointer to the DTMF generator context.

References dtmf_tx_set_level(), dtmf_tx_set_timing(), queue_init(), QUEUE_READ_ATOMIC, and QUEUE_WRITE_ATOMIC.

Referenced by v18_init().

## dtmf_tx_put()

int dtmf_tx_put | ( | dtmf_tx_state_t * | s,
|  | const char * | digits,
|  | int | len )

Put a string of digits in a DTMF generator's input buffer.

Parameters

  s | The DTMF generator context.
  digits | The string of digits to be added.
  len | The length of the string of digits. If negative, the string is assumed to be a NULL terminated string.

Returns
  The number of digits actually added. This may be less than the length of the digit string, if the buffer fills up.

References queue_free_space(), and queue_write().

Referenced by adsi_tx_put_message().

## dtmf_tx_release()

int dtmf_tx_release | ( | dtmf_tx_state_t * | s | ) |

Release a DTMF tone generator context.

Parameters

  s | The DTMF tone generator context.

Returns
  0 for OK, else -1.

## dtmf_tx_set_level()

void dtmf_tx_set_level | ( | dtmf_tx_state_t * | s,
|  | int | level,
|  | int | twist )

Change the transmit level for a DTMF tone generator context.

Parameters

  s | The DTMF generator context.
  level | The level of the low tone, in dBm0.
  twist | The twist, in dB.

References dds_scaling_dbm0f().

Referenced by dtmf_tx_init().

## dtmf_tx_set_timing()

void dtmf_tx_set_timing | ( | dtmf_tx_state_t * | s,
|  | int | on_time,
|  | int | off_time )

Change the transmit on and off time for a DTMF tone generator context.

Parameters

  s | The DTMF generator context.
  on-time | The on time, in ms.
  off_time | The off time, in ms.

Referenced by dtmf_tx_init().