00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * super_tone_rx.h - Flexible telephony supervisory tone detection. 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2003 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License version 2, as 00014 * published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id$ 00026 */ 00027 00028 #if !defined(_SPANDSP_SUPER_TONE_RX_H_x) 00029 #define _SPANDSP_SUPER_TONE_RX_H_x 00030 00031 /*! \page super_tone_rx_page Supervisory tone detection 00032 00033 \section super_tone_rx_page_sec_1 What does it do? 00034 00035 The supervisory tone detector may be configured to detect most of the world's 00036 telephone supervisory tones - things like ringback, busy, number unobtainable, 00037 and so on. 00038 00039 The detector aims to meet the need of the standard call progress tones, to 00040 ITU-T E.180/Q.35 (busy, dial, ringback, reorder). Also, the extended tones, 00041 to ITU-T E.180, Supplement 2 and EIA/TIA-464-A (recall dial tone, special 00042 ringback tone, intercept tone, call waiting tone, busy verification tone, 00043 executive override tone, confirmation tone). 00044 00045 \section super_tone_rx_page_sec_2 How does it work? 00046 00047 The input signal is complex filtered with a bandpass filter that removes DC and 00048 anything above about 800Hz, and the resulting complex signal is decimated by a 00049 factor of 10. This leaves an alias free band of 0 to 800Hz. 00050 00051 A set of periodgrams are calculated, one for each of the frequencies of interest. 00052 A Hamming window is applied to the coefficients used for this, to clean up the 00053 spectral response. The expected phasor rotation between successive periodogram 00054 results is compared with the actual rotation, to evaluate the deviation of the 00055 signal from the expected frequency. 00056 ?????????? 00057 00058 */ 00059 00060 /* The maximum number of frequencies to be monitored */ 00061 #define SUPER_TONE_MAX_FREQS 8 00062 00063 /* Bandpass filtering */ 00064 #define SUPER_TONE_BP_FIR_LEN 60 00065 #define SUPER_TONE_DECIMATION_FACTOR 10 00066 #define SUPER_TONE_FRAME_LEN (4*SUPER_TONE_DECIMATION_FACTOR) 00067 #define SUPER_TONE_BP_SLEN (SUPER_TONE_BP_FIR_LEN - SUPER_TONE_DECIMATION_FACTOR) 00068 #define SUPER_TONE_BP_ALEN (SUPER_TONE_BP_SLEN + SUPER_TONE_FRAME_LEN) 00069 00070 /* Periodogram analysis */ 00071 #define SUPER_TONE_PG_WINDOW 56 00072 00073 /* Energy history period */ 00074 #define SUPER_TONE_ENERGY_SIZE 9 00075 00076 /*! Tone detection indication callback routine */ 00077 typedef void (*tone_report_func_t)(void *user_data, int code, int level, int delay); 00078 00079 /* Statistics */ 00080 typedef struct 00081 { 00082 /*! Tone power, in dBm0 */ 00083 float energy[2]; 00084 /*! Frequency error, in Hz */ 00085 float freq_error[2]; 00086 } supervisory_stats_t; 00087 00088 typedef struct 00089 { 00090 /*! Minimum jump in power for tone detection, in dB (10 to 20dB should be OK). */ 00091 float min_power_jump; 00092 /*! Minimum acceptable level for a tone's power, in dBm0. */ 00093 float min_energy_threshold; 00094 /*! Maximum permitted ripple for a tone's power, in dB (1 to 3dB should be OK). */ 00095 float max_energy_ripple; 00096 /*! Maximum permitted normal or reverse twist, in dB. */ 00097 float max_energy_twist; 00098 /*! How much energies must be above other components, in dB (>20dB starts to be useful). */ 00099 float clean_threshold; 00100 /*! The maximum permissible frequency offset from the target, in Hz */ 00101 float max_freq_deviation; 00102 /*! Number of good frames before tone on is declared */ 00103 int min_tone_on_duration; 00104 /*! Number of low-energy frames before tone off is declared */ 00105 int min_tone_off_duration; 00106 /*! Number of inconsistent frames before tone abort is declared */ 00107 int abort_timeout; 00108 /*! The number of frequencies to be monitored */ 00109 int frequencies; 00110 complexf_t sensor_coeffs[SUPER_TONE_MAX_FREQS][SUPER_TONE_PG_WINDOW/2]; 00111 complexf_t sensor_phase_offsets[SUPER_TONE_MAX_FREQS]; 00112 } supervisory_rx_desc_t; 00113 00114 typedef struct 00115 { 00116 tone_report_func_t tone_callback; 00117 void *callback_data; 00118 /*! The descriptor for the tone detector. */ 00119 const supervisory_rx_desc_t *desc; 00120 00121 /*! The energy level at each of the frequencies being monitored */ 00122 float energy[SUPER_TONE_MAX_FREQS]; 00123 /*! The periodogram result at each of the frequencies being monitored */ 00124 complexf_t pg_result[SUPER_TONE_MAX_FREQS]; 00125 /*! The previous periodogram result at each of the frequencies being monitored */ 00126 complexf_t last_pg_result[SUPER_TONE_MAX_FREQS]; 00127 supervisory_stats_t stats; 00128 00129 /*! The energy level out of the bandpass filter, in dBm0 */ 00130 float bandpass_energy_db; 00131 00132 /*! The number of samples in the input signal buffer. */ 00133 int input_signal_len; 00134 /*! Input signal buffer, used to gather enough for a burst of processing. */ 00135 float input_signal[SUPER_TONE_BP_ALEN]; 00136 /*! The decimated signal. */ 00137 complexf_t decimated[SUPER_TONE_PG_WINDOW]; 00138 /*! A list of the last few combined energies in the 2 main responses */ 00139 float summed_energy_db_history[SUPER_TONE_ENERGY_SIZE]; 00140 /*! A smoothed version of the combined energies in the 2 main responses */ 00141 float avg_summed_energy_db; 00142 00143 /*! The highest energy level amongst the monitored frequencies, in dBm0 */ 00144 float highest_energy_db; 00145 /*! The indexes into the monitored frequency list of the two strongest 00146 responses (lower frequency first) and the third strongest response. */ 00147 int index[3]; 00148 /*! The energy levels of the two strongest responses (lower frequency first) 00149 and the third strongest response, in dBm0. */ 00150 float energy_db[3]; 00151 /*! The frequency error of the two strongest responses (lower frequency first), in Hz */ 00152 float freq_error[2]; 00153 00154 /*! A bit pattern containing all the signal test results. */ 00155 int test_results; 00156 /*! The current state of the detector. */ 00157 int state; 00158 /*! The tones which are considered to be currently present. */ 00159 int tones_present; 00160 /*! The previous tones which were considered to be present. */ 00161 int last_tones_present; 00162 /*! A counter used for the persistence checking of signal changes. */ 00163 int frame_count; 00164 /*! Time, in samples, since the last tone report. */ 00165 int since_last_report; 00166 } supervisory_rx_state_t; 00167 00168 #if defined(__cplusplus) 00169 extern "C" 00170 { 00171 #endif 00172 00173 int supervisory_rx(supervisory_rx_state_t *s, const int16_t amp[], int len); 00174 00175 supervisory_rx_desc_t *supervisory_rx_desc(supervisory_rx_desc_t *conf, 00176 const float freq_list[]); 00177 00178 supervisory_stats_t supervisory_rx_get_stats(supervisory_rx_state_t *s); 00179 00180 supervisory_rx_state_t *supervisory_rx_init(supervisory_rx_state_t *s, 00181 const supervisory_rx_desc_t *conf, 00182 tone_report_func_t callback, 00183 void *user_data); 00184 00185 #if defined(__cplusplus) 00186 } 00187 #endif 00188 00189 #endif 00190 /*- End of file ------------------------------------------------------------*/