Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

comm.SampleRateOffset

信号へのサンプル レート オフセットの適用

R2021b 以降

説明

comm.SampleRateOffset System object™ は、サンプル レート オフセットを入力信号に適用します。サンプル レート オフセットを適用することは、ADC のクロック レートを変更することと同じです。

サンプル レート オフセットを信号に適用するには、次のようにします。

  1. comm.SampleRateOffset オブジェクトを作成し、そのプロパティを設定します。

  2. 関数と同様に、引数を指定してオブジェクトを呼び出します。

System object の機能の詳細については、System object とはを参照してください。

作成

説明

sro = comm.SampleRateOffset は、サンプル レート オフセットの System object を作成します。

sro = comm.SampleRateOffset(offset) は、Offset プロパティを入力引数 offset の値に設定します。

sro = comm.SampleRateOffset(Offset=offset) は、Offset プロパティを offset で指定された値に設定します。

プロパティ

すべて展開する

100 万分の 1 (ppm) 単位で表されたサンプル レート オフセット。–1e6 より大きいスカラーとして指定します。

データ型: double

使用法

説明

y = sro(x) は、sro で設定されたサンプル レート オフセットを入力信号に適用し、その結果として得られた信号を返します。

入力引数

すべて展開する

入力信号。スカラー、NS 要素の列ベクトル、または NSNC 列の行列として指定します。NS は、時間サンプルの数です。NC は、チャネル数です。入力信号が行列である場合、各列に対してサンプル レート オフセットが個別に適用されます。

このオブジェクトは可変サイズの入力を受け入れます。オブジェクトがロックされると、各入力チャネルのサイズは変更できますが、チャネルの数は変更できません。詳細については、Variable-Size Signal Support with System Objectsを参照してください。

データ型: double | single
複素数のサポート: あり

出力引数

すべて展開する

出力信号。スカラー、または入力信号 x と同じデータ型のベクトルもしくは行列として返されます。

オブジェクト関数

オブジェクト関数を使用するには、System object を最初の入力引数として指定します。たとえば、obj という名前の System object のシステム リソースを解放するには、次の構文を使用します。

release(obj)

すべて展開する

stepSystem object のアルゴリズムの実行
releaseリソースを解放し、System object のプロパティ値と入力特性の変更を可能にします。
resetSystem object の内部状態のリセット

すべて折りたたむ

パラメーターと入力信号を設定します。

M = 16;                    % Modulation order
offset = 50;               % Parts per million
data = (0:M-1)';           % Input signal
refconst = qammod(data,M); % Reference constellation points

サンプル レート オフセットとコンスタレーション ダイアグラムの System object を作成します。

sro = comm.SampleRateOffset(offset);
constdiagram = comm.ConstellationDiagram( ...
    'ReferenceConstellation',refconst, ...
    'XLimits',[-5 5], ...
    'YLimits',[-5 5], ...
    'Title','Signal with Offset Sample Rate');

ランダム データに 16-QAM 変調を適用してから、変調後の信号にサンプル レート オフセットを適用します。基準コンスタレーション、およびサンプル レート オフセットが適用された信号をプロットします。

modData = qammod(repmat(data,100,1),M);
impairedData = sro(modData);
constdiagram(impairedData) 

30 kHz のシングル トーン正弦波にサンプル レート オフセットを適用します。正および負のサンプル レート オフセットを適用してから、送受信トーン間の周波数の差を計算し、オフセットを確認します。

30 kHz のシングル トーンを生成します。

f = 30e3;
samplerate = 100e3;
src = dsp.SineWave('Frequency',f, ...
    'SampleRate',samplerate, ...
    'SamplesPerFrame',10000, ...
    'ComplexOutput',true);
txsig = src();

トーンの周波数を確認します。

freqtx = samplerate * ...
    (mean(angle(txsig(2:end) ./ txsig(1:end-1)))/(2*pi))
freqtx = 3.0000e+04

送信トーン (txsig) に 20 ppm のサンプル レート オフセットを適用します。サンプル レート オフセットを増加させることは、ADC のクロック レートを増加させることと同じです。

sro = comm.SampleRateOffset(20);
rxsig = sro(txsig);

サンプル レートをオフセットさせてから、受信トーン (rxsig) の周波数を求めます。過渡的な影響があるサンプルをスキップするには、最初の 100 個のサンプルを無視します。

freqrx = samplerate * ...
    (mean(angle(rxsig(101:end) ./ rxsig(100:end-1)))/(2*pi))
freqrx = 2.9999e+04

ADC のクロック レートを増加させると、受信トーンの周波数が減少します。受信トーンの周波数が約 20 ppm 減少したことを示すため、送信トーンの周波数と受信トーンの周波数を比較します。

freqchangeppm = (freqrx-freqtx)/freqtx*1e6
freqchangeppm = -19.9365

送信トーン (txsig) に -30 ppm のサンプル レート オフセットを適用します。サンプル レート オフセットを減少させることは、ADC のクロック レートを減少させることと同じです。

sro = comm.SampleRateOffset(-30);
rxsig = sro(txsig);

サンプル レートをオフセットさせてから、受信トーン (rxsig) の周波数を求めます。過渡的な影響があるサンプルをスキップするには、最初の 100 個のサンプルを無視します。

freqrx = samplerate * ...
    (mean(angle(rxsig(101:end) ./ rxsig(100:end-1)))/(2*pi))
freqrx = 3.0001e+04

ADC のクロック レートを減少させると、受信トーンの周波数が増加します。受信トーンの周波数が約 30 ppm 増加したことを示すため、送信トーンの周波数と受信トーンの周波数を比較します。

freqchangeppm = (freqrx-freqtx)/freqtx*1e6
freqchangeppm = 30.0736

受信機における QPSK 信号に対するサンプル レート オフセットの影響を表示します。

固定プリアンブルとランダム ペイロードが格納されたフレームを送信します。受信機内で、プリアンブルを使用してフレームの開始を検出してから、ペイロードを復調して EVM を測定します。非ゼロの固定値でサンプル レート オフセットを適用すると、フレーム間で EVM が一定の周期で変動します。

コンフィギュレーション パラメーターを初期化し、送信機と受信機のパルス整形フィルター オブジェクトを作成します。

numFrames = 200;
numSymbolsPerFrame = 4096;
preambleLength = 64;
payloadLength = numSymbolsPerFrame - preambleLength; 
modulationOrder = 4;

rolloff = 0.2;
filterSpan = 10;
samplesPerSymbol = 8;
txFilter = comm.RaisedCosineTransmitFilter(RolloffFactor=rolloff, ...
    FilterSpanInSymbols=filterSpan, ...
    OutputSamplesPerSymbol=samplesPerSymbol);
rxFilter = comm.RaisedCosineReceiveFilter(RolloffFactor=rolloff, ...
    FilterSpanInSymbols=filterSpan, ...
    InputSamplesPerSymbol=samplesPerSymbol,DecimationFactor=1);

Gold シーケンスを使用してプリアンブルを作成します。QPSK コンスタレーション内で、Gold シーケンスを 0.7071 + 0.7071i および -0.7071 -0.7071i にマッピングします。

goldSeq = comm.GoldSequence(SamplesPerFrame=preambleLength);
preamble = goldSeq();
preamble(preamble==1)=2; 
preambleModOut = pskmod(preamble,modulationOrder,pi/modulationOrder);

プリアンブル用に、時間領域の基準信号を生成します。

preambleRefDelayed = rxFilter( ...
    txFilter([preambleModOut;zeros(filterSpan,1)]));
preambleRef = preambleRefDelayed( ...
    filterSpan*samplesPerSymbol+(1:samplesPerSymbol*preambleLength));

ランダム ペイロードと送信信号を生成します。

txPayload = pskmod( ...
    randi([0 modulationOrder-1],payloadLength,numFrames), ...
    modulationOrder, ...
    pi/modulationOrder);
txFrames = reshape([repmat(preambleModOut,1,numFrames);txPayload],[],1);
txSig = txFilter([txFrames;zeros(payloadLength,1)]);

0.8 ppm のサンプル レート オフセットを受信信号に適用します。

simulatedSRO = 0.8;
sro = comm.SampleRateOffset(simulatedSRO);
rxSig = rxFilter(sro(txSig));

整合フィルターを使用してプリアンブルを検出します。

matchedFilterResponse = conj(flipud(preambleRef));
matchedFilterOutMag = abs(filter(matchedFilterResponse,1,rxSig));

ピーク位置を求め、最初の 10 個のピークをプロットします。

threshold = max(matchedFilterOutMag)*0.7;
[~, peakLocations] = findpeaks(matchedFilterOutMag, ...
    MinPeakHeight=threshold, ...
    MinPeakDistance=preambleLength*samplesPerSymbol);
plot(matchedFilterOutMag)
title('Matched Filter Output (Magnitude)')
xlabel('Sample')
axis([0 numSymbolsPerFrame*samplesPerSymbol*10 ...
    -0.15*max(matchedFilterOutMag) 1.25*max(matchedFilterOutMag)]);
grid on

フレームを特定し、計算された EVM 値と受信した信号コンスタレーションをプロットして受信データを確認します。サンプル レート オフセットを推定します。より正確に推定するには、送信フレームの数を増やします。

frameDelay = peakLocations - length(preambleRef);
constDiag = comm.ConstellationDiagram(Title='Received Payload', ...
    Position=[20 70 600 600]);
evm = comm.EVM;
evmScope = timescope(TimeUnits='none',TimeSpan=length(frameDelay), ...
    YLabel='EVM (%)',YLimits=[0 15],TimeAxisLabels='none', ...
    Position=[650 120 800 500]);
for i = 1:length(frameDelay)
    rxFrame = rxSig(frameDelay(i) + ...
        (1:samplesPerSymbol:numSymbolsPerFrame*samplesPerSymbol));
    evmScope(evm(txPayload(:,i),rxFrame(preambleLength+1:end)));
    constDiag(rxFrame(preambleLength+1:end));
    pause(0.1)
end

peakSpacings = diff(peakLocations);
nominalPeakSpacing = numSymbolsPerFrame*samplesPerSymbol;
estimatedSRO = (mean(peakSpacings)/nominalPeakSpacing-1)*1e6
estimatedSRO = 0.7668

拡張機能

バージョン履歴

R2021b で導入