/*************************************************************************** * This file is part of the 'Shout LVCS Recognition toolkit'. * *************************************************************************** * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 by Marijn Huijbregts * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "standard.h" #include "lexicaltree.h" #include "phonemodel.h" #include "articulatorystream.h" int deltas[37][40]; double scores[37][40]; double weights[37][40]; #include "shout-misc.h" using namespace WriteFileLittleBigEndian; ///////////////////////////////////////////////////////////////////////////////////////////////////// /// \todo Docs ///////////////////////////////////////////////////////////////////////////////////////////////////// ArticulatoryStream::ArticulatoryStream(char *fileName) { assert(fileName != NULL); FILE *modelFile = fopen(fileName,"rb"); if(modelFile == NULL) { USER_ERROR("Could not open the articulatory-AM file"); } int numberOfClusters; freadEndianSafe(&vectorSize,1,sizeof(vectorSize),modelFile); freadEndianSafe(&numberOfModels,1,sizeof(numberOfModels),modelFile); if((numberOfModels / 2)*2 != numberOfModels) { USER_ERROR("The articulatory-AM is invalid!"); } numberOfModels /= 2; freadEndianSafe(&numberOfClusters,1,sizeof(numberOfClusters),modelFile); assert(numberOfClusters = 1); if(numberOfModels <= 0 || numberOfClusters <= 0) { USER_ERROR("This articulatory-AM file does not contain any acoustic models!"); } else { modelsYes = new PhoneModel*[numberOfModels]; modelsNo = new PhoneModel*[numberOfModels]; for(int i=0;igetLogPDFProbability(0,v)); probsNo[i] = (modelsNo[i]->getLogPDFProbability(0,v)); #ifdef TEST_ARTICULATORY testRT[i] += (probsYes[i]); testRF[i] += (probsNo[i]); #endif } for(int i=0;inBest = NULL; wlrStart->lattice = NULL; wlrStart->isSil = 1; wlrStart->previous = NULL; wlrStart->adminNext = NULL; wlrStart->timeStamp = -1; wlrStart->COMBlikelihood = 0.0; wlrStart->LMlikelihood = 0.0; wlrStart->usedAt = 0; wlrStart->phoneAlignment = NULL; } void ArticulatoryStream::testStream(int phoneID, int firstFrame, int lastFrame, DecoderSettings *settings, int contextKey) { for(int a=1;aphonePath = new PLRType; (*classifier[a].inputToken)->phonePath->phoneID = -1; (*classifier[a].inputToken)->phonePath->timeStamp = firstFrame; (*classifier[a].inputToken)->phonePath->likelihood = 0.0; (*classifier[a].inputToken)->phonePath->stateOffset[0] = 0; (*classifier[a].inputToken)->phonePath->stateOffset[1] = 0; (*classifier[a].inputToken)->phonePath->previous = NULL; (*classifier[a].inputToken)->path = wlrStart; (*classifier[a].inputToken)->lmLookAhead = NULL; (*classifier[a].inputToken)->lookAheadV = 0.0; (*classifier[a].inputToken)->likelihood = 0.0; (*classifier[a].inputToken)->next = NULL; } for(int i=0;igetVector(i); processVector(v); for(int a=1;aprocessVector(contextKey,v,i,-1,classifier[a].tokenSeq,classifier[a].tokenSeqLength, (*classifier[a].inputToken),settings); *classifier[a].inputToken = NULL; TokenType *resToken = NULL; phoneModels[classifier[a].modelID]->getOutput(contextKey, classifier[a].tokenSeq, classifier[a].tokenSeqLength, &resToken, settings); if(resToken != NULL) { scores[numberOfModels][a] = resToken->likelihood; } PhoneModel::initialiseToken(&resToken); } } scores[numberOfModels][0] = -9.0e300; for(int i=0;i testRF[i]) { testRulesTT[i][phoneID]++; } else { testRulesFT[i][phoneID]++; } } else { if(testRT[i] <= testRF[i]) { testRulesTF[i][phoneID]++; } else { testRulesFF[i][phoneID]++; } } } double winnerScore = testYes[0]; int winner = 0; int second = 0; for(int i=1;i winnerScore) { winnerScore = scores[numberOfModels][i]*weights[numberOfModels][i]; winner = i; } } winnerScore = testYes[0]; for(int i=1;i winnerScore) { winnerScore = testYes[i]; second = i; } } confusion[phoneID][winner]++; /* winnerScore = scores[numberOfModels][0]*weights[numberOfModels][0]; winner = 0; second = 0; for(int i=1;i winnerScore) { winnerScore = scores[numberOfModels][i]*weights[numberOfModels][i]; winner = i; } } winnerScore = scores[numberOfModels][0]*weights[numberOfModels][0]; for(int i=1;i winnerScore) { winnerScore = scores[numberOfModels][i]*weights[numberOfModels][i]; second = i; } } */ if(phoneID != winner) { second = winner; for(int i=0;i scores[i][second]) { deltas[i][phoneID]++; } } } if(winner == phoneID) { testAllOK[winner]++; } else { testAllMISS[phoneID]++; testAllFP[winner]++; } for(int i=0;i 0) { double fact = 0.05 / ((double)tot); for(int i2=0;i2