struct FDMDV;
struct FDMDV_STATS {
+ int Nc;
float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */
COMP rx_symbols[FDMDV_NSYM]; /* latest received symbols, for scatter plot */
int fest_coarse_fine; /* freq est state, 0-coarse 1-fine */
struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc);
void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
+int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync_bit, COMP rx_fdm[], int *nin);
free(fdmdv);
}
+int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv)
+{
+ return (fdmdv->Nc * NB);
+}
+
/*---------------------------------------------------------------------------*\
FUNCTION....: fdmdv_get_test_bits()
\*---------------------------------------------------------------------------*/
-void fdm_upconvert(COMP tx_fdm[], COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[])
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[])
{
int i,c;
COMP two = {2.0, 0.0};
/* Nc/2 tones below centre freq */
- for (c=0; c<NC/2; c++)
+ for (c=0; c<Nc/2; c++)
for (i=0; i<M; i++) {
phase_tx[c] = cmult(phase_tx[c], freq[c]);
tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c]));
/* Nc/2 tones above centre freq */
- for (c=NC/2; c<NC; c++)
+ for (c=Nc/2; c<Nc; c++)
for (i=0; i<M; i++) {
phase_tx[c] = cmult(phase_tx[c], freq[c]);
tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c]));
/* add centre pilot tone */
- c = NC;
+ c = Nc;
for (i=0; i<M; i++) {
phase_tx[c] = cmult(phase_tx[c], freq[c]);
pilot = cmult(cmult(two, tx_baseband[c][i]), phase_tx[c]);
/* normalise digital oscilators as the magnitude can drfift over time */
- for (c=0; c<NC+1; c++) {
+ for (c=0; c<Nc+1; c++) {
phase_tx[c].real /= cabsolute(phase_tx[c]);
phase_tx[c].imag /= cabsolute(phase_tx[c]);
}
bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit);
memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(NC+1));
tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory);
- fdm_upconvert(tx_fdm, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
+ fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
*sync_bit = fdmdv->tx_pilot_bit;
}
{
int c;
+ fdmdv_stats->Nc = fdmdv->Nc;
fdmdv_stats->snr_est = calc_snr(fdmdv->sig_est, fdmdv->noise_est);
fdmdv_stats->fest_coarse_fine = fdmdv->coarse_fine;
fdmdv_stats->foff = fdmdv->foff;
#include "codec2_fdmdv.h"
-#define BITS_PER_CODEC_FRAME (2*FDMDV_BITS_PER_FRAME)
-#define BYTES_PER_CODEC_FRAME (BITS_PER_CODEC_FRAME/8)
-
int main(int argc, char *argv[])
{
FILE *fout;
struct FDMDV *fdmdv;
- char packed_bits[BYTES_PER_CODEC_FRAME];
- int tx_bits[2*FDMDV_BITS_PER_FRAME];
+ char *packed_bits;
+ int *tx_bits;
int n, i, bit, byte;
int numBits, nCodecFrames;
+ int bits_per_fdmdv_frame;
+ int bits_per_codec_frame;
+ int bytes_per_codec_frame;
if (argc < 3) {
printf("usage: %s OutputBitFile numBits\n", argv[0]);
}
numBits = atoi(argv[2]);
- nCodecFrames = numBits/BITS_PER_CODEC_FRAME;
fdmdv = fdmdv_create(FDMDV_NC);
+ bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+ bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+ assert((bits_per_codec_frame % 8) == 0); /* make sure integer number of bytes per frame */
+ bytes_per_codec_frame = bits_per_codec_frame/8;
+
+ packed_bits = (char*)malloc(bytes_per_codec_frame);
+ assert(packed_bits != NULL);
+ tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame);
+ assert(tx_bits != NULL);
+
+ nCodecFrames = numBits/bytes_per_codec_frame;
+
for(n=0; n<nCodecFrames; n++) {
fdmdv_get_test_bits(fdmdv, tx_bits);
- fdmdv_get_test_bits(fdmdv, &tx_bits[FDMDV_BITS_PER_FRAME]);
+ fdmdv_get_test_bits(fdmdv, &tx_bits[bits_per_fdmdv_frame]);
/* pack bits, MSB received first */
bit = 7; byte = 0;
- memset(packed_bits, 0, BYTES_PER_CODEC_FRAME);
- for(i=0; i<BITS_PER_CODEC_FRAME; i++) {
+ memset(packed_bits, 0, bytes_per_codec_frame);
+ for(i=0; i<bits_per_codec_frame; i++) {
packed_bits[byte] |= (tx_bits[i] << bit);
bit--;
if (bit < 0) {
byte++;
}
}
- assert(byte == BYTES_PER_CODEC_FRAME);
+ assert(byte == bytes_per_codec_frame);
- fwrite(packed_bits, sizeof(char), BYTES_PER_CODEC_FRAME, fout);
+ fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout);
/* if this is in a pipeline, we probably don't want the usual
buffering to occur */
if (fout == stdout) fflush(stdout);
}
+ free(tx_bits);
+ free(packed_bits);
fclose(fout);
fdmdv_destroy(fdmdv);
void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit);
void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
-void fdm_upconvert(COMP tx_fdm[], COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]);
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]);
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);
#include "codec2_fdmdv.h"
-#define BITS_PER_CODEC_FRAME (2*FDMDV_BITS_PER_FRAME)
-#define BYTES_PER_CODEC_FRAME (BITS_PER_CODEC_FRAME/8)
-
int main(int argc, char *argv[])
{
FILE *fin, *fout;
struct FDMDV *fdmdv;
- char packed_bits[BYTES_PER_CODEC_FRAME];
- int tx_bits[2*FDMDV_BITS_PER_FRAME];
+ char *packed_bits;
+ int *tx_bits;
COMP tx_fdm[2*FDMDV_NOM_SAMPLES_PER_FRAME];
short tx_fdm_scaled[2*FDMDV_NOM_SAMPLES_PER_FRAME];
int frames;
int i, bit, byte;
int sync_bit;
+ int bits_per_fdmdv_frame;
+ int bits_per_codec_frame;
+ int bytes_per_codec_frame;
if (argc < 3) {
printf("usage: %s InputBitFile OutputModemRawFile\n", argv[0]);
}
fdmdv = fdmdv_create(FDMDV_NC);
+
+ bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+ bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+ assert((bits_per_codec_frame % 8) == 0); /* make sure integer number of bytes per frame */
+ bytes_per_codec_frame = bits_per_codec_frame/8;
+
+ packed_bits = (char*)malloc(bytes_per_codec_frame);
+ assert(packed_bits != NULL);
+ tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame);
+ assert(tx_bits != NULL);
+
frames = 0;
- while(fread(packed_bits, sizeof(char), BYTES_PER_CODEC_FRAME, fin) == BYTES_PER_CODEC_FRAME) {
+ while(fread(packed_bits, sizeof(char), bytes_per_codec_frame, fin) == bytes_per_codec_frame) {
frames++;
/* unpack bits, MSB first */
bit = 7; byte = 0;
- for(i=0; i<BITS_PER_CODEC_FRAME; i++) {
+ for(i=0; i<bits_per_codec_frame; i++) {
tx_bits[i] = (packed_bits[byte] >> bit) & 0x1;
bit--;
if (bit < 0) {
byte++;
}
}
- assert(byte == BYTES_PER_CODEC_FRAME);
+ assert(byte == bytes_per_codec_frame);
/* modulate even and odd frames */
fdmdv_mod(fdmdv, tx_fdm, tx_bits, &sync_bit);
assert(sync_bit == 1);
- fdmdv_mod(fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &tx_bits[FDMDV_BITS_PER_FRAME], &sync_bit);
+ fdmdv_mod(fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &tx_bits[bits_per_fdmdv_frame], &sync_bit);
assert(sync_bit == 0);
/* scale and save to disk as shorts */
//fdmdv_dump_osc_mags(fdmdv);
+ free(tx_bits);
+ free(packed_bits);
fclose(fin);
fclose(fout);
fdmdv_destroy(fdmdv);