\*---------------------------------------------------------------------------*/
-struct CODEC2 * WIN32SUPPORT codec2_create(int mode)
+struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode)
{
struct CODEC2 *c2;
int i,l;
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT codec2_destroy(struct CODEC2 *c2)
+void CODEC2_WIN32SUPPORT codec2_destroy(struct CODEC2 *c2)
{
assert(c2 != NULL);
nlp_destroy(c2->nlp);
\*---------------------------------------------------------------------------*/
-int WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *c2) {
+int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *c2) {
if (c2->mode == CODEC2_MODE_2400)
return 48;
if (c2->mode == CODEC2_MODE_1400)
\*---------------------------------------------------------------------------*/
-int WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *c2) {
+int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *c2) {
if (c2->mode == CODEC2_MODE_2400)
return 160;
if (c2->mode == CODEC2_MODE_1400)
return 0; /* shouldnt get here */
}
-void WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
+void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
{
assert(c2 != NULL);
assert(
codec2_encode_1200(c2, bits, speech);
}
-void WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
+void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
{
assert(c2 != NULL);
assert(
#ifndef __CODEC2__
#define __CODEC2__
-#ifdef __WIN32__
-#ifdef __BUILDING_DLL__
-#define WIN32SUPPORT __declspec(dllexport) __stdcall
+/* 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 WIN32SUPPORT __declspec(dllimport) __stdcall
+#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
#endif
#else
-#define WIN32SUPPORT
+#define CODEC2_WIN32SUPPORT
#endif
#define CODEC2_MODE_2400 0
struct CODEC2;
-struct CODEC2 * WIN32SUPPORT codec2_create(int mode);
-void WIN32SUPPORT codec2_destroy(struct CODEC2 *codec2_state);
-void WIN32SUPPORT codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]);
-void WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
-int WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state);
-int WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state);
+struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode);
+void CODEC2_WIN32SUPPORT codec2_destroy(struct CODEC2 *codec2_state);
+void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]);
+void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
+int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state);
+int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state);
#endif
\*---------------------------------------------------------------------------*/
-struct FDMDV * WIN32SUPPORT fdmdv_create(void)
+struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(void)
{
struct FDMDV *f;
int c, i, k;
f->noise_est[c] = 0.0;
}
+ for(i=0; i<2*FDMDV_NFFT; i++)
+ f->fft_buf[i] = 0.0;
+
return f;
}
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv)
+void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv)
{
assert(fdmdv != NULL);
free(fdmdv);
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
+void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
{
int i;
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit)
+void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[],
+ int tx_bits[], int *sync_bit)
{
COMP tx_symbols[NC+1];
COMP tx_baseband[NC+1][M];
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, int *bit_errors, int *ntest_bits, int rx_bits[])
+void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync,
+ int *bit_errors, int *ntest_bits,
+ int rx_bits[])
{
int i,j;
float ber;
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], int *sync_bit, float rx_fdm[], int *nin)
+void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
+ int *sync_bit, float rx_fdm[], int *nin)
{
float foff_coarse, foff_fine;
COMP rx_fdm_fcorr[M+M/P];
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv, struct FDMDV_STATS *fdmdv_stats)
+void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv,
+ struct FDMDV_STATS *fdmdv_stats)
{
int c;
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n)
+void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n)
{
int i,j,k,l;
\*---------------------------------------------------------------------------*/
-void WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n)
+void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n)
{
int i,j;
}
}
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: fdmdv_get_fft()
+ AUTHOR......: David Rowe
+ DATE CREATED: 9 June 2012
+
+ Performs a FFT on the received modem signal at the input of the
+ demod, returns the FDMDV_NFFT point magnitiude spectrum in dB. 0dB
+ is a signal with amplitude +/- 2^15.
+
+ The output can be used to plot a spectrum of the demod input.
+ Sucessive calls can be used to build up a waterfall or spectrogram
+ plot, but mapping the levels to colours.
+
+\*---------------------------------------------------------------------------*/
+
+void CODEC2_WIN32SUPPORT fdmdv_get_fft(struct FDMDV *f, float mag_dB[], float rx_fdm[], int nin)
+{
+ int i,j;
+ COMP F[2*FDMDV_NFFT];
+ float fullscale_dB;
+
+ /* update buffer of input samples */
+
+ for(i=0; i<2*FDMDV_NFFT-nin; i++)
+ f->fft_buf[i] = f->fft_buf[i+nin];
+ for(j=0; j<nin; j++,i++)
+ f->fft_buf[i] = rx_fdm[j];
+
+ /* window and FFT */
+
+ for(i=0; i<2*FDMDV_NFFT; i++) {
+ F[i].real = f->fft_buf[i] * (0.5 - 0.5*cos((float)i*2.0*PI/FDMDV_NFFT));
+ F[i].imag = 0.0;
+ }
+ fft(&F[0].real, 2*FDMDV_NFFT, -1);
+
+ /* scale and convert to dB */
+
+ fullscale_dB = 20*log10(FDMDV_NFFT*32767.0);
+ for(i=0; i<FDMDV_NFFT; i++) {
+ mag_dB[i] = 10*log10(F[i].real*F[i].real + F[i].imag*F[i].imag);
+ mag_dB[i] -= fullscale_dB;
+ }
+}
+
A 1400 bit/s Frequency Division Multiplexed Digital Voice (FDMDV)
modem. Used for digital audio over HF SSB. See README_fdmdv.txt for
- more information, and fdmdv_demo.c, fdmdv_mod.c and fdmdv_demod.c
- for example usage.
+ more information, and fdmdv_mod.c and fdmdv_demod.c for example
+ usage.
References:
extern "C" {
#endif
-#ifdef __WIN32__
-#ifdef __BUILDING_DLL__
-#define WIN32SUPPORT __declspec(dllexport) __stdcall
+/* 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 WIN32SUPPORT __declspec(dllimport) __stdcall
+#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
#endif
#else
-#define WIN32SUPPORT
+#define CODEC2_WIN32SUPPORT
#endif
#include "comp.h"
#define FDMDV_OS 6 /* oversampling rate */
#define FDMDV_OS_TAPS 48 /* number of OS filter taps */
+/* FFT points */
+
+#define FDMDV_NFFT 256
+
/* FDMDV states and stats structures */
struct FDMDV;
float clock_offset; /* Estimated tx/rx sample clock offset in ppm */
};
-struct FDMDV * WIN32SUPPORT fdmdv_create(void);
-void WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
+struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(void);
+void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
-void WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
-void WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync_bit, float rx_fdm[], int *nin);
+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, float rx_fdm[], int *nin);
-void WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
-void WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, int *bit_errors, int *ntest_bits, int rx_bits[]);
+void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
+void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, int *bit_errors, int *ntest_bits, int rx_bits[]);
-void WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats);
-void WIN32SUPPORT fdmdv_get_waterfall_line(struct FDMDV *fdmdv_state, float magnitudes[], int *magnitude_points);
+void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats);
+void CODEC2_WIN32SUPPORT fdmdv_get_fft(struct FDMDV *fdmdv_state, float mag_dB[], float rx_fdm[], int nin);
-void WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n);
-void WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n);
+void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n);
+void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n);
#endif
#define __FDMDV_INTERNAL__
#include "comp.h"
+#include "fdmdv.h"
/*---------------------------------------------------------------------------*\
float sig_est[NC+1];
float noise_est[NC+1];
+
+ /* Buf for FFT/waterfall */
+
+ float fft_buf[2*FDMDV_NFFT];
};
/*---------------------------------------------------------------------------*\
DLLNAME = codec2.dll\r
LIBNAME = codec2.lib\r
\r
-CFLAGS = -O2 -Wall -D__WIN32__\r
+CFLAGS = -O2 -Wall -D__CODEC2_WIN32__\r
\r
HDRS = ../src/codec2.h ../src/fdmdv.h\r
\r
$(CC_PREFIX)gcc -shared -o $(DLLNAME) $(OBJS) -Wl,--out-implib,$(LIBNAME)\r
\r
%.o: ../src/%.c $(HDRS) Makefile\r
- $(CC_PREFIX)gcc $(CFLAGS) -D__BUILDING_DLL__ -c $< -o $@\r
+ $(CC_PREFIX)gcc $(CFLAGS) -D__CODEC2_BUILDING_DLL__ -c $< -o $@\r
\r
c2demo.exe: ../src/c2demo.c $(DLLNAME) $(LIBNAME)\r
$(CC_PREFIX)gcc $(CFLAGS) $< -o $@ $(LIBNAME)\r