...
 
Commits (7)
% autoexec_cfg generated by Configure AFC. Add your local preferences here.
def.language = 'EN';
% % directory with hrir data base:
% def.hrirdir='/home/hgproc/project/data/HRIRdatabase/';
%
% % directory with ollo data base:
% def.ollodir='/home/hgproc/project/data/OLLO2.0_NO/';
% directory with hrir data base:
def.hrirdir='/media/joanna/daten/user/joanna/Data/HRIR_HendrikKayser/';
% directory with ollo data base:
def.ollodir='/media/joanna/daten/user/joanna/Data/my_OLLO/OLLO_data/OLLO2.0_NO/';
addpath(def.hrirdir)
% Avoid warning about additional variables
def.variableCheck = 0;
% experimentDOA_cfg - example measurement configuration file -
% experimentDOAMHA_cfg - example measurement configuration file -
%
% This matlab skript is called by afc_main when starting
% the experiment 'experimentDOA_cfg'.
%
% afc('main','experimentDOA','joa','10deg','ollo_male','white');
% afc('main','experimentDOA','joa',90,5,'ollo_male','noproc','white');
%
% experimentDOA_cfg constructs a structure 'def' containing the complete
% configuration for the experiment.
......@@ -16,11 +16,6 @@
% Copyright (c) 1999-2013 Stephan Ewert.
% directory with hrir data base:
def.hrirdir='/media/joanna/daten/user/joanna/Data/HRIR_HendrikKayser/'
% directory with ollo data base:
def.ollodir='/media/joanna/daten/user/joanna/Data/my_OLLO/OLLO_data/OLLO2.0_NO/'
% general measurement procedure
def.measurementProcedure = 'transformedUpDown'; % measurement procedure
def.intervalnum = 3; % number of intervals
......@@ -38,14 +33,14 @@ def.expvardescription = 'signal level'; % description of the tracking variable
% limits for experimental variable
def.minvar = -100; % minimum value of the tracking variable
def.maxvar = 100; % maximum value of the tracking variable
def.maxvar = 60; % maximum value of the tracking variable
def.terminate = 1; % terminate execution on min/maxvar hit: 0 = warning, 1 = terminate
def.endstop = 3; % Allows x nominal levels higher/lower than the limits before terminating (if def.terminate = 1)
% experimental parameter (independent variable)
def.exppar1 = [0 45 90]; % vector containing experimental parameters for which the exp is performed
def.exppar1unit = 'deg'; % unit of experimental parameter
def.exppar1description = 'reference angle';% description of the experimental parameter
%def.exppar1 = [0 45 90]; % vector containing experimental parameters for which the exp is performed
%def.exppar1unit = 'deg'; % unit of experimental parameter
%def.exppar1description = 'reference angle';% description of the experimental parameter
% experimental parameter 2...N (independent variable)
% add here if required
......@@ -63,20 +58,20 @@ def.control_path = ''; % where to save control files
def.savefcn = 'default'; % function which writes results to disk
% samplerate and sound output
def.samplerate = 48000; % sampling rate in Hz
def.intervallen = 22050; % length of each signal-presentation interval in samples (might be overloaded in 'expname_set')
def.pauselen = 22050; % length of pauses between signal-presentation intervals in samples (might be overloaded in 'expname_set')
def.presiglen = 100; % length of signal leading the first presentation interval in samples (might be overloaded in 'expname_set')
def.postsiglen = 100; % length of signal following the last presentation interval in samples (might be overloaded in 'expname_set')
def.samplerate = 44100; % sampling rate in Hz
def.intervallen = 1.1.*def.samplerate; % length of each signal-presentation interval in samples (might be overloaded in 'expname_set')
def.pauselen = def.samplerate/2; % length of pauses between signal-presentation intervals in samples (might be overloaded in 'expname_set')
def.presiglen = round(.002 * def.samplerate); % length of signal leading the first presentation interval in samples (might be overloaded in 'expname_set')
def.postsiglen = def.presiglen; % length of signal following the last presentation interval in samples (might be overloaded in 'expname_set')
def.bits = 16; % output bit depth: 8 or 16 see def.externSoundCommand for 32 bits
% computing
def.allowpredict = 0; % if 1 generate new stimuli during sound output if def.markinterval disabled
% def.markIntervalDelay = 0;
% tweaking
%def.keyboardResponseButtonMapping = {'a','s','d'};
%def.soundmexMark = 1;
%def.markinterval = 1;
def.markinterval = 0;
%def.internSoundCommand = 'sound';
%def.internSoundCommand = 'wavplay';
......
......@@ -26,21 +26,21 @@ global def
global work
global setup
addpath(genpath(def.hrirdir))
% conditions are specified in each run by:
% afc('main','experimentDOA','subject','5deg','ollo_female','white')
% Condition 1
switch work.userpar1
case '5deg'
setup.degdiff=5;
case '10deg'
setup.degdiff=10;
otherwise
error('condition not recognized');
end
% afc('main','experimentDOA','subject','135','10','ollo_female','white')
% Input argument 4
setup.ref_angle=str2double(work.userpar1);
% setup.ref_angle=def.exppar1;
% Input argument 5
setup.degdiff=str2double(work.userpar2);
% Condition 2
switch work.userpar2
% Input argument 6
switch work.userpar3
case 'ollo_female'
setup.filedir=[def.ollodir,'S01F_NO/'];
case 'ollo_male'
......@@ -49,14 +49,47 @@ otherwise
error('condition not recognized');
end
% Condition 3
% create a cell array which has the same lenght as
% the number of referece angles that we want to test
if iscell(setup.ref_angle);setup.ref_angle=cell2mat(setup.ref_angle);end
setup.HRIRs=cell(length(setup.ref_angle),1); % [0 45 90];
% Condition 4
switch work.userpar4
case 'in-ear'
def.outputChannels=2;
for k=1:length(setup.HRIRs)
%load the hrir for the reference angle
setup.HRIRs{k}.hrir_ref=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k),'in-ear')
%load the hrirs for the angle 5° away from the reference angle
setup.HRIRs{k}.hrir_refplus=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k)+setup.degdiff,'in-ear')
setup.HRIRs{k}.hrir_refminus=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k)-setup.degdiff,'in-ear')
end
case 'front'
def.outputChannels=2;
for k=1:length(setup.HRIRs)
%load the hrir for the reference angle
setup.HRIRs{k}.hrir_ref=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k),'front')
%load the hrirs for the angle 5° away from the reference angle
setup.HRIRs{k}.hrir_refplus=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k)+setup.degdiff,'front')
setup.HRIRs{k}.hrir_refminus=loadHRIR('Anechoic', 300, 0, setup.ref_angle(k)-setup.degdiff,'front')
end
end
% Condition 4
switch work.condition
case 'babble'
setup.noise=audioread('.wav');
case 'cohnoise'
setup.noise=audioread('../coherentNoise_-160_Sig_inEar.wav');
case 'white'
n1=randn(10*def.samplerate,1);
n2=randn(10*def.samplerate,1);
setup.noise=[n1 n2];
for c=1:def.outputChannels
setup.noise(:,c)=randn(10*def.samplerate,1);
end
case 'diffuse'
setup.noise=audioread('../diffuseNoise_Sig_inEar.wav');
otherwise
error('condition not recognized');
end
......@@ -68,21 +101,9 @@ setup.level=40;
% make a list of files from which one file should be
% randomly chosen in each trial
filePattern =[setup.filedir,'*.wav'];
filePattern =[setup.filedir,'*_L*_*_*_*_*.wav'];
setup.waveFiles = dir(filePattern);
% add path with the hrir data base
addpath(genpath(def.hrirdir))
% create a cell array which has the same lenght as
% the number of referece angles that we want to test
setup.HRIRs=cell(length(def.exppar1),1) % [0 45 90];
for k=1:length(setup.HRIRs)
%load the hrir for the reference angle
setup.HRIRs{k}.hrir_ref=loadHRIR('Anechoic', 80, 0, def.exppar1(k),'in-ear')
%load the hrirs for the angle 5° away from the reference angle
setup.HRIRs{k}.hrir_refplus=loadHRIR('Anechoic', 80, 0, def.exppar1(k)+setup.degdiff,'in-ear')
setup.HRIRs{k}.hrir_refminus=loadHRIR('Anechoic', 80, 0, def.exppar1(k)-setup.degdiff,'in-ear')
end
% eof
\ No newline at end of file
% experimentDOA_user - stimulus generation function of experiment 'example' -
% experimentDOAMHA_user - stimulus generation function of experiment 'example' -
%
% This function is called by afc_main when starting
% the experiment 'experimentDOA'. It generates the stimuli which
......@@ -35,9 +35,10 @@ disp(num2str(work.expvaract))
% -------------CHOOSE HRIRS ----------------
% * find which reference angle is currently tested
% * randomly choose +or- 5° or 10°
indx=find(def.exppar1==work.exppar1);
indx=1;%find(def.exppar1==work.exppar1);
hrir_fs=setup.HRIRs{indx}.hrir_ref.fs;
hrir_ref=setup.HRIRs{indx}.hrir_ref.data;
plusorminus=round(rand);%0 or 1
plusorminus=1;%round(rand);%0 or 1
if plusorminus==1
hrir_targ=setup.HRIRs{indx}.hrir_refplus.data;
elseif plusorminus==0
......@@ -52,14 +53,19 @@ fileToPlay = randi(numberOfFiles, 1);
baseWavFileName = setup.waveFiles(fileToPlay).name;
fullWavFileName = fullfile([setup.filedir, baseWavFileName]);
[sig, fssig]=audioread(fullWavFileName);
% resample the signal
[P,Q] = rat(def.samplerate/fssig);
sig=resample(sig,P,Q);
% convolve signals with IRs
sig_ref(:,1)=conv(sig,hrir_ref(:,1));
sig_ref(:,2)=conv(sig,hrir_ref(:,2));
sig_targ(:,1)=conv(sig,hrir_targ(:,1));
sig_targ(:,2)=conv(sig,hrir_targ(:,2));
sig=resample(sig,def.samplerate,fssig);
% resample the impulse response
hrir_ref=resample(hrir_ref,def.samplerate,hrir_fs);
hrir_targ=resample(hrir_targ,def.samplerate,hrir_fs);
% convolve speech signal with IRs
for c=1:def.outputChannels
sig_ref(:,c)=conv(sig,hrir_ref(:,c));
sig_targ(:,c)=conv(sig,hrir_targ(:,c));
end
%-------------- NOISE -----------------
......@@ -86,20 +92,19 @@ sig_targ=set_level(sig_targ, work.expvaract-work.currentCalLevel);
setup.hannlen = round(0.05*def.samplerate);
setup.window = hannfl(L,setup.hannlen,setup.hannlen);
% signal + noise
tref11=(sig_ref(:,1)+noise1(:,1)).* setup.window;
tref12=(sig_ref(:,2)+noise1(:,2)).* setup.window;
tref21=(sig_ref(:,1)+noise2(:,1)).* setup.window;
tref22=(sig_ref(:,2)+noise2(:,2)).* setup.window;
tuser1=(sig_targ(:,1)+noise3(:,1)).* setup.window;
tuser2=(sig_targ(:,2)+noise3(:,2)).* setup.window;
for c=1:def.outputChannels
tref1(:,c)=(sig_ref(:,c)+noise1(:,c)).* setup.window;
tref2(:,c)=(sig_ref(:,c)+noise2(:,c)).* setup.window;
tuser(:,c)=(sig_targ(:,c)+noise3(:,c)).* setup.window;
end
% pre-, post- and pausesignals (all zeros)
presig = zeros(def.presiglen,2);
postsig = zeros(def.postsiglen,2);
pausesig = zeros(def.pauselen,2);
presig = zeros(def.presiglen, def.outputChannels);
postsig = zeros(def.postsiglen, def.outputChannels);
pausesig = zeros(def.pauselen, def.outputChannels);
% make required fields in work
work.signal = [tuser1 tuser2 tref11 tref12 tref21 tref22]; % left = right (diotic) first two columns holds the test signal (left right)
work.signal = [tuser tref1 tref2];% left = right (diotic) first two columns holds the test signal (left right)
work.presig = presig; % must contain the presignal
work.postsig = postsig; % must contain the postsignal
work.pausesig = pausesig; % must contain the pausesignal
......
% Measurement script for the machine (localizer)
% in-ear HRIRs
afc('main','experimentDOA','localizer','0','5','ollo_female','in-ear', 'diffuse')
afc('main','experimentDOA','localizer','0','5','ollo_female','in-ear', 'cohnoise')
afc('main','experimentDOA','localizer','0','10','ollo_female','in-ear', 'diffuse')
afc('main','experimentDOA','localizer','0','10','ollo_female','in-ear', 'cohnoise')
afc('main','experimentDOA','localizer','45','10','ollo_female','in-ear', 'diffuse')
afc('main','experimentDOA','localizer','45','10','ollo_female','in-ear', 'cohnoise')
afc('main','experimentDOA','localizer','45','15','ollo_female','in-ear', 'diffuse')
afc('main','experimentDOA','localizer','45','15','ollo_female','in-ear', 'cohnoise')
afc('main','experimentDOA','localizer','45','20','ollo_female','in-ear', 'diffuse')
afc('main','experimentDOA','localizer','45','20','ollo_female','in-ear', 'cohnoise')
% front HG channels HRIRs
afc('main','experimentDOA','localizer','0','5','ollo_female','front', 'diffuse')
afc('main','experimentDOA','localizer','0','5','ollo_female','front', 'cohnoise')
afc('main','experimentDOA','localizer','0','10','ollo_female','front', 'diffuse')
afc('main','experimentDOA','localizer','0','10','ollo_female','front', 'cohnoise')
afc('main','experimentDOA','localizer','45','10','ollo_female','front', 'diffuse')
afc('main','experimentDOA','localizer','45','10','ollo_female','front', 'cohnoise')
afc('main','experimentDOA','localizer','45','15','ollo_female','front', 'diffuse')
afc('main','experimentDOA','localizer','45','15','ollo_female','front', 'cohnoise')
afc('main','experimentDOA','localizer','45','20','ollo_female','front', 'diffuse')
afc('main','experimentDOA','localizer','45','20','ollo_female','front', 'cohnoise')
\ No newline at end of file
......@@ -9,7 +9,7 @@ def.modelShowEnable = 0;
def.markpressed = 1;
def.showEnable = 1;
def.showEnable = 0;
def.showrun = 1;
def.showtrial = 1;
def.showspec = 1;
......
......@@ -8,19 +8,48 @@ global simwork
% we select only the left channels, the model is monaural
simwork.tmpSig = work.signal;
simwork.DOAaz = [];
simwork.DOA = [];
% for each interval, run doa=localizer_preproc(interval sound),
% so that we have an estimate of the DOA for each presented interval
% NOTE!!! the target interval of the current trial is always in the
% first two columns of work.signal (so also of simwork.tmpSig), no matter
% in which order it was presented to the subject!
for i=1:def.intervalnum
simwork.DOAaz(i) = eval([work.vpname '_preproc(simwork.tmpSig(:,2*i-1:2*i))']); % actual sig processing
simwork.DOA(i) = eval([work.vpname '_preproc(simwork.tmpSig(:,2*i-1:2*i))']); % actual sig processing
end
% now select the interval with the maximum standard deviation
[tmp,response] = max(simwork.actStd); % select max power
% Create the reasoning-scheme of the machine:
% The task for the subject is always: press the interval, which you think
% was different from two other intervals, so response is always 1,2 or 3.
% How will the machine respond if the DOA estimated for all intervals is
% the same? How would it be if they are all different?
% if it is another interval than the first, the response is wrong, since in the work.signal always carries the
% signal interval in the first column
if length(unique(simwork.DOA))==1
response=randi(3);
else
where=simwork.DOA(1)-simwork.DOA(2:3);
if where(1)==where(2)
response=1;
elseif where(1)==0
response=3;
elseif where(2)==0
response=2;
elseif where(1)~=where(2)
response=randi(3);
end
end
% NOTE!!! the target interval of the current trial is always in the
% first two columns of work.signal (so also of simwork.tmpSig), no matter
% in which order it was presented to the subject! Therefore the right anwer
% is always response=1. If it is 2 or 3, we set it here to 0 (wrong):
if response ~= 1
response = 0;
end
end
% eof
......@@ -9,11 +9,17 @@ global work
global simwork
addpath(genpath('/home/joanna/DOA4Seminars/DOASVMdemo'));
% load DOASVM model
simwork.sSensors = 'frontmiddle';
% specify the input channels of the localization algorithm (sensors)
if strcmp(work.userpar4,'in-ear')
simwork.sSensors = 'inear';
else
error('please go to function localizer_init.m and specify corresponding sensors')
end
% specify model type
simwork.sModeltype = 'HRIR';
% load DOASVM model
simwork.LocModel = load(['LocModel_' simwork.sModeltype '_' simwork.sSensors]);
% make a variable containing azimuth angles
simwork.DOAazimuth = simwork.LocModel.az;
%eof
......@@ -7,18 +7,28 @@ function response = localizer_main
global def
global work
% in this case the example model calls a detect routine for this, which returns 1 if the signal is detected.
detect = eval([work.vpname '_detect']);
% in this case the example model calls a detect routine for this, which returns 1 if the target
% interval is detected.
detect = eval([work.vpname '_detect'])
% if detected than select the current signal position as the response interval, select a random one from the
% remaining intervals otherwise
switch detect
case 1
% if the correct signal was detected, the response of the model is set
% number or the target interval (in the order it really was presented
% to the listener)
response = work.position{work.pvind}(end);
% work.position{work.pvind} contains a history of where the target
% interval was hidden [3 3 2 2 2] the last one is always the temporary
% one
case 0
responseTmp = randperm( def.intervalnum );
response = work.position{work.pvind}(end);
i = 1;
% this loop is to choose a response that is different from the right
% one
while ( response == work.position{work.pvind}(end) )
response = responseTmp(i);
i = i + 1;
......
% revision 1.00.1 beta, 07/01/04
function out = localizer_preproc(in)
function DOA = localizer_preproc(in)
% in contains one of the 3 intervals presented in the experiment
global def
......@@ -10,6 +10,7 @@ global simwork
sig=in';
fs=def.samplerate;
DOAazimuth = simwork.LocModel.az;
time = 0:1./simwork.LocModel.fs.*simwork.LocModel.wndlen./2: size(sig,2)./simwork.LocModel.fs -1./simwork.LocModel.fs.*simwork.LocModel.wndlen;
% STFT from Multi-Channel BSS Locate toolbox R. Lebarbenchon and E. Camberlein)
......@@ -57,4 +58,15 @@ for IDXt = 1 : size(mFeature,2)
% map to probability using a sigmoid transformation
probability(:,IDXt) = 1 ./ (1 + exp(-(simwork.LocModel.x.' + c .* simwork.LocModel.y.')));
end
\ No newline at end of file
end
% you can have a look at the probability map for a given sound here
%figure;imagesc(probability)
[val indxdoa]=max(probability,[],1);
DOA=mode(DOAazimuth(indxdoa));
Goal
The goal of this experiment is to compare the human and machine performance
in spatial hearing of speech signals (localisation abilities).
What do we compare?
Both humans (you) and machine (localisation algorithm) have
to participate in a psychoacoustic (AFC) experiment, that measures the SNR at
which a subject is still able to perceive a change in the direction
of arrival of speech.
The following tools/data are used:
- AFC toolbox (for designing the AFC experiment)
\url{http://medi.uni-oldenburg.de/afc/}
- Localisation Algorithm by H. Kayser (GCC-Phat features + SVM)
- OLLO data base (as speech material)
\url{http://medi.uni-oldenburg.de/ollo/}
The following scripts are important to work with:
-afc/autoexec_cfg.m
-afc/experimentDOA_config.m
-afc/experimentDOA_set.m
-afc/experimentDOA_user.m
-afc/measure_machine.m
-afc/models/localizer_cfg.m(some configuration like if you want to display the gui and answers of a machine)
- afc/models/localizer_init.m (initializing the localiser)
- afc/models/localizer_detect.m (doa estimated for each interval is turned into response)
- afc/models/localizer_preproc.m (computing doa for one interval - here the algorithm is living)
The AFC experiment can be started by running following line in matlab command window:
afc('main','experimentDOA',subject,ref_az,change_angle,speech_data,hrir_type, noise_type)
The first two input arguments are fixed.
The remaining ones are described below:
subject - is the string containing subject name
a) human subject name, like 'joanna'
b) algorithm name, in this case 'localizer'
ref_az - is the string containing reference angle in degrees
at which the snr will be measured
change - is the string with change in angle in degrees for
which the snr will be measured
speech_data - is the string specifying the speech material
a) 'ollo_female' - Logatomes spoken by female speaker
b) 'ollo_male' - Logatomes spoken by male speaker
hrir_type - specifies the HRIRs with which the mono speech signals are
convolved to generate signals coming from different directions
a) 'in-ear' - binaural in-ear impulse responses
b) 'front' - impulse responses measured at front microphones
of the hearing aid
noise_type - specifies the noise that is used in the experiment
a) 'white' - channel uncorrelated white noise
b) 'cohnoise' - Coherent spectrally speech-shaped noise that comes from -160°
c) 'diffuse' - Spatialy diffuse spectrally speech-shaped noise
Research questions:
What is better - human or machine?
How to interpret the output of a localization algorithm? (See localizer_preproc)
How to program the responses of the model in the AFC-context? (See localizer_detect)
What happens in coherent noise?
what happens for different change angles?
File added