| | 1 | function [rc, phiests] = phaseNoiseCorr(r, M, phoffset, blocksize) |
| | 2 | %% Phase noise correction. |
| | 3 | %% Inputs: |
| | 4 | %% - r: Received symbols |
| | 5 | %% - M: Order of constellation, M=4 for QPSK |
| | 6 | %% - phoffset: Phase of the 0th symbol in the constellation |
| | 7 | %% - blocksize: Viterbi-Viterbi algorithm block size |
| | 8 | %% Outputs: |
| | 9 | %% - rc: Symbols with corrected phase |
| | 10 | %% - phiests: Estimates of the phase noise |
| | 11 | |
| | 12 | n = length(r); |
| | 13 | phiests = zeros(1, n); |
| | 14 | rc = zeros(1, n); |
| | 15 | |
| | 16 | for l = 1 : blocksize : n |
| | 17 | block = r(l : min(l + blocksize - 1, n)); |
| | 18 | |
| | 19 | sum_M = sum(block .^ M); |
| | 20 | phi_est = angle(sum_M .* exp(1j * M * phoffset)) / M; |
| | 21 | |
| | 22 | if l > 1 |
| | 23 | %% Phase unwrapping |
| | 24 | phi_prev = phiests(l - 1); |
| | 25 | m = floor(0.5 + (phi_prev - phi_est) * M / (2 * pi)); |
| | 26 | phi_est = phi_est + m * 2 * pi / M; |
| | 27 | end |
| | 28 | |
| | 29 | block = block .* exp(1j * -phi_est); |
| | 30 | rc(l : min(l + blocksize - 1, n)) = block; |
| | 31 | phiests(l : min(l + blocksize - 1, n)) = phi_est; |
| | 32 | end |
| | 33 | end |