ita_tools_aliasing_demo.m 9.88 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
function ita_tools_aliasing_demo
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here

% <ITA-Toolbox>
% This file is part of the application Tools for the ITA-Toolbox. All rights reserved.
% You can find the license for this m-file in the application folder.
% </ITA-Toolbox>


%% data

data.freqRange = [10 450];
Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
14
data.freqValue = 75;
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
data.phaseValue = 0;

data.mainSineFreq = 100;
data.masterSamplingFrequency = 44100;
% use 50 waves to calculate the new frequency
data.calculateWaves = 50;
% only plot 5
data.plotWaves = 5;

data.stemPlot = 0;
data.interpolatedPlot = 0;

%% GUI

screenSize = get(0, 'ScreenSize');
screenSize(3) = 1920;
screenSize(4) = 1200;
figSize = screenSize(3:4)*0.9;

h.f = figure('outerposition',  [screenSize(3:4)*0.05  figSize ], 'name', 'ITA Aliasing Demo', 'toolbar', 'none', 'menubar', 'none',  'numberTitle', 'off', 'tag', 'ita_fsp', 'nextPlot', 'new');

h.ax_pos3d       = axes('Parent', h.f, 'outerposition', [-0.1 -0.05 1 1.1]);

% h.tx_resultInfo  = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [7 /20 1/20  1/5 1/30]);
% h.pb_exportGroup = uicontrol('style', 'pushbutton', 'parent', h.f, 'units', 'normalized', 'position', [7 2  2 1.1]/20, 'callback',@exportGroupPositions, 'string', 'export group');

% h.pb_exportResults = uicontrol('style', 'pushbutton', 'parent', h.f, 'units', 'normalized', 'position', [9.1 2.6  1.8 0.5]/20, 'callback',@exportSearchResult, 'string', 'export  all results');

Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
43
h.freqSlider = uicontrol('style', 'slider', 'parent', h.f,'units', 'normalized', 'position', [17 11  1.8 0.5]/20, 'callback',@freqSliderCallback);
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
h.freqEdit = uicontrol('style', 'edit', 'parent', h.f, 'units', 'normalized', 'position', [17 10.4  1.8 0.5]/20,'string',num2str(data.freqValue) , 'callback',@freqEditCallback);
h.hzText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [18.45 10.5  0.3 0.3]/20,'string','Hz');
h.freqInfoText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [17 11.5  1.8 0.3]/20,'string','Sampling Frequency');

set(h.freqSlider,'Interruptible','off');
set(h.freqSlider,'Min',data.freqRange(1));
set(h.freqSlider,'Max',data.freqRange(2));
set(h.freqSlider,'Value',data.freqValue);

h.phaseSlider = uicontrol('style', 'slider', 'parent', h.f, 'units', 'normalized', 'position', [17 9  1.8 0.5]/20, 'callback',@phaseSliderCallback);
h.phaseEdit = uicontrol('style', 'edit', 'parent', h.f, 'units', 'normalized', 'position', [17 8.4  1.8 0.5]/20,'string','0');
h.hzText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [18.48 8.5  0.3 0.3]/20,'string','°');
h.phaseInfoText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [17 9.5  1.8 0.3]/20,'string','Phase');

set(h.phaseSlider,'Interruptible','off');
set(h.phaseSlider,'Min',0);
set(h.phaseSlider,'Max',360);
set(h.phaseSlider,'Value',0);


h.interpolatedEdit = uicontrol('style', 'edit', 'parent', h.f, 'units', 'normalized', 'position', [17 7  1.8 0.5]/20,'string','');

h.interpolatedInfoText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [17 7.5  1.8 0.3]/20,'string','Reconstructed Sine');
h.hzText = uicontrol('style', 'text', 'parent', h.f, 'units', 'normalized', 'position', [18.45 7.1  0.3 0.3]/20,'string','Hz');

Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
69
h.showPlotCheckbox = uicontrol('style', 'checkbox','parent', h.f, 'units', 'normalized', 'position', [17 13.5  1.8 0.5]/20,'string','Plot sine' , 'callback',@sineCheckboxCallback);
70 71 72 73 74
h.samplingCheckbox = uicontrol('style', 'checkbox', 'parent', h.f, 'units', 'normalized', 'position', [17 13  1.8 0.5]/20,'string','Plot sampling points' , 'callback',@samplingCheckboxCallback);
h.reconstructedCheckbox = uicontrol('style', 'checkbox', 'parent', h.f, 'units', 'normalized', 'position',   [17 12.5  1.8 0.5]/20,'string','Plot reconstructed sine' , 'callback',@reconstructedCheckboxCallback);

data.plotSampling = 0;
data.plotReconstructed = 0;
Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
75 76
data.plotSine = 0;
data.sinePlot = 0;
77 78 79 80 81 82 83 84
guiData.handles = h;
guiData.data    = data;



guidata(h.f, guiData)


Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
85
populateGUI(guiData);
86 87 88 89

end


Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
90
function guiData = populateGUI(guiData)
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

    data = guiData.data;
    h = guiData.handles;

    % only plot the main sine here, the rest is done in "newPlot"
    masterSamplingFreq = data.masterSamplingFrequency;
    sineFreq = 100;
    sine = ita_generate('sine',1,sineFreq,masterSamplingFreq,15);

    calculateWaves = data.calculateWaves;
    plotWave = data.plotWaves;
    % plot only the first plotWaves waves
    sineTime = sine.timeData;
    % cut to 5 waves
    sineTime = sineTime(1:(calculateWaves/sineFreq*masterSamplingFreq));
Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
106 107 108
    if data.plotSine
        data.sinePlot = plot(h.ax_pos3d,sineTime,'LineWidth',4,'Color',[0 0 1]);
    end
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    hold all
    data.xAxis = 1:size(sineTime);
    
    xlim([0 (plotWave/sineFreq*masterSamplingFreq)])
    
    % set latex x-labels
    xLabel = 0:1/2:plotWave;
    xLabel = arrayfun(@num2str,xLabel,'Uniform',false);
    xLabel = strcat(xLabel,' $\lambda$');
    set(h.ax_pos3d,'Xtick',0:masterSamplingFreq/(2*sineFreq):plotWave*masterSamplingFreq/sineFreq, 'XTickLabel', '','XGrid','on')
    set(h.ax_pos3d,'YTickLabel',[]);
    for idxName = 1:numel(xLabel)
        text((idxName-1)*masterSamplingFreq/(2*sineFreq), -1.15, xLabel{idxName}, 'HorizontalAlignment', 'center', 'verticalAlignment', 'baseline','Fontsize',20,'interpreter', 'latex')
    end
    
    
    % format
    xlim([0 (plotWave/sineFreq*masterSamplingFreq)])
    ylim([-1.1 1.1])
    
    data.sineTime = sineTime;
    
    guiData.data = data;
    
    guiData = newPlot(guiData);
    guidata(h.f, guiData)

end


% this function is called whenever something changes
% first: the old plots are deleted
function guiData = newPlot(guiData)
    data = guiData.data;
    h = guiData.handles;
    % delete old plots
    if data.stemPlot ~= 0
        delete(data.stemPlot);
        data.stemPlot = 0;
    end
    
    if data.interpolatedPlot ~= 0
       delete(data.interpolatedPlot);
       data.interpolatedPlot = 0;
    end
    
Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
155 156 157 158 159 160
    if data.plotSine == 0
       if data.sinePlot ~= 0
        delete(data.sinePlot)
       end
       data.sinePlot = 0;
    end
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
    
    masterSamplingFreq = data.masterSamplingFrequency;
    calculateWaves = data.calculateWaves;
    plotWave = data.plotWaves;
    
    % get the values from the text edits
%     sineFreq = str2double(get(data.sineFreqEdit,'String'));
    sineFreq = data.mainSineFreq;
    samplingFreq = data.freqValue;
    
    % the sampling points
    samplingPoints = (0:(calculateWaves*samplingFreq/sineFreq)-1)*1/samplingFreq*masterSamplingFreq;
    % mod to avoid overflow (+1 to avoid 0)
    samplingPoints = mod(samplingPoints + data.phaseValue./360* masterSamplingFreq/sineFreq,length(data.sineTime))+1;
    sampledSine = zeros(size(data.sineTime));
    sampledSine(round(samplingPoints)) = data.sineTime(round(samplingPoints));
    % the positions of the sampling points
    x = round(samplingPoints);
    % and the values
    y = sampledSine(round(samplingPoints));

    if (data.plotSampling)
        % stem plot
        data.stemPlot = stem(x,y,'LineWidth',2,'Color',[0 0.5000 0]);
        % set(get(h,'Baseline'),'Visible','off')
    end

    if (data.plotReconstructed)
        % fit the sampling points to a new wave and plot if a fit is found
        [f,gof] = fit( x.', y, 'sin1');
        if (abs(gof.rsquare - 1)) < 0.1 % good fit
            x2 = data.xAxis;
            data.interpolatedPlot = plot(h.ax_pos3d,x2,f.a1*sin(f.b1*x2+f.c1),'Color','r');

            % calculate new frequency from interpolated values
            newFreq = f.b1*masterSamplingFreq./(2*pi);    
            set(h.interpolatedEdit,'String',num2str(round(newFreq)))
        else
            set(h.interpolatedEdit,'String','No fit')  
        end
    end
    
    guiData.data = data;
    
    
end


function freqSliderCallback(hObject, ~)
    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    realValue = get(hObject,'Value');
    guiData.data.freqValue = round(realValue);
    set(guiData.handles.freqEdit,'string',num2str(guiData.data.freqValue));
    guiData = newPlot(guiData);
    
    guidata(hObject, guiData);
    

end

function freqEditCallback(hObject,~)
    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    guiData.data.freqValue = str2double(get(hObject,'String'));
    set(guiData.handles.freqEdit,'string',num2str(guiData.data.freqValue));
Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
229 230
    set(guiData.handles.freqSlider,'Value',guiData.data.freqValue);
    
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    guiData = newPlot(guiData);
    
    guidata(hObject, guiData);
end


function phaseSliderCallback(hObject, ~)

    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    realValue = get(hObject,'Value');
    guiData.data.phaseValue = round(realValue);
    set(guiData.handles.phaseEdit,'string',num2str(guiData.data.phaseValue));
    guiData = newPlot(guiData);
    
    guidata(hObject, guiData);

end

Jan-Gerrit Richter's avatar
Jan-Gerrit Richter committed
251 252 253 254 255 256 257 258 259 260 261 262
function sineCheckboxCallback(hObject,~)
    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    realValue = get(hObject,'Value');
    guiData.data.plotSine = realValue;
    guiData = populateGUI(guiData);
    
    guidata(hObject, guiData);
end


263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
function samplingCheckboxCallback(hObject,~)
    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    realValue = get(hObject,'Value');
    guiData.data.plotSampling = realValue;
    guiData = newPlot(guiData);
    
    guidata(hObject, guiData);
end

function reconstructedCheckboxCallback(hObject,~)
    guiData = guidata(hObject);
    
    % calculate the frequency from the value and the data.freqRange
    realValue = get(hObject,'Value');
    guiData.data.plotReconstructed = realValue;
    guiData = newPlot(guiData);
    
    if (realValue == 0)
       set(guiData.handles.interpolatedEdit,'String','')   
    end
    guidata(hObject, guiData);
end