This documentation page applies to an outdated major AMT version. We show it for archival purposes only.
Click here for the documentation menu and here to download the latest AMT (1.6.0).
function output = exp_lindemann1986(varargin)
%EXP_LINDEMANN1986 Figures from Lindemann (1986)
% Usage: output = exp_lindemann1986(flag)
%
% EXP_LINDEMANN1986(flag) reproduces the results for the figure given
% by flag from the Lindemann (1986) paper. It will also plot the
% results. The format of its output depends on the chosen figure. If not
% otherwise stated, the cross-correlation of a pure tone sinusoids with
% f=500 Hz and different ITDs, ILDs or a combination of both is
% calculated. Because of the stationary character of the input signals,
% T_{int} = inf is used to produce only one time step in the crosscorr
% output.
%
% The following flags can be specified;
%
% 'plot' plot the output of the experiment. This is the default.
%
% 'noplot' Don't plot, only return data.
%
% 'auto' Re-calculate the file if it does not exist. Return 1 if the
% file exist, otherwise 0. This is the default
%
% 'redo' Always recalculate the results.
%
% 'cached' Always use the cached version. Default.
%
% 'fig6' Reproduce Fig.6 from Lindemann (1986). The cross-correlation is
% calculated for different ITDs and different inhibition factors
% c_s=0,0.3,1. Afterwards for every c_s the correlation is
% plotted for every used ITD dependend on the correlation-time
% delay. The output is cross-correlation result of the figure.
% The output has dimensions: number of c_s conditions x
% nitds x delay line length
%
% 'fig7' Reproduce Fig.7 from Lindemann (1986). The cross-correlation
% is calculated for different ITDs and different inhibition
% factors c_s=0,0.2,0.4,0.6,0.8,1.0. Afterwards for every
% c_s the displacement of the centroid of the auditory image
% is calculated and plotted depending on the ITD. The output is
% the displacement of the centroid for different c_s values.
% The output has dimensions: c_s x nitds
%
% 'fig8' Reproduce Fig.8 from Lindemann (1986). The cross-correlation
% is calculated for different ILDs and different inhibition factors
% c_s = 0.3, 1. Afterwards for every c_s the ILD is plotted
% depending on the correlation time. The output is the
% cross-correlation result of the figure. The dimensions of the
% output are: number of c_s conditions x nilds x delay line length.
%
% 'fig10' Reproduce Fig.10 from Lindemann (1986). The
% cross-correlation is calculated for different ILDs with an
% inhibition factor of c_s = 0.3 and a monaural detector
% factor w_f = 0.035. Afterwards the ILD is plotted depending
% on the correlation time. The output is the cross-correlation
% result of the figure. The output has dimensions:
% number of c_s conditions x nilds x delay line length
%
% 'fig11' Reproduce Fig.11 from Lindemann (1986). The centroid
% position is calculated for different ILDs, an inhibition
% factor c_s = 0.3 and a monaural detector factor w_f =
% 0.035. Afterwards for every c_s the displacement of the
% centroid is plotted dependend on the ILD. The output is the
% cross-correlation result of the to figure. The dimensions of
% the output are: number of c_s conditions x nilds x delay
% line length
%
% 'fig12' Reproduce Fig.12 from Lindemann (1986). The centroids are
% calculated for combinations of ITDs and ILDs. After the
% calculation the values for the centroids of the stimuli are
% searched to find the nearest value to 0. The corresponding ILD
% value is stored in output and plotted depending on the
% ITD. The output is the simulated results for a trading
% experiment. The ILD value for getting a centroid near the
% center for an combined ITD, ILD stimulus with a given ITD
% value. The output has dimensions: number of ITDs x 1
%
% 'fig13' Reproduce Fig.13 from Lindemann (1986). The centroids are
% calculated for ILD only and ITD/ILD combination
% stimuli. After the calculation the values for the centroids
% of the ILD only stimuli are searched to find the nearest
% value to the centroid of a given combined stimulus. The
% resulting ILD value is stored for different combinaition
% values and plotted dependend on ITD. The output is the ILD
% value for getting the same lateralization with an ILD only
% stimulus compared to a stimulus with both ITD and ILD.
% The output has dimensions: number of ILDs x number of ITDs
%
% 'fig14a' Reproduce fig.14 (a) from Lindemann (1986). The
% cross-correlations for a combination of ILDs and a ITD of
% ~1ms are calculated. This is done for different ILDs and
% different inhibition factors c_s = 0,0.2,0.4,0.6,1.
% Afterwards for every c_s the centroid of the auditory image
% is calculated and plotted dependend on the ILD. The output is
% the displacement of the centroid for different c_s values
% and ILDs. The output has dimensions: c_s x nilds
%
% 'fig14b' Reproduce Fig.14 (b) from Lindemann (1986). The
% cross-correlations for a combination of ILDs and a ITD of ~1ms
% are calculated. This is done for different small ILDs with a
% standard deviation of 0-5. Afterwards for every standard
% deviation the mean centroid displacement is calculated and
% plotted dependend on the ITD. The output is the displacement
% of the centroid as a function of the ITD averaged over
% different small ILD with a standard deviation of 0,1,2,3,4,5.
% The output has dimensions: nilds x nitds
% THIS FIGURE DOES NOT SEEM TO MATCH THE PAPER!
%
% 'fig15' Reproduce Fig.15 from Lindemann (1986). The cross-correlation
% for an ITD of -0.5ms is calculated. This is done for
% different ILDs, an inhibition factor c_s = 0.3 and a
% monaural detector factor w_f = 0.035. Afterwards for every
% c_s the ILD is plotted depending on the correlation
% time. The output is the cross-correlation result. The output
% has dimensions: number of c_s conditions x nilds x delay line
% length
%
% 'fig16' Reproduces Fig.16 from Lindemann (1986). The
% cross-correlations for combinations of ITDs and ILDs are
% calculated. Afterwards the combinations of ILD and ITD are
% looked for the ones that have two peaks in its
% cross-correlation which have the nearly same height. The
% corresponding ILD value is than stored in output and plotted
% dependend on the ITD. The output is the ILD value for which
% the cross-correlation for a combined ITD, ILD stimulus has
% two peaks with the same (nearest) height, depending on the
% ITD. The output has dimensions: number of ITDs x 1
%
% 'fig17' Reproduce Fig.17 from Lindemann (1986). The
% cross-correlation for ITD/ILD combination and ITD only
% stimuli is calculated. Afterwards the values for the
% centroids and maxima of the ITD only stimuli are searched to
% find the nearest value to the centroid and maxima of a given
% combined stimulus. The resulting ITD value is stored for
% different combinaition values. The output is the ITD
% value for getting the same lateralization with an ITD only
% stimulus compared to a stimulus with both ITD and ILD using
% the centroid of the cross-correlation. The output has
% dimensions: number of ITDs x number of ILDs.
%
% 'fig18' Reproduce Fig.18 from Lindemann (1986). The cross-correlation
% of pink noise with different interaural coherence values is
% calculated. Afterwards for every interaural coherence value
% the correlation is plotted dependend on the correlation-time
% delay. The output is the cross-correlation result of the
% figure. The output has dimensions: number of interaural
% coherences x delay line length
%
% If no flag is given, the function will print the list of valid flags.
%
% Examples:
% ---------
%
% To display Figure 6 use :
%
% exp_lindemann1986('fig6');
%
% To display Figure 7 use :
%
% exp_lindemann1986('fig7');
%
% To display Figure 8 use :
%
% exp_lindemann1986('fig8');
%
% To display Figure 10 use :
%
% exp_lindemann1986('fig10');
%
% To display Figure 11 use :
%
% exp_lindemann1986('fig11');
%
% To display Figure 12 use :
%
% exp_lindemann1986('fig12');
%
% To display Figure 13 use :
%
% exp_lindemann1986('fig13');
%
% To display Figure 14a use :
%
% exp_lindemann1986('fig14a');
%
% To display Figure 15 use :
%
% exp_lindemann1986('fig15');
%
% To display Figure 16 use :
%
% exp_lindemann1986('fig16');
%
% To display Figure 17 use :
%
% exp_lindemann1986('fig17');
%
% To display Figure 18 use :
%
% exp_lindemann1986('fig18');
%
% References:
% W. Lindemann. Extension of a binaural cross-correlation model by
% contralateral inhibition. I. Simulation of lateralization for
% stationary signals. J. Acoust. Soc. Am., 80:1608--1622, 1986.
%
%
%
% Url: http://amtoolbox.sourceforge.net/amt-0.10.0/doc/experiments/exp_lindemann1986.php
% Copyright (C) 2009-2020 Piotr Majdak and the AMT team.
% This file is part of Auditory Modeling Toolbox (AMT) version 0.10.0
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
% AUTHOR: Hagen Wierstorf
definput.import={'amt_cache'};
definput.flags.type={'missingflag','fig6','fig7','fig8','fig10','fig11',...
'fig12','fig13','fig14a','fig14b','fig15',...
'fig16','fig17','fig18'};
definput.flags.plot={'plot','noplot'};
[flags,keyvals] = ltfatarghelper({},definput,varargin);
if flags.do_missingflag
flagnames=[sprintf('%s, ',definput.flags.type{2:end-2}),...
sprintf('%s or %s',definput.flags.type{end-1},definput.flags.type{end})];
error('%s: You must specify one of the following flags: %s.',upper(mfilename),flagnames);
end;
%% ------ FIG 6 -----------------------------------------------------------
if flags.do_fig6
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0;
M_f = 6; % not used, if w_f==0
c_s = [0,0.3,1];
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 21 ITD points between 0~ms and 1~ms
nitds = 21; % number of used ITDs
ndl = round(fs/1000)+1; % length of the delay line (see lindemann1986_bincorr.m)
itd = linspace(0,1,nitds);
output=amt_cache('get','fig6',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nitds,ndl);
for ii = 1:nitds;
% Generate ITD shifted sinusoid
sig = sig_itdsin(f,itd(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
output(jj,ii,:) = tmp(:,fc-4);
end
end
amt_cache('set','fig6',output);
end;
if flags.do_plot
% ------ Plotting ------
% Generate time axis
tau = linspace(-1,1,ndl);
% Plot figure for every c_s condition
for jj = 1:length(c_s)
figure;
mesh(tau,itd(end:-1:1),squeeze(output(jj,:,:)));
view(0,57);
xlabel('correlation-time tau (ms)');
ylabel('interaural time difference (ms)');
set(gca,'YTick',0:0.2:1);
set(gca,'YTickLabel',{'1','0.8','0.6','0.4','0.2','0'});
tstr = sprintf('c_s = %.1f\nw_f = 0\nf = %i Hz\n',c_s(jj),f);
title(tstr);
end
end;
end;
%% ------ FIG 7 -----------------------------------------------------------
if flags.do_fig7
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0;
M_f = 6; % not used, if w_f==0
c_s = 0:0.2:1;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 21 ITD points between 0~ms and 1~ms
nitds = 21; % number of used ITDs
itd = linspace(0,1,nitds);
output=amt_cache('get','fig7',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nitds);
for ii = 1:nitds
% Generate ITD shifted sinusoid
sig = sig_itdsin(f,itd(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply an onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
cc = tmp(:,fc-4);
% Calculate the position of the centroid
output(jj,ii) = lindemann1986_centroid(cc);
end
end
amt_cache('set','fig7',output);
end;
if flags.do_plot
% ------ Plotting ------
figure;
for jj = 1:length(c_s)
plot(itd,output(jj,:));
hold on;
end
xlabel('interaural time difference (ms)');
ylabel('displacement of the centroid d');
tstr = sprintf('w_f = 0\nf = %i Hz\n',f);
title(tstr);
end;
end;
%% ------ FIG 8 -----------------------------------------------------------
if flags.do_fig8
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0;
M_f = 6; % not used, if w_f==0
c_s = [0.3,1];
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 26; % number of used ILDs
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
ild = linspace(0,25,nilds);
output=amt_cache('get','fig8',flags.cachemode);
if isempty(output)
output = zeros(2,nilds,ndl);
for ii = 1:nilds
% Generate sinusoid with given ILD
sig = sig_ildsin(f,ild(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
output(jj,ii,:) = tmp(:,fc-4);
end
end
amt_cache('set','fig8',output);
end;
if flags.do_plot
% ------ Plotting ------
% Generate time axis
tau = linspace(-1,1,ndl);
% Plot figure for every c_s condition
for jj = 1:length(c_s)
figure;
mesh(tau,ild(end:-1:1),squeeze(output(jj,:,:)));
view(0,57);
xlabel('correlation-time delay (ms)');
ylabel('interaural level difference (dB)');
set(gca,'YTick',0:5:25);
set(gca,'YTickLabel',{'25','20','15','10','5','0'});
tstr = sprintf('c_{inh} = %.1f\nw_f = 0\nf = %i Hz\n',c_s(jj),f);
title(tstr);
end
end;
end;
%% ------ FIG 10 ----------------------------------------------------------
if flags.do_fig10
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 26; % number of used ILDs
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
ild = linspace(0,25,nilds);
output=amt_cache('get','fig10',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nilds,ndl);
for ii = 1:nilds
% Generate sinusoid with given ILD
sig = sig_ildsin(f,ild(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
output(jj,ii,:) = tmp(:,fc-4);
end
end
amt_cache('set','fig10',output);
end;
% ------ Plotting ------
if flags.do_plot
% Generate time axis
tau = linspace(-1,1,ndl);
% Plot figure for every c_s condition
for jj = 1:length(c_s)
figure;
mesh(tau,ild(end:-1:1),squeeze(output(jj,:,:)));
view(0,57);
xlabel('correlation-time delay (ms)');
ylabel('interaural level difference (dB)');
set(gca,'YTick',0:5:25);
set(gca,'YTickLabel',{'25','20','15','10','5','0'});
tstr = sprintf('c_{inh} = %.1f\nw_f = 0.035\nf = %i Hz\n',c_s(jj),f);
title(tstr);
end
end;
end;
%% ------ FIG 11 ----------------------------------------------------------
if flags.do_fig11
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = [0,0,0.035];
M_f = 6; % not used, if w_f==0
c_s = [0.3,1,0.3];
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Caelculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 26; % number of used ILDs
ild = linspace(0,25,nilds);
output=amt_cache('get','fig11',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nilds);
for ii = 1:nilds
% Generate sinusoid with given ILD
sig = sig_ildsin(f,ild(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f(jj),M_f,T_int,N_1));
% Store the needed frequency channel
cc = tmp(:,fc-4);
% Calculate the position of the centroid
output(jj,ii) = lindemann1986_centroid(cc);
end
end
amt_cache('set','fig11',output);
end;
if flags.do_plot
% ------ Plotting ------
figure;
% Plot data from experiments
data = data_lindemann1986('fig11_yost');
plot(data(:,1),data(:,2)*0.058,'+');
hold on;
data = data_lindemann1986('fig11_sayers');
plot(data(:,1),data(:,2)*0.058,'*');
% Plot line for every condition
for jj = 1:length(c_s)
plot(ild,output(jj,:));
end
axis([0 25 0 0.8]);
legend('500 Hz, Yost','600 Hz, Sayers','500 Hz, model');
xlabel('interaural level difference (dB)');
ylabel('displacement of the centroid d');
end;
end;
%% ------ FIG 12 ----------------------------------------------------------
if flags.do_fig12
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 21; % number of used ILDs for the ILD only stimuli
nitds = 21; % number of used ITDs for the combined stimuli
ild = linspace(0,10,nilds);
itd = linspace(-1,0,nitds);
output=amt_cache('get','fig12',flags.cachemode);
if isempty(output)
% Calculate the centroids for ILD+ITD stimuli
cen = zeros(nitds,nilds);
for ii = 1:nitds
for jj = 1:nilds
% Generate sinusoid with given ILD
sig = sig_itdildsin(f,itd(ii),ild(jj),fs);
% Use only the beginning of the signal to generate only one time
% instance of the cross-correlation and apply a linear onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
% Store the needed frequency channel
cc = tmp(:,fc-4);
% Calculate the position of the centroid
cen(ii,jj) = lindemann1986_centroid(cc);
end
end
% ------ Fiting ------
% For every ITD find the ILD with gives a centroid near 0
output = zeros(nitds,1);
for ii = 1:nitds
% Find centroid nearest to 0
[val,idx] = min(abs(cen(ii,:)));
output(ii) = ild(idx);
end
amt_cache('set','fig12',output);
end;
if flags.do_plot
% ------ Plotting ------
figure;
data = data_lindemann1986('fig12_400');
plot(data(:,1),data(:,2),'+');
hold on;
data = data_lindemann1986('fig12_600');
plot(data(:,1),data(:,2),'*');
plot(itd,output);
axis([-1 0 0 10]);
legend('400 Hz','600 Hz','500 Hz, model');
xlabel('interaural time difference (ms)');
ylabel('interaural level difference (dB)');
end;
end;
%% ------ FIG 13 ----------------------------------------------------------
if flags.do_fig13
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
N_1 = 1;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds_p = 21; % number of used ILDs for the ILD only stimuli
nitds_t = 21; % number of used ITDs for the combined stimuli
nilds_t = 6; % number of used ILDs for the combined stimuli
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
ild_p = linspace(-10,40,nilds_p);
itd_t = linspace(-1,1,nitds_t);
ild_t = [-3,0,3,9,15,25];
output=amt_cache('get','fig13',flags.cachemode);
if isempty(output)
% Calculate the centroids for the ILD only stimuli
cen_p = zeros(1,nilds_p);
for ii = 1:nilds_p
% Generate sinusoid with given ILD
sig = sig_ildsin(f,ild_p(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply a linear onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
% Store the needed frequency channel
cc = tmp(:,fc-4);
% Calculate the position of the centroid
cen_p(ii) = lindemann1986_centroid(cc);
end
% Calculate the centroids for the combined stimuli
cen_t = zeros(nilds_t,nitds_t);
for ii = 1:nitds_t
for jj = 1:nilds_t
sig = sig_itdildsin(f,itd_t(ii),ild_t(jj),fs);
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
cc = tmp(:,fc-4);
cen_t(jj,ii) = lindemann1986_centroid(cc);
end
end
% ------ Fitting ------
% For the results for the combined centroids find the nearest centroid for the
% ILD only stimuli
output = zeros(nilds_t,nitds_t);
for ii = 1:nitds_t
for jj = 1:nilds_t
idx = findnearest(cen_p,cen_t(jj,ii));
output(jj,ii) = ild_p(idx);
end
end
amt_cache('set','fig13',output);
end;
if flags.do_plot
% ------ Plotting ------
% First plot the only data from experiments
figure;
d = data_lindemann1986('fig13');
plot(d(:,1),d(:,2),'x-r', ... % -3dB
d(:,1),d(:,3),'x-b', ... % 3dB
d(:,1),d(:,4),'x-g', ... % 9dB
d(:,1),d(:,5),'x-b', ... % 15dB
d(:,1),d(:,6),'x-r') % 25dB
legend('25dB','15dB','9dB','3dB','-3dB');
axis([-1 1 -10 40]);
set(gca,'XTick',-1:0.4:1);
xlabel('interaural time difference (ms)');
ylabel('interaural level difference (dB)');
% Then plot model results
figure;
% Plot line for every condition
for jj = 1:nilds_t
plot(itd_t,output(jj,:));
hold on;
end
axis([-1 1 -10 40]);
set(gca,'XTick',-1:0.4:1);
xlabel('interaural time difference (ms)');
ylabel('interaural level difference (dB)');
end;
end;
%% ------ FIG 14a ---------------------------------------------------------
if flags.do_fig14a
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% --- FIG 14 (a) ---
% Model parameter
T_int = inf;
w_f = 0;
M_f = 6; % not used, if w_f==0
c_s = [0.0,0.2,0.4,0.6,1.0];
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 21 ITD points between 0~ms and 1~ms
nilds = 21; % number of used ITDs
ild = linspace(-3,3,nilds);
itd = 2000/f;
output=amt_cache('get','fig14a',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nilds);
for ii = 1:nilds
% Generate ITD shifted sinusoid
sig = sig_itdildsin(f,itd,ild(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation
sig = sig(1:siglen,:);
% Apply a linear onset window with length N_1/2 to minimize onset effects
% (see lindemann1986 p. 1614)
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
cc = tmp(:,fc-4);
% Calculate the position of the centroid
output(jj,ii) = lindemann1986_centroid(cc);
end
end
amt_cache('set','fig14a',output);
end;
if flags.do_plot
% ------ Plotting ------
figure;
for jj = 1:length(c_s)
plot(ild,output(jj,:));
hold on;
end
xlabel('interaural level difference (dB)');
ylabel('displacement of the centroid d');
tstr = sprintf('w_f = 0\nf = %i Hz\n',f);
title(tstr);
end;
end;
%% ------ FIG 14b ---------------------------------------------------------
if flags.do_fig14b
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0;
M_f = 6; % not used, if w_f==0
c_s = 1.0;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 21 ITD points between 0~ms and 1~ms
nitds = 21; % number of used ITDS
nilds = 201; % number of used ILDs
itd = linspace(0,1,nitds);
ild_std = [1,2,3,4,5];
output=amt_cache('get','fig14b',flags.cachemode);
if isempty(output)
amt_disp('NOTE: this test function will need a lot of time!','progress');
output = zeros(length(ild_std)+1,nitds);
centmp = zeros(nilds,nitds);
for ii = 1:nitds
% Show progress
amt_disp([num2str(ii) ' of ' num2str(nitds)],'progress');
% First generate the result for std(ILD) == 0
sig = sig_itdsin(f,itd(ii),fs);
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
cc = tmp(:,fc-4);
cen(1,ii) = lindemann1986_centroid(cc);
% Generate results for std(ILD) ~= 0
for nn = 1:length(ild_std)
% Generate normal distributed ILDs with mean ~ 0 and std = 1
tmp = randn(nilds,1);
tmp = tmp/std(tmp);
% Generate desired ILD distribution
ild = tmp * ild_std(nn);
% For all distributed ILD values calculate the centroid
for jj = 1:nilds
sig = sig_itdildsin(f,itd(ii),ild(jj),fs);
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
cc = tmp(:,fc-4);
centmp(jj,ii) = lindemann1986_centroid(cc);
end
% Calculate the mean centroid above the ILD distribution
output(nn+1,ii) = mean(centmp(:,ii));
end
end
amt_cache('set','fig14b',output);
end;
if flags.do_plot
figure;
for nn = 1:length(ild_std)+1
plot(itd,output(nn,:)); hold on;
end
axis([0 1 0 1]);
xlabel('interaural level difference (dB)');
ylabel('displacement of the centroid d');
tstr = sprintf('w_f = 0\nc_{inh} = 1\nf = %i Hz\n',f);
title(tstr);
end;
end;
%% ------ FIG 15 ----------------------------------------------------------
if flags.do_fig15
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640 (200*T). Here I uses only N_1 = 2205 (25*T)
% which gives the same results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 26; % number of used ILDs
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
ild = linspace(0,25,nilds);
itd = -0.5;
output=amt_cache('get','fig15',flags.cachemode);
if isempty(output)
output = zeros(length(c_s),nilds,ndl);
for ii = 1:nilds
% Generate sinusoid with given ILD
sig = sig_itdildsin(f,itd,ild(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation for different inhibition factor c_s
for jj = 1:length(c_s)
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s(jj),w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
output(jj,ii,:) = tmp(:,fc-4);
end
end
amt_cache('set','fig15',output);
end;
if flags.do_plot
% ------ Plottinqg --------------------------------------------------------
% Generate time axis
tau = linspace(-1,1,ndl);
% Plot figure for every c_s condition
for jj = 1:length(c_s)
figure;
mesh(tau,ild(end:-1:1),squeeze(output(jj,:,:)));
view(0,57);
xlabel('correlation-time delay (ms)');
ylabel('interaural level difference (dB)');
set(gca,'YTick',0:5:25);
set(gca,'YTickLabel',{'25','20','15','10','5','0'});
tstr = sprintf('c_{inh} = %.1f\nw_f = 0.035\nf = %i Hz\n',c_s(jj),f);
title(tstr);
end
end;
end;
%% ------ FIG 16 ---------------------------------------------------------
if flags.do_fig16
s = [mfilename('fullpath'),'_fig16.mat'];
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nilds = 21; % number of used ILDs for the ILD only stimuli
nitds = 21; % number of used ITDs for the combined stimuli
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
ild = linspace(0,10,nilds);
itd = linspace(-1,0,nitds);
output=amt_cache('get','fig16',flags.cachemode);
if isempty(output)
% Calculate the centroids for ILD+ITD stimuli
cc = zeros(nitds,nilds,ndl);
for ii = 1:nitds
for jj = 1:nilds
% Generate sinusoid with given ILD
sig = sig_itdildsin(f,itd(ii),ild(jj),fs);
% Use only the beginning of the signal to generate only one time
% instance of the cross-correlation and apply a linear onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
% Store the needed frequency channel
cc(ii,jj,:) = tmp(:,fc-4);
end
end
% ------ Fiting ------
% For every ITD find the ILD with gives a centroid near 0
output = zeros(nitds,1);
for ii = 1:nitds
% Find two peaks of same height
idx = findpeaks(squeeze(cc(ii,:,:)));
output(ii) = ild(idx);
end
amt_cache('set','fig16',output);
end;
if flags.do_plot
% ------ Plotting ------
figure;
data = data_lindemann1986('fig16');
plot(data(:,1),data(:,2),'+');
hold on;
plot(itd,output);
axis([-1 0 0 15]);
xlabel('interaural time difference (ms)');
ylabel('interaural level difference (dB)');
end;
end;
%% ------ FIG 17 ----------------------------------------------------------
if flags.do_fig17
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.3;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
siglen = ceil(30*T*fs);
% Calculate crosscorrelations for 26 ILD points between 0~dB and 25~dB
nitds_p = 21; % number of used ITDs for the ITD only stimuli
nitds_t = 4; % number of used ITDs for the combined stimuli
nilds_t = 21; % number of used ILDs for the combined stimuli
itd_p = linspace(-0.36,0.72,nitds_p);
ild_t = linspace(-9,9,nilds_t);
itd_t = [0,0.09,0.18,0.27];
output=amt_cache('get','fig17',flags.cachemode);
if isempty(output)
% Calculate the centroids for the ITD only stimuli
cen_p = zeros(1,nitds_p);
max_p = zeros(1,nitds_p);
for ii = 1:nitds_p
% Generate sinusoid with given ILD
sig = sig_itdsin(f,itd_p(ii),fs);
% Use only the beginning of the signal to generate only one time instance of
% the cross-correlation and apply a linear onset window
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
% Store the needed frequency channel
cc = tmp(:,fc-4);
% Find the maximum position
max_p(ii) = findmax(cc);
% Calculate the position of the centroid
cen_p(ii) = lindemann1986_centroid(cc);
end
% Calculate the centroids for the combined stimuli
cen_t = zeros(nitds_t,nilds_t);
max_t = zeros(nitds_t,nilds_t);
for ii = 1:nilds_t
for jj = 1:nitds_t
sig = sig_itdildsin(f,itd_t(jj),ild_t(ii),fs);
sig = sig(1:siglen,:);
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
cc = tmp(:,fc-4);
max_t(jj,ii) = findmax(cc);
cen_t(jj,ii) = lindemann1986_centroid(cc);
end
end
% ------ Fiting ------
% For the results for the combined centroids find the nearest centroid for the
% ITD only stimuli
output.rmax = zeros(nitds_t,nilds_t);
output.rcen = output.rmax;
for ii = 1:nilds_t
for jj = 1:nitds_t
idx = findnearest(cen_p,cen_t(jj,ii));
output.rcen(jj,ii) = itd_p(idx);
idx = findnearest(max_p,max_t(jj,ii));
output.rmax(jj,ii) = itd_p(idx);
end
end
amt_cache('set','fig17',output);
end;
if flags.do_plot
% ------ Plotting ------
% First plot the only data from experiments
figure; % fig 17 (a)
d = data_lindemann1986('fig17');
plot(d(:,1),d(:,5),'x-r', ... % 0 ms
d(:,1),d(:,4),'x-b', ... % 0.09 ms
d(:,1),d(:,3),'x-g', ... % 0.18 ms
d(:,1),d(:,2),'x-b') % 0.27 ms
legend('0.27 ms','0.18 ms','0.09 ms','0 ms');
axis([-9 9 -0.36 0.72]);
set(gca,'XTick',-9:3:9);
xlabel('interaural level difference (dB)');
ylabel('interaural time difference (ms)');
% Then plot model results
figure; % fig 17 (b)
% Plot line for every condition
for jj = 1:nitds_t
plot(ild_t,output.rcen(jj,:));
hold on;
end
axis([-9 9 -0.36 0.72]);
set(gca,'XTick',-9:3:9);
xlabel('interaural level difference (dB)');
ylabel('interaural time difference (ms)');
%
figure; % fig 17 (c)
for jj = 1:nitds_t
plot(ild_t,output.rmax(jj,:));
hold on;
end
axis([-9 9 -0.36 0.72]);
set(gca,'XTick',-9:3:9);
xlabel('interaural level difference (dB)');
ylabel('interaural time difference (ms)');
end;
end;
%% ------ FIG 18 ----------------------------------------------------------
if flags.do_fig18
% Sampling rate
fs = 44100;
% Frequency of the sinusoid
f = 500;
T = 1/f;
fc = round(freqtoerb(f)); % corresponding frequency channel
% Model parameter
T_int = inf;
w_f = 0.035;
M_f = 6; % not used, if w_f==0
c_s = 0.11;
% NOTE: the longer the signal, the more time we need for computation. On the
% other side N_1 needs to be long enough to eliminate any onset effects.
% Lindemann uses N_1 = 17640. Here I uses only N_1 = 2205 which gives the same
% results for this demo.
N_1 = ceil(25*T*fs);
% Calculate crosscorrelations for 21 ITD points between 0~ms and 1~ms
niacs = 11; % number of used interaural coherence values
ndl = 2*round(fs/2000)+1; % length of the delay line (see bincorr.m)
iac = linspace(0,1,niacs);
output=amt_cache('get','fig18',flags.cachemode);
if isempty(output)
output = zeros(niacs,ndl);
for ii = 1:niacs;
% Generate ITD shifted sinusoid
sig = sig_bincorrnoise(fs,iac(ii),'pink');
% Aplly onset window
sig = rampsignal(sig,[round(N_1/2)-1 0],'tria');
% Calculate cross-correlation (and squeeze due to T_int==inf)
tmp = squeeze(lindemann1986(sig,fs,c_s,w_f,M_f,T_int,N_1));
% Store the needed frequency channel. NOTE: the cross-correlation
% calculation starts with channel 5, so we have to subtract 4.
output(ii,:) = tmp(:,fc-4);
end
amt_cache('set','fig18',output);
end;
if flags.do_plot
% ------ Plotting ------
% Generate time axis
tau = linspace(-1,1,ndl);
% Plot figure for every c_s condition
figure;
mesh(tau,iac,output);
view(0,57);
xlabel('correlation-time tau (ms)');
ylabel('degree of interaural coherence');
end;
end;
%% ------ Subfunctions ----------------------------------------------------
function idx = findnearest(list,val)
[dif,idx] = min(abs(list-val));
function idx = findpeaks(cc)
% FINDPEAKS Finds two peaks of the same height in a given cross-correlation
h = zeros(size(cc,1),1);
for ii = 1:size(cc,1)
% Find a peak in the two halfes of the cross-correlation and subtract them
h(ii) = max(cc(ii,1:30)) - max(cc(ii,31:end));
end
% Find the index with the smallest distance between the two peaks
[val,idx] = min(abs(h));
function m = findmax(list)
[m,idx] = max(list);
d = linspace(-1,1,length(list));
m = d(idx);