00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * fsk.h - FSK modem transmit and receive parts 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 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: fsk.h 5963 2008-07-27 13:06:19Z oron $ 00026 */ 00027 00028 /*! \file */ 00029 00030 /*! \page fsk_page FSK modems 00031 \section fsk_page_sec_1 What does it do? 00032 Most of the oldest telephony modems use incoherent FSK modulation. This module can 00033 be used to implement both the transmit and receive sides of a number of these 00034 modems. There are integrated definitions for: 00035 00036 - V.21 00037 - V.23 00038 - Bell 103 00039 - Bell 202 00040 - Weitbrecht (Used for TDD - Telecoms Device for the Deaf) 00041 00042 The audio output or input is a stream of 16 bit samples, at 8000 samples/second. 00043 The transmit and receive sides can be used independantly. 00044 00045 \section fsk_page_sec_2 The transmitter 00046 00047 The FSK transmitter uses a DDS generator to synthesise the waveform. This 00048 naturally produces phase coherent transitions, as the phase update rate is 00049 switched, producing a clean spectrum. The symbols are not generally an integer 00050 number of samples long. However, the symbol time for the fastest data rate 00051 generally used (1200bps) is more than 7 samples long. The jitter resulting from 00052 switching at the nearest sample is, therefore, acceptable. No interpolation is 00053 used. 00054 00055 \section fsk_page_sec_3 The receiver 00056 00057 The FSK receiver uses a quadrature correlation technique to demodulate the 00058 signal. Two DDS quadrature oscillators are used. The incoming signal is 00059 correlated with the oscillator signals over a period of one symbol. The 00060 oscillator giving the highest net correlation from its I and Q outputs is the 00061 one that matches the frequency being transmitted during the correlation 00062 interval. Because the transmission is totally asynchronous, the demodulation 00063 process must run sample by sample to find the symbol transitions. The 00064 correlation is performed on a sliding window basis, so the computational load of 00065 demodulating sample by sample is not great. 00066 00067 Two modes of symbol synchronisation are provided: 00068 00069 - In synchronous mode, symbol transitions are smoothed, to track their true 00070 position in the prescence of high timing jitter. This provides the most 00071 reliable symbol recovery in poor signal to noise conditions. However, it 00072 takes a little time to settle, so it not really suitable for data streams 00073 which must start up instantaneously (e.g. the TDD systems used by hearing 00074 impaired people). 00075 00076 - In asynchronous mode each transition is taken at face value, with no temporal 00077 smoothing. There is no settling time for this mode, but when the signal to 00078 noise ratio is very poor it does not perform as well as the synchronous mode. 00079 */ 00080 00081 #if !defined(_SPANDSP_FSK_H_) 00082 #define _SPANDSP_FSK_H_ 00083 00084 /*! 00085 FSK modem specification. This defines the frequencies, signal levels and 00086 baud rate (== bit rate for simple FSK) for a single channel of an FSK modem. 00087 */ 00088 typedef struct 00089 { 00090 /*! Short text name for the modem. */ 00091 const char *name; 00092 /*! The frequency of the zero bit state, in Hz */ 00093 int freq_zero; 00094 /*! The frequency of the one bit state, in Hz */ 00095 int freq_one; 00096 /*! The transmit power level, in dBm0 */ 00097 int tx_level; 00098 /*! The minimum acceptable receive power level, in dBm0 */ 00099 int min_level; 00100 /*! The bit rate of the modem, in units of 1/100th bps */ 00101 int baud_rate; 00102 } fsk_spec_t; 00103 00104 /* Predefined FSK modem channels */ 00105 enum 00106 { 00107 FSK_V21CH1 = 0, 00108 FSK_V21CH2, 00109 FSK_V23CH1, 00110 FSK_V23CH2, 00111 FSK_BELL103CH1, 00112 FSK_BELL103CH2, 00113 FSK_BELL202, 00114 FSK_WEITBRECHT, /* Used for TDD (Telecom Device for the Deaf) */ 00115 }; 00116 00117 extern const fsk_spec_t preset_fsk_specs[]; 00118 00119 /*! 00120 FSK modem transmit descriptor. This defines the state of a single working 00121 instance of an FSK modem transmitter. 00122 */ 00123 typedef struct 00124 { 00125 int baud_rate; 00126 get_bit_func_t get_bit; 00127 void *user_data; 00128 00129 int32_t phase_rates[2]; 00130 int scaling; 00131 int32_t current_phase_rate; 00132 uint32_t phase_acc; 00133 int baud_frac; 00134 int baud_inc; 00135 int shutdown; 00136 } fsk_tx_state_t; 00137 00138 /* The longest window will probably be 106 for 75 baud */ 00139 #define FSK_MAX_WINDOW_LEN 128 00140 00141 /*! 00142 FSK modem receive descriptor. This defines the state of a single working 00143 instance of an FSK modem receiver. 00144 */ 00145 typedef struct 00146 { 00147 int baud_rate; 00148 int sync_mode; 00149 put_bit_func_t put_bit; 00150 void *user_data; 00151 00152 int32_t carrier_on_power; 00153 int32_t carrier_off_power; 00154 power_meter_t power; 00155 /*! \brief The value of the last signal sample, using the a simple HPF for signal power estimation. */ 00156 int16_t last_sample; 00157 /*! \brief >0 if a signal above the minimum is present. It may or may not be a V.29 signal. */ 00158 int signal_present; 00159 00160 int32_t phase_rate[2]; 00161 uint32_t phase_acc[2]; 00162 00163 int correlation_span; 00164 00165 complexi32_t window[2][FSK_MAX_WINDOW_LEN]; 00166 complexi32_t dot[2]; 00167 int buf_ptr; 00168 00169 int baud_inc; 00170 int baud_pll; 00171 int lastbit; 00172 int scaling_shift; 00173 } fsk_rx_state_t; 00174 00175 #if defined(__cplusplus) 00176 extern "C" 00177 { 00178 #endif 00179 00180 /*! Initialise an FSK modem transmit context. 00181 \brief Initialise an FSK modem transmit context. 00182 \param s The modem context. 00183 \param spec The specification of the modem tones and rate. 00184 \param get_bit The callback routine used to get the data to be transmitted. 00185 \param user_data An opaque pointer. 00186 \return A pointer to the modem context, or NULL if there was a problem. */ 00187 fsk_tx_state_t *fsk_tx_init(fsk_tx_state_t *s, 00188 const fsk_spec_t *spec, 00189 get_bit_func_t get_bit, 00190 void *user_data); 00191 00192 /*! Adjust an FSK modem transmit context's power output. 00193 \brief Adjust an FSK modem transmit context's power output. 00194 \param s The modem context. 00195 \param power The power level, in dBm0 */ 00196 void fsk_tx_power(fsk_tx_state_t *s, float power); 00197 00198 void fsk_tx_set_get_bit(fsk_tx_state_t *s, get_bit_func_t get_bit, void *user_data); 00199 00200 /*! Generate a block of FSK modem audio samples. 00201 \brief Generate a block of FSK modem audio samples. 00202 \param s The modem context. 00203 \param amp The audio sample buffer. 00204 \param len The number of samples to be generated. 00205 \return The number of samples actually generated. 00206 */ 00207 int fsk_tx(fsk_tx_state_t *s, int16_t *amp, int len); 00208 00209 /*! Get the current received signal power. 00210 \param s The modem context. 00211 \return The signal power, in dBm0. */ 00212 float fsk_rx_signal_power(fsk_rx_state_t *s); 00213 00214 /*! Adjust an FSK modem receive context's carrier detect power threshold. 00215 \brief Adjust an FSK modem receive context's carrier detect power threshold. 00216 \param s The modem context. 00217 \param cutoff The power level, in dBm0 */ 00218 void fsk_rx_signal_cutoff(fsk_rx_state_t *s, float cutoff); 00219 00220 /*! Initialise an FSK modem receive context. 00221 \brief Initialise an FSK modem receive context. 00222 \param s The modem context. 00223 \param spec The specification of the modem tones and rate. 00224 \param sync_mode TRUE for synchronous modem. FALSE for asynchronous mode. 00225 \param put_bit The callback routine used to put the received data. 00226 \param user_data An opaque pointer. 00227 \return A pointer to the modem context, or NULL if there was a problem. */ 00228 fsk_rx_state_t *fsk_rx_init(fsk_rx_state_t *s, 00229 const fsk_spec_t *spec, 00230 int sync_mode, 00231 put_bit_func_t put_bit, 00232 void *user_data); 00233 00234 /*! Process a block of received FSK modem audio samples. 00235 \brief Process a block of received FSK modem audio samples. 00236 \param s The modem context. 00237 \param amp The audio sample buffer. 00238 \param len The number of samples in the buffer. 00239 \return The number of samples unprocessed. 00240 */ 00241 int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len); 00242 00243 void fsk_rx_set_put_bit(fsk_rx_state_t *s, put_bit_func_t put_bit, void *user_data); 00244 00245 #if defined(__cplusplus) 00246 } 00247 #endif 00248 00249 #endif 00250 /*- End of file ------------------------------------------------------------*/