2012 in review

The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.

Here’s an excerpt:

About 55,000 tourists visit Liechtenstein every year. This blog was viewed about 290,000 times in 2012. If it were Liechtenstein, it would take about 5 years for that many people to see it. Your blog had more visits than a small country in Europe!

Click here to see the complete report.

IEXPLORE.EXE redirected to 0749.com or 13721.net

My internet explorer was re-directed to http://www.0749.com. I removed a few links in registry like: “…iexplore.exe” http://www.0749.com. Then I started IE, it was redirected to 13721.net instead. I deleted everything I found in registry about this address. But it still did that.

I have Norton Antivirus, but it can’t detect anything.

Finally, I found a suspicous file in the IE folder: 1802120223.dat. I changed the name. Then the problem was gone. Obviously, this file is called by IE, which is marked in registry.

Then I found a key in registry:

[HKEY_CLASSES_ROOT\CLSID\{18021223-2011-0295-951B-9EA34E34E8CC}\InprocServer32]
@=”1802120223.dat”

If I remove this key and have the file there, there won’t be any problem either.

That’s why people can’t recognize. But the antivirus software is supposed to recognize it.

Gene Sequence Search for Very Large Data File

A research fellow at Harvard asked me to write a program to search for gene sequence, such as ‘TCC’, and record the next 4 codes. The data file is 14Gb. He tried some matlab codes, and the system freezes, or keeps running and never stops.

I first tested using a loop method (V1.0). It turns out it will take a month to finish 14Gb data on my 1.8GHz Core 2 Duo/3Gb RAM PC. Then I updated it to use matrix. It turns out it will only take 1.3 hours on my 1.8Gb PC or 40 minutes on my 2.33GHz Core 2 Duo/2Gb RAM PC. It beats any codes that he got using Python or other language.

Source codes are shown as follows, where v1.0 is using loop and slow for large data file, it records wanted codes and target sequence positions; v2.0 and v2.1 record wanted codes only without positions; v2.2 and v2.3 records both codes and positions.

The latest version of the program is also posted on mathworks: http://www.mathworks.com/matlabcentral/fileexchange/31966-fast-gene-sequence-search-for-very-large-data-file

%———————————– seqSearch.m V1.0 —————————————

function [p,s]=seqSearch(f,targSeq,lc,offset,M,print)
%[p,s] = seqSearch(f,targSeq,lc,offset,M,print)
%[p,s] = seqSearch(f,'','','','','') with all default parameters.
%
%  Gene Sequence Search V1.0 - search for a specific sequence targSeq and record
%  a neighboring code sequence with an offset position.
%
%Input:
% f: data file path, format: 'filepath', e.g. 'C:\sample.seq'
% targSeq: searching target sequence, by default 'TCC'
% lc: length of the code to record, by default 4
% offset: number of offset positons from the search sequence to record the
%   code. e.g., offset is 1 for the first one after the last code (to the
%   right), and negative value means before the first code (to the left).
%   by default 1
% M: length of the chunk of the codes to read into memory each time,
%   by default 10E6
% print: display first one in every "print" number of found codes,
%   by default 50
%
%Output:
% p: positions of the target sequence found (first code of the sequence)
% s: the recorded codes
%
%   Binlin Wu - CCNY
%   bwu@sci.ccny.cuny.edu
%   Jun 10th, 2011

% targetSeq = 'TCC';
% M = 1e6;

switch nargin
    case 0
        error('Parameters needed: seqSearch(f,targSeq,lc,offset,M,print)')
    case 1
        targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; print = 100;
    case 2
        lc = 4; offset = 1; M = 1e6; print = 100;
    case 3
        offset = 1; M = 1e6; print = 100;
    case 4
        M = 1e6; print = 100;
    case 5
        print = 100;
    case 6
    otherwise
        error('too many parameters: seqSearch(f,targSeq,lc,offset,M,print)')
end

if isempty(targSeq)
    targSeq = 'TCC';
end
if isempty(lc)
    lc = 4;
end
if isempty(offset)
    offset = 1;
end
if isempty(M)
    M = 1e6;
end
if isempty(print)
    print = 100;
end

% if nargin < 5
%     error('More parameters needed, seqSearch(f,targSeq,lc,offset,M,...)')
% elseif	nargin==5
%     print = 50;
% end

lt = length(targSeq); %length of the search target sequence
fclose('all');
% f = 'C:\Documents and Settings\Bin\Desktop\sample1.txt';
fid = fopen(f,'r');

% ----- initialization -------
k = 0;
n = 0;
p = [];
s = '';
C0 = '';

fprintf('Start searching ...\n')
if offset > 0
    lMin = lt+offset+lc-1; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end
    C = textscan(fid,'%c',M,'HeaderLines',1);
    C = C{1};
    if length(C) > 0 && length(C) < lMin  %too short, length < lMin
        for i = 1:length(C)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = char(zeros(1,lc));
        end
    elseif length(C) >= lMin && length(C) < M  %only read once, lMin <= length < M
        i_END = length(C) - (lMin - 1);
        for i=1:i_END
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = C(i+lt-1+offset:i+lt-1+offset+lc-1);
        end
        C0 = C(i_END+1:end);
        for i = 1:length(C0)-lt+1
            if ~isequal(C0(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i_END+i;
            s(k,:) = char(zeros(1,lc));
        end
    elseif length(C) == M %data is no less than M codes
%         M = M+offset+lc-1;
        n = 1;
        fprintf('\n  In the %dth %d codes: \n',n,M);

        i_END = length(C) - (lMin - 1);
        for i=1:i_END
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
    %             if i+lt-1+offset+lc-1 > M && length(C) < M+length(C0) %run to the end of the data
    %                 s{k} = [];
    %             end
            s(k,:) = C(i+lt-1+offset:i+lt-1+offset+lc-1);

        end
        C0 = C(i_END+1:end);
        i_END = length(C);
        while(1)
            C = textscan(fid,'%c',M);
            if isempty(C{1})
                break
            end

            n = n+1;
            i_END = length(C{1});
            fprintf('\n  In the %dth %d codes: \n',n,M);
            C = [C0;C{1}];    

%             i_END = length(C) - (lMin - 1);

            for i=1:i_END
                if ~isequal(C(i:i+lt-1)',targSeq)
                    continue
                end
                k = k+1;
                if print==1 || mod(k,print)==1
                    fprintf('  - %dth %s sequence found\n',k,targSeq);
                end
                p(k)=(n-1)*M - (lMin - 1) + i;
        %             if i+lt-1+offset+lc-1 > M && length(C) < M+length(C0) %run to the end of the data
        %                 s{k} = [];
        %             end
                s(k,:) = C(i+lt-1+offset:i+lt-1+offset+lc-1);

            end
            C0 = C(i_END+1:end);
        end

        for i = 1:length(C0)-lt+1   % rest lMin-1 codes at the end
            if ~isequal(C0(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            if i_END == M % exactly n * M codes & target sequence found in the ending lMin-1 codes
                p(k)=n*M - (lMin - 1) + i;
            else
                p(k)=(n-1)*M - (lMin - 1) + i_END + i;
            end
            s(k,:) = char(zeros(1,lc));
        end
    end
else    % when offset is negtive
    lMin = lt-offset; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end
    if -offset < lc
        error(' |offset| can not be smaller than lc, when offset < 0');
    end
    C = textscan(fid,'%c',M,'HeaderLines',1);
    C = C{1};
    if length(C) > 0 && length(C) < lMin  %too short, length < lMin
        for i = 1:length(C)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = char(zeros(1,lc));
        end
    elseif length(C) >= lMin && length(C) < M  %only read once, lMin <= length < M
        for i = 1:(lMin-1)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = char(zeros(1,lc));
        end
        i_BEGIN = i+1; %lMin-lt+1;
        for i=i_BEGIN:length(C)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = C(i+offset : i+offset+lc-1);
        end
    elseif length(C) == M %data is no less than M codes
%         M = M+offset+lc-1;
        n = 1;
        fprintf('\n  In the %dth %d codes: \n',n,M);

        i_END = lMin -  lt; %(lMin-1)-lt+1 ;
        for i = 1:i_END %(lMin-1)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = char(zeros(1,lc));
        end

        i_BEGIN = i_END + 1; %lMin-lt+1;
        i_END = M - lt + 1;

        for i=i_BEGIN:i_END %length(C)-lt+1
            if ~isequal(C(i:i+lt-1)',targSeq)
                continue
            end
            k = k+1;
            if print==1 || mod(k,print)==1
                fprintf('  - %dth %s sequence found\n',k,targSeq);
            end
            p(k) = i;
            s(k,:) = C(i+offset:i+offset+lc-1);
        end
        C0 = C(end-(lMin-1)+1:end);
        while(1)
            C = textscan(fid,'%c',M);
            if isempty(C{1})
                break
            end

            n = n+1;
            fprintf('\n  In the %dth %d codes: \n',n,M);
            C = [C0;C{1}];

            i_BEGIN = lMin-lt+1;
            i_END = length(C)-lt+1;
            for i=i_BEGIN:i_END
                if ~isequal(C(i:i+lt-1)',targSeq)
                    continue
                end
                k = k+1;
                if print==1 || mod(k,print)==1
                    fprintf('  - %dth %s sequence found\n',k,targSeq);
                end
                p(k)=(n-1)*M - (lMin - 1) + i;
                s(k,:) = C(i+offset:i+offset+lc-1);
            end
            C0 = C(end-(lMin-1)+1:end);
        end
    end
end
fprintf('\n  Searching finished! \n',n,M);
fclose(fid);
save seqSearch.mat p s

%———————————– seqSearch.m V2.0 —————————————

function seq1 = seqSearch(f,targSeq,lc,offset,M,sFlag,fs)
%seq1 = seqSearch2(f,targSeq,lc,offset,M,sFlag,fs)
%seq1 = seqSearch2(f) with all default parameters.
%seq1 = seqSearch2(f,'','','',1e7) with all default parameters except M
%** If the dataset is very large, NOT using output is highly recoomended.
%
%  Gene Sequence Search V2.0 - search for a specific sequence and record
%  a neighboring code sequence with an offset position using matrix for
%  large datasets.
%
%Input:
% f: data file path, format: 'filepath', e.g. 'C:\sample.seq'
% targSeq: search target sequence, by default 'TCC'
% lc: length of the codes to record, by default 4
% offset: number of offset positons from the search sequence to record the
%   code. e.g., offset is 1 for the first one after the last code (to the
%   right), and negative value means before the first code (to the left).
%   by default 1
% M: length of the chunk of the codes to read into memory each time,
%   by default 10E6
% sFlag: 1 for save, 0 for not save, by default 0
% fs: filename to save, only valid when sFlag = 1, e.g. 'seq.txt'
%
%Output:
% seq1: the recorded codes
%
%   Binlin Wu - CCNY
%   bwu@sci.ccny.cuny.edu
%   Jun 10th, 2011

% set default values for the parameters
switch nargin
    case 0
        error('Parameters needed: seqSearch(f,targSeq,lc,offset,M,print)')
    case 1
        targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 2
        lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 3
        offset = 1; M = 1e6; sFlag = 0;
    case 4
        M = 1e6; sFlag = 0;
    case 5
        sFlag = 0;
    case 6
        if sFlag == 1
            error('save destination file name missing');
        end
    case 7
        if isequal(sFlag,1) && isempty(fs)
            error('save destination file name missing');
        end
    otherwise
        error('too many parameters: seqSearch(f,targSeq,lc,offset,M,print)')
end

if isempty(targSeq)
    targSeq = 'TCC';
end
if isempty(lc)
    lc = 4;
end
if isempty(offset)
    offset = 1;
end
if isempty(M)
    M = 1e6;
end
if isempty(sFlag)
    sFlag = 0;
end

% ---- existing save file overwritten confirm ---
confirm = 0;
if sFlag == 1 && exist(fs,'file') == 2
    while(1)
        if confirm == 1
            break
        end
        if sFlag == 1 && exist(fs,'file') == 2
            fprintf('Filename %s already exists!\n',fs);
            reply = upper(input('Do you want to overwrite it? Y/N [N]: ', 's'));
            if isempty(reply)
                reply = 'N';
            end
            if ~isequal(reply,'Y') && ~isequal(reply,'N')
                confirm = 0;
            elseif isequal(reply,'Y')
                confirm = 1;
            else
                fs1 = input('Please enter a new file name: ', 's');
                fprintf('Codes will be recorded in file: %s\n', fs1);
                reply = upper(input('Confirm? Y/N [Y]: ', 's'));
                if isempty(reply)
                    reply = 'Y';
                end
                if isequal(reply,'Y')
                    confirm = 1;
                    fs = fs1;
                else
                    confirm = 0;
                end
                if exist(fs1,'file') == 2
                    confirm = 0;
                end
            end
        end
    end
end
% --------------------------------------

lt = length(targSeq); %length of the search target sequence
fclose('all');
% f = '.\sample.seq';
fid = fopen(f,'r');
if sFlag == 1
    sfid = fopen(fs,'w');
end

% ----- initialization -------
n = 0;
C0 = '';
seq1 = '';

fprintf('Start searching ...\n')
lMin = lt+offset+lc-1; %the least codes possible to have both a target sequence and the codes to record
if M < lMin
    errMsg = sprintf('M must be larger than %d',lMin);
    error(errMsg);
end
C = textscan(fid,'%c',0,'HeaderLines',1);

while(1)
    C = textscan(fid,'%c',M);
    if isempty(C{1})
        break
    end

    n = n+1;
    fprintf('\n  Checking the %dth %d codes ... \n',n,M);
    C = [C0;C{1}];    

    i_END = length(C) - lMin + lt;

    C1 = [C(1:i_END) C(2:i_END+1) C(3:i_END+2)];
    SEQ = repmat('TCC',i_END,1);
    seqPos = C1 == SEQ;
    seqPos = seqPos(:,1)&seqPos(:,2)&seqPos(:,3);
    seqPos1 = logical( ...
              [0; 0; 0; seqPos(1:end);  0] + ...
              [0; 0; 0; 0;             seqPos(1:end)] + ...
              [0; 0; 0; 0;             0;               seqPos(1:end-1)] + ...
              [0; 0; 0; 0;             0;               0;               seqPos(1:end-2)]);

    if sFlag == 1
        fprintf(sfid,'%s',C(seqPos1));
    end
    if nargout == 1
        seq1 = [seq1;C(seqPos1)];
    end
    fprintf('  The %dth %d codes done. \n',n,M);
    C0 = C(end - (lMin - 1) + 1:end);
end
fprintf('\n  Searching finished! \n',n,M);
fclose('all');

%———————————– seqSearch.m V2.1 —————————————

function seq1 = seqSearch(f,targSeq,lc,offset,M,sFlag,fs)
%seq1 = seqSearch2(f,targSeq,lc,offset,M,sFlag,fs)
%seq1 = seqSearch2(f) with all default parameters.
%seq1 = seqSearch2(f,'','','',1e7) with all default parameters except M
%** If the dataset is very large, NOT using output is highly recoomended.
%
%  Gene Sequence Search V2.1 - search for a specific sequence and record
%  a neighboring code sequence with an offset position using matrix for
%  large datasets.
%
%Input:
% f: data file path, format: 'filepath', e.g. 'C:\sample.seq'
% targSeq: search target sequence, by default 'TCC'
% lc: length of the codes to record, by default 4
% offset: number of offset positons from the search sequence to record the
%   code. e.g., offset is 1 for the first one after the last code (to the
%   right), and negative value means before the first code (to the left).
%   by default 1
% M: length of the chunk of the codes to read into memory each time,
%   by default 10E6
% sFlag: 1 for save, 0 for not save, by default 0
% fs: filename to save, only valid when sFlag = 1, e.g. 'seq.txt'
%
%Output:
% seq1: the recorded codes
%
%   Binlin Wu - CCNY
%   bwu@sci.ccny.cuny.edu
%   Jun 10th, 2011

% set default values for the parameters
switch nargin
    case 0
        error('Parameters needed: seqSearch(f,targSeq,lc,offset,M,print)')
    case 1
        targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 2
        lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 3
        offset = 1; M = 1e6; sFlag = 0;
    case 4
        M = 1e6; sFlag = 0;
    case 5
        sFlag = 0;
    case 6
        if sFlag == 1
            error('save destination file name missing');
        end
    case 7
        if isequal(sFlag,1) && isempty(fs)
            error('save destination file name missing');
        end
    otherwise
        error('too many parameters: seqSearch(f,targSeq,lc,offset,M,print)')
end

if isempty(targSeq)
    targSeq = 'TCC';
end
if isempty(lc)
    lc = 4;
end
if isempty(offset)
    offset = 1;
end
if isempty(M)
    M = 1e6;
end
if isempty(sFlag)
    sFlag = 0;
end

% ---- existing save file overwritten confirm ---
confirm = 0;
if sFlag == 1 && exist(fs,'file') == 2
    while(1)
        if confirm == 1
            break
        end
        if sFlag == 1 && exist(fs,'file') == 2
            fprintf('Filename %s already exists!\n',fs);
            reply = upper(input('Do you want to overwrite it? Y/N [N]: ', 's'));
            if isempty(reply)
                reply = 'N';
            end
            if ~isequal(reply,'Y') && ~isequal(reply,'N')
                confirm = 0;
            elseif isequal(reply,'Y')
                confirm = 1;
            else
                fs1 = input('Please enter a new file name: ', 's');
                fprintf('Codes will be recorded in file: %s\n', fs1);
                reply = upper(input('Confirm? Y/N [Y]: ', 's'));
                if isempty(reply)
                    reply = 'Y';
                end
                if isequal(reply,'Y')
                    confirm = 1;
                    fs = fs1;
                else
                    confirm = 0;
                end
                if exist(fs1,'file') == 2
                    confirm = 0;
                end
            end
        end
    end
end
% --------------------------------------

lt = length(targSeq); %length of the search target sequence
fclose('all');
% f = '.\sample.seq';
fid = fopen(f,'r');
if sFlag == 1
    sfid = fopen(fs,'w');
end

% ----- initialization -------
n = 0;
C0 = '';
seq1 = '';

fprintf('Start searching ...\n')
lMin = lt+offset+lc-1; %the least codes possible to have both a target sequence and the codes to record
if M < lMin
    errMsg = sprintf('M must be larger than %d',lMin);
    error(errMsg);
end
C = textscan(fid,'%c',0,'HeaderLines',1);

while(1)
    C = textscan(fid,'%c',M);
    if isempty(C{1})
        break
    end

    n = n+1;
    fprintf('\n  Checking the %dth %d codes ... \n',n,M);
    C = [C0;C{1}];    

%     i_END = length(C) - lMin + lt;
%
%     C1 = [C(1:i_END) C(2:i_END+1) C(3:i_END+2)];
%     SEQ = repmat('TCC',i_END,1);
%     seqPos = C1 == SEQ;
%     seqPos = seqPos(:,1)&seqPos(:,2)&seqPos(:,3);
%     seqPos1 = logical( ...
%               [0; 0; 0; seqPos(1:end);  0] + ...
%               [0; 0; 0; 0;             seqPos(1:end)] + ...
%               [0; 0; 0; 0;             0;               seqPos(1:end-1)] + ...
%               [0; 0; 0; 0;             0;               0;               seqPos(1:end-2)]);

%     seqPos = strfind(C(1:i_END)','TCC');
%     seqPos1 = [seqPos+lt+offset-1;seqPos+lt+offset;seqPos+lt+offset+1;seqPos+lt+offset+2];

    seqPos = strfind(C(1:end-lMin + lt)',targSeq);
    if ~isempty(seqPos)
        seqPos1 = repmat(seqPos+lt+offset-1,lc,1);
        seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos));

        seqPos1 = seqPos1(:);

        if sFlag == 1
            fprintf(sfid,'%s',C(seqPos1));
        end
        if nargout == 1
            seq1 = [seq1;C(seqPos1)];
        end
    end
    fprintf('  The %dth %d codes done. \n',n,M);
    C0 = C(end - (lMin - 1) + 1:end);
end
fprintf('\n  Searching finished! \n',n,M);
fclose('all');

%———————————– seqSearch.m V2.2 —————————————

function [seq,seqPos] = seqSearch(f,targSeq,lc,offset,M,sFlag,fs)
%[seq,seqPos] = seqSearch2(f,targSeq,lc,offset,M,sFlag,fs)
%[seq,seqPos] = seqSearch2(f) with all default parameters.
%[seq,seqPos] = seqSearch2(f,'','','',1e7) with all default parameters except M
%** If the dataset is very large, NOT using output is highly recoomended.
%
%  Gene Sequence Search V2.2 - search for a specific sequence and record
%  a neighboring code sequence with an offset position using matrix for
%  large datasets.
%
%Input:
% f: data file path, format: 'filepath', e.g. 'C:\sample.seq'
% targSeq: search target sequence, by default 'TCC'
% lc: length of the codes to record, by default 4
% offset: number of offset positons from the search sequence to record the
%   code. e.g., offset is 1 for the first one after the last code (to the
%   right), and negative value means before the first code (to the left).
%   by default 1
% M: length of the chunk of the codes to read into memory each time,
%   by default 10E6
% sFlag: 1 for save, 0 for not save, by default 0
% fs: filename to save, only valid when sFlag = 1, e.g. 'seq.txt'
%
%Output:
% seq: the recorded codes
% seqPos: positions of the target search sequence
%
%   Binlin Wu - CCNY
%   bwu@sci.ccny.cuny.edu
%   Jun 10th, 2011

% set default values for the parameters
switch nargin
    case 0
        error('Parameters needed: seqSearch(f,targSeq,lc,offset,M,print)')
    case 1
        targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 2
        lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 3
        offset = 1; M = 1e6; sFlag = 0;
    case 4
        M = 1e6; sFlag = 0;
    case 5
        sFlag = 0;
    case 6
        if sFlag == 1
            error('save destination file name missing');
        end
    case 7
        if sFlag == 1 && isempty(fs)
            error('save destination file name missing');
        end
    otherwise
        error('too many parameters: seqSearch(f,targSeq,lc,offset,M,print)')
end

if isempty(targSeq)
    targSeq = 'TCC';
end
if isempty(lc)
    lc = 4;
end
if isempty(offset)
    offset = 1;
end
if isempty(M)
    M = 1e6;
end
if isempty(sFlag)
    sFlag = 0;
end

% ---- existing save file overwritten confirm ---
confirm = 0;
if sFlag == 1 && exist(fs,'file') == 2
    while(1)
        if confirm == 1
            break
        end
        if sFlag == 1 && exist(fs,'file') == 2
            fprintf('Filename %s already exists!\n',fs);
            reply = upper(input('Do you want to overwrite it? Y/N [N]: ', 's'));
            if isempty(reply)
                reply = 'N';
            end
            if ~isequal(reply,'Y') && ~isequal(reply,'N')
                confirm = 0;
            elseif isequal(reply,'Y')
                confirm = 1;
            else
                fs1 = input('Please enter a new file name: ', 's');
                fprintf('Codes will be recorded in file: %s\n', fs1);
                reply = upper(input('Confirm? Y/N [Y]: ', 's'));
                if isempty(reply)
                    reply = 'Y';
                end
                if isequal(reply,'Y')
                    confirm = 1;
                    fs = fs1;
                else
                    confirm = 0;
                end
                if exist(fs1,'file') == 2
                    confirm = 0;
                end
            end
        end
    end
end

% ----- initialization -------

lt = length(targSeq); %length of the search target sequence
fclose('all');
% f = '.\sample.seq';
fid = fopen(f,'r');
if sFlag == 1
    sfid = fopen(fs,'w');
end

n = 0;
C0 = '';
seq = '';
seqPos = [];

% ----- start search -------

fprintf('Start searching ...\n')
if offset > 0
    lMin = lt+offset+lc-1; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end

    C = textscan(fid,'%c',M,'HeaderLines',1);
    C = C{1};

    if isempty(C)
        fprintf('\n  The data file is empty!\n')
        return
    end

    if length(C) > 0 && length(C) < lMin  %too short, length < lMin
        if nargout == 2
            seqPos0 = strfind(C',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = [seqPos seqPos0];
            end
        end

    elseif length(C) >= lMin && length(C) < M  %only read once, lMin <= length < M

        seqPos0 = strfind(C(1:end - (lMin - 1) + (lt-1))',targSeq);

        if ~isempty(seqPos0)
            seqPos1 = repmat(seqPos0+lt-1+offset,lc,1);
            seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
            seqPos1 = seqPos1(:);

            if sFlag == 1
                fprintf(sfid,'%s',C(seqPos1));
            end
            if nargout >= 1
                seq = [seq;C(seqPos1)];
            end
            if nargout >= 2
                seqPos = [seqPos seqPos0];
            end
        end             

        seqPos0 = strfind(C(end - (lMin - 1) + 1:end)',targSeq);
        if ~isempty(seqPos0)
            if nargout >= 1
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
            end
            if nargout >= 2
                seqPos = [seqPos seqPos0 + length(C) - (lMin - 1)];
            end
        end

    elseif length(C) == M %data is no less than M codes
        n=1;
        LastChunkLength = length(C);
        fprintf('\n  Checking the %dth %d codes ... \n',n,M);

        seqPos0 = strfind(C(1:end - (lMin - 1) + (lt-1))',targSeq);

        if ~isempty(seqPos0)
            seqPos1 = repmat(seqPos0+lt-1+offset,lc,1);
            seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
            seqPos1 = seqPos1(:);

            if sFlag == 1
                fprintf(sfid,'%s',C(seqPos1));
            end
            if nargout >= 1
                seq = [seq;C(seqPos1)];
            end
            if nargout >= 2
                seqPos = [seqPos seqPos0];
            end
        end
        fprintf('  The %dth %d codes done. \n',n,M);
        C0 = C(end - (lMin - 1) + 1:end);                 

        while(1)
            C = textscan(fid,'%c',M);
            if isempty(C{1})
                break
            end
            LastChunkLength = length(C{1});
            n = n+1;
            fprintf('\n  Checking the %dth %d codes ... \n',n,M);
            C = [C0;C{1}];    

        %     C1 = [C(1:i_END) C(2:i_END+1) C(3:i_END+2)];
        %     SEQ = repmat('TCC',i_END,1);
        %     seqPos = C1 == SEQ;
        %     seqPos = seqPos(:,1)&seqPos(:,2)&seqPos(:,3);
        %     seqPos1 = logical( ...
        %               [0; 0; 0; seqPos(1:end); 0;               0;               0            ] + ...
        %               [0; 0; 0; 0;             seqPos(1:end);   0;               0            ] + ...
        %               [0; 0; 0; 0;             0;               seqPos(1:end);   0            ] + ...
        %               [0; 0; 0; 0;             0;               0;
        %               seqPos(1:end)] );

    %         seqPos = strfind(C(1:i_END)','TCC');
    %         seqPos1 = [seqPos+lt+offset-1;seqPos+lt+offset;seqPos+lt+offset+1;seqPos+lt+offset+2];

            seqPos0 = strfind(C(1:end - (lMin - 1) + (lt-1))',targSeq);
            if ~isempty(seqPos0)
                seqPos1 = repmat(seqPos0+lt-1+offset,lc,1);
                seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
                seqPos1 = seqPos1(:);

                if sFlag == 1
                    fprintf(sfid,'%s',C(seqPos1));
                end
                if nargout >= 1
                    seq = [seq;C(seqPos1)];
                    if nargout >= 2
                        seqPos = [seqPos seqPos0+(n-1)*M-(lMin-1)];
                    end
                end
            end
            fprintf('  The %dth %d codes done. \n',n,M);
            C0 = C(end - (lMin - 1) + 1:end);
        end
        if nargout == 2
            seqPos0 = strfind(C0',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = [seqPos seqPos0+LastChunkLength+(n-1)*M-(lMin-1)];
            end
        end
    end 

else
    lMin = lt-offset; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end
    if -offset < lc
        error(' |offset| can not be smaller than lc, when offset < 0');
    end

    C = textscan(fid,'%c',M,'HeaderLines',1);
    C = C{1};

    if isempty(C)
        fprintf('\n  The data file is empty!\n')
        return
    end    

    if length(C) > 0 && length(C) < lMin  %too short, length < lMin

        seqPos0 = strfind(C',targSeq);
        if nargout == 2
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = seqPos0;
            end
        end

    elseif length(C) >= lMin && length(C) < M  %only read once, lMin <= length < M

        seqPos0 = strfind(C(1:lMin-1)',targSeq);
        if nargout == 2
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = seqPos0;
            end
        end     

        seqPos0 = strfind(C(-offset+1:end)',targSeq);

        if ~isempty(seqPos0)
            seqPos1 = repmat(seqPos0,lc,1);
            seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
            seqPos1 = seqPos1(:);

            if sFlag == 1
                fprintf(sfid,'%s',C(seqPos1));
            end
            if nargout >= 1
                seq = [seq;C(seqPos1)];
                if nargout >= 2
                    seqPos = [seqPos seqPos0-offset];
                end
            end
        end
    elseif length(C) == M %data is no less than M codes
        n = 1;
        fprintf('\n  Checking the %dth %d codes ... \n',n,M);

        seqPos0 = strfind(C(1:lMin-1)',targSeq);
        if nargout == 2
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = seqPos0;
            end
        end         

        seqPos0 = strfind(C(-offset+1:end)',targSeq);
        if ~isempty(seqPos0)
            seqPos1 = repmat(seqPos0,lc,1);
            seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
            seqPos1 = seqPos1(:);

            if sFlag == 1
                fprintf(sfid,'%s',C(seqPos1));
            end
            if nargout >= 1
                seq = [seq;C(seqPos1)];
                if nargout >= 2
                    seqPos = [seqPos seqPos0-offset];
                end
            end
        end
        fprintf('  The %dth %d codes done. \n',n,M);
        C0 = C(end-(lMin-1)+1:end);

        while(1)
            C = textscan(fid,'%c',M);
            if isempty(C{1})
                break
            end

            n = n+1;
            fprintf('\n  Checking the %dth %d codes ... \n',n,M);
            C = [C0;C{1}];    

            seqPos0 = strfind(C(-offset+1:end)',targSeq);

            if ~isempty(seqPos0)
                seqPos1 = repmat(seqPos0,lc,1);
                seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
                seqPos1 = seqPos1(:);
                if sFlag == 1
                    fprintf(sfid,'%s',C(seqPos1));
                end
                if nargout >= 1
                    seq = [seq;C(seqPos1)];
                    if nargout >= 2
                        seqPos = [seqPos seqPos0-offset+M*(n-1)-(lMin-1)];
                    end
                end
            end
            fprintf('  The %dth %d codes done. \n',n,M);
            C0 = C(end-(lMin-1)+1:end);
        end

    end
end

fprintf('\n  Searching finished! \n',n,M);
fclose('all');

%———————————– seqSearch.m V2.3 —————————————

function [seq,seqPos] = seqSearch(f,nHL,targSeq,lc,offset,M,sFlag,fs)
%[seq,seqPos] = seqSearch2(f,nHL,targSeq,lc,offset,M,sFlag,fs)
%[seq,seqPos] = seqSearch2(f) with all default parameters.
%[seq,seqPos] = seqSearch2(f,'','','','',1e7) with all default parameters except M
%** If the dataset is very large, NOT using output is highly recoomended.
%
%  Gene Sequence Search V2.3 - search for a specific sequence and record
%  a neighboring code sequence with an offset position using matrix for
%  large datasets.
%
%Input:
% f: data file path, format: 'filepath', e.g. 'C:\sample.seq'
% targSeq: search target sequence, by default 'TCC'
% lc: length of the codes to record, by default 4
% offset: number of offset positons from the search sequence to record the
%   code. e.g., offset is 1 for the first one after the last code (to the
%   right), and negative value means before the first code (to the left).
%   by default 1
% M: length of the chunk of the codes to read into memory each time,
%   by default 10E6
% sFlag: 1 for save, 0 for not save, by default 0
% fs: filename to save, only valid when sFlag = 1, e.g. 'seq.txt'
% nHL: number of headlines you want to remove from the data, by default 0
%
%Output:
% seq: the recorded codes
% seqPos: positions of the target search sequence
%
%   Binlin Wu - CCNY
%   bwu@sci.ccny.cuny.edu
%   Jun 10th, 2011

% set default values for the parameters
switch nargin
    case 0
        error('Parameters needed: seqSearch(f,nHL,targSeq,lc,offset,M,sFlag,fs)')
    case 1
        nHL = 0; targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 2
        targSeq = 'TCC'; lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 3
        lc = 4; offset = 1; M = 1e6; sFlag = 0;
    case 4
        offset = 1; M = 1e6; sFlag = 0;
    case 5
        M = 1e6; sFlag = 0;
    case 6
        sFlag = 0;
    case 7
        if sFlag == 1
            error('save destination file name missing');
        end
    case 8
        if isequal(sFlag,1) && isempty(fs)
            error('save destination file name missing');
        end
    otherwise
        error('too many parameters: seqSearch(f,nHL,targSeq,lc,offset,M,sFlag,fs)')
end

if isempty(nHL)
    nHL = 0;
end
if isempty(targSeq)
    targSeq = 'TCC';
end
if isempty(lc)
    lc = 4;
end
if isempty(offset)
    offset = 1;
end
if isempty(M)
    M = 1e6;
end
if isempty(sFlag)
    sFlag = 0;
end

% ---- existing save file overwritten confirm ---
confirm = 0;
if sFlag == 1 && exist(fs,'file') == 2
    while(1)
        if confirm == 1
            break
        end
        if sFlag == 1 && exist(fs,'file') == 2
            fprintf('Filename %s already exists!\n',fs);
            reply = upper(input('Do you want to overwrite it? Y/N [N]: ', 's'));
            if isempty(reply)
                reply = 'N';
            end
            if ~isequal(reply,'Y') && ~isequal(reply,'N')
                confirm = 0;
            elseif isequal(reply,'Y')
                confirm = 1;
            else
                fs1 = input('Please enter a new file name: ', 's');
                fprintf('Codes will be recorded in file: %s\n', fs1);
                reply = upper(input('Confirm? Y/N [Y]: ', 's'));
                if isempty(reply)
                    reply = 'Y';
                end
                if isequal(reply,'Y')
                    confirm = 1;
                    fs = fs1;
                else
                    confirm = 0;
                end
                if exist(fs1,'file') == 2
                    confirm = 0;
                end
            end
        end
    end
end

% ----- initialization -------

lt = length(targSeq); %length of the search target sequence
fclose('all');
% f = '.\sample.seq';
fid = fopen(f,'r');
if sFlag == 1
    sfid = fopen(fs,'w');
end

n = 0;
C0 = '';
seq = '';
seqPos = [];

% ----- start search -------

fprintf('Start searching ...\n')
if offset > 0
    lMin = lt+offset+lc-1; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end

    C = textscan(fid,'%c',M,'HeaderLines',nHL);
    C = C{1};

    if isempty(C) % && n == 1
        fprintf('\n  The data file is empty!\n')
        return

    elseif length(C) > 0 && length(C) < lMin  %too short, length < lMin
        if nargout == 2
            seqPos0 = strfind(C',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = [seqPos seqPos0];
            end
        end

    else
        while(1)
            if length(C) == 0
                break
            else
                n = n+1;
                fprintf('\n  Checking the %dth %d codes ... \n',n,M);
                LastChunkLength = length(C);
                C = [C0;C];
                seqPos0 = strfind(C(1:end - (lMin - 1) + (lt-1))',targSeq);
%                 seqPos0 = strfind(C(1:lengthC + lt-1)',targSeq); %not good for data length <=M
                if ~isempty(seqPos0)
                    seqPos1 = repmat(seqPos0+lt-1+offset,lc,1);
                    seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
                    seqPos1 = seqPos1(:);

                    if sFlag == 1
                        fprintf(sfid,'%s',C(seqPos1));
                    end
                    if nargout >= 1
                        seq = [seq;C(seqPos1)];
                        if nargout >= 2
                            if n==1 %data length <= M
                                seqPos = seqPos0;
                            else %data length > M
%                                 seqPos = [seqPos seqPos0+length(C)-(lMin-1)+(n-1)*M-(lMin-1)];  %not good for data length <=M
                                seqPos = [seqPos seqPos0+(n-1)*M-(lMin-1)];
                            end
                        end
                    end
                end
                fprintf('  The %dth %d codes done. \n',n,M);
                C0 = C(end - (lMin - 1) +1:end);
%                 C0 = C(lengthC + 1:end)  %not good for data length <=M
            end
            C = textscan(fid,'%c',M);
            C = C{1};
        end

        if nargout == 2
            seqPos0 = strfind(C0',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = [seqPos seqPos0+(n-1)*M+LastChunkLength-(lMin-1)];
            end
        end
    end
else
    lMin = lt-offset; %the least codes possible to have both a target sequence and the codes to record
    if M < lMin
        errMsg = sprintf('M must be larger than %d',lMin);
        error(errMsg);
    end
    if -offset < lc
        error(' |offset| can not be smaller than lc, when offset < 0');
    end

    C = textscan(fid,'%c',M,'HeaderLines',1);
    C = C{1};

    if isempty(C) % && n == 1
        fprintf('\n  The data file is empty!\n')
        return

    elseif length(C) > 0 && length(C) < lMin  %too short, length < lMin
        if nargout == 2
            seqPos0 = strfind(C',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = seqPos0;
            end
        end

    else
        if nargout == 2
            seqPos0 = strfind(C(1:lMin-1)',targSeq);
            if ~isempty(seqPos0)
                seq = [seq;repmat(' ',lc*length(seqPos0),1)];
                seqPos = seqPos0;
            end
        end
        while(1)
            if length(C) == 0
                break
            else
                n = n+1;
                fprintf('\n  Checking the %dth %d codes ... \n',n,M);
                C = [C0;C];
                seqPos0 = strfind(C(-offset+1:end)',targSeq);

                if ~isempty(seqPos0)
                    seqPos1 = repmat(seqPos0,lc,1);
                    seqPos1 = seqPos1 + repmat([0:lc-1]',1,length(seqPos0));
                    seqPos1 = seqPos1(:);

                    if sFlag == 1
                        fprintf(sfid,'%s',C(seqPos1));
                    end
                    if nargout >= 1
                        seq = [seq;C(seqPos1)];
                        if nargout >= 2
                            if n == 1
                                seqPos = [seqPos seqPos0-offset];
                            else
                                seqPos = [seqPos seqPos0-offset+M*(n-1)-(lMin-1)];
                            end
                        end
                    end
                end
                fprintf('  The %dth %d codes done. \n',n,M);
                C0 = C(end-(lMin-1)+1:end);
            end
            C = textscan(fid,'%c',M);
            C=C{1};
        end
    end
end

fprintf('\n  Searching finished! \n',n,M);
fclose('all');

Watch ANY Online Videos/TV (PPStream, PPLive etc) on TV via DLNA

Sometimes, we can’t get the streaming source for online videos, TV shows, and Live TV so as to send it to TV via DLNA using a DLNA server such as TVersity.

For online TV like PPStream, PPLive, these popular Chinese online TV software, there were some methods introduced using VLC: Link 1Link 2, and Link 3. The idea is this. VLC captures the online streaming, and generates a secondary streaming, which is taken by TVersity and shared on the local network. But it seems none of these works for me for uusee, pplive and ppstream, since I can’t find the streaming source for these software.

Streaming the whole screen will be an ultimate method that can work with any media source via DLNA streaming.

More details about VLC and TVersity can be found here: https://alenblog.wordpress.com/2011/04/21/stream-computer-desktop-to-tv-using-dlna-tversity-and-vlc/ and https://alenblog.wordpress.com/2011/04/07/tversity-dlna-for-samsung-tv/.

Here is how it’s done.

VLC can capture the screen using screen://. But it turns out it can’t capture audio simultaneously using input-slave: dshow://. The workaround would be to use DirecShow with a directshow filter, such as VH Screen Capture.

VH screen captures video or audio only in MP4. But both captured, video is not shown, even though MediaInfo shows video data is stored. For DIV3+MP3 (asf), VH can’t see video at all, even though video data was also stored. Without transcoding, output .asf file is fine. But the data file is so big, and VLC crashes soon. The picture captured in MP4 are really great. It’s the best picture I’ve got compared to other ways mentioned here.

UScreenCapture works fine with DIV3+mp3(asf) and MP4. But the picture quality is a lot worse, even if using larger BitRate and generate big data file. Anyway, for the time being, by using directshow (UScreenCapture), video and audio can be both captured.

Another problem is my SoundMax HD audio sound card doesn’t have Stereo Mix. So I use a stereo audio cable to connect my speaker and mic ports, sending sound from the speaker to mic directly. VLC captures the audio from the microphone.

If you can see your screen, but not the video, you may need disable the hardware accelaration, which can be found at the property of your graphics.

I make the streaming using the VLC GUI. I select the video and audio sources, transcode it to DIV3+MP3, 25fps, 4096 kbps, and then stream it to mms://127.0.0.1:1234 or http://127.0.0.1:1234, which is further shared by TVersity. Then I can watch on my Samsung HDTV anything on PC. It works great, particular for PPStream that I use it very often.

This way, I don’t need worry about that the media type for TVersity or Samsung TV any more. Whatever I can see on PC, I can see it on TV.

** When using VLC, try to transcode with some codecs that are natively supported by your TV. Then TVersity doesn’t need do another transcoding. That will work much better.

Run two Matlab functions simutaneously in parallel

My friend gave me a project: run two matlab loops (can be put in two functions) simultaneously. They have to be synchronized. They have to start at the same time, and they have to synchronize every step in loop. The problem was simplified because the two loops with run with a fairly stable step size. So what I need do is to start the two functions at the same time with error less than 0.1ms.

To run two matlab functions, we need parallel computing, or simply use two matlab sessions. For two matlab sessions, we need make a feedback in one session to trigger the other session. There are different ways to make the trigger.

1. Use hard drive to communite between two session is one way. Basically, we need first initialize a start.ini file with -1:

fid=fopen('start.ini','w');
fprintf(fid,'%d',-1);
fclose(fid);

Then one session start function 1 and write 1 to the ini file:

fid=fopen('start.ini','w');
fprintf(fid,'%d',1);
fclose(fid);

In the other session, it keeps checking the ini file, it starts once it reads 1.

while 1
    fid=fopen('start.ini','r');
    k=fscanf(fid,'%d',1);
    fclose(fid);
    if k==1
    %-------- reset start.ini to -1 start ---------------%
        fid=fopen('start.ini','w');
        fprintf(fid,'%d',-1);
        fclose(fid);
    %-------- reset start.ini to -1 end ---------------%
        break
    end
end

This works in a lot of scenarios. Here the problem with this is it takes a few milliseconds, and it fluctuates. So this is not a good solution.

2. Use a shared memory. Ram should be faster than Hard Drive. Basically, we can have one session write a variable to the memory, and have the other session read it, just like writing and reading from hard drive, but faster. The problem is two matlab sessions use two separate workspaces residing in different memory locations, not shared.

Actually, if we could, creating a shared variable in CPU cache (register) is the fastest way to read and write a variable for a computer. But I can’t find anything in matlab about that.

There is method called DDE (Dynamic Data Exchange) that makes different applications communicate.  But I didn’t find anything that can make DDE work between two matlab session.

Then I found a matlab program sharedmatrix on mathworks: http://www.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix. This program creates a memory block that will be shared by two matlab sessions. I managed to compile it in Matlab 2010a and Ubuntu. But I can’t make it work. This program seems very unstable. When the second session read the shared memory, matlab crashes. So I gave up this method.

There are other methods to make the feedback, but I can’t think of a way that can really solve my problem.

3. Use parallel computing

Another method to make the synchronization is to use parallel computing. A more detailed post can be found here about parallel computing in matlab: https://alenblog.wordpress.com/2011/03/31/parallel-computing-in-matlab/.

Basically, we can have two threads that can call two functions simultaneously. The traditional multithreading is actually through time division. So the time actually not synchronized for the two functions. But I’m not sure what the time difference is. I found a post here, where basically some codes were written in c++ for multithreading, it can be compiled in matlab to MEX file, and then be called. But like in the comment, I got same errors when compiling:

mex mythreadprog.cpp

Error mythreadprog.cpp: 11 syntax error; found `MyThread’ expecting `;’
Error mythreadprog.cpp: 19 redeclaration of `mexFunction’ previously declared at .\mex.h 135
Warning mythreadprog.cpp: 23 assignment of pointer to void function(pointer to void) to pointer to int function(pointer to void)
Error mythreadprog.cpp: 33 syntax error; found `MyThread’ expecting `;’
Warning mythreadprog.cpp: 58 missing return value
Error mythreadprog.cpp: 33 undefined size for `void cdecl’
4 errors, 2 warnings

C:\PROGRA~1\MATLAB\R2007B\BIN\MEX.PL: Error: Compile of ‘mythreadprog.cpp’ failed.

The new multithreading parallel computing using multi-core computer is built in recent matlab versions and can really do the job.

I found different ways to do parallel computing in matlab. The way posted here is using parallel computing, but it doesn’t make the synchronization. The code is shown below:

 
funList = {@fun1,@fun2,@fun3};
dataList = {data1,data2,data3}; %# or pass file names 

parfor i=1:length(funList)
    %# call the function
    funList{i}(dataList{i});
end

Finally, I got a way using matlabpool open two labs, and use spmd to run two functions in two labs separately. labBarrier is used to synchronize the two labs. The code is shown below.

function data = main

struct data1 data2;
data1.x = 1;
data2.x = 2;
funList = {@fun1,@fun2};
dataList = {data1,data2}; % or pass file names 

matlabpool open 2
spmd
    labBarrier
	funList{labindex}(dataList{labindex})
end
matlabpool close

function y = fun1(data1)
time1=clock;
fprintf('%02d : %02d : %02f\n',time1(4),time1(5),time1(6))
labindex
pause(5)
disp('run f1');

function y = fun2(data2)
time2=clock;
fprintf('%02d : %02d : %02f\n',time2(4),time2(5),time2(6))
labindex
pause(5);
disp('run f2')

We can see the two functions are starts at the same time. But the clock command only shows to the accuracy of 1ms.

Stream computer desktop to TV using DLNA, TVersity and VLC

1. What’s going on with TV?

People want their TV with more features, like internet ready, apps, web browser etc. All these extra features are basically already there on computers. Now they want a combination. Basically they want a computerized TV or a TV = TV + PC + Internet.

This is exactly what happened in the handset/phone field, Phone = game player = Handset/PDA = GPS = MP3 player = Video player = Camera/Camcorder = Book reader = Photo frame = web browser = Email browser = … = Computer! This is revolution. One is everything. Basically one thing is a PC that can of course install a lot of apps and has WIFI with extra physically dedicated features such as phone, camera, gps.

This is what’s happening now in TV field. TV companies put a dedicated board (a computer) inside their TVs to make theirs TV = TV + PC. Apple, google make some dedicated box (a computer) sitting beside the TV. Question is why bother making new things, why not just buy a netbook or any cheap desktop PC and connected to TV? The reason is this. A dedicated unit is fancier, and it can be made small, fast, and even put inside TV. It can be made so because it is only used for TV, so it doesn’t need that good quality/much cost to include all those redundant hardware/software.

2. PC to TV

For the time being, TV is not as powerful as PC yet. So sometimes, we want to stream signal from PC to TV. The specific purpose of streaming desktop to TV can be varied for people. One common reason is basically you want to see something  on TV that you can see on PC. This is the exact reason why Internet-ready/connected TV is so popular, Apple TV and google TV are so popular.

For the time being, I don’t have such a powerful TV. I have a samsung LN40c650 LCD HDTV that is internet-ready, with apps and DLNA certified. It is a nice TV, but still not as powerful as computer.

Now I want to see online TV on my TV. What can I do?

There are a variety of ways to send signal from PC to TV.

1) Connect with Video/Audio cables directly, e.g. VGA,DVI,HDMI etc. This is the simplest way. It makes good video/audio quality. But I have to move my PC and make the connection every time. It is not very convenient.

2) Connect wirelessly with PC to TV video/audio transmitters. This is good. But the devices are over $100, which is expensive to me.

3) DLNA, through network. This is compromised way, but doable. DLNA is more and more popular due to its convenience to share media within various devices. But through network, the quality is not that great. The speed is also an issue. There is a tradeoff between media quality and speed. It varies with the hardware.

In my case, I want to try DLNA, since the source media online is not great already. Using TVersity, I can get photos, audios, and videos on my computer, and online such as youtube, and even live TV such as Justin.tv. For more details about this, please refer to another post: https://alenblog.wordpress.com/2011/04/07/tversity-dlna-for-samsung-tv/.

The question is: can I watch online TV like PPStream, PPLive etc (Chinese) on TV, which are not natively supported by DLNA?

There are some methods introduced using VLC: Link 1, Link 2, and Link 3. But it seems none of these works for me for uusee, pplive and ppstream, since I can’t find the streaming source for these software.

3. Stream Desktop to TV

Now I moved to this method that streams desktop to TV, which is universal.

The new VLC version has a feasture to live stream desktop: screen://.

You can create a desktop streaming using VLC to localhost, such as mms://127.0.0.1:1234. Then you can add this live streaming media into TVersity library.

Now you can just watch this “video” on your TV through DLNA (samsung Media Player).

Of course you could also use another live streaming software if available. In principle, this can do the work. The quality and speed might be an issue. It is an issue to me for the time beining. But as least, this provides a possibility.

p.s. screen:// doesn’t actually work for video+audio YET. Please check another post here https://alenblog.wordpress.com/2011/04/24/watch-online-tv-ppstream-pplive-etc-on-tv-via-dlna/ to see how to make it.

TVersity DLNA for Samsung HDTV

Using DLNA, you can stream media (pictures, music and videos) from a DLNA server (such as PC using some DLNA media server, or phone such as Droid X etc) to a DLNA certified device, such as HDTV, PS3 and Xbox 360 etc. Here is an introduction about Droid X DLNA Application: https://motorola-global-portal.custhelp.com/app/answers/detail/a_id/50756/~/droid-x—dlna-application, and a youtube video showing DLNA for Samsung TV and Droid: http://www.youtube.com/watch?v=-QglzQmPpqM. This post is to show how to setup DLNA server for Samsung HDTV.

Some HDTV companies also provide DLNA server software, such as Samsung PC Share. For third party software, on PC, windows media player can set up a DLNA server. And there are a few popular ones with a lot of nice features, such as TVersity (has free version), Mezzmo, Serviio (free) etc.

There’s comparison on Mezzmo’s website: http://www.conceiva.com/products/mezzmo/faqs.asp#Competitors.

But my favorite is TVersity because it does URL streaming. Once you set it up, you can stream youtube videos and all other kinds of online media, even online live TV streaming. Isn’t this cool? Even though Samsung already have apps for youtube. But TVersity’s youtube streaming has much more features. But of course, due to the network capability, the picture quality may not be as good as you want.

I personally have a Samsung LN40C650 LCD HDTV. Samsung HDTVs are not officially supported by TVersity. According to what they said, Samsung seems not interested to give them support. Anyway. We already made it work.

Since Samsung HDTV is not officially supported, it’s not in the default device list of TVersity. I installed the lastest version of TVersity 1.9.3. When I first made all connections, my TV can sees all shared folder and even files. But it can play anything, not even music and pictures. After some research and getting some help the TVersity forum: http://forums.tversity.com/viewtopic.php?f=2&t=10992&st=0&sk=t&sd=a&start=60, it figured it out.

For my TVersity version, in the profiles.xml, there’s already a profile for Samsung HDTV 40A750 as follows.

<profile id=”28300414-0f77-48b3-bc6d-2361dcfcfe23″><!– SamsungTV –>
<friendlyName>Samsung TV</friendlyName>
<manufacturerName>Samsung</manufacturerName>
<modelName>LN46A750</modelName>

<HTTPHeader outServerUA=”Samsung HTTP streaming server contentFeatures.dlna.org: DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01500000000000000000000000000000 ” inUASubstr=”SamsungWiselinkPro”/>

<!– The Name of the media server device description file that should be used in conjunction with a player that corresponds to this profile –>
<deviceDescription name=”UPNP_AV_MediaServer_1.0.allservices.xml”/>

<!– The container identifier media players of this profile expect
–>
<contentDirectory shortUrl=”true” friendlyFilename=”false”/>

<!– When transcoding is needed to which format should we transcode –>
<transcodeTarget audio=”audio/mp3″ video=”video/mpeg” photo=”image/jpeg”
onlineAudio=”audio/mp3″ onlineVideo=”video/mpeg” onlinePhoto=”image/jpeg” />

<maxVideoInfo width=”1920″ height=”1080″ bitrate=”20000000″ fps=”60000/1001″></maxVideoInfo>
<minVideoInfo width=”0″ height=”0″ bitrate=”0″ fps=”15″></minVideoInfo>

<maxImageInfo width=”1920″ height=”1080″></maxImageInfo>
<minImageInfo width=”0″ height=”0″></minImageInfo>

<maxAudioInfo sampleRate=”48000″ bitsperSample=”16″ nchannels=”6″ bitrate=”1536000″></maxAudioInfo>
<minAudioInfo sampleRate=”44100″ bitsperSample=”8″ nchannels=”1″ bitrate=”20000″></minAudioInfo>

<fileInfo maxSize=”2147483647″/>

<mimetypeList>
<mimetype value=”audio/L16″/><!–PCM audio format–>
<mimetype value=”audio/wav”/><!– WAV audio format–>
<mimetype value=”audio/x-wav” rename=”audio/wav”/><!– Another mume type used for WAV audio format–>
<mimetype value=”audio/wave” rename=”audio/wav”/><!– Another mume type used for WAV audio format–>
<mimetype value=”audio/x-pn-wav” rename=”audio/wav”/><!– Another mume type used for WAV audio format–>

<mimetype value=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mpeg” rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/mp3″ rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mp3″ rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/mpeg3″ rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mpeg3″ rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/mpg” rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mpg” rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mpegaudio” rename=”audio/mpeg”/><!– MP3 audio format–>

<mimetype value=”image/jpeg”/><!– jpeg image format–>
<mimetype value=”image/jp2″/><!–JPEG2000 image format–>
<mimetype value=”image/bmp”/><!– BMP image format–>
<mimetype value=”image/png”/><!– PNG image format–>
<mimetype value=”image/gif”/><!– GIF image format–>

<mimetype value=”video/mpeg”/><!– MPEG (1 or 2 program or transport stream) video format–>
<mimetype value=”video/mpeg2″ rename=”video/mpeg”/><!– MPEG2 (program or transport stream) video format–>
<mimetype value=”video/mp2p” rename=”video/mpeg”/><!– MPEG2 program stream (VOB) video format–>
<mimetype value=”video/dvd” rename=”video/mpeg”/><!– MPEG2 program stream (VOB) video format–>
<mimetype value=”video/mp2t”/><!– MPEG2 transport stream video format–>

<mimetype value=”audio/aac” rename=”audio/mp4″/><!–MPEG4 audio format–>
<mimetype value=”audio/x-aac” rename=”audio/aac”/><!–MPEG4 audio format–>
<mimetype value=”audio/x-mpg” rename=”audio/mpeg”/><!– MP3 audio format–>
<mimetype value=”audio/x-mpegaudio” rename=”audio/mpeg”/><!– MP3 audio format–>

<mimetype value=”video/avi”><!– AVI video format–>
<codec name=”MPEG4″/><!– XVID, h263, DIVX version 4/5 and any mpeg4 ASP (layer 5) compliant stream (H264, AKA MPEG4 layer 10, is not included here)–>
<codec name=”MSMPEG4V3″/><!– MSMPEG4v3 which is also DIVX version 3 (fourcc DIV3)and AngelPotion (fourcc AP41)–>
<codec name=”H264″/><!– H264, AKA MPEG4 AVC or MPEG4 layer 10 or MPEG4.10 –>
<codec name=”MP2″ maxBitrate=”320000″/><!– MPEG2 Audio–><!– never tested in AVI–>
<codec name=”PCM_S16LE”/><!– Uncompressed PCM Audio–>
<codec name=”PCM_S16BE”/><!– Uncompressed DVD PCM Audio–><!– never tested–>
<codec name=”MP3″ maxBitrate=”320000″/><!– MPEG1 Layer 3 Audio–>
<codec name=”AC3″/><!– Dolby Digital AC3 Audio–>
</mimetype>
<mimetype value=”video/x-msvideo” rename=”video/avi”/>
<mimetype value=”video/x-divx” rename=”video/avi”/>

<mimetype value=”video/MP4V-ES”><!– MPEG4 video format–>
<codec name=”MPEG4″/><!– XVID, h263, DIVX version 4/5 and any mpeg4 ASP (layer 5) compliant stream (H264, AKA MPEG4 AVC or MPEG4 layer 10 or MPEG4.10, is not included here)–>
<codec name=”H263″/><!– h263–>
<codec name=”H264″/><!– H264, AKA MPEG4 AVC or MPEG4 layer 10 or MPEG4.10 –>
<codec name=”MP2″ maxBitrate=”320000″/><!– MPEG2 Audio–><!– never tested–>
<codec name=”PCM_S16LE”/><!– Uncompressed PCM Audio–>
<codec name=”PCM_S16BE”/><!– Uncompressed DVD PCM Audio–><!– never tested–>
<codec name=”AC3″/><!– Dolby Digital AC3 Audio–>
<codec name=”MP3″ maxBitrate=”320000″/><!– MPEG1 Layer 3 Audio–>
</mimetype>
<mimetype value=”video/mp4v” rename=”video/MP4V-ES”/>
<mimetype value=”video/mp4″ rename=”video/MP4V-ES”/><!– MPEG4 video format–>
<mimetype value=”video/h264″ rename=”video/avi”/><!– MPEG4 video format–>

</mimetypeList>
</profile>

But obviously that didn’t work for me at the beginning. The post above shows another profile, which is similar to what I have. It actually turn out that the TVersity cannot use the these profile ids to recognize my LN40C650. So then based on the info here: http://forums.tversity.com/viewtopic.php?f=2&t=10992&st=0&sk=t&sd=a&start=150#p108875, I added another line to the profile:

<devicesIP value = “x.x.x.x”/>, where xxx is your TV’s ip address. So then the top lines in the profile will be like following:

<profile id=”anything”><!– SamsungTV –>
<friendlyName>Samsung TV</friendlyName>
<manufacturerName>Samsung</manufacturerName>
<modelName>Samsung Model (LN40C650</modelName>
<icon>/images/device_icon_dtv.png</icon>
<devicesIP value=”x.x.x.x”/>

Then everything works great.

Here is my conclusion:

If we don’t have profile id of Samusng TV or another device, then basically, we can set profile id as anything. Then we put in devicesIP value. Then TVeristy will recognize Samsung TV without a problem.

Once it recognize it, we should be able to play at least some media. Whether or not we can play a media file, that’ll a matter of picking the right file format/codec and transcoding method. The whole profiles.xml specs are explained here: http://wiki.tversity.com/index.php/A_Technical_Specification_of_a_Device_Profile.

Here is the file formats and codecs supported by Samsung LN40C650 from the user manual.

Enjoy!

Follow

Get every new post delivered to your Inbox.

Join 64 other followers