From patchwork Tue Jul 11 21:19:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 42604 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:6da1:b0:131:a7d0:bc6d with SMTP id gl33csp1731341pzb; Tue, 11 Jul 2023 14:20:34 -0700 (PDT) X-Google-Smtp-Source: APBJJlHshtSjcgGj3KFy6e6BlE4+bmZiQTpl2NPUQw+8jpqaVHFPa4+NxWgOETeXhaANl6pXDA/g X-Received: by 2002:a17:906:7499:b0:98e:16b9:6c8c with SMTP id e25-20020a170906749900b0098e16b96c8cmr19908949ejl.14.1689110434577; Tue, 11 Jul 2023 14:20:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689110434; cv=none; d=google.com; s=arc-20160816; b=IvAXCn/aRAVdBFzj97zk6iGBwDku5Arr1HcnQBI37Zj/NtUNZ1beqfVFIBVVa6yVpe KHC0F4o/9gK8fxD0h4L/e2yfgMFoud/JGgxzux0Pym0GsWCXc3vquVQnXgZJXQkuUIs0 kaubnTmrn71DV4FyC/GUr6HeqiEF1ylIdILBEHN5I2s7AMBbi59TeB5oThqwqATex0FA gVQoYlNaO5A9km8Fw1ACLyzzS/Ql6DMv9DPPfYJHl1lqR4IvoH5+HPMji018ND5I5POS IAe6Ivw+Q1BF9NX9gNyI/H2QDmnRjDKSkbeFA2b3xHug4BRjwNxicZ2TzIJVviTKxODb 8LFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=eFfg5Nt9L4+BSOFZMJe6vc5A6YIijOm+3/9YW7GsOfA=; fh=YYwLYmpaV0Fpw/rxmSKNRLS2XzDkAlGbHATiKOPtZrY=; b=fK1sKimrpn3QavCJQ/Fhk5rZLBnvy9oBJXXNwwj3VAokgt7VbYQWAzTcwSwRhSLr0D uddzMnLkJW0wsR4YL/547ghEV8bAkvE5MxW2zJIj9O3PH/Z+8+PsQEoqBzBgqdyKO2FF 639GNjR6zQcxGgC8Qp2/FkSaPIbBY3fOXsdbzMDvn9D+tqLFk2znmMGpMV7wrcmMoFOW ti9x0nBV/d+q3XaXcvSEwMGZuLrr6wQpfeEv6npKCnQsviHrv5E2PaYJDrbqK2L35PZ/ j6QuVgbNjt/R/WePUyW1UOj52Oex5LlqwzSWJuZNNC+5xm7/5be0S47u94BwKM6JOa+Y poyA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id i2-20020a17090685c200b009933071fdd7si2571681ejy.680.2023.07.11.14.20.34; Tue, 11 Jul 2023 14:20:34 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6F32B68C632; Wed, 12 Jul 2023 00:19:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AC66568AEC5 for ; Wed, 12 Jul 2023 00:19:20 +0300 (EEST) Received: by mail.gandi.net (Postfix) with ESMTPSA id 1F105E0007 for ; Tue, 11 Jul 2023 21:19:19 +0000 (UTC) From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Tue, 11 Jul 2023 23:19:06 +0200 Message-Id: <20230711211910.1257355-8-michael@niedermayer.cc> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230711211910.1257355-1-michael@niedermayer.cc> References: <20230711211910.1257355-1-michael@niedermayer.cc> MIME-Version: 1.0 X-GND-Sasl: michael@niedermayer.cc Subject: [FFmpeg-devel] [PATCH 08/12] avradio/sdr: Move IFFT and block size to main context X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 4nNBhDzZJmCi This avoids duplicating this per stream instance Signed-off-by: Michael Niedermayer --- libavradio/sdr.h | 12 +++- libavradio/sdrdemux.c | 144 ++++++++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 65 deletions(-) diff --git a/libavradio/sdr.h b/libavradio/sdr.h index 834b1f40b4..79e48e6162 100644 --- a/libavradio/sdr.h +++ b/libavradio/sdr.h @@ -99,13 +99,10 @@ typedef struct FIFOElement { } FIFOElement; typedef struct SDRStream { - AVTXContext *ifft_ctx; AVTXContext *fft_ctx; AVTXContext *ifft_p2_ctx; - av_tx_fn ifft; av_tx_fn fft; av_tx_fn ifft_p2; - int block_size; int processing_index; float *out_buf; AVComplexFloat *block; @@ -160,11 +157,20 @@ typedef struct SDRContext { int sample_size; double sample_scale; + int64_t am_bandwidth; + int64_t fm_bandwidth; int64_t fm_bandwidth_p2; + int am_block_size; + int fm_block_size; int fm_block_size_p2; int rds_ring_size; float *fm_window_p2; + AVTXContext *am_ifft_ctx; + AVTXContext *fm_ifft_ctx; + av_tx_fn am_ifft; + av_tx_fn fm_ifft; + int am_mode; ///< AMMode but using int for generic option access int emphasis_mode; int am_fft_ref; diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c index 8b8c126380..443f48aebb 100644 --- a/libavradio/sdrdemux.c +++ b/libavradio/sdrdemux.c @@ -541,7 +541,7 @@ static double find_peak_macleod(const SDRContext *sdr, const AVComplexFloat *dat static int probe_am(SDRContext *sdr) { int i; - int bandwidth_f = 6000; + int bandwidth_f = sdr->am_bandwidth; int half_bw_i = bandwidth_f * (int64_t)sdr->block_size / sdr->sdr_sample_rate; int border_i = (sdr->sdr_sample_rate - sdr->bandwidth) * sdr->block_size / sdr->sdr_sample_rate; double avg = 0; @@ -675,7 +675,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) int len = (bandwidth * 2ll * sdr->block_size + sdr->sdr_sample_rate/2) / sdr->sdr_sample_rate; float *newbuf; float scale; - int sample_rate = sdr->sdr_sample_rate * (int64_t)sst->block_size / sdr->block_size; + int sample_rate = sdr->sdr_sample_rate * (int64_t)sdr->am_block_size / sdr->block_size; int ret, i; double current_station_i; float limits[2] = {-0.0, 0.0}; @@ -685,7 +685,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) #define CARRIER_SEARCH 2 if (index + len + CARRIER_SEARCH>= 2*sdr->block_size || index - len - CARRIER_SEARCH < 0 || - 2*len + 1 > 2*sst->block_size) + 2*len + 1 > 2*sdr->am_block_size) return AVERROR(ERANGE); current_station_i = find_am_carrier(sdr, sdr->block, 2*sdr->block_size, sdr->len2block, index, CARRIER_SEARCH, len); @@ -699,21 +699,21 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) am_mode = AMEnvelope; } - newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sst->block_size); + newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->am_block_size); if (!newbuf) return AVERROR(ENOMEM); #define SEPC 4 i = 2*len+1; memcpy(sst->block, sdr->block + index - len, sizeof(*sst->block) * i); - memset(sst->block + i, 0, sizeof(*sst->block) * (2 * sst->block_size - i)); + memset(sst->block + i, 0, sizeof(*sst->block) * (2 * sdr->am_block_size - i)); - sst->ifft(sst->ifft_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat)); + sdr->am_ifft(sdr->am_ifft_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat)); if (am_mode == AMEnvelope) { double vdotw = 0; double wdot = 0; // could be precalculated - for (i = 0; i<2*sst->block_size; i++) { + for (i = 0; i<2*sdr->am_block_size; i++) { float w = sst->window[i]; float v = sqrt(len2(sst->iblock[i])); sst->iblock[i].re = v; @@ -724,7 +724,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) } vdotw /= wdot ; - for (i = 0; i<2*sst->block_size; i++) { + for (i = 0; i<2*sdr->am_block_size; i++) { float w = sst->window[i]; sst->iblock[i].re -= w*vdotw; } @@ -735,14 +735,14 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) memset(sst->block, 0, sizeof(*sst->block) * i); for (i = len-SEPC+1; iblock[i] = sdr->block[index + i - len]; - sst->ifft(sst->ifft_ctx, sst->icarrier, sst->block, sizeof(AVComplexFloat)); + sdr->am_ifft(sdr->am_ifft_ctx, sst->icarrier, sst->block, sizeof(AVComplexFloat)); - synchronous_am_demodulationN(sst->iblock, sst->icarrier, sst->window, 2*sst->block_size, 1); + synchronous_am_demodulationN(sst->iblock, sst->icarrier, sst->window, 2*sdr->am_block_size, 1); scale = 0.9; } else { // Synchronous demodulation using Macleod based systhesized carrier double fcorr = F2INDEX(freq) - index + len; - double theta = -M_PI*fcorr / sst->block_size; + double theta = -M_PI*fcorr / sdr->am_block_size; AVComplexDouble mdelta = {cos(theta), sin(theta)}; AVComplexDouble m = {1,0}; AVComplexDouble dc1 = {0,0}; @@ -751,7 +751,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) double dcw = 0; float amp, stamp, wamp; - for(i = 0; i<2*sst->block_size; i++) { + for(i = 0; i<2*sdr->am_block_size; i++) { double tmp; AVComplexFloat v = sst->iblock[i]; sst->iblock[i].re = v.re*m.re - v.im*m.im; @@ -773,7 +773,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) wamp = amp/stamp; mm = (AVComplexFloat){dc1.re * amp, -dc1.im * amp}; - for(i = 0; i<2*sst->block_size; i++) { + for(i = 0; i<2*sdr->am_block_size; i++) { AVComplexFloat v = sst->iblock[i]; sst->iblock[i].re = v.re*mm.re - v.im*mm.im - sst->window[i] * wamp; sst->iblock[i].im = v.re*mm.im + v.im*mm.re; @@ -782,7 +782,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) scale = 0.9; } - for(i = 0; i<2*sst->block_size; i++) { + for(i = 0; i<2*sdr->am_block_size; i++) { av_assert0(isfinite(sst->iblock[i].re)); av_assert0(isfinite(sst->iblock[i].im)); limits[0] = FFMIN(limits[0], FFMIN(sst->iblock[i].re - sst->iblock[i].im, sst->iblock[i].re + sst->iblock[i].im)); @@ -791,17 +791,17 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) av_assert1(FFMAX(limits[1], -limits[0]) >= 0); scale = FFMIN(scale, 0.98 / FFMAX(limits[1], -limits[0])); - for(i = 0; iblock_size; i++) { + for(i = 0; iam_block_size; i++) { float m, q; m = sst->out_buf[2*i+0] + (sst->iblock[i ].re) * sst->window[i ] * scale; - newbuf[2*i+0] = (sst->iblock[i + sst->block_size].re) * sst->window[i + sst->block_size] * scale; + newbuf[2*i+0] = (sst->iblock[i + sdr->am_block_size].re) * sst->window[i + sdr->am_block_size] * scale; switch(am_mode) { case AMMidSide: case AMLeftRight: q = sst->out_buf[2*i+1] + sst->iblock[i ].im * sst->window[i ] * scale; - newbuf[2*i+1] = sst->iblock[i + sst->block_size].im * sst->window[i + sst->block_size] * scale; + newbuf[2*i+1] = sst->iblock[i + sdr->am_block_size].im * sst->window[i + sdr->am_block_size] * scale; switch(am_mode) { case AMMidSide: q *= 0.5; @@ -828,7 +828,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) } } - ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sst->block_size); + ret = av_packet_from_data(pkt, (void*)sst->out_buf, sizeof(*sst->out_buf) * 2 * sdr->am_block_size); if (ret < 0) av_free(sst->out_buf); sst->out_buf = newbuf; @@ -849,7 +849,7 @@ static int demodulate_am(SDRContext *sdr, int stream_index, AVPacket *pkt) static int probe_fm(SDRContext *sdr) { int i; - int bandwidth_f = 180*1000; + int bandwidth_f = sdr->fm_bandwidth; int half_bw_i = bandwidth_f * (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; @@ -938,19 +938,21 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt) { AVStream *st = sdr->avfmt->streams[stream_index]; SDRStream *sst = st->priv_data; - double freq = sst->station->frequency; - int64_t bandwidth = sst->station->bandwidth; + Station *station = sst->station; + + double freq = station->frequency; + int64_t bandwidth = station->bandwidth; int index = lrint(F2INDEX(freq)); int len = (bandwidth * 2ll * sdr->block_size + sdr->sdr_sample_rate/2) / sdr->sdr_sample_rate; float *newbuf; float scale; - int sample_rate = sdr->sdr_sample_rate * (int64_t)sst->block_size / sdr->block_size; + int sample_rate = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size / sdr->block_size; int sample_rate_p2 = sdr->sdr_sample_rate * (int64_t)sdr->fm_block_size_p2 / sdr->block_size; int ret, i; float clip = 1.0; - int carrier19_i = 2L*sst->block_size*19000 / sample_rate; - int len17_i = 2L*sst->block_size*16500 / sample_rate; - int len2_4_i = 2L*sst->block_size* 2400 / sample_rate; + int carrier19_i = 2L*sdr->fm_block_size*19000 / sample_rate; + int len17_i = 2L*sdr->fm_block_size*16500 / sample_rate; + int len2_4_i = 2L*sdr->fm_block_size* 2400 / sample_rate; double carrier19_i_exact; int W= 5; @@ -961,21 +963,21 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt) if (index + len >= 2*sdr->block_size || index - len < 0 || - 2*len + 1 > 2*sst->block_size) + 2*len + 1 > 2*sdr->fm_block_size) return AVERROR(ERANGE); - newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sst->block_size); + newbuf = av_malloc(sizeof(*sst->out_buf) * 2 * sdr->fm_block_size); if (!newbuf) return AVERROR(ENOMEM); i = 2*len+1; memcpy(sst->block, sdr->block + index, sizeof(*sst->block) * (len + 1)); - memcpy(sst->block + 2 * sst->block_size - len, sdr->block + index - len, sizeof(*sst->block) * len); - memset(sst->block + len + 1, 0, sizeof(*sst->block) * (2 * sst->block_size - i)); + memcpy(sst->block + 2 * sdr->fm_block_size - len, sdr->block + index - len, sizeof(*sst->block) * len); + memset(sst->block + len + 1, 0, sizeof(*sst->block) * (2 * sdr->fm_block_size - i)); - sst->ifft(sst->ifft_ctx, sst->iblock, sst->block, sizeof(AVComplexFloat)); + sdr->fm_ifft(sdr->fm_ifft_ctx, sst->iblock, sst->block, sizeof(AVComplexFloat)); - for (i = 0; i<2*sst->block_size - 1; i++) { + for (i = 0; i<2*sdr->fm_block_size - 1; i++) { AVComplexFloat x = sst->iblock[i]; AVComplexFloat y = sst->iblock[i+1]; sst->iblock[i].re = atan2(x.im * y.re - x.re * y.im, @@ -985,18 +987,18 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt) sst->iblock[i].re = 0; sst->iblock[i].im = 0; - av_assert0(sdr->fm_block_size_p2 * 2 < sst->block_size); + av_assert0(sdr->fm_block_size_p2 * 2 < sdr->fm_block_size); //FIXME this only needs to be a RDFT //CONSIDER, this and in fact alot can be done with bandpass and lowpass filters instead of FFTs, find out which is better //CONSIDER synthesizing the carrier instead of IFFT, we have all parameters for that sst->fft(sst->fft_ctx, sst->block, sst->iblock, sizeof(AVComplexFloat)); // Only the low N/2+1 are used the upper is just a reflection - carrier19_i_exact = find_am_carrier(sdr, sst->block, 2*sst->block_size, (void*)(sst->block + 1 + sst->block_size), carrier19_i, 10, 10); + carrier19_i_exact = find_am_carrier(sdr, sst->block, 2*sdr->fm_block_size, (void*)(sst->block + 1 + sdr->fm_block_size), carrier19_i, 10, 10); carrier19_i = lrint(carrier19_i_exact); if (carrier19_i >= 0) { - i = sst->block_size; + i = sdr->fm_block_size; memset(sst->block + i, 0, 2*sdr->fm_block_size_p2 * sizeof(AVComplexFloat)); memcpy(sst->block + i, sst->block + carrier19_i, sizeof(AVComplexFloat)*(W+1)); memcpy(sst->block + i + 2*sdr->fm_block_size_p2 - W, sst->block + carrier19_i - W, sizeof(AVComplexFloat)*W); @@ -1018,9 +1020,9 @@ static int demodulate_fm(SDRContext *sdr, int stream_index, AVPacket *pkt) memset(sst->block + len17_i, 0, (2*sdr->fm_block_size_p2 - len17_i) * sizeof(AVComplexFloat)); apply_deemphasis(sdr, sst->block, 2*sdr->fm_block_size_p2, sample_rate_p2, + 1); sst->ifft_p2(sst->ifft_p2_ctx, sst->iblock , sst->block, sizeof(AVComplexFloat)); - memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sst->block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat)); + memset(sst->iblock + 2*sdr->fm_block_size_p2, 0 ,(2*sdr->fm_block_size -2*sdr->fm_block_size_p2) * sizeof(AVComplexFloat)); - scale = 5 / (M_PI * 2*sst->block_size); + scale = 5 / (M_PI * 2*sdr->fm_block_size); for(i = 0; ifm_block_size_p2; i++) { float m, q; @@ -1094,13 +1096,10 @@ static void free_stream(SDRContext *sdr, int stream_index) AVStream *st = s->streams[stream_index]; SDRStream *sst = st->priv_data; - av_tx_uninit(&sst->ifft_ctx); av_tx_uninit(&sst->fft_ctx); av_tx_uninit(&sst->ifft_p2_ctx); - sst->ifft = NULL; sst->fft = NULL; sst->ifft_p2 = NULL; - sst->block_size = 0; av_freep(&sst->out_buf); av_freep(&sst->block); @@ -1110,6 +1109,16 @@ static void free_stream(SDRContext *sdr, int stream_index) av_freep(&sst->window); } +static int find_block_size(SDRContext *sdr, int64_t bandwidth) +{ + int block_size; + + for (block_size = 4; 2ll * bandwidth * sdr->block_time > block_size; block_size <<= 1) + ; + + return FFMIN(sdr->block_size, block_size); +} + static int setup_stream(SDRContext *sdr, int stream_index, Station *station) { AVFormatContext *s = sdr->avfmt; @@ -1132,17 +1141,10 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station) if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { free_stream(sdr, stream_index); - for (sst->block_size = 4; 2ll *sst->station->bandwidth * sdr->block_time > sst->block_size; sst->block_size <<= 1) - ; - sst->block_size = FFMIN(sdr->block_size, sst->block_size); - - ret = av_tx_init(&sst->ifft_ctx, &sst->ifft, AV_TX_FLOAT_FFT, 1, 2*sst->block_size, NULL, 0); - if (ret < 0) - return ret; - + int block_size; if (sst->station->modulation == FM) { //Allocate 2nd stage demodulation fields if needed - ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sst->block_size , NULL, 0); + ret = av_tx_init(&sst-> fft_ctx, &sst-> fft, AV_TX_FLOAT_FFT, 0, 2*sdr->fm_block_size , NULL, 0); if (ret < 0) return ret; @@ -1153,19 +1155,21 @@ static int setup_stream(SDRContext *sdr, int stream_index, Station *station) sst->iside = av_malloc(sizeof(*sst->iside) * 2 * sdr->fm_block_size_p2); if (!sst->iside) return AVERROR(ENOMEM); - } - - sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * sst->block_size); - sst->block = av_malloc(sizeof(*sst-> block) * 2 * sst->block_size); - sst->iblock = av_malloc(sizeof(*sst->iblock) * 2 * sst->block_size); - sst->icarrier = av_malloc(sizeof(*sst->icarrier) * 2 * sst->block_size); - sst->window = av_malloc(sizeof(*sst->window) * 2 * sst->block_size); + block_size = sdr->fm_block_size; + } else + block_size = sdr->am_block_size; + + sst->out_buf = av_mallocz(sizeof(*sst->out_buf) * 2 * block_size); + sst->block = av_malloc(sizeof(*sst-> block) * 2 * block_size); + sst->iblock = av_malloc(sizeof(*sst->iblock) * 2 * block_size); + sst->icarrier = av_malloc(sizeof(*sst->icarrier) * 2 * block_size); + sst->window = av_malloc(sizeof(*sst->window) * 2 * block_size); if (!sst->out_buf || !sst->block || !sst->iblock || !sst->icarrier || !sst->window) return AVERROR(ENOMEM); - avpriv_kbd_window_init(sst->window, sdr->kbd_alpha, sst->block_size); - for(int i = sst->block_size; i < 2 * sst->block_size; i++) { - sst->window[i] = sst->window[2*sst->block_size - i - 1]; + avpriv_kbd_window_init(sst->window, sdr->kbd_alpha, block_size); + for(int i = block_size; i < 2 * block_size; i++) { + sst->window[i] = sst->window[2*block_size - i - 1]; } sst->am_amplitude = 0; @@ -1491,10 +1495,13 @@ int ff_sdr_common_init(AVFormatContext *s) av_log(s, AV_LOG_INFO, "Block size %d\n", sdr->block_size); sdr->block_time = sdr->block_size / (double)sdr->sdr_sample_rate; - sdr->fm_bandwidth_p2 = 18 * 1000; - if (!sdr->fm_block_size_p2) - for (sdr->fm_block_size_p2 = 4; 2ll *sdr->fm_bandwidth_p2 * sdr->block_time > sdr->fm_block_size_p2; sdr->fm_block_size_p2 <<= 1) - ; + sdr->am_bandwidth = 6 * 1000; + sdr->fm_bandwidth = 180 * 1000; + sdr->fm_bandwidth_p2 = 18 * 1000; + + sdr->am_block_size = find_block_size(sdr, sdr->am_bandwidth); + sdr->fm_block_size = find_block_size(sdr, sdr->fm_bandwidth); + sdr->fm_block_size_p2 = find_block_size(sdr, sdr->fm_bandwidth_p2); sdr->windowed_block = av_malloc(sizeof(*sdr->windowed_block) * 2 * sdr->block_size); sdr->block = av_malloc(sizeof(*sdr->block ) * 2 * sdr->block_size); @@ -1509,6 +1516,15 @@ int ff_sdr_common_init(AVFormatContext *s) if (ret < 0) return ret; + ret = av_tx_init(&sdr->am_ifft_ctx, &sdr->am_ifft, AV_TX_FLOAT_FFT, 1, 2*sdr->am_block_size, NULL, 0); + if (ret < 0) + return ret; + + ret = av_tx_init(&sdr->fm_ifft_ctx, &sdr->fm_ifft, AV_TX_FLOAT_FFT, 1, 2*sdr->fm_block_size, NULL, 0); + if (ret < 0) + return ret; + + avpriv_kbd_window_init(sdr->window, sdr->kbd_alpha, sdr->block_size); for(int i = sdr->block_size; i < 2 * sdr->block_size; i++) { @@ -1973,7 +1989,11 @@ int ff_sdr_read_close(AVFormatContext *s) av_freep(&sdr->fm_window_p2); av_tx_uninit(&sdr->fft_ctx); + av_tx_uninit(&sdr->am_ifft_ctx); + av_tx_uninit(&sdr->fm_ifft_ctx); sdr->fft = NULL; + sdr->am_ifft = NULL; + sdr->fm_ifft = NULL; avio_close(sdr->dump_avio);