aboutsummaryrefslogtreecommitdiff
path: root/unittest/freedv_700d_comprx.c
diff options
context:
space:
mode:
authordrowe67 <[email protected]>2023-07-20 08:59:48 +0930
committerGitHub <[email protected]>2023-07-20 08:59:48 +0930
commit06d4c11e699b0351765f10398abb4f663a984f36 (patch)
tree33e22af0814c5b6c3d676f096ae8c2ac8a3ed9f0 /unittest/freedv_700d_comprx.c
parent6588e77f38bdebd7adffe091b22e7760d95d0ccb (diff)
parent4d6c143c0abec15e1d6ed1fd95d36f80e6cb7df8 (diff)
Merge pull request #3 from drowe67/dr-cleanup21.2.0
Cleanup Part 2
Diffstat (limited to 'unittest/freedv_700d_comprx.c')
-rw-r--r--unittest/freedv_700d_comprx.c218
1 files changed, 116 insertions, 102 deletions
diff --git a/unittest/freedv_700d_comprx.c b/unittest/freedv_700d_comprx.c
index 9fdf43b..0cf8407 100644
--- a/unittest/freedv_700d_comprx.c
+++ b/unittest/freedv_700d_comprx.c
@@ -6,121 +6,135 @@
Complex valued rx to support ctests. Includes a few operations that will
only work if complex Tx and Rx signals are being handled correctly.
-
+
\*---------------------------------------------------------------------------*/
#include <assert.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include "codec2_cohpsk.h"
+#include "comp_prim.h"
#include "freedv_api.h"
#include "freedv_api_internal.h"
#include "ofdm_internal.h"
-#include "codec2_cohpsk.h"
-#include "comp_prim.h"
int main(int argc, char *argv[]) {
-
- /* with no arguments then run with no test code */
- int test_num = 0;
- if (argc == 2) {
- if (strcmp(argv[1],"tx") == 0) {
- test_num = 1;
- }
- if (strcmp(argv[1],"rx") == 0) {
- test_num = 2;
- }
+ /* with no arguments then run with no test code */
+ int test_num = 0;
+ if (argc == 2) {
+ if (strcmp(argv[1], "tx") == 0) {
+ test_num = 1;
+ }
+ if (strcmp(argv[1], "rx") == 0) {
+ test_num = 2;
}
- fprintf(stderr,"%d\n", test_num);
-
- struct freedv *freedv;
- freedv = freedv_open(FREEDV_MODE_700D);
- assert(freedv != NULL);
-
- /* note API functions to tell us how big our buffers need to be */
- short speech_out[freedv_get_n_max_speech_samples(freedv)];
- short demod_in[2*freedv_get_n_max_modem_samples(freedv)];
- COMP demod_in_comp[2*freedv_get_n_max_modem_samples(freedv)];
-
- /* set up small freq offset */
- float foff_hz = 25;
- COMP phase_ch; phase_ch.real = 1.0; phase_ch.imag = 0.0;
-
- /* set complex sine wave interferer at -fc */
- COMP interferer_phase = {1.0,0.0};
- COMP interferer_freq;
- interferer_freq.real = cos(2.0*M_PI*freedv->ofdm->tx_centre/FREEDV_FS_8000);
- interferer_freq.imag = sin(2.0*M_PI*freedv->ofdm->tx_centre/FREEDV_FS_8000);
- interferer_freq = cconj(interferer_freq);
-
- /* log a file of demod input samples for plotting in Octave */
- FILE *fdemod = fopen("demod.f32","wb"); assert(fdemod != NULL);
-
- /* measure demod input power, interferer input power */
- float power_d = 0.0; float power_interferer = 0.0;
-
- int frames = 0, sum_sync = 0, frames_snr = 0; float sum_snr = 0.0;
- size_t nin, nout;
- nin = freedv_nin(freedv);
-
- while(fread(demod_in, sizeof(short), 2*nin, stdin) == 2*nin) {
- for(int i=0; i<nin; i++) {
- demod_in_comp[i].real = (float)demod_in[2*i];
- demod_in_comp[i].imag = (float)demod_in[2*i+1];
- //demod_in_comp[i].imag = 0;
- }
-
- if (test_num == 1) {
- /* So Tx is a complex OFDM signal centered at +fc. A small
- shift fd followed by Re{} will only work if Tx is complex.
- If Tx is real, neg freq components at -fc+fd will be
- aliased on top of fc+fd wanted signal by Re{} operation.
- This can be tested by setting demod_in_comp[i].imag = 0
- above */
- fdmdv_freq_shift_coh(demod_in_comp, demod_in_comp, foff_hz, FREEDV_FS_8000, &phase_ch, nin);
- for(int i=0; i<nin; i++)
- demod_in_comp[i].imag = 0.0;
- }
-
- if (test_num == 2) {
- /* a complex sinewave (carrier) at -fc will only be ignored if
- Rx is treating signal as complex, otherwise if real a +fc
- alias will appear in the middle of our wanted signal at
- +fc, this can be tested by setting demod_in_comp[i].imag =
- 0 below */
- for(int i=0; i<nin; i++) {
- COMP a = fcmult(2E4,interferer_phase);
- interferer_phase = cmult(interferer_phase, interferer_freq);
- power_interferer += a.real*a.real + a.imag*a.imag;
- COMP d = demod_in_comp[i];
- power_d += d.real*d.real + d.imag*d.imag;
- demod_in_comp[i] = cadd(d,a);
- //demod_in_comp[i].imag = 0;
- }
- }
-
- /* useful to take a look at this with Octave */
- fwrite(demod_in_comp, sizeof(COMP), nin, fdemod);
-
- nout = freedv_comprx(freedv, speech_out, demod_in_comp);
- nin = freedv_nin(freedv); /* call me on every loop! */
- fwrite(speech_out, sizeof(short), nout, stdout);
- int sync; float snr_est;
- freedv_get_modem_stats(freedv, &sync, &snr_est);
- fprintf(stderr, "sync: %d snr_est: %f\n", sync, snr_est);
- frames++; sum_sync += sync; if (sync) { sum_snr += snr_est; frames_snr++; }
+ }
+ fprintf(stderr, "%d\n", test_num);
+
+ struct freedv *freedv;
+ freedv = freedv_open(FREEDV_MODE_700D);
+ assert(freedv != NULL);
+
+ /* note API functions to tell us how big our buffers need to be */
+ short speech_out[freedv_get_n_max_speech_samples(freedv)];
+ short demod_in[2 * freedv_get_n_max_modem_samples(freedv)];
+ COMP demod_in_comp[2 * freedv_get_n_max_modem_samples(freedv)];
+
+ /* set up small freq offset */
+ float foff_hz = 25;
+ COMP phase_ch;
+ phase_ch.real = 1.0;
+ phase_ch.imag = 0.0;
+
+ /* set complex sine wave interferer at -fc */
+ COMP interferer_phase = {1.0, 0.0};
+ COMP interferer_freq;
+ interferer_freq.real =
+ cos(2.0 * M_PI * freedv->ofdm->tx_centre / FREEDV_FS_8000);
+ interferer_freq.imag =
+ sin(2.0 * M_PI * freedv->ofdm->tx_centre / FREEDV_FS_8000);
+ interferer_freq = cconj(interferer_freq);
+
+ /* log a file of demod input samples for plotting in Octave */
+ FILE *fdemod = fopen("demod.f32", "wb");
+ assert(fdemod != NULL);
+
+ /* measure demod input power, interferer input power */
+ float power_d = 0.0;
+ float power_interferer = 0.0;
+
+ int frames = 0, sum_sync = 0, frames_snr = 0;
+ float sum_snr = 0.0;
+ size_t nin, nout;
+ nin = freedv_nin(freedv);
+
+ while (fread(demod_in, sizeof(short), 2 * nin, stdin) == 2 * nin) {
+ for (int i = 0; i < nin; i++) {
+ demod_in_comp[i].real = (float)demod_in[2 * i];
+ demod_in_comp[i].imag = (float)demod_in[2 * i + 1];
+ // demod_in_comp[i].imag = 0;
}
- fclose(fdemod);
- freedv_close(freedv);
+ if (test_num == 1) {
+ /* So Tx is a complex OFDM signal centered at +fc. A small
+ shift fd followed by Re{} will only work if Tx is complex.
+ If Tx is real, neg freq components at -fc+fd will be
+ aliased on top of fc+fd wanted signal by Re{} operation.
+ This can be tested by setting demod_in_comp[i].imag = 0
+ above */
+ fdmdv_freq_shift_coh(demod_in_comp, demod_in_comp, foff_hz,
+ FREEDV_FS_8000, &phase_ch, nin);
+ for (int i = 0; i < nin; i++) demod_in_comp[i].imag = 0.0;
+ }
- if (test_num == 2)
- fprintf(stderr, "Demod/Interferer power ratio: %3.2f dB\n", 10*log10(power_d/power_interferer));
- float snr_av = sum_snr/frames_snr;
- fprintf(stderr, "frames: %d sum_sync: %d snr_av: %3.2f dB\n", frames, sum_sync, snr_av);
+ if (test_num == 2) {
+ /* a complex sinewave (carrier) at -fc will only be ignored if
+ Rx is treating signal as complex, otherwise if real a +fc
+ alias will appear in the middle of our wanted signal at
+ +fc, this can be tested by setting demod_in_comp[i].imag =
+ 0 below */
+ for (int i = 0; i < nin; i++) {
+ COMP a = fcmult(2E4, interferer_phase);
+ interferer_phase = cmult(interferer_phase, interferer_freq);
+ power_interferer += a.real * a.real + a.imag * a.imag;
+ COMP d = demod_in_comp[i];
+ power_d += d.real * d.real + d.imag * d.imag;
+ demod_in_comp[i] = cadd(d, a);
+ // demod_in_comp[i].imag = 0;
+ }
+ }
- if (snr_av > 8.0)
- return 0;
- else
- return 1;
+ /* useful to take a look at this with Octave */
+ fwrite(demod_in_comp, sizeof(COMP), nin, fdemod);
+
+ nout = freedv_comprx(freedv, speech_out, demod_in_comp);
+ nin = freedv_nin(freedv); /* call me on every loop! */
+ fwrite(speech_out, sizeof(short), nout, stdout);
+ int sync;
+ float snr_est;
+ freedv_get_modem_stats(freedv, &sync, &snr_est);
+ fprintf(stderr, "sync: %d snr_est: %f\n", sync, snr_est);
+ frames++;
+ sum_sync += sync;
+ if (sync) {
+ sum_snr += snr_est;
+ frames_snr++;
+ }
+ }
+
+ fclose(fdemod);
+ freedv_close(freedv);
+
+ if (test_num == 2)
+ fprintf(stderr, "Demod/Interferer power ratio: %3.2f dB\n",
+ 10 * log10(power_d / power_interferer));
+ float snr_av = sum_snr / frames_snr;
+ fprintf(stderr, "frames: %d sum_sync: %d snr_av: %3.2f dB\n", frames,
+ sum_sync, snr_av);
+
+ if (snr_av > 8.0)
+ return 0;
+ else
+ return 1;
}