aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-11-16 19:18:42 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2017-11-25 19:24:02 +0100
commitf4754dcb37fa08775ca7e4af4f1bb4ea294fabcc (patch)
tree2f7cac0f8356dd3cbfd3376b9e00a9e081ce73c2 /src/common
parent7af9b752a03675ee1f219c0bf14162c5c628870b (diff)
Restructure: Move fm_modulation from common code to 'libfm'
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/fm_modulation.c382
-rw-r--r--src/common/fm_modulation.h39
-rw-r--r--src/common/fsk.h2
-rw-r--r--src/common/sdr.c2
5 files changed, 2 insertions, 424 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 52ee381..9e9908a 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -7,7 +7,6 @@ libcommon_a_SOURCES = \
debug.c \
sound_alsa.c \
compandor.c \
- fm_modulation.c \
fsk.c \
display_wave.c \
display_measurements.c
diff --git a/src/common/fm_modulation.c b/src/common/fm_modulation.c
deleted file mode 100644
index 93621c8..0000000
--- a/src/common/fm_modulation.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/* FM modulation processing
- *
- * (C) 2017 by Andreas Eversberg <jolly@eversberg.eu>
- * All Rights Reserved
- *
- * 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, either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <math.h>
-#include "sample.h"
-#include "fm_modulation.h"
-
-//#define FAST_SINE
-
-/* init FM modulator */
-int fm_mod_init(fm_mod_t *mod, double samplerate, double offset, double amplitude)
-{
- int i;
-
- memset(mod, 0, sizeof(*mod));
- mod->samplerate = samplerate;
- mod->offset = offset;
- mod->amplitude = amplitude;
-
- mod->ramp_length = samplerate * 0.001;
- mod->ramp_tab = calloc(mod->ramp_length, sizeof(*mod->ramp_tab));
- if (!mod->ramp_tab) {
- fprintf(stderr, "No mem!\n");
- return -ENOMEM;
- }
- mod->state = MOD_STATE_OFF;
-
- /* generate ramp up with ramp_length */
- for (i = 0; i < mod->ramp_length; i++)
- mod->ramp_tab[i] = 0.5 - cos(M_PI * i / mod->ramp_length) / 2.0;
-
-#ifdef FAST_SINE
- mod->sin_tab = calloc(65536+16384, sizeof(*mod->sin_tab));
- if (!mod->sin_tab) {
- fprintf(stderr, "No mem!\n");
- fm_mod_exit(mod);
- return -ENOMEM;
- }
-
- /* generate sine and cosine */
- for (i = 0; i < 65536+16384; i++)
- mod->sin_tab[i] = sin(2.0 * M_PI * (double)i / 65536.0) * amplitude;
-#endif
-
- return 0;
-}
-
-void fm_mod_exit(fm_mod_t *mod)
-{
- if (mod->ramp_tab) {
- free(mod->ramp_tab);
- mod->ramp_tab = NULL;
- }
- if (mod->sin_tab) {
- free(mod->sin_tab);
- mod->sin_tab = NULL;
- }
-}
-
-/* do frequency modulation of samples and add them to existing baseband */
-void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, uint8_t *power, int length, float *baseband)
-{
- double dev, rate, phase, offset;
- int ramp, ramp_length;
- double *ramp_tab;
-#ifdef FAST_SINE
- double *sin_tab, *cos_tab;
-#else
- double amplitude;
-#endif
-
- rate = mod->samplerate;
- phase = mod->phase;
- offset = mod->offset;
- ramp = mod->ramp;
- ramp_length = mod->ramp_length;
- ramp_tab = mod->ramp_tab;
-#ifdef FAST_SINE
- sin_tab = mod->sin_tab;
- cos_tab = mod->sin_tab + 16384;
-#else
- amplitude = mod->amplitude;
-#endif
-
-again:
- switch (mod->state) {
- case MOD_STATE_ON:
- /* modulate */
- while (length) {
- /* is power is not set, ramp down */
- if (!(*power)) {
- mod->state = MOD_STATE_RAMP_DOWN;
- break;
- }
- /* deviation is defined by the frequency value and the offset */
- dev = offset + *frequency++;
- power++;
- length--;
-#ifdef FAST_SINE
- phase += 65536.0 * dev / rate;
- if (phase < 0.0)
- phase += 65536.0;
- else if (phase >= 65536.0)
- phase -= 65536.0;
- *baseband++ += cos_tab[(uint16_t)phase];
- *baseband++ += sin_tab[(uint16_t)phase];
-#else
- phase += 2.0 * M_PI * dev / rate;
- if (phase < 0.0)
- phase += 2.0 * M_PI;
- else if (phase >= 2.0 * M_PI)
- phase -= 2.0 * M_PI;
- *baseband++ += cos(phase) * amplitude;
- *baseband++ += sin(phase) * amplitude;
-#endif
- }
- break;
- case MOD_STATE_RAMP_DOWN:
- while (length) {
- /* if power is set, ramp up */
- if (*power) {
- mod->state = MOD_STATE_RAMP_UP;
- break;
- }
- if (ramp == 0) {
- mod->state = MOD_STATE_OFF;
- break;
- }
- dev = offset + *frequency++;
- power++;
- length--;
-#ifdef FAST_SINE
- phase += 65536.0 * dev / rate;
- if (phase < 0.0)
- phase += 65536.0;
- else if (phase >= 65536.0)
- phase -= 65536.0;
- *baseband++ += cos_tab[(uint16_t)phase] * ramp_tab[ramp];
- *baseband++ += sin_tab[(uint16_t)phase] * ramp_tab[ramp];
-#else
- phase += 2.0 * M_PI * dev / rate;
- if (phase < 0.0)
- phase += 2.0 * M_PI;
- else if (phase >= 2.0 * M_PI)
- phase -= 2.0 * M_PI;
- *baseband++ += cos(phase) * amplitude * ramp_tab[ramp];
- *baseband++ += sin(phase) * amplitude * ramp_tab[ramp];
-#endif
- ramp--;
- }
- break;
- case MOD_STATE_OFF:
- while (length) {
- /* if power is set, ramp up */
- if (*power) {
- mod->state = MOD_STATE_RAMP_UP;
- break;
- }
- frequency++;
- power++;
- length--;
- baseband += 2;
- }
- break;
- case MOD_STATE_RAMP_UP:
- while (length) {
- /* is power is not set, ramp down */
- if (!(*power)) {
- mod->state = MOD_STATE_RAMP_DOWN;
- break;
- }
- if (ramp == ramp_length - 1) {
- mod->state = MOD_STATE_ON;
- break;
- }
- /* deviation is defined by the frequency value and the offset */
- dev = offset + *frequency++;
- power++;
- length--;
-#ifdef FAST_SINE
- phase += 65536.0 * dev / rate;
- if (phase < 0.0)
- phase += 65536.0;
- else if (phase >= 65536.0)
- phase -= 65536.0;
- *baseband++ += cos_tab[(uint16_t)phase] * ramp_tab[ramp];
- *baseband++ += sin_tab[(uint16_t)phase] * ramp_tab[ramp];
-#else
- phase += 2.0 * M_PI * dev / rate;
- if (phase < 0.0)
- phase += 2.0 * M_PI;
- else if (phase >= 2.0 * M_PI)
- phase -= 2.0 * M_PI;
- *baseband++ += cos(phase) * amplitude * ramp_tab[ramp];
- *baseband++ += sin(phase) * amplitude * ramp_tab[ramp];
-#endif
- ramp++;
- }
- break;
- }
- if (length)
- goto again;
-
- mod->phase = phase;
- mod->ramp = ramp;
-}
-
-/* init FM demodulator */
-int fm_demod_init(fm_demod_t *demod, double samplerate, double offset, double bandwidth)
-{
- memset(demod, 0, sizeof(*demod));
- demod->samplerate = samplerate;
-#ifdef FAST_SINE
- demod->rot = 65536.0 * -offset / samplerate;
-#else
- demod->rot = 2 * M_PI * -offset / samplerate;
-#endif
-
- /* use fourth order (2 iter) filter, since it is as fast as second order (1 iter) filter */
- iir_lowpass_init(&demod->lp[0], bandwidth / 2.0, samplerate, 2);
- iir_lowpass_init(&demod->lp[1], bandwidth / 2.0, samplerate, 2);
-
-#ifdef FAST_SINE
- int i;
-
- demod->sin_tab = calloc(65536+16384, sizeof(*demod->sin_tab));
- if (!demod->sin_tab) {
- fprintf(stderr, "No mem!\n");
- return -ENOMEM;
- }
-
- /* generate sine and cosine */
- for (i = 0; i < 65536+16384; i++)
- demod->sin_tab[i] = sin(2.0 * M_PI * (double)i / 65536.0);
-#endif
-
- return 0;
-}
-
-void fm_demod_exit(fm_demod_t *demod)
-{
- if (demod->sin_tab) {
- free(demod->sin_tab);
- demod->sin_tab = NULL;
- }
-}
-
-/* do frequency demodulation of baseband and write them to samples */
-void fm_demodulate_complex(fm_demod_t *demod, sample_t *frequency, int length, float *baseband, sample_t *I, sample_t *Q)
-{
- double phase, rot, last_phase, dev, rate;
- double _sin, _cos;
- sample_t i, q;
- int s, ss;
-#ifdef FAST_SINE
- double *sin_tab, *cos_tab;
-#endif
-
- rate = demod->samplerate;
- phase = demod->phase;
- rot = demod->rot;
-#ifdef FAST_SINE
- sin_tab = demod->sin_tab;
- cos_tab = demod->sin_tab + 16384;
-#endif
- for (s = 0, ss = 0; s < length; s++) {
- phase += rot;
- i = baseband[ss++];
- q = baseband[ss++];
-#ifdef FAST_SINE
- if (phase < 0.0)
- phase += 65536.0;
- else if (phase >= 65536.0)
- phase -= 65536.0;
- _sin = sin_tab[(uint16_t)phase];
- _cos = cos_tab[(uint16_t)phase];
-#else
- if (phase < 0.0)
- phase += 2.0 * M_PI;
- else if (phase >= 2.0 * M_PI)
- phase -= 2.0 * M_PI;
- _sin = sin(phase);
- _cos = cos(phase);
-#endif
- I[s] = i * _cos - q * _sin;
- Q[s] = i * _sin + q * _cos;
- }
- demod->phase = phase;
- iir_process(&demod->lp[0], I, length);
- iir_process(&demod->lp[1], Q, length);
- last_phase = demod->last_phase;
- for (s = 0; s < length; s++) {
- phase = atan2(Q[s], I[s]);
- dev = (phase - last_phase) / 2 / M_PI;
- last_phase = phase;
- if (dev < -0.49)
- dev += 1.0;
- else if (dev > 0.49)
- dev -= 1.0;
- dev *= rate;
- frequency[s] = dev;
- }
- demod->last_phase = last_phase;
-}
-
-void fm_demodulate_real(fm_demod_t *demod, sample_t *frequency, int length, sample_t *baseband, sample_t *I, sample_t *Q)
-{
- double phase, rot, last_phase, dev, rate;
- double _sin, _cos;
- sample_t i;
- int s, ss;
-#ifdef FAST_SINE
- double *sin_tab, *cos_tab;
-#endif
-
- rate = demod->samplerate;
- phase = demod->phase;
- rot = demod->rot;
-#ifdef FAST_SINE
- sin_tab = demod->sin_tab;
- cos_tab = demod->sin_tab + 16384;
-#endif
- for (s = 0, ss = 0; s < length; s++) {
- phase += rot;
- i = baseband[ss++];
-#ifdef FAST_SINE
- if (phase < 0.0)
- phase += 65536.0;
- else if (phase >= 65536.0)
- phase -= 65536.0;
- _sin = sin_tab[(uint16_t)phase];
- _cos = cos_tab[(uint16_t)phase];
-#else
- if (phase < 0.0)
- phase += 2.0 * M_PI;
- else if (phase >= 2.0 * M_PI)
- phase -= 2.0 * M_PI;
- _sin = sin(phase);
- _cos = cos(phase);
-#endif
- I[s] = i * _cos;
- Q[s] = i * _sin;
- }
- demod->phase = phase;
- iir_process(&demod->lp[0], I, length);
- iir_process(&demod->lp[1], Q, length);
- last_phase = demod->last_phase;
- for (s = 0; s < length; s++) {
- phase = atan2(Q[s], I[s]);
- dev = (phase - last_phase) / 2 / M_PI;
- last_phase = phase;
- if (dev < -0.49)
- dev += 1.0;
- else if (dev > 0.49)
- dev -= 1.0;
- dev *= rate;
- frequency[s] = dev;
- }
- demod->last_phase = last_phase;
-}
-
diff --git a/src/common/fm_modulation.h b/src/common/fm_modulation.h
deleted file mode 100644
index 68f0bcd..0000000
--- a/src/common/fm_modulation.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "../libfilter/iir_filter.h"
-
-enum fm_mod_state {
- MOD_STATE_OFF, /* transmitter off, no IQ vector */
- MOD_STATE_ON, /* transmitter on, FM modulated IQ vector */
- MOD_STATE_RAMP_UP, /* use half cos to ramp up IQ vector */
- MOD_STATE_RAMP_DOWN, /* use half cos to ramp down IQ vector */
-};
-
-typedef struct fm_mod {
- double samplerate; /* sample rate of in and out */
- double offset; /* offset to calculated center frequency */
- double amplitude; /* how much amplitude to add to the buff */
- double phase; /* current phase of FM (used to shift and modulate ) */
- double *sin_tab; /* sine/cosine table for modulation */
- enum fm_mod_state state;/* state of transmit power */
- double *ramp_tab; /* half cosine ramp up */
- int ramp; /* current ramp position */
- int ramp_length; /* number of values in ramp */
-} fm_mod_t;
-
-int fm_mod_init(fm_mod_t *mod, double samplerate, double offset, double amplitude);
-void fm_mod_exit(fm_mod_t *mod);
-void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, uint8_t *power, int num, float *baseband);
-
-typedef struct fm_demod {
- double samplerate; /* sample rate of in and out */
- double phase; /* current rotation phase (used to shift) */
- double rot; /* rotation step per sample to shift rx frequency (used to shift) */
- double last_phase; /* last phase of FM (used to demodulate) */
- iir_filter_t lp[2]; /* filters received IQ signal */
- double *sin_tab; /* sine/cosine table rotation */
-} fm_demod_t;
-
-int fm_demod_init(fm_demod_t *demod, double samplerate, double offset, double bandwidth);
-void fm_demod_exit(fm_demod_t *demod);
-void fm_demodulate_complex(fm_demod_t *demod, sample_t *frequency, int length, float *baseband, sample_t *I, sample_t *Q);
-void fm_demodulate_real(fm_demod_t *demod, sample_t *frequency, int length, sample_t *baseband, sample_t *I, sample_t *Q);
-
diff --git a/src/common/fsk.h b/src/common/fsk.h
index 723fe66..a7cc428 100644
--- a/src/common/fsk.h
+++ b/src/common/fsk.h
@@ -1,4 +1,4 @@
-#include "../common/fm_modulation.h"
+#include "../libfm/fm.h"
typedef struct ffsk {
void *inst;
diff --git a/src/common/sdr.c b/src/common/sdr.c
index 01048ee..d7a445b 100644
--- a/src/common/sdr.c
+++ b/src/common/sdr.c
@@ -30,7 +30,7 @@ enum paging_signal;
#include <pthread.h>
#include <unistd.h>
#include "sample.h"
-#include "fm_modulation.h"
+#include "../libfm/fm.h"
#include "../libtimer/timer.h"
#include "sender.h"
#include "sdr_config.h"