rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: % This program is free software; you can redistribute it and/or modify rmeddis@38: % it under the terms of the GNU General Public License as published by rmeddis@38: % the Free Software Foundation; either version 2 of the License, or rmeddis@38: % (at your option) any later version. rmeddis@38: % rmeddis@38: % This program is distributed in the hope that it will be useful, rmeddis@38: % but WITHOUT ANY WARRANTY; without even the implied warranty of rmeddis@38: % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rmeddis@38: % GNU General Public License for more details. rmeddis@38: % rmeddis@38: % You can obtain a copy of the GNU General Public License from rmeddis@38: % http://www.gnu.org/copyleft/gpl.html or by writing to rmeddis@38: % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: rmeddis@38: classdef cHMM rmeddis@38: %HMMCLASS Handles all of the HTK related gubbins rmeddis@38: % Please see the documentation located in a separate file for further rmeddis@38: % information. rmeddis@38: rmeddis@38: %% ********************************************************* rmeddis@38: % properties _ _ rmeddis@38: % | | (_) rmeddis@38: % _ __ _ __ ___ _ __ ___ _ __| |_ _ ___ ___ rmeddis@38: % | '_ \| '__/ _ \| '_ \ / _ \ '__| __| |/ _ \/ __| rmeddis@38: % | |_) | | | (_) | |_) | __/ | | |_| | __/\__ \ rmeddis@38: % | .__/|_| \___/| .__/ \___|_| \__|_|\___||___/ rmeddis@38: % | | | | rmeddis@38: % |_| |_| rmeddis@38: %************************************************************ rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % Public properties - can be set by user rmeddis@38: %************************************************************ rmeddis@38: properties(Access = public) rmeddis@38: hmmFolder rmeddis@38: paramType = 'USER_D_A'; %DELTAS and ACCELERATIONS rmeddis@38: numCoeff = 27; %9*3 THIS IS FOR PROBABILITY MODEL (not high spont+low spont which would be 18*3=54) rmeddis@38: rmeddis@38: HERestDataPath = fullfile(pwd, 'def', 'HERest_digit'); rmeddis@38: binPath = fullfile(pwd, 'def', 'bin'); rmeddis@38: configFile = fullfile(pwd, 'def', 'config_STANDARD'); rmeddis@38: trainWordListFile = fullfile(pwd, 'def', 'Grammar_digit', 'words3'); rmeddis@38: testWordListFile = fullfile(pwd, 'def', 'Grammar_digit', 'wordsNoSevenZero'); rmeddis@38: wordNetFile = fullfile(pwd, 'def', 'Grammar_digit', 'wdnetNoSP.slf'); rmeddis@38: dictFile = fullfile(pwd, 'def', 'Grammar_digit', 'noSevenZeroDict'); rmeddis@38: end rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % Dependent - never set by user. Only calculated when needed rmeddis@38: %************************************************************ rmeddis@38: properties(Dependent = true) rmeddis@38: protoFile % = fullfile(pwd, 'def', 'proto_RobANonly_9'); %probability only rmeddis@38: end rmeddis@38: rmeddis@38: %% ********************************************************* rmeddis@38: % methods _ _ _ rmeddis@38: % | | | | | | rmeddis@38: % _ __ ___ ___| |_| |__ ___ __| |___ rmeddis@38: %| '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __| rmeddis@38: %| | | | | | __/ |_| | | | (_) | (_| \__ \ rmeddis@38: %|_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/ rmeddis@38: %************************************************************ rmeddis@38: rmeddis@38: methods rmeddis@38: %% ********************************************************** rmeddis@38: % Constructor rmeddis@38: %************************************************************ rmeddis@38: function obj = cHMM(hmmFolder) rmeddis@38: if nargin > 0 rmeddis@38: obj.hmmFolder = hmmFolder; rmeddis@38: end rmeddis@38: end % ------ OF CONSTRUCTOR rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % genProto - generate task specific prototype rmeddis@38: %************************************************************ rmeddis@38: function genProto(obj) rmeddis@38: % models_1mixsil.exe - takes input (hmmdef) and copies it making a rmeddis@38: % basis of one, two three etc. etc. rmeddis@38: obj.models_1mixsilMat(fullfile(obj.hmmFolder,'hmm0','hmmdef'), fullfile(obj.hmmFolder,'hmm0','models')); rmeddis@38: end % ------ OF GENPROTO rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % istrained rmeddis@38: %************************************************************ rmeddis@38: function boolans = istrained(obj) rmeddis@38: boolans = numel(dir(fullfile(obj.hmmFolder,'hmm36','models'))); rmeddis@38: end rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % Train rmeddis@38: %************************************************************ rmeddis@38: function train(obj, trainFeatureFolder) rmeddis@38: rmeddis@38: % Most of the following code block can be replaced by doing a rmeddis@38: % find and replace across the code below. I didn't rmeddis@38: % want to mess with the working code too much, so I just rmeddis@38: % copied the object properties needed into the variable names rmeddis@38: % expected. rmeddis@38: rmeddis@38: ED_CMDFILE1 = fullfile(obj.HERestDataPath, 'sil1.hed'); rmeddis@38: ED_CMDFILE2 = fullfile(obj.HERestDataPath, 'mix2_16.hed'); rmeddis@38: ED_CMDFILE3 = fullfile(obj.HERestDataPath, 'mix3_16.hed'); rmeddis@38: ED_CMDFILE4 = fullfile(obj.HERestDataPath, 'mix5_16.hed'); rmeddis@38: ED_CMDFILE5 = fullfile(obj.HERestDataPath, 'mix7_16.hed'); rmeddis@38: rmeddis@38: NUM_COEF = obj.numCoeff; rmeddis@38: PAR_TYPE = obj.paramType; rmeddis@38: LIST_FILE = fullfile(obj.hmmFolder, 'tmp.list'); rmeddis@38: rmeddis@38: word_list = obj.trainWordListFile;%fullfile(obj.grammarPath, 'words'); rmeddis@38: word_listSP = word_list; % for use in hmm4 onwards - UGLY HACK NOW SP ABANDONED rmeddis@38: proto = obj.protoFile;%Does not exist on disk just yet probably - see a few lines down rmeddis@38: config = obj.configFile; rmeddis@38: train_list = fullfile(trainFeatureFolder, 'list.scp'); rmeddis@38: labels = fullfile(trainFeatureFolder, 'labels.mlf'); rmeddis@38: labelssp = labels; % for use in hmm4 onwards - UGLY HACK NOW SP ABANDONED rmeddis@38: hmm_dir = obj.hmmFolder; rmeddis@38: rmeddis@38: FEAT_ROOT = trainFeatureFolder; rmeddis@38: rmeddis@38: % Now for the actual HMM training code rmeddis@38: mkdir(hmm_dir) rmeddis@38: for I = 0:36 rmeddis@38: h = fullfile(hmm_dir,['hmm' num2str(I)]); rmeddis@38: mkdir(h); rmeddis@38: end rmeddis@38: obj.makeProtoHmm(proto, obj.paramType, obj.numCoeff, 18); rmeddis@38: rmeddis@38: fid = fopen(train_list,'r'); rmeddis@38: disp(train_list) rmeddis@38: S = textscan(fid,'%s','Delimiter','\n'); rmeddis@38: fclose(fid); rmeddis@38: rmeddis@38: fid = fopen(LIST_FILE,'w'); rmeddis@38: rmeddis@38: for I = 1:size(S{1},1) rmeddis@38: str = fullfile(FEAT_ROOT,S{1}{I}); rmeddis@38: fprintf(fid,'%s\n',str); rmeddis@38: end; rmeddis@38: fclose(fid); rmeddis@38: rmeddis@38: % HCompV just gets the vfloor stuff out so we can begin approximating rmeddis@38: cmd = ['"HCompV" -T 2 -D -C "' config '" -o hmmdef -f 0.01 -m -S "' LIST_FILE '" -M "' hmm_dir filesep 'hmm0" "' proto '"']; rmeddis@38: system(cmd); rmeddis@38: rmeddis@38: %cmd = [BINDIR filesep 'macro' binExt ' ' num2str(NUM_COEF) ' ' PAR_TYPE ' ' '"' hmm_dir filesep 'hmm0' filesep 'vFloors' '" "' hmm_dir filesep 'hmm0' filesep 'macros' '"']; rmeddis@38: %system(cmd); rmeddis@38: obj.macroMat(NUM_COEF,PAR_TYPE, fullfile(hmm_dir, 'hmm0', 'vFloors'), fullfile(hmm_dir, 'hmm0', 'macros')); rmeddis@38: rmeddis@38: %MAKE THE INITIAL MODEL PROTOTYPE rmeddis@38: genProto(obj); rmeddis@38: rmeddis@38: disp('Seed HMM successfully Produced.....'); rmeddis@38: rmeddis@38: %Training rmeddis@38: for I = 1:3 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: % disp(cmd) rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp('3 iterations complete'); rmeddis@38: rmeddis@38: rmdir ([hmm_dir filesep 'hmm4'],'s') rmeddis@38: copyfile ([hmm_dir filesep 'hmm3'], [hmm_dir filesep 'hmm4']) rmeddis@38: rmeddis@38: % The following command takes state 3 from the silence model rmeddis@38: % and appends it to the end of the model as state 2 of the rmeddis@38: % short pause model. rmeddis@38: % Original: rmeddis@38: % cmd = [BINDIR filesep 'spmodel_gen' binExt ' ' hmm_dir filesep 'hmm3' filesep 'models ' hmm_dir filesep 'hmm4' filesep 'models']; rmeddis@38: % system(cmd); rmeddis@38: % New: rmeddis@38: obj.spmodel_genMat(fullfile(hmm_dir,'hmm3','models'), fullfile(hmm_dir,'hmm4','models')); rmeddis@38: rmeddis@38: 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 ]; rmeddis@38: system(cmd); rmeddis@38: disp ('SP model fixed') rmeddis@38: rmeddis@38: % after the spmodel_gen command - the word_list is changed to rmeddis@38: % word_listSP. The sp model is just ignored currently rmeddis@38: rmeddis@38: for I = 6:8 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp('6 iterations complete'); rmeddis@38: rmeddis@38: 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 ]; rmeddis@38: system(cmd); rmeddis@38: disp ('2 gaussians per mixture') rmeddis@38: rmeddis@38: for I = 10:12 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp ('9 iterations completed') rmeddis@38: rmeddis@38: 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 ]; rmeddis@38: system(cmd); rmeddis@38: disp ('3 gaussians per mixture') rmeddis@38: rmeddis@38: for I = 14:20 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp ('16 iterations completed') rmeddis@38: rmeddis@38: 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 ]; rmeddis@38: system(cmd); rmeddis@38: disp ('5 gaussians per mixture') rmeddis@38: rmeddis@38: for I = 22:28 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp ('23 iterations completed') rmeddis@38: rmeddis@38: 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 ]; rmeddis@38: system(cmd); rmeddis@38: disp ('7 gaussians per mixture') rmeddis@38: rmeddis@38: for I = 30:36 rmeddis@38: disp(I) rmeddis@38: j = I-1; rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end rmeddis@38: rmeddis@38: disp ('30 iterations completed') rmeddis@38: rmeddis@38: end % ------ OF TRAIN rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % Test rmeddis@38: %************************************************************ rmeddis@38: function test(obj, testFeatureFolder) rmeddis@38: flags = '-p 0.0 -s 0.0'; rmeddis@38: test_word_list = obj.testWordListFile; rmeddis@38: rmeddis@38: net = obj.wordNetFile; rmeddis@38: dict = obj.dictFile; rmeddis@38: rmeddis@38: LIST_FILE = fullfile(testFeatureFolder, 'tmp.list'); rmeddis@38: config = obj.configFile; rmeddis@38: rmeddis@38: disp ('Now testing with 7 mixture HMMs') rmeddis@38: mod_file = fullfile(obj.hmmFolder, 'hmm36', 'models'); rmeddis@38: mac_file = fullfile(obj.hmmFolder, 'hmm36', 'macros'); rmeddis@38: rmeddis@38: rmeddis@38: RESULTS_DIR = testFeatureFolder; rmeddis@38: TEST_FEAT_ROOT = testFeatureFolder; rmeddis@38: rmeddis@38: N1list = fullfile(testFeatureFolder, 'list.scp'); rmeddis@38: rmeddis@38: ftest = fopen(N1list,'r'); rmeddis@38: S = textscan(ftest,'%s','Delimiter','\n'); rmeddis@38: fclose(ftest); rmeddis@38: rmeddis@38: flist = fopen(LIST_FILE,'w'); rmeddis@38: for I = 1:size(S{1},1) rmeddis@38: str = fullfile(TEST_FEAT_ROOT,S{1}{I}); rmeddis@38: fprintf(flist,'%s\n',str); rmeddis@38: end; rmeddis@38: fclose(flist); rmeddis@38: rmeddis@38: 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]; rmeddis@38: system(cmd); rmeddis@38: end % ------ OF TEST rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % Get methods determining feature vector related gubbins rmeddis@38: %************************************************************ rmeddis@38: function value = get.protoFile(obj) rmeddis@38: value = fullfile(obj.hmmFolder, 'proto_AutoGen'); rmeddis@38: end rmeddis@38: rmeddis@38: end % ------ OF METHODS rmeddis@38: rmeddis@38: %% ********************************************************* rmeddis@38: % _ _ _ _ _ _ rmeddis@38: % | | | | (_) | | | | | | rmeddis@38: % ___| |_ __ _| |_ _ ___ _ __ ___ ___| |_| |__ ___ __| |___ rmeddis@38: % / __| __/ _` | __| |/ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __| rmeddis@38: % \__ \ || (_| | |_| | (__ | | | | | | __/ |_| | | | (_) | (_| \__ \ rmeddis@38: % |___/\__\__,_|\__|_|\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/ rmeddis@38: %************************************************************ rmeddis@38: rmeddis@38: methods(Static) rmeddis@38: %% ********************************************************** rmeddis@38: % macroMat (matlab port of macro C code) rmeddis@38: % ported by NC - Nov 2011 rmeddis@38: %************************************************************ rmeddis@38: function macroMat(VECSIZE, PARAMETER_TYPE, infile, outfile) rmeddis@38: % This function takes the vFloors file that is created after rmeddis@38: % invoking HCompV and generates a Macro file required for further rmeddis@38: % HMM training rmeddis@38: rmeddis@38: ofp = fopen(outfile,'w'); rmeddis@38: rmeddis@38: fprintf(ofp, '~o\n 1 %d\n', VECSIZE); rmeddis@38: fprintf(ofp, ' %d\n', VECSIZE); rmeddis@38: fprintf(ofp, '\n<%s>\n', PARAMETER_TYPE); rmeddis@38: rmeddis@38: fp = fopen(infile); rmeddis@38: tline = fgets(fp); rmeddis@38: while ischar(tline) rmeddis@38: fprintf(ofp,tline); rmeddis@38: tline = fgets(fp); rmeddis@38: end rmeddis@38: fclose(fp); rmeddis@38: fclose(ofp); rmeddis@38: end %---- of MACROMAT rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % spmodel_genMat (matlab port of spmodel_gen C code) rmeddis@38: % ported by NC - Nov 2011 rmeddis@38: %************************************************************ rmeddis@38: function spmodel_genMat(infile, outfile) rmeddis@38: % This function copies the middle state (3) from the silence model rmeddis@38: % and makes a sp model out of it by copying it to state 2 of the sp model. rmeddis@38: rmeddis@38: % From: http://www.voxforge.org/home/dev/acousticmodels/linux/create/htkjulius/tutorial/monophones/step-7 rmeddis@38: % In the last step you created HMM models that did not include an "sp" rmeddis@38: % (short pause) silence model - which refers to the types of short pauses rmeddis@38: % that occur between words in normal speech. However, you did create a rmeddis@38: % "sil" silence model - sil silence models are typically of longer rmeddis@38: % duration, and refer to the pauses occur at the end of a sentence. rmeddis@38: % rmeddis@38: % The HTK book says that the sp model needs to have its "emitting state rmeddis@38: % tied to the centre state of the silence model". What this means is that rmeddis@38: % you need to create a new sp model in your hmmdefs, that it will use the rmeddis@38: % centre state of sil, and then they both need to be 'tied' together. For rmeddis@38: % a bit of background on HMMs and states, see this example. rmeddis@38: % rmeddis@38: % This can be done by copying the centre state from the sil model in your rmeddis@38: % hmmdefs file and adding it to the sp model, and then running a special rmeddis@38: % tool called HHED to 'tie' the sp model to the sil model so that they rmeddis@38: % share the same centre state. The HTK book provides some background on rmeddis@38: % what this means, but you need an understanding of the basics of Hidden rmeddis@38: % Markov Modelling before tackling the HTK Book explanations rmeddis@38: rmeddis@38: ofp = fopen(outfile,'a+'); % we append this time rmeddis@38: rmeddis@38: fprintf(ofp,'~h "sp"\n'); rmeddis@38: fprintf(ofp,'\n 3\n 2\n'); rmeddis@38: rmeddis@38: %-- This block gets the hmmdef file to the MODEL rmeddis@38: lNow = []; rmeddis@38: fp = fopen(infile); rmeddis@38: while ~(strcmpi(lNow, '~h "sil"')) rmeddis@38: lNow = fgetl(fp); rmeddis@38: end rmeddis@38: %------------------------------ rmeddis@38: rmeddis@38: %-- This block gets the hmmdef file to the STATE rmeddis@38: lNow = []; rmeddis@38: fp = fopen(infile); rmeddis@38: while ~(strcmpi(lNow, [' ' num2str(3)])) rmeddis@38: lNow = fgetl(fp); rmeddis@38: end rmeddis@38: %------------------------------ rmeddis@38: rmeddis@38: %%% This block puts a copy of the hmmdef file in from the rmeddis@38: %%% correct line as found above rmeddis@38: tline = fgetl(fp); rmeddis@38: while ~(strcmpi(tline, [' ' num2str(4)])) rmeddis@38: fprintf(ofp,'%s\n', tline); rmeddis@38: tline = fgetl(fp); rmeddis@38: end rmeddis@38: fclose(fp); rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: rmeddis@38: fprintf(ofp,' 3\n0.000000e+00 1.000000e+00 0.000000e+00\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 5.000000e-01 5.000000e-01\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 0.000000e+00 0.000000e+00\n\n'); rmeddis@38: rmeddis@38: fclose(ofp); rmeddis@38: end %---- of spmodel_genMat rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % models_1mixsilMat (matlab port of models_1mixsil C code) rmeddis@38: % ported by NC - Nov 2011 rmeddis@38: %************************************************************ rmeddis@38: function models_1mixsilMat(infile, outfile) rmeddis@38: % This function takes the hmmdef file and rmeddis@38: % generates a HMM Model file rmeddis@38: rmeddis@38: ofp = fopen(outfile,'w'); rmeddis@38: for ii = 1:11 rmeddis@38: rmeddis@38: %%% This block gets the hmmdef file to the correct line rmeddis@38: lNow = []; rmeddis@38: fp = fopen(infile); rmeddis@38: while ~(strcmpi(lNow, '~h "hmmdef"')) rmeddis@38: lNow = fgetl(fp); rmeddis@38: end rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: rmeddis@38: %%% This block puts a numbered header rmeddis@38: if ii==1; fprintf(ofp,'~h "one"\n'); end rmeddis@38: if ii==2; fprintf(ofp,'~h "two"\n'); end rmeddis@38: if ii==3; fprintf(ofp,'~h "three"\n'); end rmeddis@38: if ii==4; fprintf(ofp,'~h "four"\n'); end rmeddis@38: if ii==5; fprintf(ofp,'~h "five"\n'); end rmeddis@38: if ii==6; fprintf(ofp,'~h "six"\n'); end rmeddis@38: if ii==7; fprintf(ofp,'~h "seven"\n'); end rmeddis@38: if ii==8; fprintf(ofp,'~h "eight"\n'); end rmeddis@38: if ii==9; fprintf(ofp,'~h "nine"\n'); end rmeddis@38: if ii==10; fprintf(ofp,'~h "oh"\n'); end rmeddis@38: if ii==11; fprintf(ofp,'~h "zero"\n'); end rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: rmeddis@38: %%% This block puts a copy of the hmmdef file in from the rmeddis@38: %%% correct line as found above rmeddis@38: tline = fgets(fp); rmeddis@38: while ischar(tline) rmeddis@38: fprintf(ofp,tline); rmeddis@38: tline = fgets(fp); rmeddis@38: end rmeddis@38: fclose(fp); %close it as we reached EOF rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: end rmeddis@38: rmeddis@38: %%% THIS IS THE SILENCE MODEL @ THE END rmeddis@38: fprintf(ofp,'~h "sil"\n'); rmeddis@38: fprintf(ofp,'\n 5\n'); rmeddis@38: for kk = 2:4 rmeddis@38: fprintf(ofp,' %d\n 1\n', kk); rmeddis@38: %-- This block gets the hmmdef file to the correct line rmeddis@38: lNow = []; rmeddis@38: fp = fopen(infile); rmeddis@38: while ~(strcmpi(lNow, [' ' num2str(kk)])) rmeddis@38: lNow = fgetl(fp); rmeddis@38: end rmeddis@38: %------------------------------ rmeddis@38: rmeddis@38: %%% This block puts a copy of the hmmdef file in from the rmeddis@38: %%% correct line as found above rmeddis@38: tline = fgetl(fp); rmeddis@38: while ~(strcmpi(tline, [' ' num2str(kk+1)])) rmeddis@38: fprintf(ofp,'%s\n', tline); rmeddis@38: tline = fgetl(fp); rmeddis@38: end rmeddis@38: fclose(fp); rmeddis@38: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rmeddis@38: end rmeddis@38: rmeddis@38: fprintf(ofp,' 5\n0.000000e+00 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00 0.000000e+00\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 0.000000e+00 6.000000e-01 4.000000e-01 0.000000e+00\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 0.000000e+00 0.000000e+00 7.000000e-01 3.000000e-01\n'); rmeddis@38: fprintf(ofp,'0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00\n\n'); rmeddis@38: rmeddis@38: fclose(ofp); rmeddis@38: end %---- of models_1mixsilMat rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % makeProtoHmm (Make a prototype HMM) rmeddis@38: %************************************************************ rmeddis@38: function makeProtoHmm(filename,featureType,numFeatures,numStates) rmeddis@38: % filename is obvious rmeddis@38: % featureType is usually USER_D_A rmeddis@38: % numFeatures is number of features (including differences if used) rmeddis@38: % numStates is usually 18 rmeddis@38: rmeddis@38: ofp = fopen(filename,'w'); rmeddis@38: rmeddis@38: fprintf(ofp,'\n'); rmeddis@38: fprintf(ofp,' %d %d <%s> \n',numStates,numFeatures,featureType'); rmeddis@38: fprintf(ofp,' 1 %d\n',numFeatures); rmeddis@38: for state=2:numStates-1, rmeddis@38: fprintf(ofp,' %d 1\n',state); rmeddis@38: fprintf(ofp,' 1\n'); rmeddis@38: fprintf(ofp,' 1 1.0\n'); rmeddis@38: fprintf(ofp,' %d\n',numFeatures); rmeddis@38: fprintf(ofp,' '); rmeddis@38: fprintf(ofp,'%1.1f ',zeros(1,numFeatures)); rmeddis@38: fprintf(ofp,'\n'); rmeddis@38: fprintf(ofp,' %d\n',numFeatures); rmeddis@38: fprintf(ofp,' '); rmeddis@38: fprintf(ofp,'%1.1f ',ones(1,numFeatures)); rmeddis@38: fprintf(ofp,'\n'); rmeddis@38: end rmeddis@38: fprintf(ofp,' %d\n',numStates); rmeddis@38: transp = zeros(numFeatures); rmeddis@38: transp(1,2)=1; rmeddis@38: for state=2:numStates-2, rmeddis@38: transp(state,state)=0.6; rmeddis@38: transp(state,state+1)=0.4; rmeddis@38: end rmeddis@38: transp(numStates-1,numStates-1)=0.9; rmeddis@38: transp(numStates-1,numStates)=0.1; rmeddis@38: for state=1:numStates, rmeddis@38: fprintf(ofp,'%1.3e ',transp(state,1:numStates)); rmeddis@38: fprintf(ofp,'\n'); rmeddis@38: end rmeddis@38: fprintf(ofp,'\n'); rmeddis@38: fclose(ofp); rmeddis@38: end %---- of MAKEPROTOHMM rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % createMLF - master label file - belongs with hmm class rmeddis@38: %************************************************************ rmeddis@38: function createMLF(mapFileFolder) rmeddis@38: mlfFileName = 'labels'; rmeddis@38: d = dir(fullfile(mapFileFolder, '*.map')); rmeddis@38: fid = fopen([fullfile(mapFileFolder,mlfFileName) '.mlf'],'w'); rmeddis@38: fprintf(fid,'#!MLF!#\n'); rmeddis@38: rmeddis@38: for I = 1:size(d,1) rmeddis@38: fprintf(fid,['"*/' d(I).name(1:end-3) 'lab"\n']); rmeddis@38: fprintf(fid,'sil\n'); rmeddis@38: labels = d(I).name(5:end-5); rmeddis@38: for J = 1:length(labels); rmeddis@38: switch labels(J) rmeddis@38: case 'O' rmeddis@38: S = 'oh'; rmeddis@38: case '1' rmeddis@38: S = 'one'; rmeddis@38: case '2' rmeddis@38: S = 'two'; rmeddis@38: case '3' rmeddis@38: S = 'three'; rmeddis@38: case '4' rmeddis@38: S = 'four'; rmeddis@38: case '5' rmeddis@38: S = 'five'; rmeddis@38: case '6' rmeddis@38: S = 'six'; rmeddis@38: case '7' rmeddis@38: S = 'seven'; rmeddis@38: case '8' rmeddis@38: S = 'eight'; rmeddis@38: case '9' rmeddis@38: S = 'nine'; rmeddis@38: case 'Z' rmeddis@38: S = 'zero'; rmeddis@38: end rmeddis@38: fprintf(fid,S); rmeddis@38: fprintf(fid,'\n'); rmeddis@38: end; rmeddis@38: fprintf(fid,'sil\n.\n'); rmeddis@38: end; rmeddis@38: fclose(fid); rmeddis@38: end % ------ OF CREATEMLF rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % createSCP - Just a file list rmeddis@38: %************************************************************ rmeddis@38: function createSCP(mapFileFolder) rmeddis@38: scpFileName = 'list'; rmeddis@38: d = dir(fullfile(mapFileFolder, '*.map')); rmeddis@38: fid = fopen([fullfile(mapFileFolder,scpFileName) '.scp'],'w'); rmeddis@38: rmeddis@38: for I = 1:size(d,1) rmeddis@38: fprintf(fid,[d(I).name(1:end-3) 'map\n']); rmeddis@38: end; rmeddis@38: rmeddis@38: fclose(fid); rmeddis@38: end% ------ OF createSCP rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % score - Simple non-dynamic scoring rmeddis@38: %************************************************************ rmeddis@38: function score(testMLFpath) rmeddis@38: % First get the test result files and store the file locations rmeddis@38: testIdx = 1; rmeddis@38: temp = dir(testMLFpath); rmeddis@38: for nn = 1:numel(temp) rmeddis@38: if length(temp(nn).name) > 3 rmeddis@38: if strcmp(temp(nn).name(end-3:end), '.mlf') rmeddis@38: testMLFfiles{testIdx} = temp(nn).name; rmeddis@38: testIdx = testIdx+1; rmeddis@38: end rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@38: for fileIdx = 1:numel(testMLFfiles) rmeddis@38: % Extract file name and regonised words as strings -> store in recResults. rmeddis@38: % This code block is Matt Robertson's rmeddis@38: fmlf = fopen(fullfile(testMLFpath , testMLFfiles{fileIdx}),'r'); rmeddis@38: rmeddis@38: MLF = textscan(fmlf,'%s','delimiter','\n'); rmeddis@38: replaceDownPattern = '[0-9\-\.\s]'; rmeddis@38: rmeddis@38: for I = 1:size(MLF{1},1); rmeddis@38: if strfind(MLF{1}{I},'.rec') >0 rmeddis@38: M{I} = MLF{1}{I}; rmeddis@38: else rmeddis@38: if strfind(MLF{1}{I},'MLF') >0; rmeddis@38: M{I} = MLF{1}{I}; rmeddis@38: else rmeddis@38: M{I} = regexprep(MLF{1}{I},replaceDownPattern,''); rmeddis@38: end rmeddis@38: end; rmeddis@38: end; rmeddis@38: rmeddis@38: fclose(fmlf); rmeddis@38: rmeddis@38: A = 1; rmeddis@38: for I = 1:size(M,2) rmeddis@38: if not(strcmpi(M{I},'sp')) && not(strcmpi(M{I},'sil')) && not(strcmpi(M{I},'')); rmeddis@38: M2{A} = M{I}; rmeddis@38: A = A + 1; rmeddis@38: end; rmeddis@38: end; rmeddis@38: rmeddis@38: recResults = []; rmeddis@38: X=0; rmeddis@38: for I = 1:length(M2) rmeddis@38: if strfind(M2{I},'MLF') rmeddis@38: else rmeddis@38: if strfind(M2{I},'.rec') rmeddis@38: X = X+1; rmeddis@38: rmeddis@38: % found FileName rmeddis@38: recResults(X).fileName = M2{I}; rmeddis@38: recResults(X).utterance = {}; rmeddis@38: else rmeddis@38: recResults(X).utterance = [recResults(X).utterance M2{I}]; rmeddis@38: end; rmeddis@38: end; rmeddis@38: end; rmeddis@38: rmeddis@38: % Make separate 2D arrays of input and output digits rmeddis@38: inputDigits = zeros(numel(recResults),3); rmeddis@38: outputDigits = zeros(numel(recResults),3); rmeddis@38: for nn = 1:numel(recResults) rmeddis@38: ipStr = recResults(nn).fileName(end-8:end-6); rmeddis@38: rmeddis@38: for kk = 1:3 rmeddis@38: inputDigits(nn,kk) = cHMM.htk_str2num(ipStr(kk)); %see local function @ bottom of script rmeddis@38: opStr = recResults(nn).utterance(kk); rmeddis@38: outputDigits(nn,kk) = cHMM.htk_str2num(opStr{:}); %bit of a hack to do cell2str as it were rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@38: % Now do the scoring (simple whan data in the right format) rmeddis@38: % :D rmeddis@38: scoreArray = (inputDigits == outputDigits); rmeddis@38: pcSent(fileIdx) = 100*sum(all(scoreArray,2)) / numel(recResults); rmeddis@38: pcWord(fileIdx) = 100*sum(scoreArray(:)) / numel(scoreArray); rmeddis@38: end rmeddis@38: rmeddis@38: %will output table to console if used on *nix rmeddis@38: xlsdataFull = [{'-- File Name --', '%Sent', '%Word'}; testMLFfiles' num2cell(pcSent') num2cell(pcWord')]; rmeddis@38: disp(xlsdataFull) rmeddis@38: fid = fopen(fullfile(testMLFpath,['score__' num2str(pcWord(1), '%0.1f') '__.txt']),'w'); rmeddis@38: fclose(fid); rmeddis@38: end% ------ OF SCORE rmeddis@38: rmeddis@38: %% ********************************************************** rmeddis@38: % scoreWhole folder - make my life easier @ command line rmeddis@38: %************************************************************ rmeddis@38: function scoreWholeFolder(folderToScore, searchString) rmeddis@38: if nargin < 2 rmeddis@38: searchString = '*featR*'; rmeddis@38: end rmeddis@38: dirInfo = dir(fullfile(folderToScore, searchString)); rmeddis@38: numFolders = numel(dirInfo); rmeddis@38: for nn = 1:numFolders; rmeddis@38: currentScoring = fullfile(folderToScore, dirInfo(nn).name); rmeddis@38: disp(''); rmeddis@38: disp(currentScoring); rmeddis@38: cHMM.score(currentScoring); rmeddis@38: end rmeddis@38: end rmeddis@38: rmeddis@38: %************************************************************************** rmeddis@38: % htk_str2num - Convert strings to integers rmeddis@38: %************************************************************************** rmeddis@38: function opNum = htk_str2num(ipString) rmeddis@38: switch ipString rmeddis@38: case {'oh' , 'O'} rmeddis@38: opNum = 0; rmeddis@38: case {'one' , '1'} rmeddis@38: opNum = 1; rmeddis@38: case {'two' , '2'} rmeddis@38: opNum = 2; rmeddis@38: case {'three' , '3'} rmeddis@38: opNum = 3; rmeddis@38: case {'four' , '4'} rmeddis@38: opNum = 4; rmeddis@38: case {'five' , '5'} rmeddis@38: opNum = 5; rmeddis@38: case {'six' , '6'} rmeddis@38: opNum = 6; rmeddis@38: case {'eight' , '8'} rmeddis@38: opNum = 8; rmeddis@38: case {'nine' , '9'} rmeddis@38: opNum = 9; rmeddis@38: otherwise rmeddis@38: assert(0) % throw error rmeddis@38: end rmeddis@38: end % ------ OF htk_str2num rmeddis@38: rmeddis@38: end % ------ OF STATIC METHODS rmeddis@38: rmeddis@38: end % ------ OF CLASS