mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 01:18:38 -05:00
Created an internal FreeDV API library
This commit is contained in:
parent
9411757515
commit
4deafb9893
@ -363,6 +363,11 @@ if (BUILD_DEBIAN)
|
||||
add_subdirectory(libsoapysdr)
|
||||
endif (BUILD_DEBIAN)
|
||||
|
||||
find_package(Codec2)
|
||||
if (CODEC2_FOUND)
|
||||
add_subdirectory(libfreedv)
|
||||
endif(CODEC2_FOUND)
|
||||
|
||||
add_subdirectory(devices)
|
||||
if (BUILD_GUI)
|
||||
add_subdirectory(plugins)
|
||||
|
43
libfreedv/CMakeLists.txt
Normal file
43
libfreedv/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
project(freedv)
|
||||
|
||||
set(freedv_SOURCES
|
||||
freedv_api.cpp
|
||||
)
|
||||
|
||||
set(freedv_HEADERS
|
||||
codec2_fft.h
|
||||
codec2_ofdm.h
|
||||
defines.h
|
||||
fdmdv_internal.h
|
||||
fdv_arm_math.h
|
||||
fmfsk.h
|
||||
freedv_data_channel.h
|
||||
freedv_filter.h
|
||||
freedv_vhf_framing.h
|
||||
gp_interleaver.h
|
||||
interldpc.h
|
||||
kiss_fft.h
|
||||
kiss_fftr.h
|
||||
lbfreedv.h
|
||||
modem_probe.h
|
||||
mpdecode_core.h
|
||||
ofdm_internal.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
.
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CODEC2_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_definitions(-DQT_SHARED)
|
||||
|
||||
add_library(freedv SHARED
|
||||
${freedv_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(freedv
|
||||
${CODEC2_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS freedv DESTINATION lib)
|
76
libfreedv/codec2_cohpsk.h
Normal file
76
libfreedv/codec2_cohpsk.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: codec2_cohpsk.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: March 2015
|
||||
|
||||
Functions that implement a coherent PSK FDM modem.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2015 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CODEC2_COHPSK__
|
||||
#define __CODEC2_COHPSK__
|
||||
|
||||
#define COHPSK_BITS_PER_FRAME 56 /* hard coded for now */
|
||||
#define COHPSK_NC 7 /* hard coded for now */
|
||||
#define COHPSK_NOM_SAMPLES_PER_FRAME 600
|
||||
#define COHPSK_MAX_SAMPLES_PER_FRAME 625
|
||||
#define COHPSK_RS 75
|
||||
#define COHPSK_FS 7500 /* note this is a wierd
|
||||
value to get an integer
|
||||
oversampling rate */
|
||||
#define COHPSK_CLIP 6.5 /* hard clipping for Nc*Nc=14 to reduce PAPR */
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "modem_stats.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct COHPSK;
|
||||
|
||||
extern const int test_bits_coh[];
|
||||
|
||||
struct COHPSK *cohpsk_create(void);
|
||||
void cohpsk_destroy(struct COHPSK *coh);
|
||||
void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[], int nbits);
|
||||
void cohpsk_clip(COMP tx_fdm[], float clip_thresh, int n);
|
||||
void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame);
|
||||
void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats);
|
||||
void cohpsk_set_verbose(struct COHPSK *coh, int verbose);
|
||||
void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
|
||||
void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
|
||||
int *bit_errors, char rx_bits[], int channel);
|
||||
int cohpsk_error_pattern_size(void);
|
||||
void cohpsk_set_frame(struct COHPSK *coh, int frame);
|
||||
void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs,
|
||||
COMP *foff_phase_rect, int nin);
|
||||
|
||||
void cohpsk_set_freq_est_mode(struct COHPSK *coh, int used_simple_mode);
|
||||
|
||||
/* used for accessing upper and lower bits before diversity combination */
|
||||
|
||||
float *cohpsk_get_rx_bits_lower(struct COHPSK *coh);
|
||||
float *cohpsk_get_rx_bits_upper(struct COHPSK *coh);
|
||||
void cohpsk_set_carrier_ampl(struct COHPSK *coh, int c, float ampl);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
110
libfreedv/codec2_fdmdv.h
Normal file
110
libfreedv/codec2_fdmdv.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: codec2_fdmdv.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 14 2012
|
||||
|
||||
A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice
|
||||
(FDMDV) modem. Used for digital audio over HF SSB. See
|
||||
README_fdmdv.txt for more information, and fdmdv_mod.c and
|
||||
fdmdv_demod.c for example usage.
|
||||
|
||||
The name codec2_fdmdv.h is used to make it unique when "make
|
||||
installed".
|
||||
|
||||
References:
|
||||
|
||||
[1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2012 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FDMDV__
|
||||
#define __FDMDV__
|
||||
|
||||
/* set up the calling convention for DLL function import/export for
|
||||
WIN32 cross compiling */
|
||||
|
||||
#ifdef __CODEC2_WIN32__
|
||||
#ifdef __CODEC2_BUILDING_DLL__
|
||||
#define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall
|
||||
#else
|
||||
#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
|
||||
#endif
|
||||
#else
|
||||
#define CODEC2_WIN32SUPPORT
|
||||
#endif
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "modem_stats.h"
|
||||
|
||||
#define FDMDV_NC 14 /* default number of data carriers */
|
||||
#define FDMDV_NC_MAX 20 /* maximum number of data carriers */
|
||||
#define FDMDV_BITS_PER_FRAME 28 /* 20ms frames, for nominal 1400 bit/s */
|
||||
#define FDMDV_NOM_SAMPLES_PER_FRAME 160 /* modulator output samples/frame and nominal demod samples/frame */
|
||||
/* at 8000 Hz sample rate */
|
||||
#define FDMDV_MAX_SAMPLES_PER_FRAME 200 /* max demod samples/frame, use this to allocate storage */
|
||||
#define FDMDV_SCALE 1000 /* suggested scaling for 16 bit shorts */
|
||||
#define FDMDV_FCENTRE 1500 /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
|
||||
|
||||
/* 8 to 48 kHz sample rate conversion */
|
||||
|
||||
#define FDMDV_OS 2 /* oversampling rate */
|
||||
#define FDMDV_OS_TAPS_16K 48 /* number of OS filter taps at 16kHz */
|
||||
#define FDMDV_OS_TAPS_8K (FDMDV_OS_TAPS_16K/FDMDV_OS) /* number of OS filter taps at 8kHz */
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/* FDMDV states and stats structures */
|
||||
|
||||
struct FDMDV;
|
||||
|
||||
struct FDMDV * fdmdv_create(int Nc);
|
||||
void fdmdv_destroy(struct FDMDV *fdmdv_state);
|
||||
void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
|
||||
int fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
|
||||
float fdmdv_get_fsep(struct FDMDV *fdmdv_state);
|
||||
void fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep);
|
||||
|
||||
void fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
|
||||
void fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin);
|
||||
|
||||
void fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
|
||||
int fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
|
||||
void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]);
|
||||
|
||||
void fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct MODEM_STATS *stats);
|
||||
|
||||
void fdmdv_8_to_16(float out16k[], float in8k[], int n);
|
||||
void fdmdv_8_to_16_short(short out16k[], short in8k[], int n);
|
||||
void fdmdv_16_to_8(float out8k[], float in16k[], int n);
|
||||
void fdmdv_16_to_8_short(short out8k[], short in16k[], int n);
|
||||
|
||||
void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
|
||||
|
||||
/* debug/development function(s) */
|
||||
|
||||
void fdmdv_dump_osc_mags(struct FDMDV *f);
|
||||
void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
||||
|
108
libfreedv/codec2_fft.h
Normal file
108
libfreedv/codec2_fft.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* codec2_fft.h
|
||||
*
|
||||
* Created on: 17.09.2016
|
||||
* Author: danilo
|
||||
*/
|
||||
|
||||
#ifndef DRIVERS_FREEDV_CODEC2_FFT_H_
|
||||
#define DRIVERS_FREEDV_CODEC2_FFT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
#ifdef FDV_ARM_MATH
|
||||
#include "fdv_arm_math.h"
|
||||
#else
|
||||
#define USE_KISS_FFT
|
||||
#endif
|
||||
|
||||
#include "defines.h"
|
||||
#include "codec2/comp.h"
|
||||
|
||||
|
||||
typedef COMP codec2_fft_cpx;
|
||||
#include "kiss_fftr.h"
|
||||
|
||||
#ifdef USE_KISS_FFT
|
||||
#include "kiss_fft.h"
|
||||
typedef kiss_fftr_cfg codec2_fftr_cfg;
|
||||
typedef kiss_fft_cfg codec2_fft_cfg;
|
||||
typedef kiss_fft_scalar codec2_fft_scalar;
|
||||
#else
|
||||
typedef float32_t codec2_fft_scalar;
|
||||
typedef struct {
|
||||
arm_rfft_fast_instance_f32* instance;
|
||||
int inverse;
|
||||
} codec2_fftr_struct;
|
||||
|
||||
typedef codec2_fftr_struct* codec2_fftr_cfg;
|
||||
|
||||
typedef struct {
|
||||
const arm_cfft_instance_f32* instance;
|
||||
int inverse;
|
||||
} codec2_fft_struct;
|
||||
typedef codec2_fft_struct* codec2_fft_cfg;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, codec2_fft_cpx* out)
|
||||
{
|
||||
|
||||
#ifdef USE_KISS_FFT
|
||||
kiss_fftr(cfg, in, (kiss_fft_cpx*)out);
|
||||
#else
|
||||
arm_rfft_fast_f32(cfg->instance,in,(float*)out,cfg->inverse);
|
||||
out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, codec2_fft_scalar* out)
|
||||
{
|
||||
#ifdef USE_KISS_FFT
|
||||
kiss_fftri(cfg, (kiss_fft_cpx*)in, out);
|
||||
#else
|
||||
arm_rfft_fast_f32(cfg->instance,(float*)in,out,cfg->inverse);
|
||||
// arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem);
|
||||
codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem);
|
||||
void codec2_fft_free(codec2_fft_cfg cfg);
|
||||
void codec2_fftr_free(codec2_fftr_cfg cfg);
|
||||
|
||||
|
||||
static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out)
|
||||
{
|
||||
|
||||
#ifdef USE_KISS_FFT
|
||||
kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out);
|
||||
#else
|
||||
memcpy(out,in,cfg->instance->fftLen*2*sizeof(float));
|
||||
arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse,0);
|
||||
// TODO: this is not nice, but for now required to keep changes minimal
|
||||
// however, since main goal is to reduce the memory usage
|
||||
// we should convert to an in place interface
|
||||
// on PC like platforms the overhead of using the "inplace" kiss_fft calls
|
||||
// is neglectable compared to the gain in memory usage on STM32 platforms
|
||||
if (cfg->inverse)
|
||||
{
|
||||
arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
101
libfreedv/codec2_ofdm.h
Normal file
101
libfreedv/codec2_ofdm.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: codec2_ofdm.h
|
||||
AUTHORS.....: David Rowe & Steve Sampson
|
||||
DATE CREATED: June 2017
|
||||
|
||||
External user references to the modem library.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CODEC2_OFDM_H
|
||||
#define CODEC2_OFDM_H
|
||||
|
||||
/* Includes */
|
||||
|
||||
#include <complex.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "modem_stats.h"
|
||||
|
||||
/* Defines */
|
||||
|
||||
#define OFDM_AMP_SCALE (2E5*1.1491/1.06) /* use to scale to 16 bit short */
|
||||
#define OFDM_CLIP (32767*0.35) /* experimentally derived constant to reduce PAPR to about 8dB */
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct OFDM_CONFIG;
|
||||
struct OFDM;
|
||||
|
||||
typedef enum {
|
||||
search,
|
||||
trial,
|
||||
synced
|
||||
} State;
|
||||
|
||||
typedef enum {
|
||||
unsync, /* force sync state machine to lose sync, and search for new sync */
|
||||
autosync, /* falls out of sync automatically */
|
||||
manualsync /* fall out of sync only under operator control */
|
||||
} Sync;
|
||||
|
||||
/* create and destroy modem states */
|
||||
|
||||
struct OFDM *ofdm_create(const struct OFDM_CONFIG * config);
|
||||
void ofdm_destroy(struct OFDM *);
|
||||
|
||||
/* signal processing */
|
||||
|
||||
void ofdm_mod(struct OFDM *, COMP *, const int *);
|
||||
void ofdm_demod(struct OFDM *, int *, COMP *);
|
||||
void ofdm_demod_shorts(struct OFDM *, int *, short *, float);
|
||||
int ofdm_sync_search(struct OFDM *, COMP *);
|
||||
int ofdm_sync_search_shorts(struct OFDM *, short *, float);
|
||||
void ofdm_sync_state_machine(struct OFDM *, uint8_t *);
|
||||
|
||||
/* getters */
|
||||
|
||||
struct OFDM_CONFIG *ofdm_get_config_param(void);
|
||||
int ofdm_get_nin(struct OFDM *);
|
||||
int ofdm_get_samples_per_frame(void);
|
||||
int ofdm_get_max_samples_per_frame(void);
|
||||
int ofdm_get_bits_per_frame(void);
|
||||
void ofdm_get_demod_stats(struct OFDM *ofdm, struct MODEM_STATS *stats);
|
||||
|
||||
/* option setters */
|
||||
|
||||
void ofdm_set_verbose(struct OFDM *, int);
|
||||
void ofdm_set_timing_enable(struct OFDM *, bool);
|
||||
void ofdm_set_foff_est_enable(struct OFDM *, bool);
|
||||
void ofdm_set_phase_est_enable(struct OFDM *, bool);
|
||||
void ofdm_set_off_est_hz(struct OFDM *, float);
|
||||
void ofdm_set_sync(struct OFDM *, Sync);
|
||||
void ofdm_set_tx_bpf(struct OFDM *, bool);
|
||||
|
||||
void ofdm_print_info(struct OFDM *);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
||||
|
120
libfreedv/defines.h
Normal file
120
libfreedv/defines.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: defines.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 23/4/93
|
||||
|
||||
Defines and structures used throughout the codec.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2009 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __DEFINES__
|
||||
#define __DEFINES__
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
DEFINES
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/* General defines */
|
||||
|
||||
#define N_S 0.01 /* internal proc frame length in secs */
|
||||
#define TW_S 0.005 /* trapezoidal synth window overlap */
|
||||
#define MAX_AMP 160 /* maximum number of harmonics */
|
||||
#ifndef PI
|
||||
#define PI 3.141592654 /* mathematical constant */
|
||||
#endif
|
||||
#define TWO_PI 6.283185307 /* mathematical constant */
|
||||
#define MAX_STR 2048 /* maximum string size */
|
||||
|
||||
#define FFT_ENC 512 /* size of FFT used for encoder */
|
||||
#define FFT_DEC 512 /* size of FFT used in decoder */
|
||||
#define V_THRESH 6.0 /* voicing threshold in dB */
|
||||
#define LPC_ORD 10 /* LPC order */
|
||||
#define LPC_ORD_LOW 6 /* LPC order for lower rates */
|
||||
|
||||
/* Pitch estimation defines */
|
||||
|
||||
#define M_PITCH_S 0.0400 /* pitch analysis window in s */
|
||||
#define P_MIN_S 0.0025 /* minimum pitch period in s */
|
||||
#define P_MAX_S 0.0200 /* maximum pitch period in s */
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
TYPEDEFS
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Structure to hold constants calculated at run time based on sample rate */
|
||||
|
||||
typedef struct {
|
||||
int Fs; /* sample rate of this instance */
|
||||
int n_samp; /* number of samples per 10ms frame at Fs */
|
||||
int max_amp; /* maximum number of harmonics */
|
||||
int m_pitch; /* pitch estimation window size in samples */
|
||||
int p_min; /* minimum pitch period in samples */
|
||||
int p_max; /* maximum pitch period in samples */
|
||||
float Wo_min;
|
||||
float Wo_max;
|
||||
int nw; /* analysis window size in samples */
|
||||
int tw; /* trapezoidal synthesis window overlap */
|
||||
} C2CONST;
|
||||
|
||||
/* Structure to hold model parameters for one frame */
|
||||
|
||||
typedef struct {
|
||||
float Wo; /* fundamental frequency estimate in radians */
|
||||
int L; /* number of harmonics */
|
||||
float A[MAX_AMP+1]; /* amplitiude of each harmonic */
|
||||
float phi[MAX_AMP+1]; /* phase of each harmonic */
|
||||
int voiced; /* non-zero if this frame is voiced */
|
||||
} MODEL;
|
||||
|
||||
/* describes each codebook */
|
||||
|
||||
struct lsp_codebook {
|
||||
int k; /* dimension of vector */
|
||||
int log2m; /* number of bits in m */
|
||||
int m; /* elements in codebook */
|
||||
const float * cb; /* The elements */
|
||||
};
|
||||
|
||||
extern const struct lsp_codebook lsp_cb[];
|
||||
extern const struct lsp_codebook lsp_cbd[];
|
||||
extern const struct lsp_codebook lsp_cbvq[];
|
||||
extern const struct lsp_codebook lsp_cbjnd[];
|
||||
extern const struct lsp_codebook lsp_cbdt[];
|
||||
extern const struct lsp_codebook lsp_cbjvm[];
|
||||
extern const struct lsp_codebook lsp_cbvqanssi[];
|
||||
extern const struct lsp_codebook mel_cb[];
|
||||
extern const struct lsp_codebook ge_cb[];
|
||||
extern const struct lsp_codebook lspmelvq_cb[];
|
||||
extern const struct lsp_codebook newamp1vq_cb[];
|
||||
extern const struct lsp_codebook newamp1_energy_cb[];
|
||||
extern const struct lsp_codebook newamp2vq_cb[];
|
||||
extern const struct lsp_codebook newamp2_energy_cb[];
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
200
libfreedv/fdmdv_internal.h
Normal file
200
libfreedv/fdmdv_internal.h
Normal file
@ -0,0 +1,200 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: fdmdv_internal.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 16 2012
|
||||
|
||||
Header file for FDMDV internal functions, exposed via this header
|
||||
file for testing.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2012 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FDMDV_INTERNAL__
|
||||
#define __FDMDV_INTERNAL__
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "codec2_fdmdv.h"
|
||||
#include "codec2_fft.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
DEFINES
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.141592654
|
||||
#endif
|
||||
#define FS 8000 /* sample rate in Hz */
|
||||
#define T (1.0/FS) /* sample period in seconds */
|
||||
#define RS 50 /* symbol rate in Hz */
|
||||
#define NC 20 /* max number of data carriers (plus one pilot in the centre) */
|
||||
#define NB 2 /* Bits/symbol for QPSK modulation */
|
||||
#define RB (NC*RS*NB) /* bit rate */
|
||||
#define M_FAC (FS/RS) /* oversampling factor */
|
||||
#define NSYM 6 /* number of symbols to filter over */
|
||||
#define NFILTER (NSYM*M_FAC) /* size of tx/rx filters at sample rate M */
|
||||
|
||||
#define FSEP 75 /* Default separation between carriers (Hz) */
|
||||
|
||||
#define NT 5 /* number of symbols we estimate timing over */
|
||||
#define P 4 /* oversample factor used for initial rx symbol filtering output */
|
||||
#define Q (M_FAC/4) /* oversample factor used for initial rx symbol filtering input */
|
||||
#define NRXDEC 31 /* number of taps in the rx decimation filter */
|
||||
|
||||
#define NPILOT_LUT (4*M_FAC) /* number of pilot look up table samples */
|
||||
#define NPILOTCOEFF 30 /* number of FIR filter coeffs in LP filter */
|
||||
#define NPILOTBASEBAND (NPILOTCOEFF+M_FAC+M_FAC/P) /* number of pilot baseband samples reqd for pilot LPF */
|
||||
#define NPILOTLPF (4*M_FAC) /* number of samples we DFT pilot over, pilot est window */
|
||||
#define MPILOTFFT 256
|
||||
|
||||
#define NSYNC_MEM 6
|
||||
|
||||
#define NRX_FDM_MEM (NFILTER+M_FAC+M_FAC/P) /* size of rx filter memory */
|
||||
#define NRXDECMEM (NRXDEC+M_FAC+M_FAC/P) /* size of rx decimation filter memory */
|
||||
|
||||
/* averaging filter coeffs */
|
||||
|
||||
#define TRACK_COEFF 0.5
|
||||
#define SNR_COEFF 0.9 /* SNR est averaging filter coeff */
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
STRUCT for States
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
struct FDMDV {
|
||||
|
||||
int Nc;
|
||||
float fsep;
|
||||
|
||||
/* test data (test frame) states */
|
||||
|
||||
int ntest_bits;
|
||||
int current_test_bit;
|
||||
int *rx_test_bits_mem;
|
||||
|
||||
/* Modulator */
|
||||
|
||||
int old_qpsk_mapping;
|
||||
int tx_pilot_bit;
|
||||
COMP prev_tx_symbols[NC+1];
|
||||
COMP tx_filter_memory[NC+1][NSYM];
|
||||
COMP phase_tx[NC+1];
|
||||
COMP freq[NC+1];
|
||||
float freq_pol[NC+1];
|
||||
|
||||
/* Pilot generation at demodulator */
|
||||
|
||||
COMP pilot_lut[NPILOT_LUT];
|
||||
int pilot_lut_index;
|
||||
int prev_pilot_lut_index;
|
||||
|
||||
/* freq offset estimation states */
|
||||
|
||||
codec2_fft_cfg fft_pilot_cfg;
|
||||
COMP pilot_baseband1[NPILOTBASEBAND];
|
||||
COMP pilot_baseband2[NPILOTBASEBAND];
|
||||
COMP pilot_lpf1[NPILOTLPF];
|
||||
COMP pilot_lpf2[NPILOTLPF];
|
||||
COMP S1[MPILOTFFT];
|
||||
COMP S2[MPILOTFFT];
|
||||
|
||||
/* baseband to low IF carrier states */
|
||||
|
||||
COMP fbb_rect;
|
||||
float fbb_pol;
|
||||
COMP fbb_phase_tx;
|
||||
COMP fbb_phase_rx;
|
||||
|
||||
/* freq offset correction states */
|
||||
|
||||
float foff;
|
||||
COMP foff_phase_rect;
|
||||
float foff_filt;
|
||||
|
||||
/* Demodulator */
|
||||
|
||||
COMP rxdec_lpf_mem[NRXDECMEM];
|
||||
COMP rx_fdm_mem[NRX_FDM_MEM];
|
||||
COMP phase_rx[NC+1];
|
||||
COMP rx_filter_mem_timing[NC+1][NT*P];
|
||||
float rx_timing;
|
||||
COMP phase_difference[NC+1];
|
||||
COMP prev_rx_symbols[NC+1];
|
||||
|
||||
/* sync state machine */
|
||||
|
||||
int sync_mem[NSYNC_MEM];
|
||||
int fest_state;
|
||||
int sync;
|
||||
int timer;
|
||||
|
||||
/* SNR estimation states */
|
||||
|
||||
float sig_est[NC+1];
|
||||
float noise_est[NC+1];
|
||||
|
||||
/* channel simulation */
|
||||
|
||||
float sig_pwr_av;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FUNCTION PROTOTYPES
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
|
||||
void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
|
||||
void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq_tx[],
|
||||
COMP *fbb_phase, COMP fbb_rect);
|
||||
void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
|
||||
COMP tx_filter_memory[NC+1][NSYM],
|
||||
COMP phase_tx[], COMP freq[], COMP *fbb_phase, COMP fbb_rect);
|
||||
void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
|
||||
void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
|
||||
float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft);
|
||||
void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], codec2_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft);
|
||||
void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
|
||||
void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin);
|
||||
void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_FAC/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
|
||||
void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
|
||||
COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
|
||||
float freq_pol[], int nin, int dec_rate);
|
||||
float rx_est_timing(COMP rx_symbols[], int Nc,
|
||||
COMP rx_filt[NC+1][P+1],
|
||||
COMP rx_filter_mem_timing[NC+1][NT*P],
|
||||
float env[],
|
||||
int nin,
|
||||
int m);
|
||||
float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
|
||||
void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
|
||||
int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);
|
||||
float calc_snr(int Nc, float sig_est[], float noise_est[]);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
41
libfreedv/fdv_arm_math.h
Normal file
41
libfreedv/fdv_arm_math.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: fdv_arm_math.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: Feb 13 2019
|
||||
|
||||
Bundles access to ARM CORTEX M specific functions which are enabled by
|
||||
defining FDV_ARM_MATH
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2012 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FDV_ARM_MATH__
|
||||
#define __FDV_ARM_MATH__
|
||||
|
||||
#ifdef FDV_ARM_MATH
|
||||
#include "arm_const_structs.h"
|
||||
#define SINF(a) arm_sin_f32(a)
|
||||
#define COSF(a) arm_cos_f32(a)
|
||||
#else
|
||||
#define SINF(a) sinf(a)
|
||||
#define COSF(a) cosf(a)
|
||||
#endif
|
||||
|
||||
#endif
|
116
libfreedv/fmfsk.h
Normal file
116
libfreedv/fmfsk.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: fmfsk.h
|
||||
AUTHOR......: Brady O'Brien
|
||||
DATE CREATED: 6 February 2016
|
||||
|
||||
C Implementation of 2FSK+Manchester over FM modulator/demodulator, based
|
||||
on mancyfsk.m and fmfsk.m
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2016 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __C2FMFSK_H
|
||||
#define __C2FMFSK_H
|
||||
#include <stdint.h>
|
||||
#include "codec2/comp.h"
|
||||
|
||||
#include "modem_stats.h"
|
||||
|
||||
#define FMFSK_SCALE 16383
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/*
|
||||
* fm-me-2fsk state
|
||||
*/
|
||||
struct FMFSK{
|
||||
/* Static fmfsk parameters */
|
||||
int Rb; /* Manchester-encoded bitrate */
|
||||
int Rs; /* Raw modem symbol rate */
|
||||
int Fs; /* Sample rate */
|
||||
int Ts; /* Samples-per-symbol */
|
||||
int N; /* Sample processing buffer size */
|
||||
int nsym; /* Number of raw modem symbols processed per demod call */
|
||||
int nbit; /* Number of bits spit out per demod call */
|
||||
int nmem; /* Number of samples kept around between demod calls */
|
||||
|
||||
/* State kept by demod */
|
||||
int nin; /* Number of samples to be demod-ed the next cycle */
|
||||
int lodd; /* Last integrated sample for odd bitstream generation */
|
||||
float * oldsamps; /* Memory of old samples to make clock-offset-tolerance possible */
|
||||
|
||||
/* Stats generated by demod */
|
||||
float norm_rx_timing; /* RX Timing, used to calculate clock offset */
|
||||
int ppm; /* Clock offset in parts-per-million */
|
||||
float snr_mean;
|
||||
|
||||
/* Modem stat structure */
|
||||
struct MODEM_STATS * stats;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a new fmfsk modem instance.
|
||||
*
|
||||
* int Fs - sample rate
|
||||
* int Rb - non-manchester bitrate
|
||||
* returns - new struct FMFSK on sucess, NULL on failure
|
||||
*/
|
||||
struct FMFSK * fmfsk_create(int Fs,int Rb);
|
||||
|
||||
/*
|
||||
* Destroys an fmfsk modem and deallocates memory
|
||||
*/
|
||||
void fmfsk_destroy(struct FMFSK *fmfsk);
|
||||
|
||||
/*
|
||||
* Deposit demod statistics into a MODEM_STATS struct
|
||||
*/
|
||||
void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats);
|
||||
|
||||
/*
|
||||
* Returns the number of samples that must be fed to fmfsk_demod the next
|
||||
* cycle
|
||||
*/
|
||||
uint32_t fmfsk_nin(struct FMFSK *fmfsk);
|
||||
|
||||
/*
|
||||
* Modulates nbit bits into N samples to be sent through an FM radio
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* float mod_out[] - Buffer for N samples of modulated FMFSK
|
||||
* uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
|
||||
*/
|
||||
void fmfsk_mod(struct FMFSK *fmfsk, float fmfsk_out[],uint8_t bits_in[]);
|
||||
|
||||
|
||||
/*
|
||||
* Demodulate some number of FMFSK samples. The number of samples to be
|
||||
* demodulated can be found by calling fmfsk_nin().
|
||||
*
|
||||
* struct FMFSK *fsk - FMFSK config/state struct, set up by fsk_create
|
||||
* uint8_t rx_bits[] - Buffer for nbit unpacked bits to be written
|
||||
* float fsk_in[] - nin samples of modualted FMFSK from an FM radio
|
||||
*/
|
||||
void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
2538
libfreedv/freedv_api.cpp
Normal file
2538
libfreedv/freedv_api.cpp
Normal file
File diff suppressed because it is too large
Load Diff
154
libfreedv/freedv_api_internal.h
Normal file
154
libfreedv/freedv_api_internal.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_api_internal.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: August 2014
|
||||
|
||||
This declares the structure freedv. A pointer to this structure is
|
||||
returned by the FreeDV API freedv_open() function. The pointer is used
|
||||
by the other FreeDV API functions declared in freedv_api.h. This
|
||||
structure is intended to be internal to the FreeDV API. The public
|
||||
functions are declared in freedv_api.h. Changes to this structure
|
||||
are expected. Changes (except additions) to freedv_api.h are
|
||||
discouraged.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2014 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FREEDV_API_INTERNAL__
|
||||
#define __FREEDV_API_INTERNAL__
|
||||
|
||||
#include "codec2/varicode.h"
|
||||
#include "fsk.h"
|
||||
#include "fmfsk.h"
|
||||
#include "codec2_cohpsk.h"
|
||||
#include "codec2_fdmdv.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct freedv {
|
||||
int mode;
|
||||
|
||||
/* states for various modems we support */
|
||||
|
||||
struct CODEC2 *codec2;
|
||||
struct FDMDV *fdmdv;
|
||||
struct COHPSK *cohpsk;
|
||||
struct FSK *fsk;
|
||||
struct FMFSK *fmfsk;
|
||||
struct OFDM *ofdm;
|
||||
struct LDPC *ldpc;
|
||||
struct MODEM_STATS stats;
|
||||
|
||||
struct freedv_vhf_deframer * deframer; // Extracts frames from VHF stream
|
||||
|
||||
struct quisk_cfFilter * ptFilter7500to8000; // Filters to change to/from 7500 and 8000 sps for 700 .... 700C
|
||||
struct quisk_cfFilter * ptFilter8000to7500;
|
||||
|
||||
int n_speech_samples; // number of speech samples we need for each freedv_tx() call
|
||||
// num of speech samples output by freedv_rx() call
|
||||
int n_nom_modem_samples; // size of tx and most rx modem sample buffers
|
||||
int n_max_modem_samples; // make your rx modem sample buffers this big
|
||||
int n_nat_modem_samples; // tx modem sample block length as used by the modem before interpolation to output
|
||||
// usually the same as n_nom_modem_samples, except for 700..700C
|
||||
int modem_sample_rate; // Caller is responsible for meeting this
|
||||
int modem_symbol_rate; // Useful for ext_vco operation on 2400A and 800XA
|
||||
int clip; // non-zero for cohpsk modem output clipping for low PAPR
|
||||
|
||||
unsigned char *packed_codec_bits;
|
||||
unsigned char *packed_codec_bits_tx; // for 700D we separate packed bits to maintain state due to interleaving
|
||||
int nbyte_packed_codec_bits; // keep track of size of above arrays in 700D
|
||||
int *codec_bits;
|
||||
int *tx_bits;
|
||||
int *fdmdv_bits;
|
||||
int *rx_bits;
|
||||
int n_codec_bits; // number of codec bits in a frame
|
||||
|
||||
int tx_sync_bit;
|
||||
int smooth_symbols;
|
||||
int frames;
|
||||
|
||||
/* test frame states -------------------------------------------------------------------------*/
|
||||
|
||||
int *ptest_bits_coh;
|
||||
int *ptest_bits_coh_end;
|
||||
|
||||
int test_frames; // set this baby for 1 to tx/rx test frames to look at bit error stats
|
||||
int test_frames_diversity; // 1 -> used combined carriers for error counting on 700 waveforms
|
||||
int test_frame_sync_state;
|
||||
int test_frame_sync_state_upper; // when test_frames_diveristy==0 we need extra states for upper carriers
|
||||
int test_frame_count;
|
||||
int total_bits;
|
||||
int total_bit_errors;
|
||||
int total_bits_coded;
|
||||
int total_bit_errors_coded;
|
||||
int sz_error_pattern;
|
||||
|
||||
/* optional user defined function to pass error pattern when a test frame is received */
|
||||
|
||||
void *error_pattern_callback_state;
|
||||
void (*freedv_put_error_pattern)(void *error_pattern_callback_state, short error_pattern[], int sz_error_pattern);
|
||||
|
||||
/* Misc ---------------------------------------------------------------------------------------------*/
|
||||
|
||||
int sync;
|
||||
int evenframe;
|
||||
float snr_est;
|
||||
float snr_squelch_thresh;
|
||||
int squelch_en;
|
||||
int nin;
|
||||
int verbose;
|
||||
int ext_vco; /* 2400A/800XA use external VCO flag */
|
||||
|
||||
/* Varicode txt channel states ----------------------------------------------------------------------*/
|
||||
|
||||
struct VARICODE_DEC varicode_dec_states;
|
||||
short tx_varicode_bits[VARICODE_MAX_BITS];
|
||||
int nvaricode_bits;
|
||||
int varicode_bit_index;
|
||||
|
||||
/* interleaved LDPC OFDM states ---------------------------------------------------------------------*/
|
||||
|
||||
int interleave_frames; // number of OFDM modem frames in interleaver, e.g. 1,2,4,8,16
|
||||
COMP *codeword_symbols;
|
||||
float *codeword_amps;
|
||||
int modem_frame_count_tx; // modem frame counter for tx side
|
||||
int modem_frame_count_rx; // modem frame counter for rx side
|
||||
COMP *mod_out; // output buffer of intereaved frames
|
||||
|
||||
/* user defined function ptrs to produce and consume ASCII
|
||||
characters using aux txt channel */
|
||||
|
||||
char (*freedv_get_next_tx_char)(void *callback_state);
|
||||
void (*freedv_put_next_rx_char)(void *callback_state, char c);
|
||||
void *callback_state;
|
||||
|
||||
/* user defined functions to produce and consume protocol bits */
|
||||
/* Protocol bits are packed MSB-first */
|
||||
void (*freedv_put_next_proto)(void *callback_state, char *proto_bits_packed);
|
||||
void (*freedv_get_next_proto)(void *callback_state, char *proto_bits_packed);
|
||||
void *proto_callback_state;
|
||||
int n_protocol_bits;
|
||||
};
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
||||
|
75
libfreedv/freedv_data_channel.h
Normal file
75
libfreedv/freedv_data_channel.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_data_channel.h
|
||||
AUTHOR......: Jeroen Vreeken
|
||||
DATE CREATED: 03 March 2016
|
||||
|
||||
Data channel for ethernet like packets in freedv VHF frames.
|
||||
Currently designed for-
|
||||
* 2 control bits per frame
|
||||
* 4 byte counter bits per frame
|
||||
* 64 bits of data per frame
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2016 Jeroen Vreeken
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FREEDV_DATA_CHANNEL_H
|
||||
#define _FREEDV_DATA_CHANNEL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FREEDV_DATA_CHANNEL_PACKET_MAX 2048
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
typedef void (*freedv_data_callback_rx)(void *, unsigned char *packet, size_t size);
|
||||
typedef void (*freedv_data_callback_tx)(void *, unsigned char *packet, size_t *size);
|
||||
|
||||
struct freedv_data_channel {
|
||||
freedv_data_callback_rx cb_rx;
|
||||
void *cb_rx_state;
|
||||
freedv_data_callback_tx cb_tx;
|
||||
void *cb_tx_state;
|
||||
|
||||
unsigned char rx_header[8];
|
||||
unsigned char packet_rx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2];
|
||||
int packet_rx_cnt;
|
||||
|
||||
unsigned char tx_header[8];
|
||||
unsigned char packet_tx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2];
|
||||
int packet_tx_cnt;
|
||||
size_t packet_tx_size;
|
||||
};
|
||||
|
||||
|
||||
struct freedv_data_channel *freedv_data_channel_create(void);
|
||||
void freedv_data_channel_destroy(struct freedv_data_channel *fdc);
|
||||
|
||||
void freedv_data_set_cb_rx(struct freedv_data_channel *fdc, freedv_data_callback_rx cb, void *state);
|
||||
void freedv_data_set_cb_tx(struct freedv_data_channel *fdc, freedv_data_callback_tx cb, void *state);
|
||||
|
||||
void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits);
|
||||
void freedv_data_channel_tx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int *from_bit, int *bcast_bit, int *crc_bit, int *end_bits);
|
||||
|
||||
void freedv_data_set_header(struct freedv_data_channel *fdc, unsigned char *header);
|
||||
int freedv_data_get_n_tx_frames(struct freedv_data_channel *fdc, size_t size);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif /* _FREEDV_DATA_CHANNEL_H */
|
48
libfreedv/freedv_filter.h
Normal file
48
libfreedv/freedv_filter.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (C) 2018 James C. Ahlstrom
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FILTER__
|
||||
#define __FILTER__
|
||||
|
||||
#include <complex>
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct quisk_cfFilter { // Structure to hold the static data for FIR filters
|
||||
float * dCoefs; // real filter coefficients
|
||||
std::complex<float> * cpxCoefs; // complex filter coefficients
|
||||
int nBuf; // dimension of cBuf
|
||||
int nTaps; // dimension of dSamples, cSamples, dCoefs
|
||||
int decim_index; // index of next sample for decimation
|
||||
std::complex<float> * cSamples; // storage for old samples
|
||||
std::complex<float> * ptcSamp; // next available position in cSamples
|
||||
std::complex<float> * cBuf; // auxillary buffer for interpolation
|
||||
} ;
|
||||
|
||||
extern int quisk_cfInterpDecim(std::complex<float> *, int, struct quisk_cfFilter *, int, int);
|
||||
extern void quisk_filt_cfInit(struct quisk_cfFilter *, float *, int);
|
||||
extern void quisk_filt_destroy(struct quisk_cfFilter *);
|
||||
extern void quisk_cfTune(struct quisk_cfFilter *, float);
|
||||
extern void quisk_ccfFilter(std::complex<float> *, std::complex<float> *, int, struct quisk_cfFilter *);
|
||||
|
||||
extern float quiskFilt120t480[480];
|
||||
extern float filtP550S750[160];
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
103
libfreedv/freedv_vhf_framing.h
Normal file
103
libfreedv/freedv_vhf_framing.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_vhf_framing.h
|
||||
AUTHOR......: Brady O'Brien
|
||||
DATE CREATED: 11 February 2016
|
||||
|
||||
Framer and deframer for VHF FreeDV modes 'A' and 'B'
|
||||
Currently designed for-
|
||||
* 40ms ota modem frames
|
||||
* 40ms Codec2 1300 frames
|
||||
* 52 bits of Codec2 per frame
|
||||
* 16 bits of unique word per frame
|
||||
* 28 'spare' bits per frame
|
||||
* - 4 spare bits at front and end of frame (8 total) for padding
|
||||
* - 20 'protocol' bits, either for higher layers of 'protocol' or
|
||||
* - 18 'protocol' bits and 2 vericode sidechannel bits
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2016 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FREEDV_VHF_FRAMING_H
|
||||
#define _FREEDV_VHF_FRAMING_H
|
||||
|
||||
#include "freedv_data_channel.h"
|
||||
|
||||
/* Standard frame type */
|
||||
#define FREEDV_VHF_FRAME_A 1 /* 2400A/B Frame */
|
||||
#define FREEDV_HF_FRAME_B 2 /* 800XA Frame */
|
||||
#define FREEDV_VHF_FRAME_AT 3 /* 4800T Frame */
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct freedv_vhf_deframer {
|
||||
int ftype; /* Type of frame to be looking for */
|
||||
int state; /* State of deframer */
|
||||
uint8_t * bits; /* Bits currently being decanted */
|
||||
uint8_t * invbits; /* Inversion of bits currently being decanted, for FMFSK */
|
||||
|
||||
int bitptr; /* Pointer into circular bit buffer */
|
||||
int miss_cnt; /* How many UWs have been missed */
|
||||
int last_uw; /* How many bits since the last UW? */
|
||||
int frame_size; /* How big is a frame? */
|
||||
int uw_size; /* How big is the UW */
|
||||
int on_inv_bits; /* Are we using the inverted bits? */
|
||||
int sym_size; /* How many bits in a modem symbol */
|
||||
|
||||
float ber_est; /* Bit error rate estimate */
|
||||
int total_uw_bits; /* Total RX-ed bits of UW */
|
||||
int total_uw_err; /* Total errors in UW bits */
|
||||
|
||||
struct freedv_data_channel *fdc;
|
||||
};
|
||||
|
||||
/* Init and allocate memory for a freedv-vhf framer/deframer */
|
||||
struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type,int enable_bit_flip);
|
||||
|
||||
/* Get size of various frame parameters */
|
||||
/* Frame size in bits */
|
||||
int fvhff_get_frame_size(struct freedv_vhf_deframer * def);
|
||||
/* Codec2 size in bytes */
|
||||
int fvhff_get_codec2_size(struct freedv_vhf_deframer * def);
|
||||
/* Protocol bits in bits */
|
||||
int fvhff_get_proto_size(struct freedv_vhf_deframer * def);
|
||||
/* Varicode bits in bits */
|
||||
int fvhff_get_varicode_size(struct freedv_vhf_deframer * def);
|
||||
|
||||
/* Free the memory used by a freedv-vhf framer/deframer */
|
||||
void fvhff_destroy_deframer(struct freedv_vhf_deframer * def);
|
||||
|
||||
/* Place codec and other bits into a frame */
|
||||
void fvhff_frame_bits(int frame_type,uint8_t bits_out[],uint8_t codec2_in[],uint8_t proto_in[],uint8_t vc_in[]);
|
||||
void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]);
|
||||
|
||||
/* Find and extract frames from a stream of bits */
|
||||
int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]);
|
||||
|
||||
/* Is the de-framer synchronized? */
|
||||
int fvhff_synchronized(struct freedv_vhf_deframer * def);
|
||||
|
||||
/* Search for a complete UW in a buffer of bits */
|
||||
std::size_t fvhff_search_uw(const uint8_t bits[],size_t nbits,
|
||||
const uint8_t uw[], std::size_t uw_len,
|
||||
std::size_t * delta_out, std::size_t bits_per_sym);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif //_FREEDV_VHF_FRAMING_H
|
209
libfreedv/fsk.h
Normal file
209
libfreedv/fsk.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: fsk.h
|
||||
AUTHOR......: Brady O'Brien
|
||||
DATE CREATED: 6 January 2016
|
||||
|
||||
C Implementation of 2FSK/4FSK modulator/demodulator, based on octave/fsk_horus.m
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2016 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __C2FSK_H
|
||||
#define __C2FSK_H
|
||||
#include <stdint.h>
|
||||
#include "codec2/comp.h"
|
||||
#include "kiss_fftr.h"
|
||||
#include "modem_stats.h"
|
||||
|
||||
#define MODE_2FSK 2
|
||||
#define MODE_4FSK 4
|
||||
|
||||
#define MODE_M_MAX 4
|
||||
|
||||
#define FSK_SCALE 16383
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct FSK {
|
||||
/* Static parameters set up by fsk_init */
|
||||
int Ndft; /* buffer size for freq offset est fft */
|
||||
int Fs; /* sample freq */
|
||||
int N; /* processing buffer size */
|
||||
int Rs; /* symbol rate */
|
||||
int Ts; /* samples per symbol */
|
||||
int Nmem; /* size of extra mem for timing adj */
|
||||
int P; /* oversample rate for timing est/adj */
|
||||
int Nsym; /* Number of symbols spat out in a processing frame */
|
||||
int Nbits; /* Number of bits spat out in a processing frame */
|
||||
int f1_tx; /* f1 for modulator */
|
||||
int fs_tx; /* Space between TX freqs for modulatosr */
|
||||
int mode; /* 2FSK or 4FSK */
|
||||
int est_min; /* Minimum frequency for freq. estimator */
|
||||
int est_max; /* Maximum frequency for freq. estimaotr */
|
||||
int est_space; /* Minimum frequency spacing for freq. estimator */
|
||||
float* hann_table; /* Precomputed or runtime computed hann window table */
|
||||
|
||||
/* Parameters used by demod */
|
||||
COMP phi_c[MODE_M_MAX];
|
||||
|
||||
kiss_fft_cfg fft_cfg; /* Config for KISS FFT, used in freq est */
|
||||
float norm_rx_timing; /* Normalized RX timing */
|
||||
|
||||
COMP* samp_old; /* Tail end of last batch of samples */
|
||||
int nstash; /* How many elements are in there */
|
||||
|
||||
float* fft_est; /* Freq est FFT magnitude */
|
||||
|
||||
/* Memory used by demod but not important between demod frames */
|
||||
|
||||
/* Parameters used by mod */
|
||||
COMP tx_phase_c; /* TX phase, but complex */
|
||||
|
||||
/* Statistics generated by demod */
|
||||
float EbNodB; /* Estimated EbNo in dB */
|
||||
float f_est[MODE_M_MAX];/* Estimated frequencies */
|
||||
float ppm; /* Estimated PPM clock offset */
|
||||
|
||||
/* Parameters used by mod/demod and driving code */
|
||||
int nin; /* Number of samples to feed the next demod cycle */
|
||||
int burst_mode; /* enables/disables 'burst' mode */
|
||||
|
||||
/* modem statistic struct */
|
||||
struct MODEM_STATS *stats;
|
||||
int normalise_eye; /* enables/disables normalisation of eye diagram */
|
||||
};
|
||||
|
||||
/*
|
||||
* Create an FSK config/state struct from a set of config parameters
|
||||
*
|
||||
* int Fs - Sample frequency
|
||||
* int Rs - Symbol rate
|
||||
* int tx_f1 - '0' frequency
|
||||
* int tx_fs - frequency spacing
|
||||
*/
|
||||
struct FSK * fsk_create(int Fs, int Rs, int M, int tx_f1, int tx_fs);
|
||||
|
||||
/*
|
||||
* Create an FSK config/state struct from a set of config parameters
|
||||
*
|
||||
* int Fs - Sample frequency
|
||||
* int Rs - Symbol rate
|
||||
* int tx_f1 - '0' frequency
|
||||
* int tx_fs - frequency spacing
|
||||
*/
|
||||
struct FSK * fsk_create_hbr(int Fs, int Rs, int P, int M, int tx_f1, int tx_fs);
|
||||
|
||||
/*
|
||||
* Set a new number of symbols per processing frame
|
||||
*/
|
||||
void fsk_set_nsym(struct FSK *fsk,int nsym);
|
||||
|
||||
/*
|
||||
* Set the minimum and maximum frequencies at which the freq. estimator can find tones
|
||||
*/
|
||||
void fsk_set_est_limits(struct FSK *fsk,int fmin, int fmax);
|
||||
|
||||
/*
|
||||
* Clear the estimator states
|
||||
*/
|
||||
void fsk_clear_estimators(struct FSK *fsk);
|
||||
|
||||
/*
|
||||
* Fills MODEM_STATS struct with demod statistics
|
||||
*/
|
||||
void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats);
|
||||
|
||||
/*
|
||||
* Destroy an FSK state struct and free it's memory
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct to be destroyed
|
||||
*/
|
||||
void fsk_destroy(struct FSK *fsk);
|
||||
|
||||
/*
|
||||
* Modulates Nsym bits into N samples
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* float fsk_out[] - Buffer for N samples of modulated FSK
|
||||
* uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
|
||||
*/
|
||||
void fsk_mod(struct FSK *fsk, float fsk_out[], uint8_t tx_bits[]);
|
||||
|
||||
/*
|
||||
* Modulates Nsym bits into N samples
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* float fsk_out[] - Buffer for N samples of "voltage" used to modulate an external VCO
|
||||
* uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
|
||||
*/
|
||||
void fsk_mod_ext_vco(struct FSK *fsk, float vco_out[], uint8_t tx_bits[]);
|
||||
|
||||
/*
|
||||
* Modulates Nsym bits into N complex samples
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* comp fsk_out[] - Buffer for N samples of modulated FSK
|
||||
* uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
|
||||
*/
|
||||
void fsk_mod_c(struct FSK *fsk, COMP fsk_out[], uint8_t tx_bits[]);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the number of samples needed for the next fsk_demod() cycle
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* returns - number of samples to be fed into fsk_demod next cycle
|
||||
*/
|
||||
uint32_t fsk_nin(struct FSK *fsk);
|
||||
|
||||
|
||||
/*
|
||||
* Demodulate some number of FSK samples. The number of samples to be
|
||||
* demodulated can be found by calling fsk_nin().
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* uint8_t rx_bits[] - Buffer for Nbits unpacked bits to be written
|
||||
* float fsk_in[] - nin samples of modualted FSK
|
||||
*/
|
||||
void fsk_demod(struct FSK *fsk, uint8_t rx_bits[],COMP fsk_in[]);
|
||||
|
||||
/*
|
||||
* Demodulate some number of FSK samples. The number of samples to be
|
||||
* demodulated can be found by calling fsk_nin().
|
||||
*
|
||||
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
|
||||
* float rx_bits[] - Buffer for Nbits soft decision bits to be written
|
||||
* float fsk_in[] - nin samples of modualted FSK
|
||||
*/
|
||||
void fsk_demod_sd(struct FSK *fsk, float rx_bits[],COMP fsk_in[]);
|
||||
|
||||
/* enables/disables normalisation of eye diagram samples */
|
||||
|
||||
void fsk_stats_normalise_eye(struct FSK *fsk, int normalise_enable);
|
||||
|
||||
/* Set the FSK modem into burst demod mode */
|
||||
|
||||
void fsk_enable_burst_mode(struct FSK *fsk,int nsyms);
|
||||
|
||||
} // FreeSV
|
||||
|
||||
#endif
|
46
libfreedv/gp_interleaver.h
Normal file
46
libfreedv/gp_interleaver.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: gp_interleaver.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2018
|
||||
|
||||
Golden Prime Interleaver. My interprestation of "On the Analysis and
|
||||
Design of Good Algebraic Interleavers", Xie et al,eq (5).
|
||||
|
||||
See also octvae/gp_interleaver.m
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2018 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GP_INTERLEAVER__
|
||||
#define __GP_INTERLEAVER__
|
||||
|
||||
#include "codec2/comp.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
void gp_interleave_comp(COMP interleaved_frame[], COMP frame[], int Nbits);
|
||||
void gp_deinterleave_comp(COMP frame[], COMP interleaved_frame[], int Nbits);
|
||||
void gp_interleave_float(float frame[], float interleaved_frame[], int Nbits);
|
||||
void gp_deinterleave_float(float interleaved_frame[], float frame[], int Nbits);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
59
libfreedv/interldpc.h
Normal file
59
libfreedv/interldpc.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: interldpc.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2018
|
||||
|
||||
Helper functions for interleaved LDPC modems.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2018 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __INTERLDPC__
|
||||
#define __INTERLDPC__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "mpdecode_core.h"
|
||||
#include "ofdm_internal.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/* CRC type function, used to compare QPSK vectors when debugging */
|
||||
|
||||
COMP test_acc(COMP v[], int n);
|
||||
void printf_n(COMP v[], int n);
|
||||
void set_up_hra_112_112(struct LDPC *ldpc, struct OFDM_CONFIG *);
|
||||
void ldpc_encode_frame(struct LDPC *ldpc, int codeword[], unsigned char tx_bits_char[]);
|
||||
void qpsk_modulate_frame(COMP tx_symbols[], int codeword[], int n);
|
||||
void interleaver_sync_state_machine(struct OFDM *ofdm, struct LDPC *ldpc, struct OFDM_CONFIG *config,
|
||||
COMP codeword_symbols_de[],
|
||||
float codeword_amps_de[],
|
||||
float EsNo, int interleave_frames,
|
||||
int *inter, int *parityCheckCount, int *Nerrs_coded);
|
||||
int count_uncoded_errors(struct LDPC *ldpc, struct OFDM_CONFIG *config, int Nerrs_raw[], int interleave_frames, COMP codeword_symbols_de[]);
|
||||
int count_errors(uint8_t tx_bits[], uint8_t rx_bits[], int n);
|
||||
void ofdm_ldpc_interleave_tx(struct OFDM *ofdm, struct LDPC *ldpc, std::complex<float> tx_sams[], uint8_t tx_bits[], uint8_t txt_bits[], int interleave_frames, struct OFDM_CONFIG *config);
|
||||
void build_modulated_uw(struct OFDM *ofdm, std::complex<float> tx_symbols[], uint8_t txt_bits[], struct OFDM_CONFIG *config);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
122
libfreedv/kiss_fft.h
Normal file
122
libfreedv/kiss_fft.h
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef FREEDV_KISS_FFT_H
|
||||
#define FREEDV_KISS_FFT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
ATTENTION!
|
||||
If you would like a :
|
||||
-- a utility that will handle the caching of fft objects
|
||||
-- real-only (no imaginary time component ) FFT
|
||||
-- a multi-dimensional FFT
|
||||
-- a command-line utility to perform ffts
|
||||
-- a command-line utility to perform fast-convolution filtering
|
||||
|
||||
Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
|
||||
in the tools/ directory.
|
||||
*/
|
||||
|
||||
#ifdef USE_SIMD
|
||||
# include <xmmintrin.h>
|
||||
# define kiss_fft_scalar __m128
|
||||
#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
|
||||
#define KISS_FFT_FREE _mm_free
|
||||
#else
|
||||
#define KISS_FFT_MALLOC malloc
|
||||
#define KISS_FFT_FREE free
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#include <sys/types.h>
|
||||
# if (FIXED_POINT == 32)
|
||||
# define kiss_fft_scalar int32_t
|
||||
# else
|
||||
# define kiss_fft_scalar int16_t
|
||||
# endif
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
/* default is float */
|
||||
# define kiss_fft_scalar float
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
kiss_fft_scalar r;
|
||||
kiss_fft_scalar i;
|
||||
}kiss_fft_cpx;
|
||||
|
||||
typedef struct kiss_fft_state* kiss_fft_cfg;
|
||||
|
||||
/*
|
||||
* kiss_fft_alloc
|
||||
*
|
||||
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
|
||||
*
|
||||
* typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
|
||||
*
|
||||
* The return value from fft_alloc is a cfg buffer used internally
|
||||
* by the fft routine or NULL.
|
||||
*
|
||||
* If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
|
||||
* The returned value should be free()d when done to avoid memory leaks.
|
||||
*
|
||||
* The state can be placed in a user supplied buffer 'mem':
|
||||
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
|
||||
* then the function places the cfg in mem and the size used in *lenmem
|
||||
* and returns mem.
|
||||
*
|
||||
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
|
||||
* then the function returns NULL and places the minimum cfg
|
||||
* buffer size in *lenmem.
|
||||
* */
|
||||
|
||||
kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
|
||||
|
||||
/*
|
||||
* kiss_fft(cfg,in_out_buf)
|
||||
*
|
||||
* Perform an FFT on a complex input buffer.
|
||||
* for a forward FFT,
|
||||
* fin should be f[0] , f[1] , ... ,f[nfft-1]
|
||||
* fout will be F[0] , F[1] , ... ,F[nfft-1]
|
||||
* Note that each element is complex and can be accessed like
|
||||
f[k].r and f[k].i
|
||||
* */
|
||||
void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
|
||||
/*
|
||||
A more generic version of the above function. It reads its input from every Nth sample.
|
||||
* */
|
||||
void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
|
||||
|
||||
/* If kiss_fft_alloc allocated a buffer, it is one contiguous
|
||||
buffer and can be simply free()d when no longer needed*/
|
||||
#define kiss_fft_free free
|
||||
|
||||
/*
|
||||
Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
|
||||
your compiler output to call this before you exit.
|
||||
*/
|
||||
void kiss_fft_cleanup(void);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
|
||||
*/
|
||||
int kiss_fft_next_fast_size(int n);
|
||||
|
||||
/* for real ffts, we need an even size */
|
||||
#define kiss_fftr_next_fast_size_real(n) \
|
||||
(kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif // FREEDV_KISS_FFT_H
|
44
libfreedv/kiss_fftr.h
Normal file
44
libfreedv/kiss_fftr.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef KISS_FTR_H
|
||||
#define KISS_FTR_H
|
||||
|
||||
#include "kiss_fft.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/*
|
||||
|
||||
Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
typedef struct kiss_fftr_state *kiss_fftr_cfg;
|
||||
|
||||
|
||||
kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
/*
|
||||
nfft must be even
|
||||
|
||||
If you don't care to allocate space, use mem = lenmem = NULL
|
||||
*/
|
||||
|
||||
|
||||
void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
/*
|
||||
input timedata has nfft scalar points
|
||||
output freqdata has nfft/2+1 complex points
|
||||
*/
|
||||
|
||||
void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
/*
|
||||
input freqdata has nfft/2+1 complex points
|
||||
output timedata has nfft scalar points
|
||||
*/
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#define kiss_fftr_free free
|
||||
|
||||
#endif
|
186
libfreedv/libfreedv.h
Normal file
186
libfreedv/libfreedv.h
Normal file
@ -0,0 +1,186 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// freedv_api.h replacement //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_api.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: August 2014
|
||||
|
||||
Library of API functions that implement FreeDV "modes", useful for
|
||||
embedding FreeDV in other programs. Please see the documentation
|
||||
for each function in freedv_api.c, and the sample freedv_tx.c and
|
||||
freedv_rx.c programs.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2014 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBFREEDV_LIBFREEDV_H_
|
||||
#define LIBFREEDV_LIBFREEDV_H_
|
||||
|
||||
// This declares a single-precision (float) complex number
|
||||
#include <cstddef>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "codec2_ofdm.h"
|
||||
|
||||
#define FREEDV_MODE_1600 0
|
||||
#define FREEDV_MODE_700 1
|
||||
#define FREEDV_MODE_700B 2
|
||||
#define FREEDV_MODE_2400A 3
|
||||
#define FREEDV_MODE_2400B 4
|
||||
#define FREEDV_MODE_800XA 5
|
||||
#define FREEDV_MODE_700C 6
|
||||
#define FREEDV_MODE_700D 7
|
||||
|
||||
/* operator control of 700D state machine */
|
||||
|
||||
#define FREEDV_SYNC_UNSYNC 0 /* force sync state machine to lose sync, and search for new sync */
|
||||
#define FREEDV_SYNC_AUTO 1 /* falls out of sync automatically */
|
||||
#define FREEDV_SYNC_MANUAL 2 /* fall out of sync only under operator control */
|
||||
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct freedv;
|
||||
|
||||
/* advanced freedv open options rqd by some modes */
|
||||
|
||||
struct freedv_advanced {
|
||||
int interleave_frames;
|
||||
};
|
||||
|
||||
/* Called when text message char is decoded */
|
||||
typedef void (*freedv_callback_rx)(void *, char);
|
||||
/* Called when new text message char is needed */
|
||||
typedef char (*freedv_callback_tx)(void *);
|
||||
typedef void (*freedv_calback_error_pattern)
|
||||
(void *error_pattern_callback_state, short error_pattern[], int sz_error_pattern);
|
||||
|
||||
/* Protocol bits are packed MSB-first */
|
||||
/* Called when a frame containing protocol data is decoded */
|
||||
typedef void (*freedv_callback_protorx)(void *, char *);
|
||||
/* Called when a frame containing protocol data is to be sent */
|
||||
typedef void (*freedv_callback_prototx)(void *, char *);
|
||||
|
||||
/* Data packet callbacks */
|
||||
/* Called when a packet has been received */
|
||||
typedef void (*freedv_callback_datarx)(void *, unsigned char *packet, std::size_t size);
|
||||
/* Called when a new packet can be send */
|
||||
typedef void (*freedv_callback_datatx)(void *, unsigned char *packet, std::size_t *size);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FreeDV API functions
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// open, close ----------------------------------------------------------------
|
||||
|
||||
struct freedv *freedv_open(int mode);
|
||||
struct freedv *freedv_open_advanced(int mode, struct freedv_advanced *adv);
|
||||
void freedv_close (struct freedv *freedv);
|
||||
|
||||
// Transmit -------------------------------------------------------------------
|
||||
|
||||
void freedv_tx (struct freedv *freedv, short mod_out[], short speech_in[]);
|
||||
void freedv_comptx (struct freedv *freedv, COMP mod_out[], short speech_in[]);
|
||||
void freedv_codectx (struct freedv *f, short mod_out[], unsigned char *packed_codec_bits);
|
||||
void freedv_datatx (struct freedv *f, short mod_out[]);
|
||||
int freedv_data_ntxframes (struct freedv *freedv);
|
||||
|
||||
// Receive -------------------------------------------------------------------
|
||||
|
||||
int freedv_nin (struct freedv *freedv);
|
||||
int freedv_rx (struct freedv *freedv, short speech_out[], short demod_in[]);
|
||||
int freedv_shortrx (struct freedv *freedv, short speech_out[], short demod_in[], float gain);
|
||||
int freedv_floatrx (struct freedv *freedv, short speech_out[], float demod_in[]);
|
||||
int freedv_comprx (struct freedv *freedv, short speech_out[], COMP demod_in[]);
|
||||
int freedv_codecrx (struct freedv *freedv, unsigned char *packed_codec_bits, short demod_in[]);
|
||||
|
||||
// Set parameters ------------------------------------------------------------
|
||||
|
||||
void freedv_set_callback_txt (struct freedv *freedv, freedv_callback_rx rx, freedv_callback_tx tx, void *callback_state);
|
||||
void freedv_set_callback_protocol (struct freedv *freedv, freedv_callback_protorx rx, freedv_callback_prototx tx, void *callback_state);
|
||||
void freedv_set_callback_data (struct freedv *freedv, freedv_callback_datarx datarx, freedv_callback_datatx datatx, void *callback_state);
|
||||
void freedv_set_test_frames (struct freedv *freedv, int test_frames);
|
||||
void freedv_set_test_frames_diversity (struct freedv *freedv, int test_frames_diversity);
|
||||
void freedv_set_smooth_symbols (struct freedv *freedv, int smooth_symbols);
|
||||
void freedv_set_squelch_en (struct freedv *freedv, int squelch_en);
|
||||
void freedv_set_snr_squelch_thresh (struct freedv *freedv, float snr_squelch_thresh);
|
||||
void freedv_set_clip (struct freedv *freedv, int val);
|
||||
void freedv_set_total_bit_errors (struct freedv *freedv, int val);
|
||||
void freedv_set_total_bits (struct freedv *freedv, int val);
|
||||
void freedv_set_callback_error_pattern (struct freedv *freedv, freedv_calback_error_pattern cb, void *state);
|
||||
void freedv_set_varicode_code_num (struct freedv *freedv, int val);
|
||||
void freedv_set_data_header (struct freedv *freedv, unsigned char *header);
|
||||
int freedv_set_alt_modem_samp_rate (struct freedv *freedv, int samp_rate);
|
||||
void freedv_set_carrier_ampl (struct freedv *freedv, int c, float ampl);
|
||||
void freedv_set_sync (struct freedv *freedv, Sync sync_cmd);
|
||||
void freedv_set_verbose (struct freedv *freedv, int verbosity);
|
||||
void freedv_set_tx_bpf (struct freedv *freedv, int val);
|
||||
void freedv_set_ext_vco (struct freedv *f, int val);
|
||||
|
||||
// Get parameters -------------------------------------------------------------------------
|
||||
|
||||
struct MODEM_STATS;
|
||||
int freedv_get_version(void);
|
||||
int freedv_get_mode (struct freedv *freedv);
|
||||
void freedv_get_modem_stats (struct freedv *freedv, int *sync, float *snr_est);
|
||||
void freedv_get_modem_extended_stats(struct freedv *freedv, struct MODEM_STATS *stats);
|
||||
int freedv_get_test_frames (struct freedv *freedv);
|
||||
int freedv_get_n_speech_samples (struct freedv *freedv);
|
||||
int freedv_get_modem_sample_rate (struct freedv *freedv);
|
||||
int freedv_get_modem_symbol_rate (struct freedv *freedv);
|
||||
int freedv_get_n_max_modem_samples (struct freedv *freedv);
|
||||
int freedv_get_n_nom_modem_samples (struct freedv *freedv);
|
||||
int freedv_get_total_bits (struct freedv *freedv);
|
||||
int freedv_get_total_bit_errors (struct freedv *freedv);
|
||||
int freedv_get_total_bits_coded (struct freedv *freedv);
|
||||
int freedv_get_total_bit_errors_coded(struct freedv *freedv);
|
||||
int freedv_get_sync (struct freedv *freedv);
|
||||
int freedv_get_sync_interleaver (struct freedv *freedv);
|
||||
struct FSK * freedv_get_fsk (struct freedv *f);
|
||||
struct CODEC2 *freedv_get_codec2 (struct freedv *freedv);
|
||||
int freedv_get_n_codec_bits (struct freedv *freedv);
|
||||
int freedv_get_sz_error_pattern (struct freedv *freedv);
|
||||
int freedv_get_protocol_bits (struct freedv *freedv);
|
||||
|
||||
} // namespace FreeDV
|
||||
|
||||
#endif /* LIBFREEDV_LIBFREEDV_H_ */
|
134
libfreedv/modem_probe.h
Normal file
134
libfreedv/modem_probe.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: modem_probe.h
|
||||
AUTHOR......: Brady O'Brien
|
||||
DATE CREATED: 9 January 2016
|
||||
|
||||
Library to easily extract debug traces from modems during development
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2016 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __MODEMPROBE_H
|
||||
#define __MODEMPROBE_H
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <complex.h>
|
||||
#include "comp.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
#ifdef MODEMPROBE_ENABLE
|
||||
|
||||
/* Internal functions */
|
||||
void modem_probe_init_int(char *modname, char *runname);
|
||||
void modem_probe_close_int();
|
||||
|
||||
void modem_probe_samp_i_int(char * tracename,int samp[],size_t cnt);
|
||||
void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt);
|
||||
void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt);
|
||||
|
||||
/*
|
||||
* Init the probe library.
|
||||
* char *modname - Name of the modem under test
|
||||
* char *runname - Name/path of the file data is dumped to
|
||||
*/
|
||||
static inline void modem_probe_init(char *modname,char *runname){
|
||||
modem_probe_init_int(modname,runname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump traces to a file and clean up
|
||||
*/
|
||||
static inline void modem_probe_close(){
|
||||
modem_probe_close_int();
|
||||
}
|
||||
|
||||
/*
|
||||
* Save some number of int samples to a named trace
|
||||
* char *tracename - name of trace being saved to
|
||||
* int samp[] - int samples
|
||||
* size_t cnt - how many samples to save
|
||||
*/
|
||||
static inline void modem_probe_samp_i(char *tracename,int samp[],size_t cnt){
|
||||
modem_probe_samp_i_int(tracename,samp,cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save some number of float samples to a named trace
|
||||
* char *tracename - name of trace being saved to
|
||||
* float samp[] - int samples
|
||||
* size_t cnt - how many samples to save
|
||||
*/
|
||||
static inline void modem_probe_samp_f(char *tracename,float samp[],size_t cnt){
|
||||
modem_probe_samp_f_int(tracename,samp,cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save some number of complex samples to a named trace
|
||||
* char *tracename - name of trace being saved to
|
||||
* COMP samp[] - int samples
|
||||
* size_t cnt - how many samples to save
|
||||
*/
|
||||
static inline void modem_probe_samp_c(char *tracename,COMP samp[],size_t cnt){
|
||||
modem_probe_samp_c_int(tracename,samp,cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save some number of complex samples to a named trace
|
||||
* char *tracename - name of trace being saved to
|
||||
* float complex samp[] - int samples
|
||||
* size_t cnt - how many samples to save
|
||||
*/
|
||||
static inline void modem_probe_samp_cft(char *tracename,complex float samp[],size_t cnt){
|
||||
modem_probe_samp_c_int(tracename,(COMP*)samp,cnt);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void modem_probe_init(char *modname,char *runname){
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void modem_probe_close(){
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void modem_probe_samp_i(char *name,int samp[],size_t sampcnt){
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void modem_probe_samp_f(char *name,float samp[],size_t cnt){
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void modem_probe_samp_c(char *name,COMP samp[],size_t cnt){
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void modem_probe_samp_cft(char *name,complex float samp[],size_t cnt){
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
79
libfreedv/modem_stats.h
Normal file
79
libfreedv/modem_stats.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: modem_stats.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: June 2015
|
||||
|
||||
Common structure for returning demod stats from fdmdv and cohpsk modems.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2015 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FREEDV_MODEM_STATS__
|
||||
#define __FREEDV_MODEM_STATS__
|
||||
|
||||
#include "codec2/comp.h"
|
||||
#include "kiss_fft.h"
|
||||
|
||||
#define MODEM_STATS_NC_MAX 20
|
||||
#define MODEM_STATS_NR_MAX 8
|
||||
#define MODEM_STATS_ET_MAX 8
|
||||
#define MODEM_STATS_EYE_IND_MAX 160
|
||||
#define MODEM_STATS_NSPEC 512
|
||||
#define MODEM_STATS_MAX_F_HZ 4000
|
||||
#define MODEM_STATS_MAX_F_EST 4
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct MODEM_STATS {
|
||||
int Nc;
|
||||
float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */
|
||||
COMP rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX+1];
|
||||
/* latest received symbols, for scatter plot */
|
||||
int nr; /* number of rows in rx_symbols */
|
||||
int sync; /* demod sync state */
|
||||
float foff; /* estimated freq offset in Hz */
|
||||
float rx_timing; /* estimated optimum timing offset in samples */
|
||||
float clock_offset; /* Estimated tx/rx sample clock offset in ppm */
|
||||
float sync_metric; /* number between 0 and 1 indicating quality of sync */
|
||||
|
||||
/* eye diagram traces */
|
||||
/* Eye diagram plot -- first dim is trace number, second is the trace idx */
|
||||
float rx_eye[MODEM_STATS_ET_MAX][MODEM_STATS_EYE_IND_MAX];
|
||||
int neyetr; /* How many eye traces are plotted */
|
||||
int neyesamp; /* How many samples in the eye diagram */
|
||||
|
||||
/* optional for FSK modems - est tone freqs */
|
||||
|
||||
float f_est[MODEM_STATS_MAX_F_EST];
|
||||
|
||||
/* Buf for FFT/waterfall */
|
||||
|
||||
float fft_buf[2*MODEM_STATS_NSPEC];
|
||||
kiss_fft_cfg fft_cfg;
|
||||
};
|
||||
|
||||
void modem_stats_open(struct MODEM_STATS *f);
|
||||
void modem_stats_close(struct MODEM_STATS *f);
|
||||
void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
51
libfreedv/mpdecode_core.h
Normal file
51
libfreedv/mpdecode_core.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
FILE...: mpdecode_core.h
|
||||
AUTHOR.: David Rowe
|
||||
CREATED: Sep 2016
|
||||
|
||||
C-callable core functions for MpDecode, so they can be used for
|
||||
Octave and C programs. Also some convenience functions to help use
|
||||
the C-callable LDPC decoder in C programs.
|
||||
*/
|
||||
|
||||
#ifndef __MPDECODE_CORE__
|
||||
#define __MPDECODE_CORE__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "codec2/comp.h"
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
struct LDPC {
|
||||
int max_iter;
|
||||
int dec_type;
|
||||
int q_scale_factor;
|
||||
int r_scale_factor;
|
||||
int CodeLength;
|
||||
int NumberParityBits;
|
||||
int NumberRowsHcols;
|
||||
int max_row_weight;
|
||||
int max_col_weight;
|
||||
int data_bits_per_frame;
|
||||
int coded_bits_per_frame;
|
||||
int coded_syms_per_frame;
|
||||
uint16_t *H_rows;
|
||||
uint16_t *H_cols;
|
||||
};
|
||||
|
||||
void encode(struct LDPC *ldpc, unsigned char ibits[], unsigned char pbits[]);
|
||||
|
||||
int run_ldpc_decoder(struct LDPC *ldpc, uint8_t out_char[], float input[], int *parityCheckCount);
|
||||
|
||||
void sd_to_llr(float llr[], double sd[], int n);
|
||||
void Demod2D(float symbol_likelihood[], COMP r[], COMP S_matrix[], float EsNo, float fading[], float mean_amp, int number_symbols);
|
||||
void Somap(float bit_likelihood[], float symbol_likelihood[], int number_symbols);
|
||||
void symbols_to_llrs(float llr[], COMP rx_qpsk_symbols[], float rx_amps[], float EsNo, float mean_amp, int nsyms);
|
||||
|
||||
void ldpc_print_info(struct LDPC *ldpc);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
137
libfreedv/ofdm_internal.h
Normal file
137
libfreedv/ofdm_internal.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: ofdm_internal.h
|
||||
AUTHORS.....: David Rowe & Steve Sampson
|
||||
DATE CREATED: June 2017
|
||||
|
||||
OFDM Internal definitions.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OFDM_INTERNAL_H
|
||||
#define OFDM_INTERNAL_H
|
||||
|
||||
#include <complex.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "codec2_ofdm.h"
|
||||
#include "freedv_filter.h"
|
||||
#include "fdv_arm_math.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#define TAU (2.0f * M_PI)
|
||||
#define ROT45 (M_PI / 4.0f)
|
||||
|
||||
#define cmplx(value) (COSF(value) + SINF(value) * I)
|
||||
#define cmplxconj(value) (COSF(value) + SINF(value) * -I)
|
||||
|
||||
namespace FreeDV
|
||||
{
|
||||
|
||||
/*
|
||||
* Contains user configuration for OFDM modem
|
||||
*/
|
||||
|
||||
struct OFDM_CONFIG {
|
||||
float tx_centre; /* TX Centre Audio Frequency */
|
||||
float rx_centre; /* RX Centre Audio Frequency */
|
||||
float fs; /* Sample Frequency */
|
||||
float rs; /* Modulation Symbol Rate */
|
||||
float ts; /* symbol duration */
|
||||
float tcp; /* Cyclic Prefix duration */
|
||||
float ofdm_timing_mx_thresh;
|
||||
|
||||
int nc; /* Number of carriers */
|
||||
int ns; /* Number of Symbol frames */
|
||||
int bps; /* Bits per Symbol */
|
||||
int txtbits; /* number of auxiliary data bits */
|
||||
int ftwindowwidth;
|
||||
};
|
||||
|
||||
struct OFDM {
|
||||
std::complex<float> *pilot_samples;
|
||||
std::complex<float> *rxbuf;
|
||||
std::complex<float> *pilots;
|
||||
std::complex<float> **rx_sym;
|
||||
std::complex<float> *rx_np;
|
||||
|
||||
float *rx_amp;
|
||||
float *aphase_est_pilot_log;
|
||||
|
||||
uint8_t *tx_uw;
|
||||
|
||||
State sync_state;
|
||||
State last_sync_state;
|
||||
State sync_state_interleaver;
|
||||
State last_sync_state_interleaver;
|
||||
|
||||
Sync sync_mode;
|
||||
|
||||
struct quisk_cfFilter *ofdm_tx_bpf;
|
||||
|
||||
std::complex<float> foff_metric;
|
||||
|
||||
float foff_est_gain;
|
||||
float foff_est_hz;
|
||||
float timing_mx;
|
||||
float coarse_foff_est_hz;
|
||||
float timing_norm;
|
||||
float sig_var;
|
||||
float noise_var;
|
||||
float mean_amp;
|
||||
|
||||
int clock_offset_counter;
|
||||
int verbose;
|
||||
int sample_point;
|
||||
int timing_est;
|
||||
int timing_valid;
|
||||
int nin;
|
||||
int uw_errors;
|
||||
int sync_counter;
|
||||
int frame_count;
|
||||
|
||||
int frame_count_interleaver;
|
||||
|
||||
bool sync_start;
|
||||
bool sync_end;
|
||||
bool timing_en;
|
||||
bool foff_est_en;
|
||||
bool phase_est_en;
|
||||
bool tx_bpf_en;
|
||||
};
|
||||
|
||||
/* function headers exposed for LDPC work */
|
||||
|
||||
std::complex<float> qpsk_mod(int *);
|
||||
void qpsk_demod(std::complex<float>, int *);
|
||||
void ofdm_txframe(struct OFDM *, std::complex<float> *, std::complex<float> []);
|
||||
void ofdm_assemble_modem_frame(struct OFDM *, uint8_t [], uint8_t [], uint8_t []);
|
||||
void ofdm_assemble_modem_frame_symbols(std::complex<float> [], COMP [], uint8_t []);
|
||||
void ofdm_disassemble_modem_frame(struct OFDM *, uint8_t [], COMP [], float [], short []);
|
||||
void ofdm_rand(uint16_t [], int);
|
||||
void ofdm_generate_payload_data_bits(uint8_t payload_data_bits[], int data_bits_per_frame);
|
||||
|
||||
} // FreeDV
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user