00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * v22bis.h - ITU V.22bis modem 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2004 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 Lesser General Public License version 2.1, 00014 * as 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 Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id: v22bis.h,v 1.30 2008/07/25 13:56:54 steveu Exp $ 00026 */ 00027 00028 /*! \file */ 00029 00030 /*! \page v22bis_page The V.22bis modem 00031 \section v22bis_page_sec_1 What does it do? 00032 The V.22bis modem is a duplex modem for general data use on the PSTN, at rates 00033 of 1200 and 2400 bits/second. It is a compatible extension of the V.22 modem, 00034 which is a 1200 bits/second only design. It is a band-split design, using carriers 00035 of 1200Hz and 2400Hz. It is the fastest PSTN modem in general use which does not 00036 use echo-cancellation. 00037 00038 \section v22bis__page_sec_2 How does it work? 00039 V.22bis uses 4PSK modulation at 1200 bits/second or 16QAM modulation at 2400 00040 bits/second. At 1200bps the symbols are so long that a fixed compromise equaliser 00041 is sufficient to recover the 4PSK signal reliably. At 2400bps an adaptive 00042 equaliser is necessary. 00043 00044 The V.22bis training sequence includes sections which allow the modems to determine 00045 if the far modem can support (or is willing to support) 2400bps operation. The 00046 modems will automatically use 2400bps if both ends are willing to use that speed, 00047 or 1200bps if one or both ends to not acknowledge that 2400bps is OK. 00048 */ 00049 00050 #if !defined(_V22BIS_H_) 00051 #define _V22BIS_H_ 00052 00053 #define V22BIS_EQUALIZER_LEN 7 /* this much to the left and this much to the right */ 00054 #define V22BIS_EQUALIZER_MASK 15 /* one less than a power of 2 >= (2*V22BIS_EQUALIZER_LEN + 1) */ 00055 00056 #define V22BIS_TX_FILTER_STEPS 9 00057 00058 #define V22BIS_RX_FILTER_STEPS 37 00059 00060 /*! 00061 V.22bis modem descriptor. This defines the working state for a single instance 00062 of a V.22bis modem. 00063 */ 00064 typedef struct 00065 { 00066 /*! \brief The bit rate of the modem. Valid values are 1200 and 2400. */ 00067 int bit_rate; 00068 /*! \brief TRUE is this is the calling side modem. */ 00069 int caller; 00070 /*! \brief The callback function used to put each bit received. */ 00071 put_bit_func_t put_bit; 00072 /*! \brief The callback function used to get the next bit to be transmitted. */ 00073 get_bit_func_t get_bit; 00074 /*! \brief A user specified opaque pointer passed to the callback routines. */ 00075 void *user_data; 00076 00077 /* RECEIVE SECTION */ 00078 struct 00079 { 00080 /*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */ 00081 float rrc_filter[2*V22BIS_RX_FILTER_STEPS]; 00082 /*! \brief Current offset into the RRC pulse shaping filter buffer. */ 00083 int rrc_filter_step; 00084 00085 /*! \brief The register for the data scrambler. */ 00086 unsigned int scramble_reg; 00087 /*! \brief A counter for the number of consecutive bits of repeating pattern through 00088 the scrambler. */ 00089 int scrambler_pattern_count; 00090 00091 /*! \brief 0 if receiving user data. A training stage value during training */ 00092 int training; 00093 /*! \brief A count of how far through the current training step we are. */ 00094 int training_count; 00095 00096 /*! \brief >0 if a signal above the minimum is present. It may or may not be a V.22bis signal. */ 00097 int signal_present; 00098 00099 /*! \brief A measure of how much mismatch there is between the real constellation, 00100 and the decoded symbol positions. */ 00101 float training_error; 00102 00103 /*! \brief The current phase of the carrier (i.e. the DDS parameter). */ 00104 uint32_t carrier_phase; 00105 /*! \brief The update rate for the phase of the carrier (i.e. the DDS increment). */ 00106 int32_t carrier_phase_rate; 00107 /*! \brief The proportional part of the carrier tracking filter. */ 00108 float carrier_track_p; 00109 /*! \brief The integral part of the carrier tracking filter. */ 00110 float carrier_track_i; 00111 00112 /*! \brief A callback function which may be enabled to report every symbol's 00113 constellation position. */ 00114 qam_report_handler_t qam_report; 00115 /*! \brief A user specified opaque pointer passed to the qam_report callback 00116 routine. */ 00117 void *qam_user_data; 00118 00119 /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */ 00120 power_meter_t rx_power; 00121 /*! \brief The power meter level at which carrier on is declared. */ 00122 int32_t carrier_on_power; 00123 /*! \brief The power meter level at which carrier off is declared. */ 00124 int32_t carrier_off_power; 00125 /*! \brief The scaling factor accessed by the AGC algorithm. */ 00126 float agc_scaling; 00127 00128 int constellation_state; 00129 00130 /*! \brief The current delta factor for updating the equalizer coefficients. */ 00131 float eq_delta; 00132 #if defined(SPANDSP_USE_FIXED_POINTx) 00133 /*! \brief The adaptive equalizer coefficients. */ 00134 complexi_t eq_coeff[2*V22BIS_EQUALIZER_LEN + 1]; 00135 /*! \brief The equalizer signal buffer. */ 00136 complexi_t eq_buf[V22BIS_EQUALIZER_MASK + 1]; 00137 #else 00138 complexf_t eq_coeff[2*V22BIS_EQUALIZER_LEN + 1]; 00139 complexf_t eq_buf[V22BIS_EQUALIZER_MASK + 1]; 00140 #endif 00141 /*! \brief Current offset into the equalizer buffer. */ 00142 int eq_step; 00143 /*! \brief Current write offset into the equalizer buffer. */ 00144 int eq_put_step; 00145 00146 /*! \brief Integration variable for damping the Gardner algorithm tests. */ 00147 int gardner_integrate; 00148 /*! \brief Current step size of Gardner algorithm integration. */ 00149 int gardner_step; 00150 /*! \brief The total symbol timing correction since the carrier came up. 00151 This is only for performance analysis purposes. */ 00152 int total_baud_timing_correction; 00153 /*! \brief The current fractional phase of the baud timing. */ 00154 int baud_phase; 00155 00156 int sixteen_way_decisions; 00157 } rx; 00158 00159 /* TRANSMIT SECTION */ 00160 struct 00161 { 00162 /*! \brief The gain factor needed to achieve the specified output power. */ 00163 float gain; 00164 00165 /*! \brief The route raised cosine (RRC) pulse shaping filter buffer. */ 00166 complexf_t rrc_filter[2*V22BIS_TX_FILTER_STEPS]; 00167 /*! \brief Current offset into the RRC pulse shaping filter buffer. */ 00168 int rrc_filter_step; 00169 00170 /*! \brief The register for the data scrambler. */ 00171 unsigned int scramble_reg; 00172 /*! \brief A counter for the number of consecutive bits of repeating pattern through 00173 the scrambler. */ 00174 int scrambler_pattern_count; 00175 00176 /*! \brief 0 if transmitting user data. A training stage value during training */ 00177 int training; 00178 /*! \brief A counter used to track progress through sending the training sequence. */ 00179 int training_count; 00180 /*! \brief The current phase of the carrier (i.e. the DDS parameter). */ 00181 uint32_t carrier_phase; 00182 /*! \brief The update rate for the phase of the carrier (i.e. the DDS increment). */ 00183 int32_t carrier_phase_rate; 00184 /*! \brief The current phase of the guard tone (i.e. the DDS parameter). */ 00185 uint32_t guard_phase; 00186 /*! \brief The update rate for the phase of the guard tone (i.e. the DDS increment). */ 00187 int32_t guard_phase_rate; 00188 float guard_level; 00189 /*! \brief The current fractional phase of the baud timing. */ 00190 int baud_phase; 00191 /*! \brief The code number for the current position in the constellation. */ 00192 int constellation_state; 00193 /*! \brief An indicator to mark that we are tidying up to stop transmission. */ 00194 int shutdown; 00195 /*! \brief The get_bit function in use at any instant. */ 00196 get_bit_func_t current_get_bit; 00197 } tx; 00198 00199 int detected_unscrambled_ones; 00200 int detected_unscrambled_zeros; 00201 00202 int detected_unscrambled_ones_or_zeros; 00203 int detected_unscrambled_0011_ending; 00204 int detected_scrambled_ones_or_zeros_at_1200bps; 00205 int detected_scrambled_ones_at_2400bps; 00206 00207 /*! \brief Error and flow logging control */ 00208 logging_state_t logging; 00209 } v22bis_state_t; 00210 00211 extern const complexf_t v22bis_constellation[16]; 00212 00213 #if defined(__cplusplus) 00214 extern "C" 00215 { 00216 #endif 00217 00218 /*! Reinitialise an existing V.22bis modem receive context. 00219 \brief Reinitialise an existing V.22bis modem receive context. 00220 \param s The modem context. 00221 \param bit_rate The bit rate of the modem. Valid values are 1200 and 2400. 00222 \return 0 for OK, -1 for bad parameter */ 00223 int v22bis_rx_restart(v22bis_state_t *s, int bit_rate); 00224 00225 /*! Process a block of received V.22bis modem audio samples. 00226 \brief Process a block of received V.22bis modem audio samples. 00227 \param s The modem context. 00228 \param amp The audio sample buffer. 00229 \param len The number of samples in the buffer. 00230 \return The number of samples unprocessed. */ 00231 int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len); 00232 00233 /*! Get a snapshot of the current equalizer coefficients. 00234 \brief Get a snapshot of the current equalizer coefficients. 00235 \param coeffs The vector of complex coefficients. 00236 \return The number of coefficients in the vector. */ 00237 int v22bis_equalizer_state(v22bis_state_t *s, complexf_t **coeffs); 00238 00239 /*! Get the current received carrier frequency. 00240 \param s The modem context. 00241 \return The frequency, in Hertz. */ 00242 float v22bis_rx_carrier_frequency(v22bis_state_t *s); 00243 00244 /*! Get the current symbol timing correction since startup. 00245 \param s The modem context. 00246 \return The correction. */ 00247 float v22bis_symbol_timing_correction(v22bis_state_t *s); 00248 00249 /*! Get a current received signal power. 00250 \param s The modem context. 00251 \return The signal power, in dBm0. */ 00252 float v22bis_rx_signal_power(v22bis_state_t *s); 00253 00254 /*! Set a handler routine to process QAM status reports 00255 \param s The modem context. 00256 \param handler The handler routine. 00257 \param user_data An opaque pointer passed to the handler routine. */ 00258 void v22bis_set_qam_report_handler(v22bis_state_t *s, qam_report_handler_t handler, void *user_data); 00259 00260 /*! Generate a block of V.22bis modem audio samples. 00261 \brief Generate a block of V.22bis modem audio samples. 00262 \param s The modem context. 00263 \param amp The audio sample buffer. 00264 \param len The number of samples to be generated. 00265 \return The number of samples actually generated. */ 00266 int v22bis_tx(v22bis_state_t *s, int16_t amp[], int len); 00267 00268 /*! Adjust a V.22bis modem transmit context's power output. 00269 \brief Adjust a V.22bis modem transmit context's output power. 00270 \param s The modem context. 00271 \param power The power level, in dBm0 */ 00272 void v22bis_tx_power(v22bis_state_t *s, float power); 00273 00274 /*! Reinitialise an existing V.22bis modem context, so it may be reused. 00275 \brief Reinitialise an existing V.22bis modem context. 00276 \param s The modem context. 00277 \param bit_rate The bit rate of the modem. Valid values are 1200 and 2400. 00278 \return 0 for OK, -1 for bad parameter. */ 00279 int v22bis_restart(v22bis_state_t *s, int bit_rate); 00280 00281 /*! Initialise a V.22bis modem context. This must be called before the first 00282 use of the context, to initialise its contents. 00283 \brief Initialise a V.22bis modem context. 00284 \param s The modem context. 00285 \param bit_rate The bit rate of the modem. Valid values are 1200 and 2400. 00286 \param guard The guard tone option. 0 = none, 1 = 550Hz, 2 = 1800Hz. 00287 \param caller TRUE if this is the calling modem. 00288 \param get_bit The callback routine used to get the data to be transmitted. 00289 \param put_bit The callback routine used to get the data to be transmitted. 00290 \param user_data An opaque pointer, passed in calls to the get and put routines. 00291 \return A pointer to the modem context, or NULL if there was a problem. */ 00292 v22bis_state_t *v22bis_init(v22bis_state_t *s, 00293 int bit_rate, 00294 int guard, 00295 int caller, 00296 get_bit_func_t get_bit, 00297 put_bit_func_t put_bit, 00298 void *user_data); 00299 00300 /*! Free a V.22bis modem receive context. 00301 \brief Free a V.22bis modem receive context. 00302 \param s The modem context. 00303 \return 0 for OK */ 00304 int v22bis_free(v22bis_state_t *s); 00305 00306 /*! Change the get_bit function associated with a V.22bis modem context. 00307 \brief Change the get_bit function associated with a V.22bis modem context. 00308 \param s The modem context. 00309 \param get_bit The callback routine used to get the data to be transmitted. 00310 \param user_data An opaque pointer. */ 00311 void v22bis_set_get_bit(v22bis_state_t *s, get_bit_func_t get_bit, void *user_data); 00312 00313 /*! Change the get_bit function associated with a V.22bis modem context. 00314 \brief Change the put_bit function associated with a V.22bis modem context. 00315 \param s The modem context. 00316 \param put_bit The callback routine used to process the data received. 00317 \param user_data An opaque pointer. */ 00318 void v22bis_set_put_bit(v22bis_state_t *s, put_bit_func_t put_bit, void *user_data); 00319 00320 #if defined(__cplusplus) 00321 } 00322 #endif 00323 00324 #endif 00325 /*- End of file ------------------------------------------------------------*/