% Automatic Picture Transmission (APT) Decoding
% Developed by Bill Dower, Kawaya Swana Eric Mbaka, Mark Roland, Vijo Varghese
% at the University of Kansas Electrical Engineering Department, May 2006

%%WXSat demodulation
clear all;
location=input('What is the location of the wav file?','s');
[x1, fs, bits]=wavread(location);
x=x1(1:length(x1),1);
if fs~=11025
    'The sampling rate must be 11.025 kHz'
    return;
end

max_amplitude = max([max(x), abs(min(x))]); % find the maximum amplitude
x = x./max_amplitude; % normalize the input signal
x=x-mean(x);
%%Low pass filter used in demodulation of the AM signal
%%LPF2=[0.00094088,0.0033589,0.0055189,0.0036794,-0.0033052,-0.010483,-0.011044,-0.0048324,0.00064426,-0.00029549,-0.0042247,-0.0042689,-0.00034302,0.0015215,-0.00087888,-0.00284,-0.00095985,0.0014604,0.0005022,-0.0017433,-0.0012112,0.0010288,0.0010139,-0.00099595,-0.0012617,0.00060163,0.0011518,-0.00049311,-0.0012128,0.00025968,0.0011333,-0.00015079,-0.0011211,2.2776e-006,0.0010536,8.8091e-005,-0.0010142,-0.00018761,0.00095439,0.00025906,-0.00090653,-0.00032863,0.00085345,0.00038515,-0.00080487,-0.00043647,0.00075673,0.00048101,-0.00071142,-0.00052183,0.0006671,0.00055825,-0.00062523,-0.00059312,0.00058287,0.00062378,-0.00054312,-0.00065385,0.00050271,0.00068074,-0.0004642,-0.00070706,0.00042611,0.00073308,-0.00038675,-0.00075643,0.00034931,0.00078155,-0.00030847,-0.00080293,0.00026944,0.00082547,-0.00022774,-0.00084549,0.00018605,0.00086492,-0.0001429,-0.0008824,9.9779e-005,0.0008999,-5.4113e-005,-0.00091426,9.5215e-006,0.00092986,3.9118e-005,-0.00094117,-8.6579e-005,0.00095279,0.00013694,-0.00096098,-0.00018676,0.0009689,0.0002391,-0.00097356,-0.00029074,0.00097894,0.00034702,-0.0009783,-0.00040037,0.00097982,0.00045977,-0.00097357,-0.0005148,0.00096989,0.0005754,-0.00095951,-0.00063325,0.0009499,0.00069531,-0.00093443,-0.0007558,0.000918,0.00081948,-0.00089514,-0.00088027,0.00087203,0.0009443,-0.00084232,-0.0010051,0.0008124,0.0010686,-0.00077672,-0.0011306,0.00073816,0.0011927,-0.00069513,-0.0012537,0.00064859,0.0013139,-0.00059801,-0.0013722,0.00054516,0.0014311,-0.00048714,-0.0014883,0.00042496,0.0015435,-0.00035955,-0.0015987,0.00028719,0.0016479,-0.00021506,-0.0016991,0.00013506,0.0017446,-5.3995e-005,-0.0017903,-3.4117e-005,0.0018301,0.00012371,-0.001869,-0.00022005,0.0019008,0.00031576,-0.0019336,-0.00041963,0.0019588,0.00052427,-0.001982,-0.00063387,0.0020003,0.00074747,-0.0020127,-0.00086228,0.002023,0.0009833,-0.0020261,-0.0011062,0.0020254,0.0012347,-0.0020155,-0.0013622,0.0020038,0.0014965,-0.0019828,-0.0016314,0.0019567,0.0017703,-0.0019222,-0.0019096,0.0018829,0.0020535,-0.0018346,-0.0021997,0.0017754,0.002342,-0.0017152,-0.0024909,0.0016457,0.0026443,-0.0015635,-0.0027972,0.0014686,0.0029414,-0.0013785,-0.0031004,0.0012694,0.0032571,-0.001148,-0.0034102,0.0010194,0.0035652,-0.00087886,-0.0037186,0.00072862,0.0038718,-0.00056956,-0.00403,0.00039237,0.0041846,-0.0002002,-0.0043313,3.7925e-006,0.0044855,0.00021392,-0.0046317,-0.00043952,0.004783,0.00068494,-0.0049331,-0.00095188,0.0050747,0.0012314,-0.0052178,-0.001533,0.0053554,0.0018526,-0.0054917,-0.0021941,0.0056273,0.0025625,-0.0057587,-0.0029592,0.0058831,0.0033814,-0.0060076,-0.0038404,0.006123,0.0043302,-0.0062394,-0.0048634,0.0063531,0.0054478,-0.0064579,-0.0060814,0.0065655,0.0067885,-0.0066577,-0.0075618,0.006751,0.0084287,-0.006836,-0.0094022,0.0069144,0.010504,-0.0069948,-0.011781,0.0070622,0.013264,-0.0071316,-0.015035,0.0071898,0.017181,-0.0072417,-0.019853,0.0072908,0.0233,-0.0073271,-0.027928,0.0073651,0.034542,-0.0073911,-0.044827,0.0074146,0.0632,-0.0074322,-0.10583,0.0074398,0.31822,0.49255,0.31822,0.0074398,-0.10583,-0.0074322,0.0632,0.0074146,-0.044827,-0.0073911,0.034542,0.0073651,-0.027928,-0.0073271,0.0233,0.0072908,-0.019853,-0.0072417,0.017181,0.0071898,-0.015035,-0.0071316,0.013264,0.0070622,-0.011781,-0.0069948,0.010504,0.0069144,-0.0094022,-0.006836,0.0084287,0.006751,-0.0075618,-0.0066577,0.0067885,0.0065655,-0.0060814,-0.0064579,0.0054478,0.0063531,-0.0048634,-0.0062394,0.0043302,0.006123,-0.0038404,-0.0060076,0.0033814,0.0058831,-0.0029592,-0.0057587,0.0025625,0.0056273,-0.0021941,-0.0054917,0.0018526,0.0053554,-0.001533,-0.0052178,0.0012314,0.0050747,-0.00095188,-0.0049331,0.00068494,0.004783,-0.00043952,-0.0046317,0.00021392,0.0044855,3.7925e-006,-0.0043313,-0.0002002,0.0041846,0.00039237,-0.00403,-0.00056956,0.0038718,0.00072862,-0.0037186,-0.00087886,0.0035652,0.0010194,-0.0034102,-0.001148,0.0032571,0.0012694,-0.0031004,-0.0013785,0.0029414,0.0014686,-0.0027972,-0.0015635,0.0026443,0.0016457,-0.0024909,-0.0017152,0.002342,0.0017754,-0.0021997,-0.0018346,0.0020535,0.0018829,-0.0019096,-0.0019222,0.0017703,0.0019567,-0.0016314,-0.0019828,0.0014965,0.0020038,-0.0013622,-0.0020155,0.0012347,0.0020254,-0.0011062,-0.0020261,0.0009833,0.002023,-0.00086228,-0.0020127,0.00074747,0.0020003,-0.00063387,-0.001982,0.00052427,0.0019588,-0.00041963,-0.0019336,0.00031576,0.0019008,-0.00022005,-0.001869,0.00012371,0.0018301,-3.4117e-005,-0.0017903,-5.3995e-005,0.0017446,0.00013506,-0.0016991,-0.00021506,0.0016479,0.00028719,-0.0015987,-0.00035955,0.0015435,0.00042496,-0.0014883,-0.00048714,0.0014311,0.00054516,-0.0013722,-0.00059801,0.0013139,0.00064859,-0.0012537,-0.00069513,0.0011927,0.00073816,-0.0011306,-0.00077672,0.0010686,0.0008124,-0.0010051,-0.00084232,0.0009443,0.00087203,-0.00088027,-0.00089514,0.00081948,0.000918,-0.0007558,-0.00093443,0.00069531,0.0009499,-0.00063325,-0.00095951,0.0005754,0.00096989,-0.0005148,-0.00097357,0.00045977,0.00097982,-0.00040037,-0.0009783,0.00034702,0.00097894,-0.00029074,-0.00097356,0.0002391,0.0009689,-0.00018676,-0.00096098,0.00013694,0.00095279,-8.6579e-005,-0.00094117,3.9118e-005,0.00092986,9.5215e-006,-0.00091426,-5.4113e-005,0.0008999,9.9779e-005,-0.0008824,-0.0001429,0.00086492,0.00018605,-0.00084549,-0.00022774,0.00082547,0.00026944,-0.00080293,-0.00030847,0.00078155,0.00034931,-0.00075643,-0.00038675,0.00073308,0.00042611,-0.00070706,-0.0004642,0.00068074,0.00050271,-0.00065385,-0.00054312,0.00062378,0.00058287,-0.00059312,-0.00062523,0.00055825,0.0006671,-0.00052183,-0.00071142,0.00048101,0.00075673,-0.00043647,-0.00080487,0.00038515,0.00085345,-0.00032863,-0.00090653,0.00025906,0.00095439,-0.00018761,-0.0010142,8.8091e-005,0.0010536,2.2776e-006,-0.0011211,-0.00015079,0.0011333,0.00025968,-0.0012128,-0.00049311,0.0011518,0.00060163,-0.0012617,-0.00099595,0.0010139,0.0010288,-0.0012112,-0.0017433,0.0005022,0.0014604,-0.00095985,-0.00284,-0.00087888,0.0015215,-0.00034302,-0.0042689,-0.0042247,-0.00029549,0.00064426,-0.0048324,-0.011044,-0.010483,-0.0033052,0.0036794,0.0055189,0.0033589,0.00094088];
[B,A] = butter(9,1000/(fs/2),'low');
ensig=abs(x);  %%Rectifies the AM signal                   
out=filter(B,A,ensig);  %%Preforms the smothing function in Envelope detection
out=out-mean(out);%% Remove any DC                 
y=out/max(out);%%Normalizes the message signal
t=[0:1/fs:1/160];%%Length of the sync wave form in time at the 
%%sampling freq
cA=(square(1040*t*(2*pi)));%%Creates the expected sync pulse
hA=conv(transpose(cA),y(1:length(y)));%%Preforms the correlation
syncA=hA(length(cA):length(hA));%%Removes the convolution tails

lines=floor(length(syncA)*2/fs);%%Determines the number of possible rows 
%%in the picture
len=floor(.5*fs);%%Determines the length in samples of each line
%%Finds the largest point in the correlation to determine where each row
%%starts
for l=1:lines;
    [H,I]=max(syncA((l-1)*len+1:l*len));
    list(l)=I+len*l;
end
%%Determines the spacing between the current end of the sync wave and
%%the end of the sync wave four lines previous to the current position 
test(1:4)=[0, 0, 0, 0];
for l=5:(length(list)-1)
    test(l)=list(l)-list(l-4);
end
%%Determines the first detected sync pulse with the correct spacing.  start
%%determines where the first sample of the first line is.
count=1;
start=0;
while(start==0)
    if test(count)>(2*fs-5)
        if test(count)<(2*fs+5)
            start=list(count);
        end
    end
   count=count+1;
end

badcount=0; %%refers to the number of incorrectly spaced detected sync pulses
goodindex=count;%%list of the index points for each row
for k=count:(length(list)-1)
    if test(k)>(2*fs-5) && test(k)<(2*fs+5) %%Checks to see if the index is 
%%correctly spaced from the index value 2 seconds before
            goodlist(k-count+1)=list(k);%%If so adds the value to the list
            badcount=0;%%Resets the number of badcounts
            goodindex=k;%%Saves the last known good index
    else
        %%If false the number of badcounts is increased by one
        badcount=badcount+1;
        %%The value of the bad index is interpolated from the last known
        %%good value
        goodlist(k-count+1)=list(goodindex)+floor((fs/2)*badcount);
    end
end

%%determines the length of each row due to the sampling frequency
colums=ceil(fs/2);
%%determines the number of rows from the data
rows=floor((length(y)-start)/colums)
if (rows/2-floor(rows/2))==0
    rows=rows-3;
end
%%Creates a matrix of the signal that was sent using the interpolated index
for l=1:rows-1
raw(l,1:5513)=y(goodlist(l):goodlist(l)+colums-1);
end

%%Resamples the signal in each row so that the picture will have the right
%%number of data points so that the aspect ratio is 1:1
for k=1:length(goodlist)
    M(k,1:4161)=resample(raw(k,1:colums),1664,2205);
end
fs=4160;%%New sampling frequency
%%Contrast Loop so that the signal will have the right amount of contrast
%%for the user.
% loop=1;
% scale=0;
% while (loop==1)
% %%Normalizes the data points between 0 and 255 for the image
% minM=min(min(M));
% maxM=max(max(M));
% range=(maxM-minM);
% Map=M./range;
% minMap=min(min(Map));
% Map=Map-minMap;
% Map=Map*255*.25^scale;
figure(1)
imagesc(M);
axis image;
colormap(gray);
% contrast=input('Would you like to make the image brighter or darker?(b=bright d=dark n=no)','s');
% %%increases of decreases the scaling exponent
% if contrast=='d'
%     scale=scale+1;
% elseif contrast=='b'
%     scale=scale-1;
% else
%     loop=0;
%     figure(1)
% end;
% end;
%%Since some satelites pass South to North the Image will have the south at
%%the top of the image and the north at the botom of the image which defies
%%the normal convention.  This loop flips the data, scales and normalizes
%%it.
flip=input('Would you like to flip the image? (y=yes n=no)','s');
if flip=='y'
    M=flipud(M);
    M=fliplr(M);
%     minM=min(min(M));
%     maxM=max(max(M));
%     range=(maxM-minM);
%     Map=M./range;
%     minMap=min(min(Map));
%     Map=Map-minMap;
%     Map=Map*255*.25^scale;
%     figure(1)
    imagesc(M);
    axis image;
    colormap(gray);
end
%%This is the color mapping for the data which does not work that well
% color=[0.290196090936661,0.560784339904785,0.709803938865662;0.293725490570068,0.559215724468231,0.713464081287384;0.297254920005798,0.557647109031677,0.717124223709106;0.300784319639206,0.556078433990478,0.720784306526184;0.304313749074936,0.554509818553925,0.724444448947906;0.307843148708344,0.552941203117371,0.728104591369629;0.311372548341751,0.551372587680817,0.731764733791351;0.314901977777481,0.549803972244263,0.735424876213074;0.318431377410889,0.548235297203064,0.739084959030151;0.321960806846619,0.54666668176651,0.742745101451874;0.325490206480026,0.545098066329956,0.746405243873596;0.329019606113434,0.543529450893402,0.750065386295319;0.332549035549164,0.541960835456848,0.753725528717041;0.336078435182571,0.540392160415649,0.757385611534119;0.339607864618301,0.538823544979096,0.761045753955841;0.343137264251709,0.537254929542542,0.764705896377564;0.346666663885117,0.535686314105988,0.768366038799286;0.350196093320847,0.534117698669434,0.772026181221008;0.353725492954254,0.532549023628235,0.775686264038086;0.357254922389984,0.530980408191681,0.779346406459808;0.360784322023392,0.529411792755127,0.783006548881531;0.364313721656799,0.527843177318573,0.786666691303253;0.367843151092529,0.526274561882019,0.790326833724976;0.371372550725937,0.52470588684082,0.793986916542053;0.374901980161667,0.523137271404266,0.797647058963776;0.378431379795074,0.521568655967712,0.801307201385498;0.381960779428482,0.520000040531158,0.80496734380722;0.385490208864212,0.518431425094604,0.808627486228943;0.38901960849762,0.516862750053406,0.81228756904602;0.39254903793335,0.515294134616852,0.815947711467743;0.396078437566757,0.513725519180298,0.819607853889465;0.431372553110123,0.426143825054169,0.546405255794525;0.466666698455811,0.338562101125717,0.273202627897263;0.501960813999176,0.250980406999588,0;0.418300688266754,0.292810469865799,0;0.33464053273201,0.33464053273201,0;0.250980406999588,0.376470625400543,0;0.167320266366005,0.418300688266754,0;0.083660133183002,0.460130751132965,0;0,0.501960813999176,0;0.107563026249409,0.537815153598785,0.107563026249409;0.215126052498817,0.573669493198395,0.215126052498817;0.322689086198807,0.609523832798004,0.322689086198807;0.430252104997635,0.645378172397614,0.430252104997635;0.537815153598785,0.681232511997223,0.537815153598785;0.645378172397614,0.717086851596832,0.645378172397614;0.752941191196442,0.752941191196442,0.752941191196442;0.767474055290222,0.767474055290222,0.767474055290222;0.782006919384003,0.782006919384003,0.782006919384003;0.796539783477783,0.796539783477783,0.796539783477783;0.811072647571564,0.811072647571564,0.811072647571564;0.825605571269989,0.825605571269989,0.825605571269989;0.84013843536377,0.84013843536377,0.84013843536377;0.85467129945755,0.85467129945755,0.85467129945755;0.869204163551331,0.869204163551331,0.869204163551331;0.883737027645111,0.883737027645111,0.883737027645111;0.898269891738892,0.898269891738892,0.898269891738892;0.912802755832672,0.912802755832672,0.912802755832672;0.927335619926453,0.927335619926453,0.927335619926453;0.941868543624878,0.941868543624878,0.941868543624878;0.956401407718658,0.956401407718658,0.956401407718658;0.970934271812439,0.970934271812439,0.970934271812439;0.98546713590622,0.98546713590622,0.98546713590622;1,1,1];
% imwrite(Map, 'test_image.jpg', 'jpg');
% colormap(color);