[FFmpeg-cvslog] [ffmpeg-radio] 01/02: avradio/sdr: Add CQUAM support
Michael Niedermayer
ffmpeg-git at ffmpeg.org
Sat Aug 5 21:16:36 EEST 2023
This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository libavradio.
commit c7aaa5a82cb1e585d33d58188008841844dd8763
Author: Michael Niedermayer <michael at niedermayer.cc>
AuthorDate: Wed Jul 26 14:18:27 2023 +0200
Commit: Michael Niedermayer <michael at niedermayer.cc>
CommitDate: Thu Jul 27 17:42:10 2023 +0200
avradio/sdr: Add CQUAM support
untested as i have no clean signal from a CQUAM station
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
libavradio/sdr.h | 1 +
libavradio/sdrdemux.c | 37 +++++++++++++++++++++++++++++++------
2 files changed, 32 insertions(+), 6 deletions(-)
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},
More information about the ffmpeg-cvslog
mailing list