* [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size
@ 2023-07-17 0:26 Michael Niedermayer
2023-07-17 0:26 ` [FFmpeg-devel] [PATCH 2/7] avradio/sdr: compensate for RTLSDR frequency limitations Michael Niedermayer
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdrdemux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 5a6a9b8894..a545e7cb4c 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -1543,7 +1543,7 @@ int ff_sdr_common_init(AVFormatContext *s)
sdr->fm_iside = av_malloc(sizeof(*sdr->fm_iside) * 2 * sdr->fm_block_size_p2);
sdr->fm_block = av_malloc(sizeof(*sdr->fm_block) * 2 * sdr->fm_block_size);
sdr->fm_iblock = av_malloc(sizeof(*sdr->fm_iblock) * 2 * sdr->fm_block_size);
- sdr->fm_icarrier = av_malloc(sizeof(*sdr->fm_icarrier) * 2 * sdr->fm_block_size);
+ sdr->fm_icarrier = av_malloc(sizeof(*sdr->fm_icarrier) * 2 * sdr->fm_block_size_p2);
sdr->fm_window = av_malloc(sizeof(*sdr->fm_window) * 2 * sdr->fm_block_size);
if (!sdr->windowed_block || !sdr->len2block || !sdr->block || !sdr->window || !sdr->fm_window_p2 || !sdr->fm_iside ||
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 2/7] avradio/sdr: compensate for RTLSDR frequency limitations
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
@ 2023-07-17 0:26 ` Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 3/7] avradio/sdrinradio: Print all tunable elements Michael Niedermayer
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 2 +-
libavradio/sdrdemux.c | 9 ++++-----
libavradio/sdrinradio.c | 10 ++++++++--
3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index ac6b7dffe0..dc20415457 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -210,7 +210,7 @@ typedef struct SDRContext {
/**
* Setup the hardware for the requested frequency
*/
- int (*set_frequency_callback)(struct SDRContext *sdr, int64_t frequency);
+ int64_t (*set_frequency_callback)(struct SDRContext *sdr, int64_t frequency);
/**
* Read from the hardware, block if nothing available with a reasonable timeout
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index a545e7cb4c..5a3af23a74 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -1129,11 +1129,10 @@ ModulationDescriptor ff_sdr_modulation_descs[] = {
int ff_sdr_set_freq(SDRContext *sdr, int64_t freq)
{
freq = av_clip64(freq, sdr->min_center_freq, sdr->max_center_freq);
-
if (sdr->set_frequency_callback) {
- int ret = sdr->set_frequency_callback(sdr, freq);
- if (ret < 0)
- return ret;
+ freq = sdr->set_frequency_callback(sdr, freq);
+ if (freq < 0)
+ return freq;
}
sdr->freq = freq;
@@ -1421,7 +1420,7 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr)
if (sdr->seek_direction && block_counter > 5) {
sdr->wanted_freq = snap2band(sdr, sdr->wanted_freq, sdr->seek_direction*sdr->bandwidth*0.5);
}
- if (sdr->wanted_freq != sdr->freq) {
+ if (fabs(sdr->wanted_freq - sdr->freq) > 1500) {
//We could use a seperate MUTEX for the FIFO and for soapy
ff_sdr_set_freq(sdr, sdr->wanted_freq);
//This shouldnt really cause any problem if we just continue on error except that we continue returning data with the previous target frequency range
diff --git a/libavradio/sdrinradio.c b/libavradio/sdrinradio.c
index 0e7442fddf..f078d27e7b 100644
--- a/libavradio/sdrinradio.c
+++ b/libavradio/sdrinradio.c
@@ -68,7 +68,7 @@ static int sdrindev_read_callback(SDRContext *sdr, FIFOElement *fifo_element, in
return ret;
}
-static int sdrindev_set_frequency_callback(SDRContext *sdr, int64_t freq)
+static int64_t sdrindev_set_frequency_callback(SDRContext *sdr, int64_t freq)
{
AVFormatContext *avfmt = sdr->avfmt;
SoapySDRDevice *soapy = sdr->soapy;
@@ -83,6 +83,12 @@ static int sdrindev_set_frequency_callback(SDRContext *sdr, int64_t freq)
} else
sdr->current_direct_samp = value;
}
+ //The R820T has a 16 bit fractional PLL which can do only multiplies of 439.45
+ //Its more complex but this approximation works
+ //It has to be noted that SOAPY does not tell us about this, instead saopy
+ //pretends whatever we ask for we get exactly, but we dont
+ //For more details see: michelebavaro.blogspot.com/2014/05/gnss-carrier-phase-rtlsdr-and.html
+ freq = lrint(freq / 439.45) * 439.45;
}
if (SoapySDRDevice_setFrequency(soapy, SOAPY_SDR_RX, 0, freq, NULL) != 0) {
@@ -90,7 +96,7 @@ static int sdrindev_set_frequency_callback(SDRContext *sdr, int64_t freq)
return AVERROR_EXTERNAL;
}
}
- return 0;
+ return freq;
}
static void print_and_free_list(AVFormatContext *s, char** names, size_t length, const char *title)
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 3/7] avradio/sdrinradio: Print all tunable elements
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
2023-07-17 0:26 ` [FFmpeg-devel] [PATCH 2/7] avradio/sdr: compensate for RTLSDR frequency limitations Michael Niedermayer
@ 2023-07-17 0:27 ` Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 4/7] avradio/sdrdemux: Use a local noise floor in FM Probing Michael Niedermayer
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:27 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdrinradio.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libavradio/sdrinradio.c b/libavradio/sdrinradio.c
index f078d27e7b..3956c18375 100644
--- a/libavradio/sdrinradio.c
+++ b/libavradio/sdrinradio.c
@@ -184,6 +184,10 @@ static int sdrindev_initial_hw_setup(AVFormatContext *s)
names = SoapySDRDevice_listAntennas(soapy, SOAPY_SDR_RX, 0, &length);
print_and_free_list(s, names, length, "Antennas");
+ //Go over all tunable elements
+ names = SoapySDRDevice_listFrequencies(soapy, SOAPY_SDR_RX, 0, &length);
+ print_and_free_list(s, names, length, "Tunables");
+
//Go over all Gain Elements and print them
names = SoapySDRDevice_listGains(soapy, SOAPY_SDR_RX, 0, &length);
print_and_free_list(s, names, length, "Rx Gain Elements");
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 4/7] avradio/sdrdemux: Use a local noise floor in FM Probing
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
2023-07-17 0:26 ` [FFmpeg-devel] [PATCH 2/7] avradio/sdr: compensate for RTLSDR frequency limitations Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 3/7] avradio/sdrinradio: Print all tunable elements Michael Niedermayer
@ 2023-07-17 0:27 ` Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 5/7] avradio/sdrdemux: adjust bandwidth to 200khz for FM probing Michael Niedermayer
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:27 UTC (permalink / raw)
To: FFmpeg development discussions and patches
The global one caused problems when the spectrum is not flat
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdrdemux.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 5a3af23a74..a4c590acf2 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -861,17 +861,20 @@ static int probe_fm(SDRContext *sdr)
int i;
int bandwidth_f = sdr->fm_bandwidth;
int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
+ int floor_bw_i = 10*1000 * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
float last_score[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
int border_i = (sdr->sdr_sample_rate - FFMIN(sdr->bandwidth, sdr->sdr_sample_rate*7/8)) * sdr->block_size / sdr->sdr_sample_rate;
- double noise_floor = FLT_MAX;
if (2*half_bw_i > 2*sdr->block_size)
return 0;
- for (int pass = 0; pass < 2; pass ++) {
+ {
double avg[2] = {0}, tri = 0;
+ double floor[2] = {0};
double mean = 0;
double center = 0;
+ float floor_compensation = half_bw_i * half_bw_i / (float)floor_bw_i;
+
for (i = 0; i<half_bw_i; i++) {
avg[0] += sdr->len2block[i];
tri += i*sdr->len2block[i];
@@ -883,12 +886,19 @@ static int probe_fm(SDRContext *sdr)
mean += i*sdr->len2block[i];
}
+ for (i=0; i<floor_bw_i; i++)
+ floor[0] += sdr->len2block[i];
+ for (i=2*half_bw_i - floor_bw_i; i<2*half_bw_i; i++)
+ floor[1] += sdr->len2block[i];
+
for(i = half_bw_i; i<2*sdr->block_size - half_bw_i; i++) {
double b = avg[0] + sdr->len2block[i];
avg[0] += sdr->len2block[i] - sdr->len2block[i - half_bw_i];
avg[1] -= sdr->len2block[i] - sdr->len2block[i + half_bw_i];
b += avg[1];
tri += avg[1] - avg[0];
+ floor[0] += sdr->len2block[i - half_bw_i + floor_bw_i] - sdr->len2block[i - half_bw_i];
+ floor[1] -= sdr->len2block[i + half_bw_i - floor_bw_i] - sdr->len2block[i + half_bw_i];
mean += (i+half_bw_i)*sdr->len2block[i+half_bw_i];
center = mean / b;
@@ -897,17 +907,24 @@ static int probe_fm(SDRContext *sdr)
if (i < border_i || i > 2*sdr->block_size - border_i)
continue;
- if (pass == 0) {
- noise_floor = FFMIN(noise_floor, tri);
- } else {
+ {
+ float noise_floor;
+ if (i - half_bw_i < border_i) {
+ noise_floor = floor[1];
+ } else if (i + half_bw_i >= 2*sdr->block_size - border_i) {
+ noise_floor = floor[0];
+ } else
+ noise_floor = (floor[0] + floor[1])/2;
+ noise_floor *= floor_compensation;
+
last_score[2] = last_score[1];
last_score[1] = last_score[0];
- last_score[0] = tri / (noise_floor);
+ last_score[0] = tri;
if (last_score[1] >= last_score[0] &&
last_score[1] > last_score[2] &&
- last_score[1] > sdr->fm_threshold) {
- double score = last_score[1];
+ last_score[1] / noise_floor > sdr->fm_threshold) {
+ double score = last_score[1] / noise_floor;
float rmax = max_in_range(sdr, i-half_bw_i/4, i+half_bw_i/4);
int lowcount = countbelow(sdr, i-half_bw_i/4, i+half_bw_i/4, rmax / 100);
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 5/7] avradio/sdrdemux: adjust bandwidth to 200khz for FM probing
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
` (2 preceding siblings ...)
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 4/7] avradio/sdrdemux: Use a local noise floor in FM Probing Michael Niedermayer
@ 2023-07-17 0:27 ` Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 6/7] avradio/sdr: Support setting gain value manually and automatic Michael Niedermayer
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:27 UTC (permalink / raw)
To: FFmpeg development discussions and patches
This improves the local noise floor value
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdrdemux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index a4c590acf2..a0b80785ef 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -860,7 +860,7 @@ static int probe_fm(SDRContext *sdr)
{
int i;
int bandwidth_f = sdr->fm_bandwidth;
- int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
+ int half_bw_i = 200*1000 * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
int floor_bw_i = 10*1000 * (int64_t)sdr->block_size / sdr->sdr_sample_rate;
float last_score[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
int border_i = (sdr->sdr_sample_rate - FFMIN(sdr->bandwidth, sdr->sdr_sample_rate*7/8)) * sdr->block_size / sdr->sdr_sample_rate;
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 6/7] avradio/sdr: Support setting gain value manually and automatic
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
` (3 preceding siblings ...)
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 5/7] avradio/sdrdemux: adjust bandwidth to 200khz for FM probing Michael Niedermayer
@ 2023-07-17 0:27 ` Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 7/7] avradio/sdr: workaround inverted gain parameter on sdrplay Michael Niedermayer
2023-07-18 21:26 ` [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:27 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 23 +++++++++++++++++-
libavradio/sdrdemux.c | 53 ++++++++++++++++++++++++++++++++++++++++-
libavradio/sdrinradio.c | 41 +++++++++++++++++++++++++++++--
3 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index dc20415457..395b056531 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -68,6 +68,12 @@ typedef enum Modulation {
//QAM, PSK, ...
} Modulation;
+typedef enum SDR_GAIN {
+ GAIN_DEFAULT = -3,
+ GAIN_SW_AGC = -2,
+ GAIN_SDR_AGC = -1,
+} SDR_GAIN;
+
#define HISTOGRAMM_SIZE 9
typedef struct Station {
@@ -105,6 +111,7 @@ typedef struct Station {
typedef struct FIFOElement {
int64_t center_frequency;
+ float gain;
void *halfblock;
} FIFOElement;
@@ -146,7 +153,15 @@ typedef struct SDRContext {
int64_t min_center_freq;
int64_t max_center_freq;
int sdr_sample_rate;
- int sdr_agc;
+ float min_gain;
+ float max_gain;
+ int sdr_gain;
+ float agc_min_headroom;
+ float agc_max_headroom;
+ float agc_max_headroom_time;
+ int agc_low_time;
+ float agc_gain; ///< current gain, should be accessed only by buffer thread after init
+ atomic_int wanted_gain;
int sdr_adcc;
int64_t bandwidth;
int64_t last_pts;
@@ -212,6 +227,12 @@ typedef struct SDRContext {
*/
int64_t (*set_frequency_callback)(struct SDRContext *sdr, int64_t frequency);
+ /**
+ * Setup the hardware for the requested gain
+ * This must only be called from the buffer thread after setup (or more mutex calls are needed)
+ */
+ int (*set_gain_callback)(struct SDRContext *sdr, float gain);
+
/**
* Read from the hardware, block if nothing available with a reasonable timeout
*
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index a0b80785ef..5214aea7be 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -1409,6 +1409,7 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr)
FIFOElement fifo_element;
int remaining, ret;
int empty_blocks, full_blocks;
+ float wanted_gain = atomic_load(&sdr->wanted_gain) / 65536.0;
//i wish av_fifo was thread safe
pthread_mutex_lock(&sdr->mutex);
@@ -1444,9 +1445,17 @@ static void *soapy_needs_bigger_buffers_worker(SDRContext *sdr)
//And theres not much else we can do, an error message was already printed by ff_sdr_set_freq() in that case
block_counter = 0; // we just changed the frequency, do not trust the next blocks content
}
+ if (sdr->sdr_gain == GAIN_SW_AGC &&
+ fabs(wanted_gain - sdr->agc_gain) > 0.001 &&
+ sdr->set_gain_callback
+ ) {
+ sdr->set_gain_callback(sdr, wanted_gain);
+ sdr->agc_gain = wanted_gain;
+ }
pthread_mutex_unlock(&sdr->mutex);
fifo_element.center_frequency = block_counter > 0 ? sdr->freq : 0;
+ fifo_element.gain = sdr->agc_gain; //we make only small changes so slightly mixing should be ok
remaining = sdr->block_size;
while (remaining && !atomic_load(&sdr->close_requested)) {
@@ -1624,6 +1633,7 @@ int ff_sdr_common_init(AVFormatContext *s)
av_fifo_auto_grow_limit(sdr-> full_block_fifo, sdr->sdr_sample_rate / sdr->block_size);
atomic_init(&sdr->close_requested, 0);
+ atomic_init(&sdr->wanted_gain, lrint((sdr->min_gain + sdr->max_gain) * 65536 / 2));
ret = pthread_mutex_init(&sdr->mutex, NULL);
if (ret) {
av_log(s, AV_LOG_ERROR, "pthread_mutex_init failed: %s\n", strerror(ret));
@@ -1886,6 +1896,37 @@ process_next_block:
}
}
+ float smaller_block_gain = FFMIN(fifo_element[0].gain, fifo_element[1].gain);
+ float bigger_block_gain = FFMAX(fifo_element[0].gain, fifo_element[1].gain);
+
+ if (sdr->sdr_gain == GAIN_SW_AGC) {
+ float inmax = 0;
+ float wanted_gain = atomic_load(&sdr->wanted_gain) / 65536.0;
+ // We only check 25% of the data to safe computations
+ int start = 3*sdr->block_size / 4;
+ int end = 5*sdr->block_size / 4;
+ for (i = start; i < end; i++) {
+ float v = fmaxf(fabsf(sdr->windowed_block[i].re), fabsf(sdr->windowed_block[i].im));
+ inmax = fmaxf(inmax, v);
+ }
+
+ if (inmax > 1.0 - sdr->agc_min_headroom && wanted_gain > sdr->min_gain) {
+ //according to docs this is a dB scale, in reality it beheaves differnt to that
+ //Because of this we will try to just make small changes and not assume too much
+ wanted_gain = FFMIN(wanted_gain, FFMAX(smaller_block_gain - 1.0, smaller_block_gain * 0.9));
+
+ sdr->agc_low_time = 0;
+ } else if (inmax < 1.0 - sdr->agc_max_headroom && wanted_gain < sdr->max_gain) {
+ sdr->agc_low_time += sdr->block_size;
+ if (sdr->agc_low_time > sdr->agc_max_headroom_time * sdr->sdr_sample_rate) {
+ sdr->agc_low_time = 0;
+ wanted_gain = FFMAX(wanted_gain, FFMIN(bigger_block_gain + 1.0, bigger_block_gain * 1.1));
+ }
+ } else
+ sdr->agc_low_time = 0;
+ atomic_store(&sdr->wanted_gain, (int)lrint(wanted_gain * 65536));
+ }
+
inject_block_into_fifo(sdr, sdr->empty_block_fifo, &fifo_element[0], "Cannot pass next buffer, freeing it\n");
#ifdef SYN_TEST //synthetic test signal
static int64_t synp=0;
@@ -2141,7 +2182,17 @@ const AVOption ff_sdr_options[] = {
{ "rtlsdr_fixes" , "workaround rtlsdr issues", OFFSET(rtlsdr_fixes), AV_OPT_TYPE_INT , {.i64 = -1}, -1, 1, DEC},
{ "sdr_sr" , "sdr sample rate" , OFFSET(sdr_sample_rate ), AV_OPT_TYPE_INT , {.i64 = 0}, 0, INT_MAX, DEC},
{ "sdr_freq", "sdr frequency" , OFFSET(wanted_freq), AV_OPT_TYPE_INT64 , {.i64 = 9000000}, 0, INT64_MAX, DEC},
- { "sdr_agc" , "sdr automatic gain control", OFFSET(sdr_agc), AV_OPT_TYPE_BOOL , {.i64 = 1}, -1, 1, DEC},
+ { "gain" , "sdr overall gain", OFFSET(sdr_gain), AV_OPT_TYPE_INT , {.i64 = GAIN_SDR_AGC}, -3, INT_MAX, DEC, "gain"},
+ { "sdr_agc", "SDR AGC (if supported)", 0, AV_OPT_TYPE_CONST, {.i64 = GAIN_SDR_AGC}, 0, 0, DEC, "gain"},
+ { "sw_agc", "Software AGC", 0, AV_OPT_TYPE_CONST, {.i64 = GAIN_SW_AGC}, 0, 0, DEC, "gain"},
+ { "default_gain", "Never touch gain", 0, AV_OPT_TYPE_CONST, {.i64 = GAIN_DEFAULT}, 0, 0, DEC, "gain"},
+
+ { "agc_min_headroom", "AGC min headroom", OFFSET(agc_min_headroom), AV_OPT_TYPE_FLOAT, {.dbl = 0.4}, 0, 1.0, DEC},
+ { "agc_max_headroom", "AGC max headroom", OFFSET(agc_max_headroom), AV_OPT_TYPE_FLOAT, {.dbl = 0.8}, 0, 1.0, DEC},
+ { "agc_max_headroom_time", "AGC max headroom time", OFFSET(agc_max_headroom_time), AV_OPT_TYPE_FLOAT, {.dbl = 0.1}, 0, INT_MAX, DEC},
+ { "min_gain", "minimum gain", OFFSET(min_gain ), AV_OPT_TYPE_FLOAT , {.dbl = 0}, 0, INT_MAX, DEC},
+ { "max_gain", "maximum gain", OFFSET(max_gain ), AV_OPT_TYPE_FLOAT , {.dbl = 0}, 0, INT_MAX, DEC},
+
{ "sdr_adcc" ,"sdr automatic dc correction", OFFSET(sdr_adcc), AV_OPT_TYPE_BOOL , {.i64 = -1}, -1, 1, DEC},
{ "min_freq", "minimum frequency", OFFSET(min_freq ), AV_OPT_TYPE_INT64 , {.i64 = 0}, 0, INT64_MAX, DEC},
{ "max_freq", "maximum frequency", OFFSET(max_freq ), AV_OPT_TYPE_INT64 , {.i64 = 0}, 0, INT64_MAX, DEC},
diff --git a/libavradio/sdrinradio.c b/libavradio/sdrinradio.c
index 3956c18375..63a9cade78 100644
--- a/libavradio/sdrinradio.c
+++ b/libavradio/sdrinradio.c
@@ -68,6 +68,30 @@ static int sdrindev_read_callback(SDRContext *sdr, FIFOElement *fifo_element, in
return ret;
}
+static int sdrindev_set_gain_callback(SDRContext *sdr, float gain)
+{
+ AVFormatContext *avfmt = sdr->avfmt;
+ SoapySDRDevice *soapy = sdr->soapy;
+
+ if (sdr->sdr_gain == GAIN_DEFAULT)
+ return 0;
+
+ if (soapy) {
+ int ret = SoapySDRDevice_setGainMode(soapy, SOAPY_SDR_RX, 0, sdr->sdr_gain == GAIN_SDR_AGC);
+ if (ret) {
+ av_log(avfmt, AV_LOG_WARNING, "Failed to set gain mode %d (%s)\n", sdr->sdr_gain == GAIN_SDR_AGC, SoapySDRDevice_lastError());
+ }
+
+ if (sdr->sdr_gain != GAIN_SDR_AGC) {
+ ret = SoapySDRDevice_setGain(soapy, SOAPY_SDR_RX, 0, gain);
+ if (ret) {
+ av_log(avfmt, AV_LOG_WARNING, "Failed to set gain to %f (%s)\n", gain, SoapySDRDevice_lastError());
+ }
+ }
+ }
+ return 0;
+}
+
static int64_t sdrindev_set_frequency_callback(SDRContext *sdr, int64_t freq)
{
AVFormatContext *avfmt = sdr->avfmt;
@@ -135,6 +159,7 @@ static int sdrindev_initial_hw_setup(AVFormatContext *s)
sdr->read_callback = sdrindev_read_callback;
sdr->set_frequency_callback = sdrindev_set_frequency_callback;
+ sdr->set_gain_callback = sdrindev_set_gain_callback;
// Go over all available soapy devices
// Print the usable ones, and choose one unless the user has choosen one
@@ -195,8 +220,10 @@ static int sdrindev_initial_hw_setup(AVFormatContext *s)
//Inform the user if AGC is supported and setup AGC as requested by the user
has_agc = SoapySDRDevice_hasGainMode(soapy, SOAPY_SDR_RX, 0);
av_log(s, AV_LOG_INFO, "RX AGC Supported: %s\n", has_agc ? "yes" : "no");
- if (has_agc && sdr->sdr_agc >= 0)
- SoapySDRDevice_setGainMode(soapy, SOAPY_SDR_RX, 0, sdr->sdr_agc);
+ if (!has_agc && sdr->sdr_gain == GAIN_SDR_AGC) {
+ av_log(s, AV_LOG_WARNING, "hardware AGC unsupported switching to software AGC\n");
+ sdr->sdr_gain = GAIN_SW_AGC;
+ }
//Inform the user if automatic DC correction is supported and setup DC correction as requested by the user
has_adcc = SoapySDRDevice_hasDCOffsetMode(soapy, SOAPY_SDR_RX, 0);
@@ -208,6 +235,16 @@ static int sdrindev_initial_hw_setup(AVFormatContext *s)
range = SoapySDRDevice_getGainRange(soapy, SOAPY_SDR_RX, 0);
av_log(s, AV_LOG_INFO, "Rx Gain range: %f dB - %f dB\n", range.minimum, range.maximum);
+ if (!sdr->min_gain)
+ sdr->min_gain = range.minimum;
+
+ if (!sdr->max_gain)
+ sdr->max_gain = range.maximum;
+ if (sdr->min_gain > sdr->max_gain) {
+ av_log(s, AV_LOG_ERROR, "Invalid gain range\n");
+ return AVERROR(EINVAL);
+ }
+
//Inform the user about the Frequency ranges available, verify the range requested by the user and set the range if the user has not specified one
ranges = SoapySDRDevice_getFrequencyRange(soapy, SOAPY_SDR_RX, 0, &length);
av_log(s, AV_LOG_INFO, "Rx freq ranges: ");
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 7/7] avradio/sdr: workaround inverted gain parameter on sdrplay
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
` (4 preceding siblings ...)
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 6/7] avradio/sdr: Support setting gain value manually and automatic Michael Niedermayer
@ 2023-07-17 0:27 ` Michael Niedermayer
2023-07-18 21:26 ` [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-17 0:27 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavradio/sdr.h | 1 +
libavradio/sdrdemux.c | 1 +
libavradio/sdrinradio.c | 7 +++++++
3 files changed, 9 insertions(+)
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 395b056531..27ec1db4f3 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -257,6 +257,7 @@ typedef struct SDRContext {
int missing_streams;
int rtlsdr_fixes;
+ int sdrplay_fixes;
} SDRContext;
typedef struct ModulationDescriptor {
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 5214aea7be..1b3061a406 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -2180,6 +2180,7 @@ const AVOption ff_sdr_options[] = {
{ "driver" , "sdr driver name" , OFFSET(driver_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC},
{ "rtlsdr_fixes" , "workaround rtlsdr issues", OFFSET(rtlsdr_fixes), AV_OPT_TYPE_INT , {.i64 = -1}, -1, 1, DEC},
+ { "sdrplay_fixes" , "workaround sdrplay issues", OFFSET(sdrplay_fixes), AV_OPT_TYPE_INT , {.i64 = -1}, -1, 1, DEC},
{ "sdr_sr" , "sdr sample rate" , OFFSET(sdr_sample_rate ), AV_OPT_TYPE_INT , {.i64 = 0}, 0, INT_MAX, DEC},
{ "sdr_freq", "sdr frequency" , OFFSET(wanted_freq), AV_OPT_TYPE_INT64 , {.i64 = 9000000}, 0, INT64_MAX, DEC},
{ "gain" , "sdr overall gain", OFFSET(sdr_gain), AV_OPT_TYPE_INT , {.i64 = GAIN_SDR_AGC}, -3, INT_MAX, DEC, "gain"},
diff --git a/libavradio/sdrinradio.c b/libavradio/sdrinradio.c
index 63a9cade78..f824a1d190 100644
--- a/libavradio/sdrinradio.c
+++ b/libavradio/sdrinradio.c
@@ -76,6 +76,11 @@ static int sdrindev_set_gain_callback(SDRContext *sdr, float gain)
if (sdr->sdr_gain == GAIN_DEFAULT)
return 0;
+ //sdrplay has a inverted gain range, not using max_gain as this is a user parameter
+ if (sdr->sdrplay_fixes > 0) {
+ gain = FFMIN(48 - gain, 45);
+ }
+
if (soapy) {
int ret = SoapySDRDevice_setGainMode(soapy, SOAPY_SDR_RX, 0, sdr->sdr_gain == GAIN_SDR_AGC);
if (ret) {
@@ -192,6 +197,8 @@ static int sdrindev_initial_hw_setup(AVFormatContext *s)
if (sdr->rtlsdr_fixes < 0)
sdr->rtlsdr_fixes = !strcmp(sdr->driver_name, "rtlsdr");
+ if (sdr->sdrplay_fixes < 0)
+ sdr->sdrplay_fixes = !strcmp(sdr->driver_name, "sdrplay");
SoapySDRKwargs_set(&args, "driver", sdr->driver_name);
sdr->soapy = soapy = SoapySDRDevice_make(&args);
--
2.31.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
` (5 preceding siblings ...)
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 7/7] avradio/sdr: workaround inverted gain parameter on sdrplay Michael Niedermayer
@ 2023-07-18 21:26 ` Michael Niedermayer
6 siblings, 0 replies; 8+ messages in thread
From: Michael Niedermayer @ 2023-07-18 21:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 509 bytes --]
On Mon, Jul 17, 2023 at 02:26:58AM +0200, Michael Niedermayer wrote:
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
> libavradio/sdrdemux.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
will apply patchset
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Homeopathy is like voting while filling the ballot out with transparent ink.
Sometimes the outcome one wanted occurs. Rarely its worse than filling out
a ballot properly.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-07-18 21:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-17 0:26 [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
2023-07-17 0:26 ` [FFmpeg-devel] [PATCH 2/7] avradio/sdr: compensate for RTLSDR frequency limitations Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 3/7] avradio/sdrinradio: Print all tunable elements Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 4/7] avradio/sdrdemux: Use a local noise floor in FM Probing Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 5/7] avradio/sdrdemux: adjust bandwidth to 200khz for FM probing Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 6/7] avradio/sdr: Support setting gain value manually and automatic Michael Niedermayer
2023-07-17 0:27 ` [FFmpeg-devel] [PATCH 7/7] avradio/sdr: workaround inverted gain parameter on sdrplay Michael Niedermayer
2023-07-18 21:26 ` [FFmpeg-devel] [PATCH 1/7] avradio/sdrdemux: icarrier just needs phase 2 block size Michael Niedermayer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git