1 | % Dieses Script analysiert die Signaleigenschaften wie, snr, thd, sinad, sfdr
|
2 | % und enob.
|
3 | load JitterCorrectedData_0.txt;
|
4 | signal = JitterCorrectedData_0;
|
5 | numberOfSamples = length(signal);
|
6 | samplingRate = 5e9;
|
7 | maxNumberOfHarmonics = 5;
|
8 | harmonicWidth = 9; % breite der Peaks
|
9 |
|
10 | % Spektrum berechen
|
11 | window = blackman(numberOfSamples);
|
12 | signal = signal(:,1);
|
13 | signal = signal .* window;
|
14 | signal = abs(fft(signal));
|
15 | signal = signal(1:numberOfSamples/2);
|
16 |
|
17 | % DC und erste Harmonische suchen. Der grösste Wert, ausser DC, wird als erste
|
18 | % Harmonische gedeutet.
|
19 | levels = signal(1);
|
20 | positions = 0;
|
21 | [level positionH1] = max(signal(2:numberOfSamples/2));
|
22 | positionH1 = positionH1;
|
23 | levels = [levels level];
|
24 | positions = [positions positionH1];
|
25 |
|
26 | % Alle anderen Harmonischen finden.
|
27 | currentPosition = 2 * positionH1;
|
28 | while currentPosition-2 < numberOfSamples/2 && length(levels) < maxNumberOfHarmonics
|
29 | [level lastPosition] = max(signal(currentPosition-2:min(currentPosition+2, numberOfSamples/2)));
|
30 | lastPosition = lastPosition + currentPosition - 3;
|
31 | levels = [levels level];
|
32 | positions = [positions lastPosition];
|
33 | currentPosition = currentPosition + positionH1;
|
34 | end;
|
35 |
|
36 | % Pegels skalieren damit die 1. Harmonische eins beträgt.
|
37 | levelScalingFactor = 1 / levels(2);
|
38 | levels = levels * levelScalingFactor;
|
39 | signal = signal * levelScalingFactor;
|
40 |
|
41 | % Noise vom Signal trennen und Leistungen der Harmonischen berechnen.
|
42 | noiseMasked = signal;
|
43 | harmonicWidth2 = ceil(harmonicWidth/2);
|
44 | noiseMasked(1:harmonicWidth2) = zeros(1,harmonicWidth2)*-1;
|
45 | powers = sum(signal(1:harmonicWidth2).^2);
|
46 | for i=2:length(positions)
|
47 | from = positions(i) - harmonicWidth2 + 2;
|
48 | to = from + harmonicWidth - 1;
|
49 | noiseMasked(from:to) = zeros(1,harmonicWidth)*-1;
|
50 | power = sum(signal(from:to).^2);
|
51 | powers = [powers power];
|
52 | end;
|
53 |
|
54 | % Lehrstellen aus dem noiseMasked Vektor entfernen.
|
55 | noiseContinuous = [];
|
56 | for i=1:length(noiseMasked)
|
57 | if noiseMasked(i) ~= 0
|
58 | noiseContinuous = [noiseContinuous; noiseMasked(i)];
|
59 | end;
|
60 | end;
|
61 |
|
62 | % snr, thd, sinad, sfdr und enob berechnen.
|
63 | noisePower = sum(noiseContinuous.^2);
|
64 | signalPower = powers(2);
|
65 | harmonicsPower = sum(powers(3:end));
|
66 |
|
67 | snr = 10*log10(signalPower/noisePower);
|
68 | thd = 10*log10(harmonicsPower/signalPower);
|
69 | sinad = 10*log10(signalPower/(noisePower+harmonicsPower));
|
70 |
|
71 | [highestHarmonicsLevel highestHarmonicsPosition] = max(levels(3:end));
|
72 | [highestNoiseLevel highestNoisePosition] = max(noiseMasked);
|
73 | sfdr = mag2db(levels(2)/max([highestHarmonicsLevel highestNoiseLevel]));
|
74 | enob = (sinad - 1.76) / 6.02;
|
75 |
|
76 | % Resultate ausgeben.
|
77 | disp(['SNR = ' num2str(snr) ' dB']);
|
78 | disp(['THD = ' num2str(thd) ' dB']);
|
79 | disp(['SINAD = ' num2str(sinad) ' dB']);
|
80 | disp(['SFDR = ' num2str(sfdr) ' dB']);
|
81 | disp(['ENOB = ' num2str(enob) ' bit']);
|
82 |
|
83 | % Plotten.
|
84 | xScalingFactor = samplingRate/numberOfSamples;
|
85 | x = linspace(0,samplingRate/2-xScalingFactor,numberOfSamples/2);
|
86 | plot(x, mag2db(signal));
|
87 | hold on
|
88 | plot(x, mag2db(noiseMasked), 'LineWidth', 3);
|
89 | plot(0, mag2db(levels(1)), 'rs');
|
90 | plot(positions(2)*xScalingFactor, mag2db(levels(2)), 'rv');
|
91 | plot(positions(3:end)*xScalingFactor, mag2db(levels(3:end)), 'ro');
|
92 | plot((highestNoisePosition-1)*xScalingFactor, mag2db(highestNoiseLevel), 'rd');
|
93 | hold off;
|
94 |
|
95 | legendText = num2str(round(mag2db(1/levels(3))));
|
96 | for i=4:length(levels)
|
97 | legendText = [legendText ', ' num2str(round(mag2db(1/levels(i))))];
|
98 | end;
|
99 |
|
100 | legend('signal', ...
|
101 | 'noise', ...
|
102 | ['dc component ' num2str(round(mag2db(1/levels(1)))) ' dBc'], ...
|
103 | 'fundamental signal', ...
|
104 | ['harmonics ' legendText ' dBc'], ...
|
105 | ['highest spur ' num2str(round(mag2db(1/highestNoiseLevel(1)))) ' dBc']);
|
106 |
|
107 | title('Frequency Domain Analysis');
|
108 | xlabel('Frequency [Hz]');
|
109 | ylabel('Level [dB]');
|
110 | set(gca,'YLim',[-80 20]);
|