DVB-S2 Receiver Using Software-Defined Radio
This example shows how to capture Digital Video Broadcasting Satellite Second Generation (DVB-S2) waveforms using the software-defined radio (SDR) device. The example then shows you how to perform synchronization, demodulation, and decoding of the received waveform, and measure the packet error rate (PER). To generate and transmit DVB-S2 waveforms, see the DVB-S2 Transmitter Using Software-Defined Radio example, and configure your test environment with:
Two SDR platforms connected to the same host computer. You must run two MATLAB® sessions, one for transmission and another for reception.
Two SDR platforms connected to different host computers. You must run a MATLAB session on each, one for transmission and another for reception.
Introduction
For this example, use the comm.SDRuReceiver, basebandReceiver, or sdrrx System object™ to receive data corrupted by over-the-air transmission at a sample rate of 2 Msps. The receiver design consists of matched filtering, symbol timing synchronization, frame synchronization, and carrier synchronization. To decode the physical layer (PL) frames, the receiver recovers the physical layer transmission parameters such as modulation scheme, code rate, and forward error correction (FEC) frame type from the PL header. To regenerate the input bit stream, receiver decodes the baseband (BB) header. Every baseband frame is a concatenation of user packets. The receiver returns the cyclic redundancy check (CRC) status of each packet is returned along with the decoded bits, and then measures the PER.
If you don't have an SDR device to capture the waveform, this example supports importing a file with a captured waveform.
This diagram summarizes the reception process.

For details on receiver design, see the DVB-S2 Link Simulation with RF Impairments and Corrections example.
This example supports these SDRs for capturing the waveform.
ADALM-PLUTO (requires Communications Toolbox™ Support Package for Analog Devices® ADALM-PLUTO Radio)
USRP™ B200/B210/N200/N210/USRP2 (requires Communications Toolbox Support Package for USRP™ Radio)
USRP™ N3xx/X3xx/X4xx (requires Wireless Testbench™ Support Package for NI™ USRP Radios)
Example Setup
To receive a waveform off the air, set useSDR to true. To import a waveform from a MAT file, set useSDR to false.
useSDR =
false;Specify the filename of a precaptured waveform to the fileName variable.
fileName = "capturedDVBS2Waveform.mat";If you set useSDR to true, configure the variables required for SDR reception.
if useSDR rxsim.DeviceName ="B200"; rxsim.RadioCenterFrequency = 915e6; rxsim.RadioGain = 20; end
Initialize Receiver Parameters
At the receiver, you first perform DC offset compensation, followed by automatic gain control (AGC), symbol timing synchronization, and then frame synchronization, in order. The receiver algorithms include coarse and fine frequency impairment correction algorithms. The preferred loop bandwidth for symbol timing and coarse frequency compensation depends on the setting. If the captured signal is buried under noise, you can reduce the loop bandwidth to filter out more noise during acquisition. The number of frames required for the symbol synchronization and frame synchronization depends on the loop bandwidth setting.
Set rxParams.symbSyncLock to ceil(1e5/rxParams.plFrameSize) for signals heavily corrupted by noise. For signals whose SNR is less than 1 dB, set rxParams.frameSyncLock to a value in the range of [5, 15] frames. Set these fields of the rxParams structure for synchronization processing. Set valid values for fecFrame, modCod, Fsamp, and Rsym, for proper capture and validation of the demodulated signal.
fecFrame = "short"; % DVB-S2 FECFrame type modCod = 24; % 32APSK 3/4 Fsamp = 2e6; % Sampling rate in samples per second Rsym = 1e6; % Symbol rate in symbols per second sps = Fsamp/Rsym; rxParams = getRxParams(fecFrame,modCod); rxParams.carrSyncLoopBW = 4e-4; % Coarse frequency estimator loop bandwidth normalized by symbol rate rxParams.symbSyncLoopBW = 1e-4; % Symbol timing synchronizer loop bandwidth normalized by symbol rate rxParams.symbSyncLock = 1; % Number of frames required for symbol timing error convergence rxParams.frameSyncUsePilots = modCod < 6; rxParams.sps = sps;
Capture DVB-S2 Waveform Using SDR
Discover radio(s) connected to your computer. This example uses the first SDR radio found using the rxsim.DeviceName and findsdru function. Check if the radio is available and record the radio type. Initialize sdrrx, basebandReceiver, or comm.SDRuReceiver System object. Set the platform, center frequency, sample rate, gain, and other relevant properties. Receive the DVB-S2 waveform over-the-air using the SDR device.
numFrames = 50; % Number of PL frames to capture enableBurstMode = true; numFramesInBurst = numFrames; if useSDR if matches(rxsim.DeviceName,"Pluto") radioRx = sdrrx("Pluto"); radioRx.RadioID = "usb:0"; radioRx.CenterFrequency = rxsim.RadioCenterFrequency; radioRx.BasebandSampleRate = Fsamp; radioRx.GainSource = "Manual"; elseif matches(rxsim.DeviceName,"N3xx/X3xx/X410") savedRadioConfigurations = radioConfigurations; savedRadioConfigurationNames = [string({savedRadioConfigurations.Name})]; % Specify the index of the saved radio configuration to be utilized % as the receiver radioIndex = 1; radio = savedRadioConfigurationNames(radioIndex); if ~exist("bbrx","var") radioRx = basebandReceiver(radio); end radioRx.RadioGain = rxsim.RadioGain; radioRx.SampleRate = Fsamp; radioRx.CaptureDataType = "double"; radioRx.CenterFrequency = rxsim.RadioCenterFrequency; else connectedRadios = findsdru; rIdx = find(strcmp(rxsim.DeviceName,{connectedRadios.Platform})); if strcmp(connectedRadios(rIdx).Status,"Success") usrpRx.Platform = connectedRadios(rIdx).Platform; switch usrpRx.Platform case {'B200','B210'} usrpRx.SerialNum = connectedRadios(rIdx).SerialNum; usrpRx.MasterClockRate = 20e6; case 'N200/N210/USRP2' usrpRx.IPAddress = connectedRadios(rIdx).IPAddress; usrpRx.MasterClockRate = 100e6; otherwise error("%s\n","Unsupported USRP device"); end end switch usrpRx.Platform case {'B200','B210'} radioRx = comm.SDRuReceiver( ... Platform = usrpRx.Platform, ... SerialNum = usrpRx.SerialNum, ... CenterFrequency = rxsim.RadioCenterFrequency, ... MasterClockRate = usrpRx.MasterClockRate, ... DecimationFactor = usrpRx.MasterClockRate/Fsamp); case 'N200/N210/USRP2' radioRx = comm.SDRuReceiver( ... Platform = usrpRx.Platform, ... IPAddress = usrpRx.IPAddress, ... CenterFrequency = rxsim.RadioCenterFrequency, ... MasterClockRate = usrpRx.MasterClockRate, ... DecimationFactor = usrpRx.MasterClockRate/Fsamp); end end if matches(rxsim.DeviceName,"N3xx/X3xx/X410") rxDuration = numFrames*(rxParams.plFrameSize*sps)/radioRx.SampleRate; [rxIn,~] = capture(radioRx,milliseconds(rxDuration*1e3)); else radioRx.Gain = rxsim.RadioGain; % In dB radioRx.OutputDataType = "double"; radioRx.SamplesPerFrame = rxParams.plFrameSize*sps; if enableBurstMode radioRx.EnableBurstMode = enableBurstMode; radioRx.NumFramesInBurst = numFramesInBurst; end disp(radioRx) rxLength = numFrames*radioRx.SamplesPerFrame; rxIn = zeros(rxLength,1) + 1i*zeros(rxLength,1); for l = 1:numFrames [rxIn((l-1)*radioRx.SamplesPerFrame+1:l*radioRx.SamplesPerFrame),numSamps,overrun] = radioRx(); if overrun && ~enableBurstMode fprintf("Overrun detected in loop #%d\n",l); end end release(radioRx); end
Import Waveform from File
This section loads the DVB-S2 data from a MAT file.
else fprintf("Reading DVB-S2 IQ data from a captured file\n") load(fileName) end
Reading DVB-S2 IQ data from a captured file
rxIn = rxIn./(max(abs(rxIn))); rxParams.initialTimeFreqSync = numFrames; rxParams.totalSyncFrames = numFrames;
Visualize Received Waveform
Visualize the spectrum of the captured waveform and its constellation.
specAn = spectrumAnalyzer(SampleRate=Fsamp); specAn(rxIn(1:100000));

rxConst = comm.ConstellationDiagram(Title="Received data", ... AxesLimits=[-1 1], ... ShowReferenceConstellation=false, ... SamplesPerSymbol=rxParams.sps); rxConst(rxIn(1:10000))

Initialize Receiver Processing System Objects
Create a time and coarse frequency synchronization System object by using the HelperDVBS2TimeFreqSynchronizer helper object. Initialize the comm.AGC, dsp.DCBlocker, and comm.ConstellationDiagram System objects.
% Create symbol timing and coarse frequency synchronization System object % by using HelperDVBS2Synchronizer helper object timeFreqSync = HelperDVBS2Synchronizer( ... CarrSyncLoopBW = rxParams.carrSyncLoopBW, ... SymbSyncLoopBW = rxParams.symbSyncLoopBW, ... SamplesPerSymbol = sps, ... DataFrameSize = rxParams.xFecFrameSize); % Create frame synchronization System object by using % HelperDVBS2FrameSynchronizer helper object if strcmp(fecFrame,"normal") numPilotBlks = 8; else numPilotBlks = 2; end frameSync = HelperDVBS2FrameSynchronizer( ... UsePilots = rxParams.frameSyncUsePilots, ... PLFrameLength = rxParams.plFrameSize, ... NumOfPilotBlocks = numPilotBlks); agc = comm.AGC(AveragingLength=2000,AdaptationStepSize = 0.001); dcBlock = dsp.DCBlocker(Algorithm="FIR",Length=2000); syncConst = comm.ConstellationDiagram(Title="Synchronized data", ... AxesLimits=[-2 2], ... ShowReferenceConstellation = false); coarseCFOEstMinFrames = 2; %floor(4/(rxParams.carrSyncLoopBW*length(rxParams.pilotInd))); % Initialize error computing and data indexing parameters [numFramesLost,pktsErr,bitsErr,pktsRec,dataStInd,stIdx] = deal(0); % Variables for storing symbol synchronization output length, estimated coarse % frequency offset, average coarse frequency offset, and % starting index for every PL frame [symSyncOutLen,cCFOEst,cCFOEstMean,syncIndex] = deal([]); % Boolean variable that indicates whether the simulation has reached the last frame, % and whether coarse frequency offset tracking has converged. [isLastFrame,isCoarseFreqLocked] = deal(false); % Counter to track the number of PL frames used for fine frequency % offset estimation numFreqEst = 0; plFrameSize = rxParams.plFrameSize; % Initialize FSM variables % Use the variables to denote current state of receiver % STR - Symbol Timing Recovery, FS - Frame Synchronization, % CFL - Coarse Frequency Loop, FFS - Fine Frequency Synchronization, % PS - Phase Synchronization, FPS - Fine Phase Synchronization % PLR - PL Frame Recovery stateVal = num2cell([1 2 3 4 5 6 7]); [STR, FS, CFL, FFS, PS, FPS, PLR] = stateVal{:}; state = STR; activeState = [true false false false false false false]'; headerDataDisplayCounter = 0; streamFormat = "packetized"; rxParams.fineFreqEstTemp = zeros(numFrames,1);
Synchronization and Data Recovery
To synchronize the received data and recover the input bit stream, process the distorted DVB-S2 waveform samples one frame at a time by following these steps.
Apply DC offset compensation to remove any DC components.
Apply AGC to normalize the input signal amplitude.
Apply matched filtering, outputting at a rate of 2 samples per symbol.
Apply symbol timing synchronization using the Gardner timing error detector (TED) with an output generated at the symbol rate. The Gardner TED is not data-aided, so you can perform before carrier synchronization.
Apply frame synchronization to detect the start of frame and to identify the pilot positions.
Estimate and apply coarse frequency offset correction.
Estimate and apply fine frequency offset correction.
Estimate and compensate for residual carrier frequency and phase noise.
Decode the PL header and compute the transmission parameters.
Demodulate and decode the PL frames.
Perform CRC check on the BB header. If the check passes, recover the header parameters.
Regenerate the input stream of data or packets from BB frames.
while stIdx < length(rxIn) % Use one DVB-S2 PL frame for each iteration. endIdx = stIdx + rxParams.plFrameSize*rxParams.sps; % In the last iteration, consider all the remaining samples in the received % waveform. isLastFrame = endIdx > length(rxIn); endIdx(isLastFrame) = length(rxIn); rxData = rxIn(stIdx+1:endIdx); % Apply DC offset compensation, AGC, matched filtering, symbol timing synchronization, frame % synchronization, and coarse frequency offset compensation. syncIn = dcBlock(rxData); syncIn = agc(syncIn)/sps; [coarseFreqSyncOut,phEst] = timeFreqSync(syncIn,syncIndex,isCoarseFreqLocked); coarseCFOEst = diff(phEst(1:sps:end)/(2*pi)); cCFOEst = [cCFOEst;coarseCFOEst]; switch state case STR symSyncOutLen = [symSyncOutLen;length(coarseFreqSyncOut)]; if any(abs(diff(symSyncOutLen(1:rxParams.frameCount-1))) > 5) error("Symbol timing synchronization failed. The loop will not " + ... "converge. No frame will be recovered. Update the symbSyncLoopBW " + ... "parameter according to the EsNo setting for proper loop convergence."); end if rxParams.frameCount >= rxParams.symbSyncLock state = FS; fprintf("\nPerforming frame synchronization ...\n"); end case FS activeState(FS) = true; if ~isempty(syncIndex) state = CFL; fprintf("\nPerforming coarse frequency synchronization ...\n"); end case CFL activeState(CFL) = true; cCFOEstMean=[cCFOEstMean;mean(coarseCFOEst)]; %#ok<*AGROW> % Check for FLL convergence based on estimated coarse frequency % offset values across frames if length(cCFOEstMean) > coarseCFOEstMinFrames diffVal = diff(abs(cCFOEstMean)); if all(abs(diffVal(end-1:end)) < 1e-2) isCoarseFreqLocked = true; state = FFS; figure; plot(cCFOEst*Rsym) grid on ylabel("Estimated coarse frequency offset (Hz)"); xlabel("Data Samples") title("Coarse Frequency Locked Loop Characteristics") fprintf("\nPerforming fine frequency synchronization ...\n"); elseif rxParams.frameCount == numFrames fprintf("%s\n",["Coarse frequency error estimation has either failed or it did not meet " ... "convergence criteria. Try analyzing the coarse FLL characteristics from the displayed figure." ... "If the CFO estimation (FLL tracking) across samples looks noisy but trends towards the correct estimation, " ... "try reducing carrSyncLoopBW and increasing coarseCFOEstMinFrames. Ensure that numFrames provides " + ... "enough frames for processing. If the CFO estimation across samples is incorrect, examine syncIndex output. " + ... "Since FLL uses pilots, syncIndex must be accurate for proper estimation"]); end end case FFS activeState(FFS) = true; if rxParams.fineFreqCorrVal ~= 0 rxParams.fineFreqEstTemp(1:end-1) = rxParams.fineFreqEstTemp(2:end); rxParams.fineFreqEstTemp(end) = freqEst; numFreqEst = numFreqEst+1; end % Check whether the normalized fine frequency offset estimation % has converged to within an order of 1e–5. if numFreqEst>=5 cg = abs(diff(rxParams.fineFreqEstTemp(end-numFreqEst+1:end))); if all(cg(end-2:end) < 1e-4) state = PS; activeState(FFS) = false; fprintf("Estimated carrier frequency offset in Hz = %f\n",(coarseCFOEst(end)+freqEst).*Rsym); fprintf("\nPerforming phase synchronization ...\n"); elseif rxParams.frameCount == numFrames fprintf("%s\n","Fine frequency error estimation has either failed or it did not meet " + ... "convergence criteria. Analyze rxParams.fineFreqEstTemp to check whether the value " + ... "of (coarseCFOEst(end) + freqEst) * Rsym is approaching the actual CFO. If the " + ... "estimation is trending in the right direction but the simulation has reached the final frame, " + ... "increase numFrames to allow more frames for convergence. If the estimation " + ... "appears incorrect, examine the coarse FLL estimation. After coarse correction, the residual " + ... "normalized CFO should be less than 2% of the symbol rate."); end end case PS activeState(PS) = true; if rxParams.prevPhaseEst ~= 0 state = PLR; rxParams.totalSyncFrames = rxParams.frameCount; fprintf("\nPerforming PL frame demodulation and decoding ...\n"); end case PLR activeState(PLR) = true; end if ~isempty(rxParams.cfBuffer) fineFreqIn = [rxParams.cfBuffer; coarseFreqSyncOut(1:rxParams.plFrameSize-length(rxParams.cfBuffer))]; end if ~isempty(syncIndex) rxParams.cfBuffer = coarseFreqSyncOut(syncIndex:end); end if activeState(FS) syncIndex = frameSync(coarseFreqSyncOut); end if activeState(FFS) rxParams.fineFreqCorrVal = HelperDVBS2FineFreqEst( ... fineFreqIn(rxParams.pilotInd),rxParams.numPilots, ... rxParams.refPilots,rxParams.fineFreqCorrVal); % Normalize the frequency estimate by the input symbol rate % freqEst = angle(R)/(pi*(N+1)), where N (18) is the number of elements % used to compute the mean of auto correlation (R) in % HelperDVBS2FineFreqEst. freqEst = angle(rxParams.fineFreqCorrVal)/(pi*(19)); end if activeState(PS) % Generate the symbol indices using frameCount and plFrameSize. % Subtract 2 from the rxParams.frameCount because the buffer used to get one % PL frame introduces a delay of one to the count. ind = (rxParams.frameCount-2)*plFrameSize:(rxParams.frameCount-1)*plFrameSize-1; phErr = exp(-1j*2*pi*freqEst*ind); fineFreqOut = fineFreqIn.*phErr(:); % Estimate the phase error estimation by using the HelperDVBS2PhaseEst % helper function. [phEstRes,prevPhaseEstTemp] = HelperDVBS2PhaseEst( ... fineFreqOut,rxParams.refPilots,rxParams.prevPhaseEst,rxParams.pilotInd); if rxParams.prevPhaseEst ~= 0 phaseCompOut = HelperDVBS2PhaseCompensate(rxParams.ffBuffer, ... rxParams.pilotEst,rxParams.pilotInd,phEstRes(2)); end rxParams.ffBuffer = fineFreqOut; rxParams.pilotEst = phEstRes; rxParams.prevPhaseEst = prevPhaseEstTemp; end if activeState(PLR) % Data valid signal % Decode the PL header by using the dvbsPLHeaderRecover % function syncOut = phaseCompOut/sqrt(mean(abs(phaseCompOut).^2)); rxPLHeader = syncOut(1:90); phyParams = dvbsPLHeaderRecover(rxPLHeader,Mode="DVB-S2/S2X regular"); M = phyParams.ModulationOrder; R = eval(phyParams.LDPCCodeIdentifier); fecFrame = phyParams.FECFrameLength; pilotStat = phyParams.HasPilots; xFECFrameLen = fecFrame/log2(M); % Validate the decoded PL header. if M ~= rxParams.modOrder || abs(R-rxParams.codeRate) > 1e-3 || ... fecFrame ~= rxParams.cwLen || ~pilotStat fprintf("Pl frame number %d , %s\n",rxParams.frameCount, ... "PL header decoding failed") else % Demodulation and decoding if ~headerDataDisplayCounter fprintf("%s\n","Physical layer header detection summary") detPLParams = generatePLParamsTable(M,R,fecFrame,pilotStat) headerDataDisplayCounter = headerDataDisplayCounter + 1; end rxFrame = syncOut(1:plFrameSize); % Estimate noise variance by using % HelperDVBS2NoiseVarEstimate helper function. nVar = HelperDVBS2NoiseVarEstimate(rxFrame,rxParams.pilotInd,... rxParams.refPilots,false); snr_dB = 10*log10(1/nVar); fprintf("PL frame number = %d\n",rxParams.frameCount) fprintf("Estimated SNR in dB = %f\n",snr_dB) % Recover the input bit stream by using % dvbs2BitRecover function % Recover the input bit stream by using % dvbs2BitRecover function [decBitsTemp,isFrameLost,pktCRC] = dvbs2BitRecover(rxFrame,nVar); decBits = decBitsTemp{:}; if ~isLastFrame pktsErr = pktsErr + numel(pktCRC{:}) - sum(pktCRC{:}); pktsRec = pktsRec + numel(pktCRC{:}); end if ~isFrameLost fprintf("%s\n","BB header decoding passed") if isempty(pktCRC{1}) streamFormat = "continuous"; else streamFormat = "packetized"; end else fprintf("%s\n","BB header decoding failed") end % Compute the number of frames lost. Consider CRC failure of the baseband header % as a frame loss. numFramesLost = isFrameLost + numFramesLost; fprintf("Total number of frames lost = %1d\n",numFramesLost) end end stIdx = endIdx; rxParams.frameCount = rxParams.frameCount + 1; end
Performing frame synchronization ...
Performing coarse frequency synchronization ...

Performing fine frequency synchronization ...
Estimated carrier frequency offset in Hz = 3282.922363
Performing phase synchronization ...
Performing PL frame demodulation and decoding ...
Physical layer header detection summary
detPLParams=1×4 table
Modulation Code Rate FEC Frame Pilot Status
__________ _________ _________ ____________
"32APSK" "3/4" "short" "true"
PL frame number = 16
Estimated SNR in dB = 14.958315
BB header decoding passed
Total number of frames lost = 0
PL frame number = 17
Estimated SNR in dB = 15.665258
BB header decoding passed
Total number of frames lost = 0
PL frame number = 18
Estimated SNR in dB = 14.788181
BB header decoding passed
Total number of frames lost = 0
PL frame number = 19
Estimated SNR in dB = 15.360274
BB header decoding passed
Total number of frames lost = 0
PL frame number = 20
Estimated SNR in dB = 16.706640
BB header decoding passed
Total number of frames lost = 0
Visualization and Error Logs
Plot the constellation of the synchronized data and compute PER.
if exist('rxFrame','var') scatterplot(rxFrame) end

% Error metrics display % For GS and TS packetized streams if strcmp(streamFormat,"packetized") if pktsRec == 0 fprintf("All frames are lost. No packets are retrieved from BB frames.") else per = pktsErr/pktsRec; fprintf("PER: %1.2e\n",per) end end
PER: 0.00e+00
Further Exploration
Transmit a DVB-S2 waveform by using the
DVB-S2 Transmitter Using Software-Defined Radioexample. You can then decode the waveform using this example. In the companion example, try changing theFECFrameandMODCOD, and observe the detected PL parameters decoded in this example.For details on how to configure the synchronization parameters of the
rxParamsfor other configurations, see the Further Exploration section of DVB-S2 Link Simulation with RF Impairments and Corrections example.
SDR Troubleshooting
ADALM-PLUTO Radio Common Problems and Fixes (Communications Toolbox Support Package for Analog Devices ADALM-Pluto Radio)
USRP Radio Common Problems and Fixes
Supporting Files
The example uses these helper functions and data file:
HelperDVBS2Synchronizer.m: Perform matched filtering, symbol timing synchronization, frame synchronization, and coarse frequency estimation and correctionHelperDVBS2FrameSynchronizer.m: Perform frame synchronization and detect the start of frameHelperDVBS2FineFreqEst.m: Estimate fine frequency offsetHelperDVBS2PhaseEst.m: Estimate carrier phase offsetHelperDVBS2PhaseCompensate.m: Perform carrier phase compensationHelperDVBS2NoiseVarEstimate.m: Estimate noise variance of received datacapturedDVBS2Waveform.mat: DVB-S2 IQ data captured usingDVB-S2 Transmitter Using Software-Defined Radioexample and SDRs.
References
ETSI Standard EN 302 307-1 V1.4.1(2014-11). Digital Video Broadcasting (DVB); Second Generation Framing Structure, Channel Coding and Modulation Systems for Broadcasting, Interactive Services, News Gathering and other Broadband Satellite Applications (DVB-S2).
ETSI Standard TR 102 376-1 V1.2.1(2015-11). Digital Video Broadcasting (DVB); Implementation Guidelines for the Second Generation System for Broadcasting, Interactive Services, News Gathering and other Broadband Satellite Applications (DVB-S2).
Local Functions
function rxParams = getRxParams(fecFrame,modCod) % Receiver parameters generation [modOrder,codeRate,cwLen] = satcom.internal.dvbs.getS2PHYParams(modCod,fecFrame); dataLen = cwLen/log2(modOrder); % Pilot sequence and indices generation slotLen = 90; pilotBlkFreq = 16; % In slots numPilotBlks = floor(dataLen/(slotLen*pilotBlkFreq)); if floor(dataLen/(slotLen*16)) == dataLen/(slotLen*pilotBlkFreq) numPilotBlks = numPilotBlks - 1; end pilotLen = numPilotBlks*36; % one pilot block contains 36 pilot symbols frameSize = dataLen + pilotLen + slotLen; plScrambIntSeq = satcom.internal.dvbs.plScramblingIntegerSequence(0); cMap = [1 1j -1 -1j].'; cSeq = cMap(plScrambIntSeq+1); [~, pilotInd] = satcom.internal.dvbs.pilotBlock(numPilotBlks); rxParams.plFrameSize = frameSize; rxParams.xFecFrameSize = dataLen; rxParams.modOrder = modOrder; rxParams.codeRate = codeRate; rxParams.cwLen = cwLen; rxParams.frameCount = 1; rxParams.numPilots = numPilotBlks; rxParams.pilotInd = pilotInd + slotLen; rxParams.refPilots = (1+1j)/sqrt(2).*cSeq(pilotInd); rxParams.cfBuffer = []; rxParams.ffBuffer = complex(zeros(frameSize, 1)); rxParams.pilotPhEst = zeros(numPilotBlks+1, 1); [rxParams.prevPhaseEst, rxParams.fineFreqCorrVal] = deal(0); rxParams.syncIndex = 1; end function tbl = generatePLParamsTable(M,R,fecFrame,pilotStat) modScheme = ["QPSK" "8PSK" "16APSK" "32APSK"]; Modulation = modScheme(log2(M)-1); [n,d] = rat(R); CodeRate = strcat(string(n),"/",string(d)); if fecFrame == 64800 FECFrame = "normal"; else FECFrame = "short"; end if pilotStat PilotStatus = "true"; else PilotStatus = "false"; end tbl = table(Modulation,CodeRate,FECFrame,PilotStatus); tbl = renamevars(tbl,["Modulation","CodeRate","FECFrame", "PilotStatus"],["Modulation","Code Rate","FEC Frame", "Pilot Status"]); end
