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