18051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfunction rtpAnalyze( input_file )
28051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%RTP_ANALYZE Analyze RTP stream(s) from a txt file
38051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   The function takes the output from the command line tool rtp_analyze
48051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   and analyzes the stream(s) therein. First, process your rtpdump file
58051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   through rtp_analyze (from command line):
68051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   $ out/Debug/rtp_analyze my_file.rtp my_file.txt
78051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   Then load it with this function (in Matlab):
88051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   >> rtpAnalyze('my_file.txt')
98051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
108051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
118051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%
128051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% Use of this source code is governed by a BSD-style license
138051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% that can be found in the LICENSE file in the root of the source
148051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% tree. An additional intellectual property rights grant can be found
158051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% in the file PATENTS.  All contributing project authors may
168051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% be found in the AUTHORS file in the root of the source tree.
178051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
188051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin[SeqNo,TimeStamp,ArrTime,Size,PT,M,SSRC] = importfile(input_file);
198051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
20d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundin%% Filter out RTCP packets.
21d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundin% These appear as RTP packets having payload types 72 through 76.
22d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinix = not(ismember(PT, 72:76));
23d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinfprintf('Removing %i RTCP packets\n', length(SeqNo) - sum(ix));
24d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinSeqNo = SeqNo(ix);
25d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinTimeStamp = TimeStamp(ix);
26d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinArrTime = ArrTime(ix);
27d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinSize = Size(ix);
28d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinPT = PT(ix);
29d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinM = M(ix);
30d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundinSSRC = SSRC(ix);
31d84dcbd2ecd28bd57e1f17bc00dc6390cbbd0cdahenrik.lundin
3260508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Find streams.
338051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin[uSSRC, ~, uix] = unique(SSRC);
348051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
3560508f8621ae9188871c68a7317413a274071550Henrik Lundin% If there are multiple streams, select one and purge the other
3660508f8621ae9188871c68a7317413a274071550Henrik Lundin% streams from the data vectors. If there is only one stream, the
3760508f8621ae9188871c68a7317413a274071550Henrik Lundin% vectors are good to use as they are.
388051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinif length(uSSRC) > 1
398051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    for i=1:length(uSSRC)
408051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        uPT = unique(PT(uix == i));
418051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        fprintf('%i: %s (%d packets, pt: %i', i, uSSRC{i}, ...
428051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin            length(find(uix==i)), uPT(1));
438051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        if length(uPT) > 1
448051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin            fprintf(', %i', uPT(2:end));
458051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        end
468051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        fprintf(')\n');
478051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    end
488051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    sel = input('Select stream number: ');
498051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    if sel < 1 || sel > length(uSSRC)
508051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        error('Out of range');
518051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    end
5260508f8621ae9188871c68a7317413a274071550Henrik Lundin    ix = find(uix == sel);
5360508f8621ae9188871c68a7317413a274071550Henrik Lundin    % This is where the data vectors are trimmed.
548051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    SeqNo = SeqNo(ix);
558051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    TimeStamp = TimeStamp(ix);
568051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    ArrTime = ArrTime(ix);
578051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    Size = Size(ix);
588051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    PT = PT(ix);
598051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    M = M(ix);
608051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    SSRC = SSRC(ix);
618051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
628051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
6360508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Unwrap SeqNo and TimeStamp.
648051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSeqNoUW = maxUnwrap(SeqNo, 65535);
658051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinTimeStampUW = maxUnwrap(TimeStamp, 4294967295);
668051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
6760508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Generate some stats for the stream.
688051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Statistics:\n');
698051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('SSRC: %s\n', SSRC{1});
708051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinuPT = unique(PT);
718051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinif length(uPT) > 1
728051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    warning('This tool cannot yet handle changes in codec sample rate');
738051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
748051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Payload type(s): %i', uPT(1));
758051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinif length(uPT) > 1
768051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    fprintf(', %i', uPT(2:end));
778051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
788051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('\n');
798051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Packets: %i\n', length(SeqNo));
8076381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinSortSeqNo = sort(SeqNoUW);
818051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Missing sequence numbers: %i\n', ...
8276381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin    length(find(diff(SortSeqNo) > 1)));
8376381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinfprintf('Duplicated packets: %i\n', length(find(diff(SortSeqNo) == 0)));
8476381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinreorderIx = findReorderedPackets(SeqNoUW);
8576381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinfprintf('Reordered packets: %i\n', length(reorderIx));
868051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundintsdiff = diff(TimeStampUW);
878051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundintsdiff = tsdiff(diff(SeqNoUW) == 1);
888051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin[utsdiff, ~, ixtsdiff] = unique(tsdiff);
898051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Common packet sizes:\n');
908051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfor i = 1:length(utsdiff)
918051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    fprintf('  %i samples (%i%%)\n', ...
928051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        utsdiff(i), ...
9360508f8621ae9188871c68a7317413a274071550Henrik Lundin        round(100 * length(find(ixtsdiff == i))/length(ixtsdiff)));
948051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
958051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
9660508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Trying to figure out sample rate.
978051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfs_est = (TimeStampUW(end) - TimeStampUW(1)) / (ArrTime(end) - ArrTime(1));
988051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfs_vec = [8, 16, 32, 48];
998051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfs = 0;
1008051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfor f = fs_vec
1018051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    if abs((fs_est-f)/f) < 0.05  % 5% margin
1028051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        fs = f;
1038051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        break;
1048051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    end
1058051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
1068051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinif fs == 0
1078051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    fprintf('Cannot determine sample rate. I get it to %.2f kHz\n', ...
1088051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        fs_est);
1098051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    fs = input('Please, input a sample rate (in kHz): ');
1108051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinelse
1118051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    fprintf('Sample rate estimated to %i kHz\n', fs);
1128051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
1138051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1148051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSendTimeMs = (TimeStampUW - TimeStampUW(1)) / fs;
1158051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1168051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Stream duration at sender: %.1f seconds\n', ...
1178051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    (SendTimeMs(end) - SendTimeMs(1)) / 1000);
1188051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1198051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Stream duration at receiver: %.1f seconds\n', ...
1208051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    (ArrTime(end) - ArrTime(1)) / 1000);
1218051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1228051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Clock drift: %.2f%%\n', ...
1238051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    100 * ((ArrTime(end) - ArrTime(1)) / ...
1248051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    (SendTimeMs(end) - SendTimeMs(1)) - 1));
1258051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1268051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Sent average bitrate: %i kbps\n', ...
1278051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    round(sum(Size) * 8 / (SendTimeMs(end)-SendTimeMs(1))));
12860508f8621ae9188871c68a7317413a274071550Henrik Lundin
1298051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfprintf('Received average bitrate: %i kbps\n', ...
1308051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    round(sum(Size) * 8 / (ArrTime(end)-ArrTime(1))));
1318051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
13260508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Plots.
1338051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundindelay = ArrTime - SendTimeMs;
1348051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundindelay = delay - min(delay);
13576381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundindelayOrdered = delay;
13676381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundindelayOrdered(reorderIx) = nan;  % Set reordered packets to NaN.
13776381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundindelayReordered = delay(reorderIx);  % Pick the reordered packets.
13876381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinsendTimeMsReordered = SendTimeMs(reorderIx);
13976381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin
14076381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin% Sort time arrays in packet send order.
14176381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin[~, sortix] = sort(SeqNoUW);
14276381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinSendTimeMs = SendTimeMs(sortix);
14376381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinSize = Size(sortix);
14476381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundindelayOrdered = delayOrdered(sortix);
14576381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin
1468051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfigure
14776381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinplot(SendTimeMs / 1000, delayOrdered, ...
14876381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin    sendTimeMsReordered / 1000, delayReordered, 'r.');
1498051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinxlabel('Send time [s]');
1508051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinylabel('Relative transport delay [ms]');
1518051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundintitle(sprintf('SSRC: %s', SSRC{1}));
1528051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1538051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSendBitrateKbps = 8 * Size(1:end-1) ./ diff(SendTimeMs);
1548051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfigure
1558051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinplot(SendTimeMs(1:end-1)/1000, SendBitrateKbps);
1568051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinxlabel('Send time [s]');
1578051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinylabel('Send bitrate [kbps]');
1588051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
1598051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
16076381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin%% Subfunctions.
16176381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin
16276381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin% findReorderedPackets returns the index to all packets that are considered
16376381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin% old compared with the largest seen sequence number. The input seqNo must
16476381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin% be unwrapped for this to work.
16576381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinfunction reorderIx = findReorderedPackets(seqNo)
16676381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinlargestSeqNo = seqNo(1);
16776381d921f817888d9c050d5f2fcbe3de412e0d7Henrik LundinreorderIx = [];
16876381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinfor i = 2:length(seqNo)
16976381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin    if seqNo(i) < largestSeqNo
17076381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin        reorderIx = [reorderIx; i]; %#ok<AGROW>
17176381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin    else
17276381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin        largestSeqNo = seqNo(i);
17376381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin    end
17476381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinend
17576381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundinend
17676381d921f817888d9c050d5f2fcbe3de412e0d7Henrik Lundin
17760508f8621ae9188871c68a7317413a274071550Henrik Lundin%% Auto-generated subfunction.
1788051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfunction [SeqNo,TimeStamp,SendTime,Size,PT,M,SSRC] = ...
1798051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    importfile(filename, startRow, endRow)
1808051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%IMPORTFILE Import numeric data from a text file as column vectors.
1818051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   [SEQNO,TIMESTAMP,SENDTIME,SIZE,PT,M,SSRC] = IMPORTFILE(FILENAME) Reads
1828051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   data from text file FILENAME for the default selection.
1838051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%
1848051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   [SEQNO,TIMESTAMP,SENDTIME,SIZE,PT,M,SSRC] = IMPORTFILE(FILENAME,
1858051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   STARTROW, ENDROW) Reads data from rows STARTROW through ENDROW of text
1868051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   file FILENAME.
1878051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%
1888051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% Example:
1898051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   [SeqNo,TimeStamp,SendTime,Size,PT,M,SSRC] =
1908051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   importfile('rtpdump_recv.txt',2, 123);
1918051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%
1928051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%    See also TEXTSCAN.
1938051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1948051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% Auto-generated by MATLAB on 2015/05/28 09:55:50
1958051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
1968051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Initialize variables.
1978051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinif nargin<=2
1988051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    startRow = 2;
1998051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    endRow = inf;
2008051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
2018051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2028051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Format string for each line of text:
2038051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column1: double (%f)
2048051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column2: double (%f)
2058051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column3: double (%f)
2068051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column4: double (%f)
2078051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column5: double (%f)
2088051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column6: double (%f)
2098051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%   column7: text (%s)
2108051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% For more information, see the TEXTSCAN documentation.
2118051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinformatSpec = '%5f%11f%11f%6f%6f%3f%s%[^\n\r]';
2128051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2138051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Open the text file.
2148051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinfileID = fopen(filename,'r');
2158051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2168051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Read columns of data according to format string.
2178051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% This call is based on the structure of the file used to generate this
2188051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% code. If an error occurs for a different file, try regenerating the code
2198051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% from the Import Tool.
2208051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundindataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, ...
2218051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    'Delimiter', '', 'WhiteSpace', '', 'HeaderLines', startRow(1)-1, ...
2228051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    'ReturnOnError', false);
2238051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfor block=2:length(startRow)
2248051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    frewind(fileID);
2258051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    dataArrayBlock = textscan(fileID, formatSpec, ...
2268051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        endRow(block)-startRow(block)+1, 'Delimiter', '', 'WhiteSpace', ...
2278051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        '', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false);
2288051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    for col=1:length(dataArray)
2298051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin        dataArray{col} = [dataArray{col};dataArrayBlock{col}];
2308051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin    end
2318051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
2328051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2338051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Close the text file.
2348051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinfclose(fileID);
2358051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2368051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Post processing for unimportable data.
2378051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% No unimportable data rules were applied during the import, so no post
2388051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% processing code is included. To generate code which works for
2398051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% unimportable data, select unimportable cells in a file and regenerate the
2408051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin% script.
2418051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
2428051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin%% Allocate imported array to column variable names
2438051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSeqNo = dataArray{:, 1};
2448051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinTimeStamp = dataArray{:, 2};
2458051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSendTime = dataArray{:, 3};
2468051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSize = dataArray{:, 4};
2478051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinPT = dataArray{:, 5};
2488051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinM = dataArray{:, 6};
2498051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik LundinSSRC = dataArray{:, 7};
2508051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundinend
2518051832a9d2d3a18dabeaf6fd09103a4055aceeeHenrik Lundin
252