1 /*---------------------------------------------------------------------------*\
2 
3   FILE........: codec2_fdmdv.h
4   AUTHOR......: David Rowe
5   DATE CREATED: April 14 2012
6 
7   A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice
8   (FDMDV) modem.  Used for digital audio over HF SSB. See
9   README_fdmdv.txt for more information, and fdmdv_mod.c and
10   fdmdv_demod.c for example usage.
11 
12   The name codec2_fdmdv.h is used to make it unique when "make
13   installed".
14 
15   References:
16 
17     [1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
18 
19 \*---------------------------------------------------------------------------*/
20 
21 /*
22   Copyright (C) 2012 David Rowe
23 
24   All rights reserved.
25 
26   This program is free software; you can redistribute it and/or modify
27   it under the terms of the GNU Lesser General Public License version 2.1, as
28   published by the Free Software Foundation.  This program is
29   distributed in the hope that it will be useful, but WITHOUT ANY
30   WARRANTY; without even the implied warranty of MERCHANTABILITY or
31   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
32   License for more details.
33 
34   You should have received a copy of the GNU Lesser General Public License
35   along with this program; if not, see <http://www.gnu.org/licenses/>.
36 */
37 
38 #ifndef __FDMDV__
39 #define __FDMDV__
40 
41 #include "comp.h"
42 #include "modem_stats.h"
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /* set up the calling convention for DLL function import/export for
49    WIN32 cross compiling */
50 
51 #ifdef __CODEC2_WIN32__
52 #ifdef __CODEC2_BUILDING_DLL__
53 #define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall
54 #else
55 #define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
56 #endif
57 #else
58 #define CODEC2_WIN32SUPPORT
59 #endif
60 
61 #define FDMDV_NC                      14  /* default number of data carriers                                */
62 #define FDMDV_NC_MAX                  20  /* maximum number of data carriers                                */
63 #define FDMDV_BITS_PER_FRAME          28  /* 20ms frames, for nominal 1400 bit/s                            */
64 #define FDMDV_NOM_SAMPLES_PER_FRAME  160  /* modulator output samples/frame and nominal demod samples/frame */
65                                           /* at 8000 Hz sample rate                                         */
66 #define FDMDV_MAX_SAMPLES_PER_FRAME  200  /* max demod samples/frame, use this to allocate storage          */
67 #define FDMDV_SCALE                  750   /* suggested scaling for 16 bit shorts                            */
68 #define FDMDV_FCENTRE               1500  /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
69 
70 /* 8 to 18 kHz sample rate conversion */
71 
72 #define FDMDV_OS                 2                            /* oversampling rate                   */
73 #define FDMDV_OS_TAPS_16K       48                            /* number of OS filter taps at 16kHz   */
74 #define FDMDV_OS_TAPS_8K        (FDMDV_OS_TAPS_16K/FDMDV_OS)  /* number of OS filter taps at 8kHz    */
75 
76 /* 8 to 48 kHz sample rate conversion */
77 
78 #define FDMDV_OS_48             6                               /* oversampling rate                   */
79 #define FDMDV_OS_TAPS_48K       48                              /* number of OS filter taps at 48kHz   */
80 #define FDMDV_OS_TAPS_48_8K     (FDMDV_OS_TAPS_48K/FDMDV_OS_48) /* number of OS filter taps at 8kHz    */
81 
82 /* FDMDV states and stats structures */
83 
84 struct FDMDV;
85 
86 struct FDMDV * fdmdv_create(int Nc);
87 void           fdmdv_destroy(struct FDMDV *fdmdv_state);
88 void           fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
89 int            fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
90 float          fdmdv_get_fsep(struct FDMDV *fdmdv_state);
91 void           fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep);
92 
93 void           fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
94 void           fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin);
95 
96 void           fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
97 int            fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
98 void           fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]);
99 
100 void           fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct MODEM_STATS *stats);
101 
102 void           fdmdv_8_to_16(float out16k[], float in8k[], int n);
103 void           fdmdv_8_to_16_short(short out16k[], short in8k[], int n);
104 void           fdmdv_16_to_8(float out8k[], float in16k[], int n);
105 void           fdmdv_16_to_8_short(short out8k[], short in16k[], int n);
106 void           fdmdv_8_to_48(float out48k[], float in8k[], int n);
107 void           fdmdv_48_to_8(float out8k[], float in48k[], int n);
108 void           fdmdv_8_to_48_short(short out48k[], short in8k[], int n);
109 void           fdmdv_48_to_8_short(short out8k[], short in48k[], int n);
110 
111 void           fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
112 
113 /* debug/development function(s) */
114 
115 void fdmdv_dump_osc_mags(struct FDMDV *f);
116 void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr);
117 
118 #ifdef __cplusplus
119 }
120 #endif
121 
122 #endif
123