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