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 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,v 1.32 2008/10/13 13:14:00 steveu Exp $
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 fsk_tx_state_s fsk_tx_state_t;
00124 
00125 /* The longest window will probably be 106 for 75 baud */
00126 #define FSK_MAX_WINDOW_LEN 128
00127 
00128 /*!
00129     FSK modem receive descriptor. This defines the state of a single working
00130     instance of an FSK modem receiver.
00131 */
00132 typedef struct fsk_rx_state_s fsk_rx_state_t;
00133 
00134 #if defined(__cplusplus)
00135 extern "C"
00136 {
00137 #endif
00138 
00139 /*! Initialise an FSK modem transmit context.
00140     \brief Initialise an FSK modem transmit context.
00141     \param s The modem context.
00142     \param spec The specification of the modem tones and rate.
00143     \param get_bit The callback routine used to get the data to be transmitted.
00144     \param user_data An opaque pointer.
00145     \return A pointer to the modem context, or NULL if there was a problem. */
00146 fsk_tx_state_t *fsk_tx_init(fsk_tx_state_t *s,
00147                             const fsk_spec_t *spec,
00148                             get_bit_func_t get_bit,
00149                             void *user_data);
00150 
00151 /*! Adjust an FSK modem transmit context's power output.
00152     \brief Adjust an FSK modem transmit context's power output.
00153     \param s The modem context.
00154     \param power The power level, in dBm0 */
00155 void fsk_tx_power(fsk_tx_state_t *s, float power);
00156 
00157 void fsk_tx_set_get_bit(fsk_tx_state_t *s, get_bit_func_t get_bit, void *user_data);
00158 
00159 /*! Change the modem status report function associated with an FSK modem transmit context.
00160     \brief Change the modem status report function associated with an FSK modem transmit context.
00161     \param s The modem context.
00162     \param handler The callback routine used to report modem status changes.
00163     \param user_data An opaque pointer. */
00164 void fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, modem_tx_status_func_t handler, void *user_data);
00165 
00166 /*! Generate a block of FSK modem audio samples.
00167     \brief Generate a block of FSK modem audio samples.
00168     \param s The modem context.
00169     \param amp The audio sample buffer.
00170     \param len The number of samples to be generated.
00171     \return The number of samples actually generated.
00172 */
00173 int fsk_tx(fsk_tx_state_t *s, int16_t *amp, int len);
00174 
00175 /*! Get the current received signal power.
00176     \param s The modem context.
00177     \return The signal power, in dBm0. */
00178 float fsk_rx_signal_power(fsk_rx_state_t *s);
00179 
00180 /*! Adjust an FSK modem receive context's carrier detect power threshold.
00181     \brief Adjust an FSK modem receive context's carrier detect power threshold.
00182     \param s The modem context.
00183     \param cutoff The power level, in dBm0 */
00184 void fsk_rx_signal_cutoff(fsk_rx_state_t *s, float cutoff);
00185 
00186 /*! Initialise an FSK modem receive context.
00187     \brief Initialise an FSK modem receive context.
00188     \param s The modem context.
00189     \param spec The specification of the modem tones and rate.
00190     \param sync_mode TRUE for synchronous modem. FALSE for asynchronous mode.
00191     \param put_bit The callback routine used to put the received data.
00192     \param user_data An opaque pointer.
00193     \return A pointer to the modem context, or NULL if there was a problem. */
00194 fsk_rx_state_t *fsk_rx_init(fsk_rx_state_t *s,
00195                             const fsk_spec_t *spec,
00196                             int sync_mode,
00197                             put_bit_func_t put_bit,
00198                             void *user_data);
00199 
00200 /*! Process a block of received FSK modem audio samples.
00201     \brief Process a block of received FSK modem audio samples.
00202     \param s The modem context.
00203     \param amp The audio sample buffer.
00204     \param len The number of samples in the buffer.
00205     \return The number of samples unprocessed.
00206 */
00207 int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len);
00208 
00209 void fsk_rx_set_put_bit(fsk_rx_state_t *s, put_bit_func_t put_bit, void *user_data);
00210 
00211 /*! Change the modem status report function associated with an FSK modem receive context.
00212     \brief Change the modem status report function associated with an FSK modem receive context.
00213     \param s The modem context.
00214     \param handler The callback routine used to report modem status changes.
00215     \param user_data An opaque pointer. */
00216 void fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, modem_rx_status_func_t handler, void *user_data);
00217 
00218 #if defined(__cplusplus)
00219 }
00220 #endif
00221 
00222 #endif
00223 /*- End of file ------------------------------------------------------------*/

Generated on Thu Feb 12 14:16:06 2009 for spandsp by  doxygen 1.5.5