fsk.h

Go to the documentation of this file.
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 ------------------------------------------------------------*/

Generated on Fri Nov 10 09:40:23 2006 for libspandsp by  doxygen 1.5.1