I am reading about the sampling frequency offset (SFO) of OFDM system. According to my understanding and all sources I read, it can be defined in similar way to the carrier frequency effect (CFO). I mean the effect is added into the signal in time domain as following:

$x[n] = x[n] e^{2\pi j \frac{\Delta f_s}{f_s}n}$

where $n$ is $0,1,2,... N-1$ and $N$ the length of the signal $x$, and $\varepsilon = \frac{\Delta f_s}{f_s}$ is the presented effect of the sampling frequency offset. Here is a source explaining it with a clear way : https://ieeexplore.ieee.org/document/957773

I have also read those sources describing that effect, Offset in Carrier and Timing


What is the difference between (Sample Timing Offset), (Carrier Frequency offset), and (Sampling Frequency Offset)?

I agree with the above description, but what I am looking for is related how to add the effect of sampling frequency offset into the signal, is my way above right? if so, how can I convert the added percentage $\varepsilon$ into ppm? for example if I added $\varepsilon = 0.00001$, what is the equivalent value in ppm?

On the other hand, if the way of adding that effect is not right, could please guide me how to add it with clear steps? However, that was described here How to Emulate Sample Frequency Offset for OFDM in Matlab? but I couldn't understand how to do it in matlab.


Here is the the code where I tried to add the SFO using the Eq. explained here How to Emulate Sample Frequency Offset for OFDM in Matlab? :

clc; clear all; close all;
n_sym = 10;  % The number of symbols
N = 1024;    % The symbole length 
mod = 4;     %the modulation order 
len= n_sym* log2(mod)*N;  %Lenght of whole data (N * Number of symbol* M)

%This part will generate binary vector as per length entered by user
%Mapping of binary data
mapper_out = qammod(bi2de(reshape(data,[],log2(mod))), mod,'UnitAveragePower', true);
% Take the iFFt operation after S/P operation  
sn = ifft(reshape(mapper_out,N,[]));

        for sy = 1 : n_sym
            S_y = sn(:,sy);       %Taking every symbol separatly
            for nn = 1 : length(S_y)-1 
                X_te(nn) = S_y(nn) + (nn*(S_y(nn+1) - S_y(nn)))/200000;   %Doing linear interpolation with 5ppm
            X_te2(:,sy) = [S_y(1); X_te.'];                 %[x[1] x[nn]]
    out = fft(X_te2); 
    out = out(:);  %P/S
figure;plot(real(out),imag(out),'b+');title('constellation with and without  Sampling Frequency Offset'); hold on; 

And, here is the figure with the effect of 5 ppm.

enter image description here

It's ok now, But the question now why do I find a rotation also when I add 1 ppm ? However, that normally should be more similar into the ideal constellation.

  • 3
    $\begingroup$ Your proposed technique only works for a very small set of signals. Sinusoidal signals fall into that category. If you're signal has a nonzero bandwidth you will need to resample it properly to produce the effect of a sampling frequency offset. $\endgroup$
    – hops
    Jun 17, 2022 at 14:54
  • $\begingroup$ @hops could you please explain for me how to produce for example 100 ppm using resampling function? if I have the signal $x(n)$, I can use resample(x(n), Z, Y);, so what should be the value of Z and Y ? $\endgroup$
    – Sajjad
    Jun 18, 2022 at 2:57
  • $\begingroup$ One ppm is one part per million. In principle, that means you should use 1 and 1 million (1e6). Unless I'm mistaken, that is impractical the way that the resample function is implemented. Instead I would look into interpolation techniques. If I get time, I will provide a more detailed answer unless someone else beats me to it. $\endgroup$
    – hops
    Jun 19, 2022 at 0:01
  • $\begingroup$ @hops Ok, please awaiting for your detailed answer to close that question too. thank you in advance. $\endgroup$
    – Sajjad
    Jun 19, 2022 at 2:04
  • $\begingroup$ @hops I used resample(x(n), 20000, 19999); to produce for example 50 ppm, but when I scatterplot the resulted signal the effect is strange, it is not similar into the normal one. I mean the signal is not rotated. $\endgroup$
    – Sajjad
    Jun 20, 2022 at 3:29

1 Answer 1


If $x[n]$ is your OFDM signal in the time domain, and you compute $x[n] e^{j 2\pi \frac{\Delta f_s}{f_s} n}$ then you are simulating a carrier frequency offset of magnitude $\Delta f_s$ given a carrier $f_s$. For an OFDM signal with only one active carrier (SC-FDM), that might be a good enough approximation to carrier frequency offset as well.

If I were you and wanted to learn more about the fundamentals of OFDM, and the effect of sampling frequency offset (SFO) on the OFDM signal. I would write a function that computes the OFDM signal naively and allows me to vary the sampling period.

If you recall, an OFDM signal transforms a stream of symbols $s[n]$ into $N$ parallel streams of symbols $s_k[n] = s[n N + k]$. Let's ignore the computationally efficient transmitter and just try to replicate the signal. For a basic OFDM system (by basic I mean that I will not apply a window or a filter to the system to improve its spectral properties, but you could do that on your own once you understand the basic approach I'm putting forth here), you can form the $N^{\mbox{th}}$ OFDM symbol by multiplying each subcarrier by the complex gain $s_k[n]$ and summing the result. This is done for a length of time equal to your symbol period $T$ plus your cyclic prefix length $T_{CP}$. We can compute the OFDM symbol from time $t=n (T + T_{CP})$ until time $t=(n + 1) (T + T_{CP})$ at any given time instant. Let's define a new variable $\tau=0$ when $t = n (T + T_{CP})$. Now we can compute the OFDM symbol for any instant $0 \leq \tau \leq T + T_{CP}$ as follows $$ y_n(\tau) = \sum_{k=0}^{N-1} s_k[n] e^{j 2\pi \frac{k}{f_s} \tau}. $$ and every value outside the range $0 \leq \tau \leq T + T_{CP}$ is understood to be zero.

This can be used to write a formula for the entire sequence: $$ y(t) = \sum_{n=0}^{M/N-1} y_n(t - n (T + T_{CP})). $$

This formula assumes that the original sequence $s[n]$ was of length $M$. If it wasn't, just zero pad it and the equation still holds. Now, we can sample this at any rate we want by simply computing the samples at $t = m T'_s$, $$ y(m T'_s) = \sum_{n=0}^{M/N-1} y_n(m T'_s - n (T + T_{CP})). $$

So, now we can define a function that computes $y_n(\tau)$ and $y(t)$ and use them to compute your OFDM transmit signal sampled at an arbitrary rate $T'_s$. It is late where I am, so I am going to head to bed. Maybe you can see how to translate this into Matlab already? If so, that is great. If not, I will see what I can do to provide you with a simple example later.

  • $\begingroup$ Thank you for explanation, I get your meaning but I couldn't explore that in matlab. I think I have an issue in how to use the interpolation to resample the time-domain signal. I have updated the question and added the code I built and also included the resulted figure. I get 4 circles instead of one, that's the issue I face !! $\endgroup$
    – Sajjad
    Jun 20, 2022 at 10:16
  • 1
    $\begingroup$ I'm suggesting you sidestep the need to resample by simply constructing the samples you want from the formulas presented. If you are dead set on resampling, look up interpolation techniques. If I get a chance I'll expand my answer. $\endgroup$
    – hops
    Jun 20, 2022 at 18:10
  • $\begingroup$ If you could provide me a simple example for a code following your formulas, that will be really appreciated. $\endgroup$
    – Sajjad
    Jun 21, 2022 at 1:33
  • $\begingroup$ I accepted the answer and opened the updated question here dsp.stackexchange.com/questions/83532/…. If you can help me by a simple code which can do that, I will really appreciate your help. $\endgroup$
    – Sajjad
    Jun 21, 2022 at 9:39
  • 1
    $\begingroup$ I haven't forgotten just got slammed with other things. I'm sorry. I will try to find time this weekend. $\endgroup$
    – hops
    Jul 13, 2022 at 18:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.