diff mbox series

[FFmpeg-devel,1/2] avradio/sdr: Add CQUAM support

Message ID 20230727223837.3970793-1-michael@niedermayer.cc
State New
Headers show
Series [FFmpeg-devel,1/2] avradio/sdr: Add CQUAM support | expand

Checks

Context Check Description
andriy/configure_x86 warning Failed to apply patch
yinshiyou/configure_loongarch64 warning Failed to apply patch

Commit Message

Michael Niedermayer July 27, 2023, 10:38 p.m. UTC
untested as i have no clean signal from a CQUAM station

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavradio/sdr.h      |  1 +
 libavradio/sdrdemux.c | 37 +++++++++++++++++++++++++++++++------
 2 files changed, 32 insertions(+), 6 deletions(-)

Comments

Michael Niedermayer Aug. 5, 2023, 5:56 p.m. UTC | #1
On Fri, Jul 28, 2023 at 12:38:36AM +0200, Michael Niedermayer wrote:
> untested as i have no clean signal from a CQUAM station
> 
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavradio/sdr.h      |  1 +
>  libavradio/sdrdemux.c | 37 +++++++++++++++++++++++++++++++------
>  2 files changed, 32 insertions(+), 6 deletions(-)

will apply patchset

[...]
Paul B Mahol Aug. 5, 2023, 6:26 p.m. UTC | #2
NAK
diff mbox series

Patch

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 6d11ef794f..b27e6a719e 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -50,6 +50,7 @@  typedef enum AMMode {
     AMLeftRight,
     AMInPhase,
     AMEnvelope,
+    AMCQUAM,
     AMModeNB,
 } AMMode;
 
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 3b24cfedef..78c933f6f1 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -805,13 +805,35 @@  static int demodulate_am(SDRContext *sdr, Station *station, AVStream *st, AVPack
         wamp = amp/stamp;
 
         mm = (AVComplexFloat){dc1.re * amp, -dc1.im * amp};
-        for(i = 0; i<2*sdr->am_block_size; i++) {
-            AVComplexFloat v = sdr->am_iblock[i];
-            sdr->am_iblock[i].re = v.re*mm.re - v.im*mm.im - sdr->am_window[i] * wamp;
-            sdr->am_iblock[i].im = v.re*mm.im + v.im*mm.re;
-        }
+        if (am_mode == AMCQUAM) {
+            double vdotw = 0;
+            for(i = 0; i<2*sdr->am_block_size; i++) {
+                AVComplexFloat v = sdr->am_iblock[i];
+                float I = v.re*mm.re - v.im*mm.im;
+                float Q = v.re*mm.im + v.im*mm.re;
+                float m = sqrt(I*I + Q*Q);
+                //An ideal signal needs no limit but a real noisy signal can become 0 and negative, The limit of 2.0 is arbitrary and still needs to be tuned once we have real world test signals
+                float s = Q * FFMIN(m / fabs(I), 2.0);
+
+                sdr->am_iblock[i].re = m;
+                sdr->am_iblock[i].im = s;
+                vdotw += sdr->am_window[i] * m;
+            }
+            vdotw /= dcw ;
+            for (i = 0; i<2*sdr->am_block_size; i++) {
+                float w = sdr->am_window[i];
+                sdr->am_iblock[i].re -= w*vdotw;
+            }
 
-        scale = 0.9;
+            scale = 0.9/vdotw;
+        } else {
+            for(i = 0; i<2*sdr->am_block_size; i++) {
+                AVComplexFloat v = sdr->am_iblock[i];
+                sdr->am_iblock[i].re = v.re*mm.re - v.im*mm.im - sdr->am_window[i] * wamp;
+                sdr->am_iblock[i].im = v.re*mm.im + v.im*mm.re;
+            }
+            scale = 0.9;
+        }
     }
 
     for(i = 0; i<2*sdr->am_block_size; i++) {
@@ -832,10 +854,12 @@  static int demodulate_am(SDRContext *sdr, Station *station, AVStream *st, AVPack
         switch(am_mode) {
         case AMMidSide:
         case AMLeftRight:
+        case AMCQUAM:
             q = sst->out_buf[2*i+1] +  sdr->am_iblock[i                     ].im * sdr->am_window[i                     ] * scale;
             newbuf[2*i+1]           =  sdr->am_iblock[i + sdr->am_block_size].im * sdr->am_window[i + sdr->am_block_size] * scale;
             switch(am_mode) {
             case AMMidSide:
+            case AMCQUAM:
                 q *= 0.5;
                 sst->out_buf[2*i+0] = m + q;
                 sst->out_buf[2*i+1] = m - q;
@@ -2316,6 +2340,7 @@  const AVOption ff_sdr_options[] = {
         { "am_midside", "AM Demodulation Mid Side", 0, AV_OPT_TYPE_CONST,   {.i64 = AMMidSide}, 0, 0, DEC, "am_mode"},
         { "am_inphase", "AM Demodulation In Phase", 0, AV_OPT_TYPE_CONST,   {.i64 = AMInPhase}, 0, 0, DEC, "am_mode"},
         { "am_envelope","AM Demodulation EnvelopeDC", 0, AV_OPT_TYPE_CONST, {.i64 = AMEnvelope}, 0, 0, DEC, "am_mode"},
+        { "am_cquam","CQUAM Stereo Demodulation", 0, AV_OPT_TYPE_CONST, {.i64 = AMCQUAM}, 0, 0, DEC, "am_mode"},
 
     { "am_fft_ref", "Use FFT Based carrier for AM demodulation", OFFSET(am_fft_ref), AV_OPT_TYPE_INT , {.i64 = 0}, 0, 1, DEC},