Revision 38:c2204b18f4a2 userProgramsASRforDummies

View differences:

userProgramsASRforDummies/Exp_Ray_1.m
1
function Exp_Ray_1(isMasterNode)
2

  
3
% Some description of the experiment goes here
4

  
5
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6
% Set up the basic folders
7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8
expName = 'scrap6_with_eff';
9
dataFolderPrefix = 'featR';
10
if isunix
11
    expFolderPrefix = '/scratch/nrclark/exps/';
12
else
13
    expFolderPrefix = 'D:\Exps';
14
end
15

  
16
expFolder = fullfile(expFolderPrefix,expName);
17
hmmFolder = fullfile(expFolder,'hmm');
18

  
19
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20
% Sort out the training (LEARNING) condition
21
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
learnFolder = fullfile(expFolder,'featL');
23

  
24
xL = cJob('L', learnFolder);
25

  
26
xL.participant = 'Normal';
27
xL.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=0;', 'OMEParams.rateToAttenuationFactorProb=0;' };
28
xL.MAPparamChanges= {};
29

  
30
xL.noiseLevToUse   =  -200;
31
xL.noiseLevToUse   =  20;
32
xL.speechLevToUse  =  50;
33

  
34
xL.MAPopHSR = 1;
35
xL.MAPopMSR = 0;
36
xL.MAPopLSR = 0;
37

  
38

  
39
xL.numCoeff = 14;
40
xL.removeEnergyStatic = 0;
41

  
42
%%%%% Group of params that will influence simulation run time %%%%%%%
43
xL.numWavs = 512; %MAX=8440
44
testWavs = 48; %MAX = 358
45
nzLevel = [-200 40 60];
46
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47

  
48
xL.noisePreDur = 1;
49
xL.noisePostDur = 0.1;
50
xL.truncateDur  = xL.noisePreDur-0.1; 
51

  
52
xL.noiseName = '20TalkerBabble';
53

  
54
if isMasterNode && ~isdir(xL.opFolder)
55
    mkdir(xL.opFolder);
56
    xL = xL.assignFiles;
57
    xL.storeSelf; % This is a call to a member function and is not a pointless line of code!
58
end
59

  
60

  
61
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
% Sort out the testing (RECOGNITION) conditions
63
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64
recConditions = numel(nzLevel);
65

  
66
tmpIdx=0;
67
for nn = 0*recConditions+1:1*recConditions    
68
    tmpIdx=tmpIdx+1;
69
    xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
70
    recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
71
    xR{nn}.opFolder = recFolder;    
72
    
73
    %These are the interesting differences between training and testing
74
    xR{nn}.numWavs = testWavs; %MAX = 358
75
    xR{nn}.noiseLevToUse = nzLevel(tmpIdx);
76
    %xR{nn}.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=0;'};
77
        
78
    %Now just to wrap it up ready for processing
79
    if isMasterNode && ~isdir(xR{nn}.opFolder)
80
        mkdir(xR{nn}.opFolder);
81
        xR{nn} = xR{nn}.assignWavPaths('R');
82
        xR{nn} = xR{nn}.assignFiles;
83
        xR{nn}.storeSelf;
84
    end
85
end
86

  
87
% tmpIdx=0;
88
% for nn = 1*recConditions+1:2*recConditions    
89
%     tmpIdx=tmpIdx+1;
90
%     xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
91
%     recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
92
%     xR{nn}.opFolder = recFolder;    
93
%     
94
%     %These are the interesting differences between training and testing
95
%     xR{nn}.numWavs = testWavs; %MAX = 358
96
%     xR{nn}.noiseLevToUse = nzLevel(tmpIdx);
97
%     xR{nn}.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=-10^(-10/20);'};
98
%     
99
%     
100
%     %Now just to wrap it up ready for processing
101
%     if isMasterNode && ~isdir(xR{nn}.opFolder)
102
%         mkdir(xR{nn}.opFolder);
103
%         xR{nn} = xR{nn}.assignWavPaths('R');
104
%         xR{nn} = xR{nn}.assignFiles;
105
%         xR{nn}.storeSelf;
106
%     end
107
% end
108

  
109

  
110
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111
% ** Generate features **
112
% This is the time consuming, processing intensive portion of the program.
113
% Nodes that are not the master node are only interested in the opFolder
114
% member of the jobjects.
115
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116
worker(xL.opFolder);
117
maxConds = nn;
118
if ~isMasterNode %dont bother wasting master node effort on generating testing features (for now)
119
    for nn = 1:maxConds
120
        worker(xR{nn}.opFolder);
121
    end
122
end
123

  
124
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125
% Train and test the recogniser - a job for the master node only
126
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127
if isMasterNode    
128
    while(~all(xL.todoStatus==2))        
129
        disp('Waiting on straggler nodes to complete their jobs before HMM is trained . . .')
130
        pause(30); %Wait for 30 seconds before looking again
131
        xL.lockJobList;
132
        xL = xL.loadSelf; %Reload incase changed
133
        xL.unlockJobList;
134
    end
135
    y = cHMM(hmmFolder);    
136
    y.numCoeff = (xL.numCoeff-logical(xL.removeEnergyStatic)) * 3;
137
    y.createSCP(xL.opFolder)
138
    y.createMLF(xL.opFolder)
139
    y.train(xL.opFolder) %This node can be busy training, even if other jobs are being processed for testing
140
    
141
    % ALLOW MASTER NODE TO MUCK IN WITH GENERATING TESTING FEATURES ONCE
142
    % HMM HAS BEEN TRAINED
143
    for nn = 1:maxConds
144
        worker(xR{nn}.opFolder);
145
    end    
146
    
147
    xR{end}.lockJobList;
148
    xR{end} = xR{end}.loadSelf; %Reload changes
149
    xR{end}.unlockJobList;
150
    while(~all(xR{end}.todoStatus==2))        
151
        disp('Waiting on straggler nodes to complete their jobs before HMM is tested . . .')
152
        pause(30); %Wait for 30 seconds before looking again
153
        xR{end}.lockJobList;
154
        xR{end} = xR{end}.loadSelf; %Reload incase changed
155
        xR{end}.unlockJobList;
156
    end
157
      
158
    for nn = 1:maxConds
159
        y.createSCP(xR{nn}.opFolder);
160
        y.test(xR{nn}.opFolder);
161
    end
162
    
163
    %Show all of the scores in the command window at the end
164
    for nn = 1:maxConds
165
        y.score(xR{nn}.opFolder);
166
    end
167
end
userProgramsASRforDummies/Exp_Tutorial_1.m
1
function Exp_Tutorial_1(isMasterNode)
2

  
3
% Some description of the experiment goes here
4

  
5
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6
% Set up the basic folders
7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8
expName = 'Tutorial';
9
dataFolderPrefix = 'featR';
10
if isunix
11
    expFolderPrefix = '/scratch/nrclark/exps/';
12
else
13
    expFolderPrefix = 'D:\Exps';
14
end
15

  
16
expFolder = fullfile(expFolderPrefix,expName);
17
hmmFolder = fullfile(expFolder,'hmm');
18

  
19
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20
% Sort out the training (LEARNING) condition
21
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
learnFolder = fullfile(expFolder,'featL');
23

  
24
xL = cJob('L', learnFolder);
25

  
26
xL.participant = 'Normal';
27
xL.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=0;', 'OMEParams.rateToAttenuationFactorProb=0;' };
28

  
29
xL.noiseLevToUse   =  -200;
30
xL.speechLevToUse  =  60;
31

  
32
xL.MAPopHSR = 1;
33
xL.MAPopMSR = 0;
34
xL.MAPopLSR = 0;
35

  
36

  
37
xL.numCoeff = 14;
38
xL.removeEnergyStatic = 0;
39

  
40
%%%%% Group of params that will influence simulation run time %%%%%%%
41
xL.numWavs = 12; %MAX=8440
42
testWavs = 6; %MAX = 358
43
nzLevel = [-200 40:10:70];
44
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45

  
46
xL.noisePreDur = 1;
47
xL.noisePostDur = 0.1;
48
xL.truncateDur  = xL.noisePreDur-0.1; 
49

  
50
xL.noiseName = 'pink_demo';
51

  
52
if isMasterNode && ~isdir(xL.opFolder)
53
    mkdir(xL.opFolder);
54
    xL = xL.assignFiles;
55
    xL.storeSelf; % This is a call to a member function and is not a pointless line of code!
56
end
57

  
58

  
59
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60
% Sort out the testing (RECOGNITION) conditions
61
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
recConditions = numel(nzLevel);
63

  
64
tmpIdx=0;
65
for nn = 0*recConditions+1:1*recConditions    
66
    tmpIdx=tmpIdx+1;
67
    xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
68
    recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
69
    xR{nn}.opFolder = recFolder;    
70
    
71
    %These are the interesting differences between training and testing
72
    xR{nn}.numWavs = testWavs; %MAX = 358
73
    xR{nn}.noiseLevToUse = nzLevel(tmpIdx);
74
    xR{nn}.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=0;'};
75
        
76
    %Now just to wrap it up ready for processing
77
    if isMasterNode && ~isdir(xR{nn}.opFolder)
78
        mkdir(xR{nn}.opFolder);
79
        xR{nn} = xR{nn}.assignWavPaths('R');
80
        xR{nn} = xR{nn}.assignFiles;
81
        xR{nn}.storeSelf;
82
    end
83
end
84

  
85
tmpIdx=0;
86
for nn = 1*recConditions+1:2*recConditions    
87
    tmpIdx=tmpIdx+1;
88
    xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
89
    recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
90
    xR{nn}.opFolder = recFolder;    
91
    
92
    %These are the interesting differences between training and testing
93
    xR{nn}.numWavs = testWavs; %MAX = 358
94
    xR{nn}.noiseLevToUse = nzLevel(tmpIdx);
95
    xR{nn}.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=-10^(-10/20);'};
96
    
97
    
98
    %Now just to wrap it up ready for processing
99
    if isMasterNode && ~isdir(xR{nn}.opFolder)
100
        mkdir(xR{nn}.opFolder);
101
        xR{nn} = xR{nn}.assignWavPaths('R');
102
        xR{nn} = xR{nn}.assignFiles;
103
        xR{nn}.storeSelf;
104
    end
105
end
106

  
107

  
108
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109
% ** Generate features **
110
% This is the time consuming, processing intensive portion of the program.
111
% Nodes that are not the master node are only interested in the opFolder
112
% member of the jobjects.
113
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114
worker(xL.opFolder);
115
maxConds = nn;
116
if ~isMasterNode %dont bother wasting master node effort on generating testing features (for now)
117
    for nn = 1:maxConds
118
        worker(xR{nn}.opFolder);
119
    end
120
end
121

  
122
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123
% Train and test the recogniser - a job for the master node only
124
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125
if isMasterNode    
126
    while(~all(xL.todoStatus==2))        
127
        disp('Waiting on straggler nodes to complete their jobs before HMM is trained . . .')
128
        pause(30); %Wait for 30 seconds before looking again
129
        xL.lockJobList;
130
        xL = xL.loadSelf; %Reload incase changed
131
        xL.unlockJobList;
132
    end
133
    y = cHMM(hmmFolder);    
134
    y.numCoeff = (xL.numCoeff-logical(xL.removeEnergyStatic)) * 3;
135
    y.createSCP(xL.opFolder)
136
    y.createMLF(xL.opFolder)
137
    y.train(xL.opFolder) %This node can be busy training, even if other jobs are being processed for testing
138
    
139
    % ALLOW MASTER NODE TO MUCK IN WITH GENERATING TESTING FEATURES ONCE
140
    % HMM HAS BEEN TRAINED
141
    for nn = 1:maxConds
142
        worker(xR{nn}.opFolder);
143
    end    
144
    
145
    xR{end}.lockJobList;
146
    xR{end} = xR{end}.loadSelf; %Reload changes
147
    xR{end}.unlockJobList;
148
    while(~all(xR{end}.todoStatus==2))        
149
        disp('Waiting on straggler nodes to complete their jobs before HMM is tested . . .')
150
        pause(30); %Wait for 30 seconds before looking again
151
        xR{end}.lockJobList;
152
        xR{end} = xR{end}.loadSelf; %Reload incase changed
153
        xR{end}.unlockJobList;
154
    end
155
      
156
    for nn = 1:maxConds
157
        y.createSCP(xR{nn}.opFolder);
158
        y.test(xR{nn}.opFolder);
159
    end
160
    
161
    %Show all of the scores in the command window at the end
162
    for nn = 1:maxConds
163
        y.score(xR{nn}.opFolder);
164
    end
165
end
userProgramsASRforDummies/Exp_Tutorial_2.m
1
function Exp_Tutorial_2(isMasterNode)
2

  
3
% This tutorial recycles a HMM
4

  
5
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6
% Set up the basic experiment parameters
7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8
expName = 'Tutorial';
9
dataFolderPrefix = 'recycle_featR';
10
if isunix
11
    expFolderPrefix = '/scratch/nrclark/exps/';
12
else
13
    expFolderPrefix = 'D:\Exps';
14
end
15

  
16
% expFolderPrefix = pwd;
17
expFolder = fullfile(expFolderPrefix,expName);
18
hmmFolder = fullfile(expFolder,'hmm');
19

  
20
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
% Sort out the training (LEARNING) condition
22
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23
learnFolder = fullfile(expFolder,'featL');
24

  
25
xL = cJob('L', learnFolder);
26

  
27
xL.participant = 'Normal';
28
xL.MAPparamChanges= {'DRNLParams.rateToAttenuationFactorProb=0;', 'OMEParams.rateToAttenuationFactorProb=0;' };
29

  
30
xL.noiseLevToUse   =  -200;
31
xL.speechLevToUse  =  60;
32

  
33
xL.MAPopHSR = 1;
34
xL.MAPopMSR = 0;
35
xL.MAPopLSR = 0;
36

  
37

  
38
xL.numCoeff = 14;
39
xL.removeEnergyStatic = 0;
40

  
41
%%%%% Group of params that will influence simulation run time %%%%%%%
42
xL.numWavs = 12; %MAX=8440
43
testWavs = 6; %MAX = 358
44
nzLevel = [-200 40:10:70];
45
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46

  
47
xL.noisePreDur = 1;
48
xL.noisePostDur = 0.1;
49
xL.truncateDur  = xL.noisePreDur-0.1; 
50
xL.noiseName = 'pink_demo';
51

  
52

  
53
% if isMasterNode && ~isdir(xL.opFolder)
54
%     mkdir(xL.opFolder);
55
%     xL = xL.assignFiles;
56
%     xL.storeSelf;
57
% end
58

  
59
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60
% Sort out the testing (RECOGNITION) conditions
61
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
recConditions = numel(nzLevel);
63

  
64
tmpIdx=0;
65
for nn = 0*recConditions+1:1*recConditions    
66
    tmpIdx=tmpIdx+1;
67
    xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
68
    recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
69
    xR{nn}.opFolder = recFolder;    
70
    
71
    %These are the interesting differences between training and testing
72
    xR{nn}.numWavs = testWavs; %MAX = 358
73
    xR{nn}.noiseLevToUse = nzLevel(tmpIdx); 
74
    xR{nn}.MAPparamChanges= {'DRNLParams.a=400;'};
75

  
76
    
77
    %Now just to wrap it up ready for processing
78
    if isMasterNode && ~isdir(xR{nn}.opFolder)
79
        mkdir(xR{nn}.opFolder);
80
        xR{nn} = xR{nn}.assignWavPaths('R');
81
        xR{nn} = xR{nn}.assignFiles;
82
        xR{nn}.storeSelf;
83
    end
84
end
85

  
86
tmpIdx=0;
87
for nn = 1*recConditions+1:2*recConditions    
88
    tmpIdx=tmpIdx+1;
89
    xR{nn} = xL; %simply copy the "Learn" object and change it a bit below
90
    recFolder = fullfile(expFolder,[dataFolderPrefix num2str(nn)]);
91
    xR{nn}.opFolder = recFolder;    
92
    
93
    %These are the interesting differences between training and testing
94
    xR{nn}.numWavs = testWavs; %MAX = 358
95
    xR{nn}.noiseLevToUse = nzLevel(tmpIdx); 
96
    xR{nn}.MAPparamChanges= {'DRNLParams.a=400;'};
97
    
98
    xR{nn}.mainGain = [27.2013;   26.0797;   26.0939;   26.7997;   26.0520];  
99
    xR{nn}.TCdBO    = [37;   37;   37;   37;   37];      %Compression thresholds (in dB OUTPUT from 2nd filt)
100
    xR{nn}.TMdBO    = [20;   20;   20;   20;   20];      %MOC thresholds (in dB OUTPUT from 2nd filt)
101
    xR{nn}.ARthresholddB = 85;       % dB SPL (input signal level) =>200 to disable
102
    xR{nn}.MOCtau = 1;
103
    xR{nn}.useAid = 1;
104
    
105
    %Now just to wrap it up ready for processing
106
    if isMasterNode && ~isdir(xR{nn}.opFolder)
107
        mkdir(xR{nn}.opFolder);
108
        xR{nn} = xR{nn}.assignWavPaths('R');
109
        xR{nn} = xR{nn}.assignFiles;
110
        xR{nn}.storeSelf;
111
    end
112
end
113

  
114

  
115

  
116
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117
% ** Generate features **
118
% This is the time consuming, processing intensive portion of the program.
119
% Nodes that are not the master node are only interested in the opFolder
120
% member of the jobjects.
121
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122
% worker(xL.opFolder);
123
maxConds = nn;
124
if ~isMasterNode %dont bother wasting master node effort on generating testing features (for now)
125
    for nn = 1:maxConds
126
        worker(xR{nn}.opFolder);
127
    end
128
end
129

  
130
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
% Train and test the recogniser - a job for the master node only
132
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133
if isMasterNode    
134
%     while(~all(xL.todoStatus==2))        
135
%         disp('Waiting on straggler nodes to complete their jobs before HMM is trained . . .')
136
%         pause(30); %Wait for 30 seconds before looking again
137
%         xL.lockJobList;
138
%         xL = xL.loadSelf; %Reload incase changed
139
%         xL.unlockJobList;
140
%     end
141
    y = cHMM(hmmFolder);    
142
    y.numCoeff = 14*3;
143
%     y.createSCP(xL.opFolder)
144
%     y.createMLF(xL.opFolder)
145
%     y.train(xL.opFolder) %This node can be busy training, even if other jobs are being processed for testing
146
    
147
    % ALLOW MASTER NODE TO MUCK IN WITH GENERATING TESTING FEATURES ONCE
148
    % HMM HAS BEEN TRAINED
149
    for nn = 1:maxConds
150
        worker(xR{nn}.opFolder);
151
    end    
152
    
153
    xR{end}.lockJobList;
154
    xR{end} = xR{end}.loadSelf; %Reload changes
155
    xR{end}.unlockJobList;
156
    while(~all(xR{end}.todoStatus==2))        
157
        disp('Waiting on straggler nodes to complete their jobs before HMM is tested . . .')
158
        pause(30); %Wait for 30 seconds before looking again
159
        xR{end}.lockJobList;
160
        xR{end} = xR{end}.loadSelf; %Reload incase changed
161
        xR{end}.unlockJobList;
162
    end
163
      
164
    for nn = 1:maxConds
165
        y.createSCP(xR{nn}.opFolder);
166
        y.test(xR{nn}.opFolder);
167
    end
168
    
169
    %Show all of the scores in the command window at the end
170
    for nn = 1:maxConds
171
        y.score(xR{nn}.opFolder);
172
    end
173
end
userProgramsASRforDummies/MAPwrap.m
1
% This function wraps up whatever version of MAP I want to call. It is
2
% implemented partly because I want to avoid messing with jobject too much
3
% and mostly because I dont want to declare globals in my class.
4

  
5
function [myANprobRateOutput, mydt, myBF] = MAPwrap(stimulus, sampleRate, BFlist, participant, AN_spikesOrProbability, paramChanges)
6

  
7

  
8
global ANprobRateOutput  dt BFlist
9
% disp(20*log10(sqrt(mean(stimulus.^2))/20e-6))
10
MAP1_14(stimulus, sampleRate, BFlist, participant, AN_spikesOrProbability, paramChanges);
11
% disp(20*log10(sqrt(mean(stimulus.^2))/20e-6))
12
myANprobRateOutput   = ANprobRateOutput;
13
mydt = dt;
14
myBF = BFlist;
userProgramsASRforDummies/cEssexAid.m
1
classdef cEssexAid
2
    %ESSEXAID_WRAPCLASS Wrapper for the EssexAid - Nick Clark July 2011
3
    %   This class wraps up the EssexAid algorithm function that processes
4
    %   each block of samples. This wrapper closely emulates the GUI used
5
    %   in the lab and runs stimuli through the exact same algorithm used
6
    %   in the lab. It even includes a helper function to generate C code
7
    %   from the algorithm for use in a real-time framework.
8

  
9
    
10
    %% *********************************************************
11
    %  properties                      _   _
12
    %                                 | | (_)
13
    %  _ __  _ __ ___  _ __   ___ _ __| |_ _  ___  ___
14
    % | '_ \| '__/ _ \| '_ \ / _ \ '__| __| |/ _ \/ __|
15
    % | |_) | | | (_) | |_) |  __/ |  | |_| |  __/\__ \
16
    % | .__/|_|  \___/| .__/ \___|_|   \__|_|\___||___/
17
    % | |             | |
18
    % |_|             |_|
19
    %************************************************************
20
    
21
    %% **********************************************************
22
    % Public properties - can be set by user
23
    %************************************************************
24
    properties(Access = public)
25
        sr         = 48e3;
26
        numSamples = 1024; %MAX=6912, LAB_USE=48
27
        stimulusUSER                   
28
        
29
        %------------------------------------------------------------------
30
        % Params for audiometric freqs 250, 500, 1000, 2000, 4000, 8000 Hz
31
        %------------------------------------------------------------------
32
        audiometry_dB= [ 0;    0;    0;    0;    0;   0];   %Pure tone threshold in dB SPL
33
        mainGain_dB  = [ 0;    0;    0;    0;    0;   0];   %Gain applied at audiometric frequencies
34
        TC_dBHL      = [40;   40;   40;   40;   40;  40];   %Compression thresholds (in dB HL from 2nd filt)
35
        TM_dBHL      = [10;   10;   10;   10;   10;  10];   %MOC thresholds (in dB OUTPUT from 2nd filt)
36
        DRNLc        = [ 0.2;  0.2;  0.2;  0.2;  0.2; 0.2]; %Compression exponent at audiometric frequencies
37
        
38
        %------------------------------------------------------------------
39
        % Dynamic compression properties
40
        %------------------------------------------------------------------
41
        ARtau = 60e-3;       %decay time constant
42
        ARthreshold_dB = 85; %dB SPL (input signal level) =>200 to disable
43
        MOCtau = 450e-3;     %Time constant in Seconds
44
        MOCfactor = 0.5;     %dB attenuation applied to the input per dB exceeding output threshold
45
        
46
        %------------------------------------------------------------------
47
        % Band filtering properties
48
        %------------------------------------------------------------------
49
        bwOct = 1/2; %1/1, 1/2, 1/3, 1/4, 1/5
50
        filterOrder = 2 %BUTTER=2, GTF=3
51
        useGTF = false; %If false, revert to butterworth
52
    end
53
    
54
    %% **********************************************************
55
    % Read only properties that are not dependent
56
    %************************************************************
57
    properties(SetAccess = private)          
58
        MOCrecord
59
    end
60
    
61
    %% **********************************************************
62
    % Constant properties 
63
    %************************************************************
64
    properties(Constant = true, Hidden = true)  
65
        numAudiometricFreqs = 6;
66
    end
67
    
68
    %% **********************************************************
69
    % Dependent visable properties - calculated at runtime
70
    %************************************************************
71
    properties(Dependent = true, Hidden = false)
72
        channelBFs %= 250 * 2.^((0:fNmax)'*params.bwOct);        
73
        numChannels %= numel(channelBFs);        
74
        aidOPnice %aid output reformatted to be exactly the same dimensions as the input stimulus                               
75
    end
76
    
77
    %% **********************************************************
78
    % Dependent invisable properties - calculated at runtime
79
    %************************************************************
80
    properties(Dependent = true, Hidden = true)
81
        TC_dBO_INTERP % Compression threshold in terms of 2nd filter o/p in dB SPL
82
        TM_dBO_INTERP % MOC threshold in terms of 2nd filter o/p in dB SPL                    
83
        bwOct_INTERP
84
        DRNLb_INTERP %=  ( 2e-5 .* 10.^(TCdBO/20)) .^ (1-DRNLc)  ; 
85
        DRNLc_INTERP               
86
        mainGain_INTERP %Interp'd and in linear units 
87
        
88
        ARthresholdPa %=  20e-6*10^(ARthreshold_dB/20);% Pa thresh for triggering AR        
89
        stimulusINTERNAL %input stimulus in correct format for the Aid algo
90
    end
91
    
92
    %% **********************************************************
93
    % Protected properties - The user never needs to set
94
    %************************************************************
95
    properties(Access = protected)  
96
        aidOP
97
        emlc_z
98
        
99
        %--------------------------------------------------------------
100
        % ENUMERATIONS USED IN THE FRAME PROCESSOR
101
        %--------------------------------------------------------------
102
        enumC_ARb  = 0;
103
        enumC_ARa  = 2;
104
        enumC_MOCb = 4;
105
        enumC_MOCa = 6;
106
        
107
        % enumC_BPb1 = 8;
108
        % enumC_BPa1 = 13;
109
        % enumC_BPb2 = 18;
110
        % enumC_BPa2 = 23;
111
        % enumC_BPb3 = 28;
112
        % enumC_BPa3 = 33;
113
        % enumC_BPb4 = 38;
114
        % enumC_BPa4 = 43;
115
        
116
        enumS_AR  = 0;
117
        
118
        % enumS_MOC1  = 1;
119
        % enumS_BPin_1_1 = 2;
120
        % enumS_BPin_2_1 = 6;
121
        % enumS_BPout_1_1 = 10;
122
        % enumS_BPout_2_1 = 14;
123
        %
124
        % enumS_MOC2 = 18;
125
        % enumS_BPin_1_2 = 19;
126
        % enumS_BPin_2_2 = 23;
127
        % enumS_BPout_1_2 = 27;
128
        % enumS_BPout_2_2 = 31;
129
        % ...
130
    end
131
        
132
    %% **********************************************************
133
    % methods        _   _               _
134
    %               | | | |             | |
135
    % _ __ ___   ___| |_| |__   ___   __| |___
136
    %| '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
137
    %| | | | | |  __/ |_| | | | (_) | (_| \__ \
138
    %|_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
139
    %************************************************************
140
    
141
    methods
142
        %% **********************************************************
143
        % Constructor
144
        %************************************************************
145
        function obj = EssexAid_WrapClass(sr, stimulus)          
146
            
147
            if nargin > 0
148
                obj.sr = sr;
149
            end
150
            
151
            if nargin > 1
152
                obj.stimulusUSER = stimulus;
153
            else         
154
                obj.stimulusUSER = obj.pipSequence(obj.sr);
155
            end
156
        end
157
        
158
        %% **********************************************************
159
        % Get method for channelBFs 
160
        %************************************************************
161
        function value = get.channelBFs(obj)
162
            fNmax = 5/obj.bwOct;
163
            value = 250 * 2.^((0:fNmax)'*obj.bwOct);
164
        end
165
        
166
        %% **********************************************************
167
        % Get method for numChannels 
168
        %************************************************************
169
        function value = get.numChannels(obj)
170
            value = numel(obj.channelBFs);
171
        end
172
        
173
        %% **********************************************************
174
        % Get method for ARthresholdPa 
175
        %************************************************************
176
        function value = get.ARthresholdPa(obj)
177
            value = 20e-6*10^(obj.ARthreshold_dB/20);% Pa thresh for triggering AR
178
        end
179
        
180
        %% **********************************************************
181
        % Get method for TC_dBO_INTERP
182
        %************************************************************
183
        function value = get.TC_dBO_INTERP(obj)
184
            TC_dBO = obj.audiometry_dB - obj.mainGain_dB + obj.TC_dBHL;
185
            value  = obj.interpPars(TC_dBO, obj.numChannels);
186
        end
187
        
188
        %% **********************************************************
189
        % Get method for TM_dBO_INTERP
190
        %************************************************************
191
        function value = get.TM_dBO_INTERP(obj)
192
            TM_dBO = obj.audiometry_dB - obj.mainGain_dB + obj.TM_dBHL;
193
            value  = obj.interpPars(TM_dBO, obj.numChannels);
194
        end
195
        
196
        %% **********************************************************
197
        % Get method for bwOct_INTERP 
198
        %************************************************************
199
        function value = get.bwOct_INTERP(obj)
200
            value = repmat(obj.bwOct, 1, obj.numChannels);
201
        end
202
        
203
        %% **********************************************************
204
        % Get method for DRNLb_INTERP 
205
        %************************************************************
206
        function value = get.DRNLb_INTERP(obj)
207
            value = ( 2e-5 .* 10.^(obj.TC_dBO_INTERP/20)) .^ (1-obj.DRNLc_INTERP); 
208
        end
209
        
210
        %% **********************************************************
211
        % Get method for DRNLc_INTERP 
212
        %************************************************************
213
        function value = get.DRNLc_INTERP(obj)
214
            value  = obj.interpPars(obj.DRNLc, obj.numChannels);
215
        end
216
        
217
        %% **********************************************************
218
        % Get method for mainGain_INTERP 
219
        %************************************************************
220
        function value = get.mainGain_INTERP(obj)
221
            mainGainLin = 10.^(obj.mainGain_dB/20); %lin units
222
            value  = obj.interpPars(mainGainLin, obj.numChannels);
223
        end                
224
        
225
        %% ***********************************************************
226
        % Get method for stimulus
227
        % -----------------------
228
        % The hearing aid expects a stereo signal, as the MOC control is
229
        % linked for left and right channels. It would be more efficient to
230
        % use a mono version of the aid for simulation in Matlab. However,
231
        % I always want to use the exact same code for the hardware in the
232
        % lab and current simulations. This code will make a mono signal
233
        % stereo if needs be and/or rotate to 2xN array.
234
        %*************************************************************
235
        function value = get.stimulusINTERNAL(obj)            
236
            [nRows, nCols] = size(obj.stimulusUSER);
237
            
238
            % Assume that the stimulus duration is greater than 2 samples.
239
            % Therefore the number of channels is the min dim.            
240
            [nChans, I] = min([nRows nCols]);                                                
241
            
242
            if nChans == 2
243
                if I == 2
244
                    value = obj.stimulusUSER;
245
                else
246
                    value = obj.stimulusUSER';
247
                end
248
            elseif nChans == 1 %Just to be explicit
249
                if I == 2
250
                    value = [obj.stimulusUSER obj.stimulusUSER];   
251
                else
252
                    value = [obj.stimulusUSER; obj.stimulusUSER]';
253
                end
254
            end
255
        end
256
        
257
        %% ***********************************************************
258
        % Get method for aid output
259
        % -----------------------
260
        % This get method is linked to the above internal stimulus method
261
        % and allows the user to extract the hearing aid output in exactly
262
        % the same shape and size as the original input stimulus. This is
263
        % very useful for the speech recognition work and presumably
264
        % for multithreshold also.
265
        %*************************************************************
266
        function value = get.aidOPnice(obj)
267
            if ~isempty(obj.aidOP)
268
                [nRows, nCols] = size(obj.stimulusUSER);
269
                
270
                % Assume that the stimulus duration is greater than 2 samples.
271
                % Therefore the number of channels is the min dim.
272
                [nChans, I] = min([nRows nCols]);
273
                
274
                %** The aid output will ALWAYS be a 2xN array **
275
                %The fist job is to remove trailing zeros that may have been
276
                %introduced by the framing process
277
                aidOPtruncated = obj.aidOP(:, 1:max([nRows nCols]));
278
                
279
                %The next task is to arrange the op like the ip
280
                if nChans == 2
281
                    if I == 1
282
                        value = aidOPtruncated;
283
                    else
284
                        value = aidOPtruncated';
285
                    end
286
                elseif nChans == 1 %Just to be explicit
287
                    if I == 1
288
                        value = aidOPtruncated(1,:);
289
                    else
290
                        value = aidOPtruncated(1,:)';
291
                    end
292
                end
293
            else % ---- of if isempty statement
294
                value = [];
295
            end
296
        end
297
        
298
        %% ***********************************************************
299
        % *** Set methods ***
300
        % -----------------------
301
        % This is a bunch of unexciting error hunting functions. They also
302
        % flush the aid output if any parameters change. Therefore,
303
        % processStim will have to be called explicity by the user once
304
        % again. 
305
        %*************************************************************
306
        function obj = set.stimulusUSER(obj,value)
307
            [nRows, nCols] = size(value);
308
            
309
            % Assume that the stimulus duration is greater than 2 samples.
310
            % Therefore the number of channels is the min dim.            
311
            nChans = min([nRows nCols]);            
312
            assert(nChans<3 && nChans, 'Number of stimulus channels must be 1 or 2')
313
            
314
            obj = obj.flushAidData; %flush any previous hearing aid data if the input stimulus changes
315
            obj.stimulusUSER = value;
316
        end                     
317
        function obj = set.sr(obj,value)
318
            assert(value>=20e3 && value<=192e3, 'sr must be between 20 and 192 kHz')            
319
            obj = obj.flushAidData;
320
            obj.sr = value;
321
        end
322
        function obj = set.numSamples(obj,value)
323
            assert(value>=48 && value<=6912, 'must be between 48 and 6912 samples')            
324
            obj = obj.flushAidData;
325
            obj.numSamples = value;
326
        end
327
        function obj = set.audiometry_dB(obj,value)
328
            [nRows,nCols] = size(value);
329
            assert(nRows==obj.numAudiometricFreqs && nCols==1, 'must be 6x1 column vector') %#ok<MCSUP>
330
            obj = obj.flushAidData;
331
            obj.audiometry_dB = value;
332
        end
333
        function obj = set.mainGain_dB(obj,value)
334
            [nRows,nCols] = size(value);
335
            assert(nRows==obj.numAudiometricFreqs && nCols==1, 'must be 6x1 column vector') %#ok<MCSUP>
336
            obj = obj.flushAidData;
337
            obj.mainGain_dB = value;
338
        end
339
        function obj = set.TC_dBHL(obj,value)
340
            [nRows,nCols] = size(value);
341
            assert(nRows==obj.numAudiometricFreqs && nCols==1, 'must be 6x1 column vector') %#ok<MCSUP>
342
            obj = obj.flushAidData;
343
            obj.TC_dBHL = value;
344
        end
345
        function obj = set.TM_dBHL(obj,value)
346
            [nRows,nCols] = size(value);
347
            assert(nRows==obj.numAudiometricFreqs && nCols==1, 'must be 6x1 column vector') %#ok<MCSUP>
348
            obj = obj.flushAidData;
349
            obj.TM_dBHL = value;
350
        end
351
        function obj = set.DRNLc(obj,value)
352
            [nRows,nCols] = size(value);
353
            assert(nRows==obj.numAudiometricFreqs && nCols==1, 'must be 6x1 column vector') %#ok<MCSUP>
354
            assert(all(value)>=0 && all(value)<=1, 'all DRNLc values must be between 0 and 1')
355
            obj = obj.flushAidData;
356
            obj.DRNLc = value;
357
        end
358
        function obj = set.ARtau(obj,value)
359
            assert(value>=1e-3 && value<=1, 'must be between 1e-3 and 1s')            
360
            obj = obj.flushAidData;
361
            obj.ARtau = value;
362
        end
363
        function obj = set.ARthreshold_dB(obj,value)
364
            assert(value>0, 'set AR to a high value to disable it')            
365
            obj = obj.flushAidData;
366
            obj.ARthreshold_dB = value;
367
        end
368
        function obj = set.MOCtau(obj,value)
369
            assert(value>=1e-3 && value<=2, 'must be between 1e-3 and 2s')            
370
            obj = obj.flushAidData;
371
            obj.MOCtau = value;
372
        end
373
        function obj = set.MOCfactor(obj,value)
374
            assert(value>=0 && value<=1, 'must be between 0 and 1')
375
            obj = obj.flushAidData;
376
            obj.MOCfactor = value;
377
        end
378
        function obj = set.bwOct(obj,value)
379
            assert(value==1/1 || value==1/2 || value==1/3 || value==1/4 || value==1/5, 'must be one of 1./(1:5)')
380
            obj = obj.flushAidData;
381
            obj.bwOct = value;
382
        end
383
        function obj = set.filterOrder(obj,value)
384
            assert(value>0 && value<5, 'must be one of 1:4')
385
            obj = obj.flushAidData;
386
            obj.filterOrder = value;
387
        end
388
        function obj = set.useGTF(obj,value)
389
            obj = obj.flushAidData;
390
            obj.useGTF = value;
391
        end                    
392
        
393
        %% **********************************************************
394
        % flushAidData        
395
        % This second function is a workaround allowing a set method to
396
        % change another property value.
397
        %************************************************************
398
        function obj = flushAidData(obj) 
399
            obj.aidOP = [];
400
            obj.MOCrecord = [];
401
        end 
402
        
403
        
404
        %% **********************************************************
405
        % OVERLOADED plot method 
406
        %************************************************************
407
        function plot(obj)
408
            clf
409
            sig2dBSPL = @(sig)20*log10(abs(sig/20e-6)+(1/(2^32)));
410
            dt = 1/obj.sr;
411
            tAxis = dt:dt:dt*size(obj.stimulusINTERNAL,1);
412
            
413
            subplot(2,1,1)
414
            plot(tAxis(1:length(obj.stimulusUSER)), sig2dBSPL(obj.stimulusUSER), 'k')
415
            if ~isempty(obj.aidOPnice)
416
                hold on
417
                plot(tAxis(1:length(obj.stimulusUSER)), sig2dBSPL(obj.aidOPnice), 'r')
418
            end                                   
419
            ylim([0 100])
420
            xlim([0 tAxis(length(obj.stimulusUSER))])
421
            title('Level response')
422
            xlabel('Time in seconds')
423
            ylabel('Level in dB SPL')
424
            
425
            subplot(2,1,2) 
426
            if ~isempty(obj.MOCrecord)
427
                imagesc(tAxis, 1:obj.numChannels, flipud(-20*log10(obj.MOCrecord)))
428
                colorbar                               
429
            end         
430
            title('MOC attenuation')
431
            xlabel('Time in seconds')
432
            ylabel('Band frequency in Hz')
433
            numSpacers = 1 + (obj.numChannels-numel(obj.DRNLc)) / (numel(obj.DRNLc)-1);
434
            set(gca, 'YTick', 1:numSpacers:obj.numChannels);
435
            set(gca, 'YTickLabel', num2str(flipud([250; 500; 1000; 2000; 4000; 8000])));
436
        end% ------ OVERLOADED plot method
437
        
438
        %% **********************************************************
439
        % OVERLOADED soundsc method 
440
        %************************************************************
441
        function soundsc(obj)
442
            soundsc(obj.aidOPnice, obj.sr)
443
        end                 
444
        
445
        %% **********************************************************
446
        % processStim
447
        %************************************************************
448
        function obj = processStim(obj)
449
            %--------------------------------------------------------------
450
            % EMULATION OF THE GUI PARAMETER CONVERSIONS
451
            %--------------------------------------------------------------
452
            biggestNumSamples = obj.numSamples; 
453
            
454
            filterStatesL = (zeros(3000,1));
455
            filterStatesR = filterStatesL;
456
            filterCoeffs = (zeros(5000,1));
457
            
458
            %filter coefficients
459
            ARcutOff=1/(2*pi*obj.ARtau);
460
            [b,a] = butter(1,ARcutOff/(obj.sr/2));
461
            filterCoeffs(obj.enumC_ARb+1:obj.enumC_ARb+2) = b;
462
            filterCoeffs(obj.enumC_ARa+1:obj.enumC_ARa+2) = a;
463
            
464
            MOCcutOff=1/(2*pi*obj.MOCtau);
465
            [bMOC,aMOC] = butter(1,MOCcutOff/(obj.sr/2));
466
            filterCoeffs(obj.enumC_MOCb+1:obj.enumC_MOCb+2) = bMOC;
467
            filterCoeffs(obj.enumC_MOCa+1:obj.enumC_MOCa+2) = aMOC;
468
            
469
            
470
            for filterCount = 1:obj.numChannels
471
                %-----------------------------------
472
                % nonlinear path - filter bws
473
                %-----------------------------------
474
                lowerCutOff=obj.channelBFs(filterCount)*2^(-obj.bwOct_INTERP(filterCount)/2);
475
                upperCutOff=obj.channelBFs(filterCount)*2^( obj.bwOct_INTERP(filterCount)/2);
476
                
477
                if obj.useGTF
478
                    bwHz = upperCutOff - lowerCutOff;
479
                    [b_DRNL,a_DRNL] = obj.gammatone(bwHz, obj.channelBFs(filterCount), 1/obj.sr);
480
                    filterCoeffs(10*(filterCount-1)+9 :10*(filterCount-1)+10) = b_DRNL;
481
                    filterCoeffs(10*(filterCount-1)+14:10*(filterCount-1)+16) = a_DRNL;
482
                else                                             
483
                    [b_DRNL,a_DRNL] = butter(2,[lowerCutOff upperCutOff]/(obj.sr/2));
484
                    filterCoeffs(10*(filterCount-1)+9 :10*(filterCount-1)+13) = b_DRNL;
485
                    filterCoeffs(10*(filterCount-1)+14:10*(filterCount-1)+18) = a_DRNL;
486
                end
487
            end
488
            
489
            %--------------------------------------------------------------
490
            % EMULATION OF THE IO CALLBACK THREAD
491
            %--------------------------------------------------------------
492
            frameBufferL = buffer(obj.stimulusINTERNAL(:,1), obj.numSamples);
493
            frameBufferR = buffer(obj.stimulusINTERNAL(:,2), obj.numSamples);
494
            nFrames = size(frameBufferL,2);
495
            
496
            pad = zeros(1,biggestNumSamples-obj.numSamples);
497
            ARampL=ones(1,biggestNumSamples);
498
            ARampR = ARampL;
499
            MOCcontrol = ones(obj.numChannels, biggestNumSamples);
500
            
501
            peakIPL = zeros(5,1);
502
            peakOPL = peakIPL;
503
            rmsIPL  = peakIPL;
504
            rmsOPL  = peakIPL;
505
            
506
            peakIPR = peakIPL;
507
            peakOPR = peakIPL;
508
            rmsIPR  = peakIPL;
509
            rmsOPR  = peakIPL;
510
            
511
            MOCend = zeros(obj.numChannels,1);
512
            
513
            op = [];
514
            moc= [];
515
            for nn = 1:nFrames
516
                frameBufferPadL = [frameBufferL(:,nn)' pad];
517
                frameBufferPadR = [frameBufferR(:,nn)' pad];
518
                
519
                [ outBufferL, outBufferR, filterStatesL, filterStatesR,  ARampL, ARampR, MOCend, peakIPL, peakOPL, rmsIPL, rmsOPL, peakIPR, peakOPR, rmsIPR, rmsOPR, MOCcontrol ] =...
520
                    EssexAidProcessVFrameSwitchable( ...
521
                    frameBufferPadL,...
522
                    frameBufferPadR,...
523
                    filterStatesL,...
524
                    filterStatesR,...
525
                    filterCoeffs,...
526
                    obj.numChannels,...
527
                    obj.numSamples,...
528
                    ARampL,...
529
                    ARampR,...
530
                    obj.ARthresholdPa,...
531
                    obj.filterOrder,...
532
                    obj.DRNLb_INTERP,...
533
                    obj.DRNLc_INTERP,...
534
                    obj.TM_dBO_INTERP,...
535
                    obj.MOCfactor,...
536
                    peakIPL,...
537
                    peakOPL,...
538
                    rmsIPL,...
539
                    rmsOPL,...
540
                    peakIPR,...
541
                    peakOPR,...
542
                    rmsIPR,...
543
                    rmsOPR,...
544
                    MOCend,...
545
                    MOCcontrol,...
546
                    obj.mainGain_INTERP,...
547
                    obj.useGTF);
548
                                
549
                
550
                outBuffer = ( [outBufferL(:, 1:obj.numSamples); outBufferR(:, 1:obj.numSamples)] );                
551
                op = [op outBuffer]; %#ok<AGROW>   
552
                moc= [moc MOCcontrol]; %#ok<AGROW>
553
                
554
            end %End of frame processing emulation loop
555
            obj.aidOP = op;
556
            obj.MOCrecord=moc;
557
                       
558
            
559
        end %End of process stim method          
560
        
561
    end %End of methods block
562
    
563
    %%  *********************************************************
564
    %      _        _   _                       _   _               _
565
    %     | |      | | (_)                     | | | |             | |
566
    %  ___| |_ __ _| |_ _  ___   _ __ ___   ___| |_| |__   ___   __| |___
567
    % / __| __/ _` | __| |/ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
568
    % \__ \ || (_| | |_| | (__  | | | | | |  __/ |_| | | | (_) | (_| \__ \
569
    % |___/\__\__,_|\__|_|\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
570
    %************************************************************
571
    
572
    methods(Static)        
573
        %% ********************************************************
574
        % pipOut - sequence of tone pips at various levels
575
        %**********************************************************        
576
        function pipOut = pipSequence(sampleRate, freq, dBlevs, pulseDur, silDur)
577
            if nargin < 5
578
                silDur = 0.3;
579
            end
580
            if nargin < 4
581
                pulseDur = 0.1;
582
            end
583
            if nargin < 3
584
                dBlevs = 20:20:100;
585
            end
586
            if nargin < 2
587
                freq = 500;
588
            end
589
            if nargin < 1
590
                sampleRate = 48e3;
591
            end
592
            
593
            dt = 1/sampleRate;
594
            tAxis = dt:dt:pulseDur;
595
            sPulse = sin(2*pi*freq*tAxis);
596
            sPulse = sPulse./sqrt(mean(sPulse.^2));
597
            rms2dBspl = @(dBspl)20e-6*10^(dBspl/20); %sneaky short-hand function by (ab)using function handles
598
            zPad = zeros(1,ceil(sampleRate*silDur));
599
            
600
            pipOut = [];
601
            for nn = 1:numel(dBlevs)                
602
                pipOut = [ pipOut sPulse*rms2dBspl(dBlevs(nn))  zPad]; %#ok<AGROW>
603
            end
604

  
605
        end% ------ OF pipSequence
606
        
607
        %% ********************************************************
608
        % interpPars - Linear interpolation of given parameter to mimic GUI
609
        % fitting functionality.
610
        %**********************************************************        
611
        function fullArray = interpPars(shortArray, numBands)
612
            nGUIbands = numel(shortArray);
613
            if numBands == nGUIbands
614
                fullArray = shortArray;
615
            else
616
                numSpacers = (numBands-nGUIbands) / (nGUIbands-1);
617
                fullArray = shortArray(1);
618
                for nn = 2:nGUIbands
619
                    fullArray = [fullArray,...
620
                        repmat(mean([shortArray(nn) shortArray(nn-1)]),1,numSpacers),...
621
                        shortArray(nn)]; %#ok<AGROW>
622
                end                    
623
            end                        
624
        end% ----- OF interpPars
625
        
626
        %% ********************************************************
627
        % gammatone - get filter coefficients
628
        %********************************************************** 
629
        function [b,a] = gammatone(bw, cf, dt)
630
            phi = 2 * pi * bw * dt;
631
            theta = 2 * pi * cf * dt;
632
            cos_theta = cos(theta);
633
            sin_theta = sin(theta);
634
            alpha = -exp(-phi) * cos_theta;
635
            b0 = 1.0;
636
            b1 = 2 * alpha;
637
            b2 = exp(-2 * phi);
638
            z1 = (1 + alpha * cos_theta) - (alpha * sin_theta) * 1i;
639
            z2 = (1 + b1 * cos_theta) - (b1 * sin_theta) * 1i;
640
            z3 = (b2 * cos(2 * theta)) - (b2 * sin(2 * theta)) * 1i;
641
            tf = (z2 + z3) / z1;
642
            a0 = abs(tf);
643
            a1 = alpha * a0;
644
            
645
            a = [b0, b1, b2];
646
            b = [a0, a1];
647
        end% ------ OF gammatone
648
    end% ------ OF static methods
649
    
650
end %End of classdef
651

  
userProgramsASRforDummies/cHMM.m
1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
%   This program is free software; you can redistribute it and/or modify
3
%   it under the terms of the GNU General Public License as published by
4
%   the Free Software Foundation; either version 2 of the License, or
5
%   (at your option) any later version.
6
%
7
%   This program is distributed in the hope that it will be useful,
8
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
%   GNU General Public License for more details.
11
%
12
%   You can obtain a copy of the GNU General Public License from
13
%   http://www.gnu.org/copyleft/gpl.html or by writing to
14
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
15
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16

  
17
classdef cHMM
18
    %HMMCLASS Handles all of the HTK related gubbins
19
    %   Please see the documentation located in a separate file for further
20
    %   information.     
21
    
22
    %%  *********************************************************
23
    %  properties                      _   _
24
    %                                 | | (_)
25
    %  _ __  _ __ ___  _ __   ___ _ __| |_ _  ___  ___
26
    % | '_ \| '__/ _ \| '_ \ / _ \ '__| __| |/ _ \/ __|
27
    % | |_) | | | (_) | |_) |  __/ |  | |_| |  __/\__ \
28
    % | .__/|_|  \___/| .__/ \___|_|   \__|_|\___||___/
29
    % | |             | |
30
    % |_|             |_|
31
    %************************************************************
32
    
33
    %% **********************************************************
34
    % Public properties - can be set by user
35
    %************************************************************
36
    properties(Access = public)
37
        hmmFolder
38
        paramType               = 'USER_D_A'; %DELTAS and ACCELERATIONS
39
        numCoeff                = 27; %9*3 THIS IS FOR PROBABILITY MODEL (not high spont+low spont which would be 18*3=54)
40
                
41
        HERestDataPath      = fullfile(pwd, 'def', 'HERest_digit');
42
        binPath             = fullfile(pwd, 'def', 'bin');
43
        configFile          = fullfile(pwd, 'def', 'config_STANDARD');
44
        trainWordListFile   = fullfile(pwd, 'def', 'Grammar_digit', 'words3');
45
        testWordListFile    = fullfile(pwd, 'def', 'Grammar_digit', 'wordsNoSevenZero');
46
        wordNetFile         = fullfile(pwd, 'def', 'Grammar_digit', 'wdnetNoSP.slf');
47
        dictFile            = fullfile(pwd, 'def', 'Grammar_digit', 'noSevenZeroDict');
48
    end
49
    
50
    %% **********************************************************
51
    % Dependent - never set by user. Only calculated when needed
52
    %************************************************************
53
    properties(Dependent = true)
54
        protoFile              % = fullfile(pwd, 'def', 'proto_RobANonly_9'); %probability only
55
    end
56
    
57
    %%  *********************************************************
58
    % methods        _   _               _
59
    %               | | | |             | |
60
    % _ __ ___   ___| |_| |__   ___   __| |___
61
    %| '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
62
    %| | | | | |  __/ |_| | | | (_) | (_| \__ \
63
    %|_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
64
    %************************************************************
65
    
66
    methods
67
        %% **********************************************************
68
        % Constructor
69
        %************************************************************
70
        function obj = cHMM(hmmFolder)
71
            if nargin > 0
72
                obj.hmmFolder = hmmFolder;
73
            end
74
        end % ------ OF CONSTRUCTOR
75
        
76
        %% **********************************************************
77
        % genProto - generate task specific prototype
78
        %************************************************************
79
        function genProto(obj)
80
            % models_1mixsil.exe - takes input (hmmdef) and copies it making a
81
            % basis of one, two three etc. etc.
82
            obj.models_1mixsilMat(fullfile(obj.hmmFolder,'hmm0','hmmdef'), fullfile(obj.hmmFolder,'hmm0','models'));            
83
        end % ------ OF GENPROTO
84
        
85
        %% **********************************************************
86
        % istrained
87
        %************************************************************
88
        function boolans = istrained(obj)
89
            boolans = numel(dir(fullfile(obj.hmmFolder,'hmm36','models')));
90
        end
91
        
92
        %% **********************************************************
93
        % Train
94
        %************************************************************
95
        function train(obj, trainFeatureFolder)
96
                       
97
            % Most of the following code block can be replaced by doing a
98
            % find and replace across the  code below. I didn't
99
            % want to mess with the working code too much, so I just
100
            % copied the object properties needed into the variable names
101
            % expected.
102
            
103
            ED_CMDFILE1 = fullfile(obj.HERestDataPath, 'sil1.hed');
104
            ED_CMDFILE2 = fullfile(obj.HERestDataPath, 'mix2_16.hed');
105
            ED_CMDFILE3 = fullfile(obj.HERestDataPath, 'mix3_16.hed');
106
            ED_CMDFILE4 = fullfile(obj.HERestDataPath, 'mix5_16.hed');
107
            ED_CMDFILE5 = fullfile(obj.HERestDataPath, 'mix7_16.hed');
108
            
109
            NUM_COEF        = obj.numCoeff;
110
            PAR_TYPE        = obj.paramType;
111
            LIST_FILE       = fullfile(obj.hmmFolder, 'tmp.list');
112
            
113
            word_list       = obj.trainWordListFile;%fullfile(obj.grammarPath, 'words');
114
            word_listSP     = word_list; % for use in hmm4 onwards - UGLY HACK NOW SP ABANDONED
115
            proto           = obj.protoFile;%Does not exist on disk just yet probably - see a few lines down
116
            config          = obj.configFile;
117
            train_list      = fullfile(trainFeatureFolder, 'list.scp');
118
            labels          = fullfile(trainFeatureFolder, 'labels.mlf');
119
            labelssp        = labels; % for use in hmm4 onwards - UGLY HACK NOW SP ABANDONED
120
            hmm_dir         = obj.hmmFolder;
121
            
122
            FEAT_ROOT       = trainFeatureFolder;
123
            
124
            % Now for the actual HMM training code
125
            mkdir(hmm_dir)
126
            for I = 0:36
127
                h = fullfile(hmm_dir,['hmm' num2str(I)]);
128
                mkdir(h);
129
            end
130
            obj.makeProtoHmm(proto, obj.paramType, obj.numCoeff, 18);
131
            
132
            fid = fopen(train_list,'r');
133
            disp(train_list)
134
            S = textscan(fid,'%s','Delimiter','\n');
135
            fclose(fid);
136
            
137
            fid = fopen(LIST_FILE,'w');
138
            
139
            for I = 1:size(S{1},1)
140
                str  = fullfile(FEAT_ROOT,S{1}{I});
141
                fprintf(fid,'%s\n',str);
142
            end;
143
            fclose(fid);
144
            
145
            % HCompV just gets the vfloor stuff out so we can begin approximating
146
            cmd = ['"HCompV" -T 2 -D -C "' config '" -o hmmdef -f 0.01 -m -S "' LIST_FILE '" -M "' hmm_dir filesep 'hmm0" "' proto '"'];
147
            system(cmd);                        
148
            
149
            %cmd = [BINDIR filesep 'macro' binExt ' ' num2str(NUM_COEF) ' ' PAR_TYPE ' ' '"' hmm_dir filesep 'hmm0' filesep 'vFloors' '" "' hmm_dir filesep 'hmm0' filesep 'macros' '"'];
150
            %system(cmd);            
151
            obj.macroMat(NUM_COEF,PAR_TYPE, fullfile(hmm_dir, 'hmm0', 'vFloors'), fullfile(hmm_dir, 'hmm0', 'macros'));
152
            
153
            %MAKE THE INITIAL MODEL PROTOTYPE
154
            genProto(obj);
155
                        
156
            disp('Seed HMM successfully Produced.....');
157
            
158
            %Training
159
            for I = 1:3
160
                disp(I)
161
                j = I-1;
162
                cmd = ['HERest -D -C ' config ' -I ' labels ' -t 250.0 150.0 1000.0 -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_list];
163
                %                 disp(cmd)
164
                system(cmd);
165
            end
166
            
167
            disp('3 iterations complete');
168
            
169
            rmdir ([hmm_dir filesep 'hmm4'],'s')
170
            copyfile ([hmm_dir filesep 'hmm3'], [hmm_dir filesep 'hmm4'])                                                
171
            
172
            % The following command takes state 3 from the silence model
173
            % and appends it to the end of the model as state 2 of the
174
            % short pause model.
175
            % Original:
176
            % cmd = [BINDIR filesep 'spmodel_gen' binExt ' ' hmm_dir filesep 'hmm3' filesep 'models ' hmm_dir filesep 'hmm4' filesep 'models'];
177
            % system(cmd);
178
            % New:
179
            obj.spmodel_genMat(fullfile(hmm_dir,'hmm3','models'), fullfile(hmm_dir,'hmm4','models'));                                     
180
            
181
            cmd = ['HHEd  -T 2 -H ' hmm_dir filesep 'hmm4' filesep 'macros -H ' hmm_dir filesep 'hmm4' filesep 'models -M ' hmm_dir filesep 'hmm5 ' ED_CMDFILE1 ' ' word_listSP ];
182
            system(cmd);
183
            disp ('SP model fixed')
184
            
185
            % after the spmodel_gen command - the word_list is changed to
186
            % word_listSP. The sp model is just ignored currently
187
            
188
            for I = 6:8
189
                disp(I)
190
                j = I-1;
191
                cmd = ['HERest -C ' config ' -I ' labelssp ' -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_listSP];
192
                system(cmd);
193
            end
194
            
195
            disp('6 iterations complete');
196
            
197
            cmd = ['HHEd  -T 2 -H ' hmm_dir filesep 'hmm8' filesep 'macros -H ' hmm_dir filesep 'hmm8' filesep 'models -M ' hmm_dir filesep 'hmm9 ' ED_CMDFILE2 ' ' word_listSP ];
198
            system(cmd);
199
            disp ('2 gaussians per mixture')
200
            
201
            for I = 10:12
202
                disp(I)
203
                j = I-1;
204
                cmd = ['HERest -C ' config ' -I ' labelssp ' -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_listSP];
205
                system(cmd);
206
            end
207
            
208
            disp ('9 iterations completed')
209
            
210
            cmd = ['HHEd  -T 2 -H ' hmm_dir filesep 'hmm12'  filesep 'macros -H ' hmm_dir filesep 'hmm12' filesep 'models -M ' hmm_dir filesep 'hmm13 ' ED_CMDFILE3 ' ' word_listSP ];
211
            system(cmd);
212
            disp ('3 gaussians per mixture')
213
            
214
            for I = 14:20
215
                disp(I)
216
                j = I-1;
217
                cmd = ['HERest -C ' config ' -I ' labelssp ' -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_listSP];
218
                system(cmd);
219
            end
220
            
221
            disp ('16 iterations completed')
222
            
223
            cmd = ['HHEd  -T 2 -H ' hmm_dir filesep 'hmm20'  filesep 'macros -H ' hmm_dir filesep 'hmm20' filesep 'models -M ' hmm_dir filesep 'hmm21 ' ED_CMDFILE4 ' ' word_listSP ];
224
            system(cmd);
225
            disp ('5 gaussians per mixture')
226
            
227
            for I = 22:28
228
                disp(I)
229
                j = I-1;
230
                cmd = ['HERest -C ' config ' -I ' labelssp ' -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_listSP];
231
                system(cmd);
232
            end
233
            
234
            disp ('23 iterations completed')
235
            
236
            cmd = ['HHEd  -T 2 -H ' hmm_dir filesep 'hmm28'  filesep 'macros -H ' hmm_dir filesep 'hmm28' filesep 'models -M ' hmm_dir filesep 'hmm29 ' ED_CMDFILE5 ' ' word_listSP ];
237
            system(cmd);
238
            disp ('7 gaussians per mixture')
239
            
240
            for I = 30:36
241
                disp(I)
242
                j = I-1;
243
                cmd = ['HERest -C ' config ' -I ' labelssp ' -S ' LIST_FILE  ' -H ' hmm_dir filesep 'hmm' num2str(j)  filesep 'macros -H ' hmm_dir filesep 'hmm' num2str(j) filesep 'models -M ' hmm_dir filesep 'hmm' num2str(I) ' ' word_listSP];
244
                system(cmd);
245
            end
246
            
247
            disp ('30 iterations completed')
248
            
249
        end % ------ OF TRAIN
250
        
251
        %% **********************************************************
252
        % Test
253
        %************************************************************
254
        function test(obj, testFeatureFolder)
255
            flags = '-p 0.0 -s 0.0';
256
            test_word_list = obj.testWordListFile;
257
            
258
            net = obj.wordNetFile;
259
            dict = obj.dictFile;
260
            
261
            LIST_FILE       = fullfile(testFeatureFolder, 'tmp.list');
262
            config          = obj.configFile;
263
            
264
            disp ('Now testing with 7 mixture HMMs')
265
            mod_file = fullfile(obj.hmmFolder, 'hmm36', 'models');
266
            mac_file = fullfile(obj.hmmFolder, 'hmm36', 'macros');
267
            
268
            
269
            RESULTS_DIR = testFeatureFolder;
270
            TEST_FEAT_ROOT  = testFeatureFolder;
271
            
272
            N1list =  fullfile(testFeatureFolder, 'list.scp');
273
            
274
            ftest = fopen(N1list,'r');
275
            S = textscan(ftest,'%s','Delimiter','\n');
276
            fclose(ftest);
277
            
278
            flist = fopen(LIST_FILE,'w');
279
            for I = 1:size(S{1},1)
280
                str  = fullfile(TEST_FEAT_ROOT,S{1}{I});
281
                fprintf(flist,'%s\n',str);
282
            end;
283
            fclose(flist);
284
            
285
            cmd = ['HVite -D -H ' mac_file ' -H ' mod_file ' -S ' LIST_FILE ' -C ' config ' -w ' net ' -l ''*'' -i ' RESULTS_DIR filesep 'result.mlf ' flags ' ' dict ' ' test_word_list];
286
            system(cmd);
287
        end % ------ OF TEST
288
        
289
        %% **********************************************************
290
        % Get methods determining feature vector related gubbins
291
        %************************************************************
292
        function value = get.protoFile(obj)
293
            value = fullfile(obj.hmmFolder, 'proto_AutoGen');
294
        end
295
        
296
    end % ------ OF METHODS
297
    
298
    %%  *********************************************************
299
    %      _        _   _                       _   _               _
300
    %     | |      | | (_)                     | | | |             | |
301
    %  ___| |_ __ _| |_ _  ___   _ __ ___   ___| |_| |__   ___   __| |___
302
    % / __| __/ _` | __| |/ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
303
    % \__ \ || (_| | |_| | (__  | | | | | |  __/ |_| | | | (_) | (_| \__ \
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff