vc2005调用dll:在vc++6.0/2003/2005/2008中调用HTK



Application Example using the ATK Real-Time API

下面是个有关HTK例子

# "stdafx.h"

# "dllSudx.h"
typedef vector<STRING> TStringArray;

struct ASampleSet
{
char name[256];
TSoundTag tags[301];
};

typedef vector<ASAMPLESET> TSampleSetList;

TStringArray sampleList;
TSampleSetList sampleSetList;
vector_count = 0;

ListWavFiles(char* dir, TStringArray& fileList)
{
struct _finddata_t c_file;
long hFile;
char tmp[1024];
retVal = 0;

sprf(tmp, "%s\\%s", dir, "*.wav");

/* Find first .c file in current directory */
( (hFile = _findfirst( tmp, &c_file )) -1L )
retVal;

{
sprf(tmp, "%s\\%s", dir, c_file.name);
fileList.push_back(tmp);
retVal;
while( _findnext( hFile, &c_file ) 0 )
{
sprf(tmp, "%s\\%s", dir, c_file.name);
fileList.push_back(tmp);
retVal;
}
_findclose( hFile );
}

retVal;
}


ListVecFiles(char* dir, TStringArray& fileList)
{
struct _finddata_t c_file;
long hFile;
char tmp[1024];
retVal = 0;

sprf(tmp, "%s\\%s", dir, "*.vec");

/* Find first .c file in current directory */
( (hFile = _findfirst( tmp, &c_file )) -1L )
retVal;

{
sprf(tmp, "%s\\%s", dir, c_file.name);
fileList.push_back(tmp);
retVal;
while( _findnext( hFile, &c_file ) 0 )
{
sprf(tmp, "%s\\%s", dir, c_file.name);
fileList.push_back(tmp);
retVal;
}
_findclose( hFile );
}

retVal;
}


LoadVecFiles(TStringArray& fileList, TSampleSetList& sampleSetList)
{
retVal = 0;

for( i=0; i<FILELIST.SIZE; <声音文件名 prf(?使用思路方法:test prf(?参数\n?); { *(argc!="4)" bVolumeFlag) bool , vecDirectory char* *VoiceName, VRecognize16BitWav(char ; g_TestVectorFileName="test.vec" } FALSE; : TRUE ? matchCount="0;" matchCount; i"3;" pMatchResult[matchCount].dwMatchOff="i;" pMatchResult[matchCount].ucScore="score;" &score)) bMode, pSampleVec, (sudxCompareEx(pSrcVec+i, score; i) matchCount<100; && i<nSrcLen-tailLen i="0;" for( tailLen="64;" 0; (nSampleLen<300) (nSampleLen<64) (bMode="=TRUE)" tailLen; 输出匹配结果(得分、偏移量) pMatchResult) MATCHRESULT* 输出匹配结果个数 pnMaxMatch, * 模式="TRUE:快速模式;=FALSE:准确模式" BOOL 样本向量个数 nSampleLen, 样本向量首地址指针 TSoundTag* 信号源向量长度(以TSoundTag为计量单位) nSrcLen, 待识别信号源向量首地址指针 pSrcVec, sudxMatch(TSoundTag* 注意事项:pnMaxMatch存储空间由应用分配最大为100条记录 返回:1:成功0:失败 MATCHRESULT; dwMatchOff; DWORD ucScore; char unsigned tagMATCHRESULT struct typedef retVal; ); fflush(stdout fileList[i].c_str); [%s]\n?, file open not prf(?can fclose(fp); !\n?, OK [%s] prf(?sample retVal; sampleSetList.push_back(a); strcpy(a.name, !\n?, too (size!="80)" fp); 80, (TSoundTag), size="fread(a.tags," a; ASampleSet (fp) ?rb?); fp="fopen(fileList[i].c_str," FILE*> <样本目录> <音量标志>\n");
prf("\t声音文件名是要被识别声音文件样本目录中包含已经预先处理好样本\n"
"\t 音量标志: 表示识别时是否采用音量相关方式,为0表示识别时不管音量大小为1表示识别时需要考虑音量大小\n"
"Press any key continue...");
getch;
-1;
}*/

// volFlag = atol(argv[3]);
(bVolumeFlag)
{
sudxSetCompVolumeFlag(TRUE);
prf("采用和音量相关方式比较\n");
}

{
sudxSetCompVolumeFlag(FALSE);
prf("采用和音量无关方式比较\n");
}

TStringArray sampleList;
i = ListVecFiles(vecDirectory, sampleList);
(i<=0)
{
prf("No sample files in dir [%s]\n", vecDirectory);
-2;
}

TSampleSetList sampleSetList;
vector_count = LoadVecFiles(sampleList, sampleSetList);
(vector_count<=0)
{
prf("没有找到样本集合文件\n");
-3;
}


prf("Now start...\n");
const bufSampleSize = 49306; ////充值成功,你账户余额为 8k采样,8位长度编码语音文件大小
unsigned char * p8bitBuf = unsigned char[ bufSampleSize];
*pFileBuf = [bufSampleSize*2]; //每次处理2M个16bit pcm样本也就是4M 数据


// char outFile[1000];


// sprf(outFile, "%s\\%s.vec", "c:", VoiceName);
// FILE* fout = fopen(outFile, "w+b"); //打开或创建向量文件

FILE *fp = fopen(VoiceName, "rb");
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 44L, SEEK_SET); //跳过wav头

old_clock = clock;
// long segSize = fread(p8bitBuf, (char), bufSampleSize, fp);
//alaw2linear( p8bitBuf , bufSampleSize , pFileBuf );

long segSize = fread(pFileBuf, (), bufSampleSize, fp);
TSoundTag* pOut;
outSize, tailSize;
* pTail=NULL;

last_result[17];
iMax = sudxGetMaxInputSampleSize;

error = sudxCalcBuffer( pFileBuf, segSize, &pOut, &outSize, &pTail, &tailSize, last_result);
( error > 0 )
{
( outSize > (64 + 1 ))
{
old_clock = clock;

compare_turn = outSize - 64 - 1;
for(i=0; i<COMPARE_TURN; { i) for( [%s]\n?, file (tailSize tailSize="compare_turn+64-300-i;" sampleSetList[j].name); (i+1)*128, %d, pos sample at Match prf(?Quick ) FALSE) &(sampleSetList[j].tags[1]), sudxCompare(pOut+1+i, ( j) j<vector_count; j="0;">300)
{
(sudxCompare(pOut+1+i, sampleSetList[j].tags+1, TRUE))
prf("精确匹配位置 %d, file[%s]\n", (i+1)*128, sampleSetList[j].name);

prf("!!Slow Not Match at sample pos %d, file[%s]\n", (i+1)*128, sampleSetList[j].name);
}
}

{
prf("Not Match at sample pos %d, file [%s]\n", (i+1)*128, sampleSetList[j].name);
}

}
}
time_passed = clock-old_clock;
prf("计算结束, 耗时%d ms\n", time_passed);
prf("比较速度为每秒钟可查找%f秒音乐\n", double(compare_turn)*128.0/8000.0/(double(time_passed)/1000.0));

}

{
prf("输入声音过短,不能比较\n");
-2;
}

}

{
-1;
}
0;
}


VRecoInit(char * vecDirectory )
{


i = ListVecFiles(vecDirectory, sampleList);
(i<=0)
{
prf("No sample files in dir [%s]\n", vecDirectory);
-2;
}


vector_count = LoadVecFiles(sampleList, sampleSetList);
(vector_count<=0)
{
prf("没有找到样本集合文件\n");
-3;
}

0;




}
///
VRecognize(char *VoiceName, char* vecDirectory , bool bVolumeFlag, * iMatchCount)
{
/*(argc!=4)
{
prf("参数\n");
prf("使用思路方法:test <声音文件名> <样本目录> <音量标志>\n");
prf("\t声音文件名是要被识别声音文件样本目录中包含已经预先处理好样本\n"
"\t 音量标志: 表示识别时是否采用音量相关方式,为0表示识别时不管音量大小为1表示识别时需要考虑音量大小\n"
"Press any key continue...");
getch;
-1;
}*/

// volFlag = atol(argv[3]);
(bVolumeFlag)
{
sudxSetCompVolumeFlag(TRUE);
prf("采用和音量相关方式比较\n");
}

{
sudxSetCompVolumeFlag(FALSE);
prf("采用和音量无关方式比较\n");
}

char gcaMsg[1000];
sprf(gcaMsg , "Now start...%s\n", VoiceName);
prf( gcaMsg );
fflush(stdout);
const bufSampleSize = 2048*1024; ////充值成功,你账户余额为 8k采样,8位长度编码语音文件大小
unsigned char * p8bitBuf = unsigned char[ bufSampleSize];
*pFileBuf = [bufSampleSize]; //每次处理2M个16bit pcm样本也就是4M 数据



// char outFile[1000];
// sprf(outFile, "%s\\%s.vec", "c:", VoiceName);
// FILE* fout = fopen(outFile, "w+b"); //打开或创建向量文件

try
{

sprf(gcaMsg , "bf fopen...%s\n", VoiceName);
prf( gcaMsg );
fflush(stdout);

FILE *fp = fopen(VoiceName, "rb");
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 44L, SEEK_SET); //跳过wav头


sprf(gcaMsg , "af fopen...%s\n", VoiceName);
prf( gcaMsg );
fflush(stdout);


old_clock = clock;
long segSize = fread(p8bitBuf, (char), bufSampleSize, fp);
alaw2linear( p8bitBuf , bufSampleSize , pFileBuf );

sprf(gcaMsg , "Af alaw2linear...%s\n", VoiceName);
prf( gcaMsg );
fflush(stdout);

// long segSize = fread(pFileBuf, (), bufSampleSize, fp);
TSoundTag* pOut;
outSize, tailSize;
* pTail=NULL;

last_result[17];
// iMax = sudxGetMaxInputSampleSize;




error = sudxCalcBuffer( pFileBuf, segSize, &pOut, &outSize, &pTail, &tailSize, last_result);

( error > 0 )
{
sprf(gcaMsg , "Af sudxCalcBuffer...%s\n", VoiceName);
prf( gcaMsg );
fflush(stdout);

( outSize > (64 + 1 ))
{
old_clock = clock;

compare_turn = outSize - 64 - 1;
for( i=0; i<COMPARE_TURN; { i) for( [%s]\n?, file (tailSize tailSize="compare_turn+64-300-i;" sampleSetList[j].name); (i+1)*128, %d, pos sample at Match prf(?Quick ) FALSE) &(sampleSetList[j].tags[1]), sudxCompare(pOut+1+i, ( j) j<vector_count; j="0;" iMatchCount); (*>300)
{
(sudxCompare(pOut+1+i, sampleSetList[j].tags+1, TRUE))
{

(* iMatchCount) ;
prf("精确匹配位置 %d, file[%s]\n", (i+1)*128, sampleSetList[j].name);
}

{
// prf("!!Slow Not Match at sample pos %d, file[%s]\n", (i+1)*128, sampleSetList[j].name);
}
}
}
}
}
time_passed = clock-old_clock;
prf("计算结束, 耗时%d ms Match Count =%d\n", time_passed,(* iMatchCount) );
prf("比较速度为每秒钟可查找%f秒音乐\n", double(compare_turn)*128.0/8000.0/(double(time_passed)/1000.0));
fflush( stdout );

}

{
prf("输入声音过短,不能比较\n");
-2;
}

}

{
sprf(gcaMsg , "Now Fail ...%s\n -1", "CalcBuffer");
prf( gcaMsg );
fflush(stdout);

-1;
}
}
catch ( ... )
{

sprf(gcaMsg , "Now Fail ...%s\n -3", "Catch");
prf( gcaMsg );
fflush(stdout);
-3;
}

0;
}


char * asds_version="!HVER!ASDS: 1.6.0 [SJY 01/06/07]";

# "AMonitor.h"
# "AIO.h"

// ---------------- Globals To Define the Recognition -----------------
QA;

// Information Channel - connects to AIO output
ABuffer *inChan; // input channel from AIO

// Active components (threads)
// NB: AIO will start-up its own ASource,ASyn,ACode & ARec
AIO *aio; // the AIO subsystem
AMonitor *amon; // system monitor

// Global resources - these will be passed to AIO _disibledevent=>
const float minconf = 0.5;

QA {
public:
QA(const & aname, // name of qa object
const & aprompt, // query prompt
const & gramfile, // name of grammar file
const & ahelp); // help message
ASRStatus Listen( prompt, rgroup, SynStatus& ss);
// output prompt and listen using given res group and update slot value
void Ask; // ask question, record answer and status
void Check; // check answer and status
void GetSlot; // get a value for the slot by asking and checking
GetValue; // strip tag and actual value
void Show; // show current slot status
void Re;
SlotStatus status; // slot status
value; // slot value
float curconf; // current input
curtag;
curwords;
private:
name; // name of slot (also name of semantic tag)
prompt; // question
help; // help
ResourceGroup *ask;
ResourceGroup *chk;
};

// construct a QA object with given prompt and grammar
QA::QA(const & aname, const & aprompt,
const & gramfile, const & ahelp)
{
// save the prompts
prompt = aprompt; help = ahelp; name = aname;
// create grammar specic to this question


AGram *g1 = AGram(name,gramfile);
rman->StoreGram(g1);
ask = rman->NewGroup(name+"-ask");
ask->AddHMMs(h); // Add the global resources
ask->AddDict(dict);
ask->AddGram(ggrm); // global grammar in parallel with
ask->AddGram(g1); // qa specic grammar
// create copy of ask but prepend "No" to front of qa grammar
// and add confirm in parallel
chk = rman->NewGroup(name+"-chk");
chk->AddHMMs(h); // Add the global resources
chk->AddDict(dict);
chk->AddGram(ggrm); // global grammar
AGram *g2 = AGram(*g1); // copy g1
rman->StoreGram(g2);
g2->OpenEdit; // Mody copy of g1 by prepending
GramSubN *s = g2->; // "NO" to front with skip to end
GramNode *ent = s->NewNullNode(99);
GramNode *no = s->NewWordNode("NO","no");
GramNode *yes = s->NewCallNode("confirm","yes"); // Add confirm in //
s->AddLink(ent,no); s->AddLink(ent,yes); s->AddLink(yes,s->exit);
s->AddLink(no,s->entry); s->AddLink(no,s->exit);
s->entry = ent;
g2->CloseEdit;
chk->AddGram(g2); // Add the "correction" grammar
// initial status is unknown
status = unknown; value = "";
}

// Re slot values for a dialogue
void QA::Re
{
status = unknown; value = "";
}

// For debugging _disibledevent=>
switch (status){
unknown: s = "unknown"; ;
unconfirmed: s = "unconfirmed"; ;
grounded: s = "grounded"; ;
cancelled: s = "cancelled"; ;
}
prf("Slot: %s: status=%s value=%s [cur=%s(%s) %.1f]\n",
name.c_str,s.c_str,value.c_str,curtag.c_str,curwords.c_str,curconf);
}

// listen to rec packets and construct slot value
// system status when finished listening
ASRStatus QA::Listen( prompt, rgroup, SynStatus& ss)
{
APacket p;
s="";
float conf=0.0;
numwords=0;
ASRStatus as;

curtag=""; curwords="";
// the resource group to use and start recognising
grp = "group("+rgroup+")";
prmpt = "ask(\""+prompt+"\")";
prf("%s --> %s\n",prmpt.c_str,grp.c_str);
aio->SendMessage(grp);
aio->SendMessage(prmpt);
// listen to response of form "tag(w1 w2 ...)"
// Following implements a simple state machine ss= syn state as=asr state
ss = sActive; as = aActive;
do {
AStringData *sd;
ACommandData *cd;
APhraseData *pd;
cmd;
p = inChan->GetPacket;
switch(p.GetKind) {
StringPacket:
sd = (AStringData *)p.GetData;
(sd->data.find("TERMINATED") != ::npos) {
as = aTerminated;
}
;
CommandPacket:
cd = (ACommandData *)p.GetData;
cmd = cd->GetCommand;
(cmd"synFinished")
ss = sDone;
(cmd"synInterrupted")
ss = sInt;
(cmd"asrTimeOut")
as = aTimeout;
;
PhrasePacket:
pd = (APhraseData *)p.GetData;
(as aActive && pd->ptype OpenTag_PT){
assert(s "" && numwords 0);
as = aInProcess;
} (as aInProcess && pd->ptype Word_PT) {
(s"") s = pd->word; s = s + " " + pd->word;
// prf("{%s[%.2f]}",pd->word.c_str,pd->confidence);
conf pd->confidence; numwords;
} (as aInProcess &&
(pd->ptype CloseTag_PT || pd->ptype End_PT)){
curtag = pd->tag;
curwords = s;
as = aDone;
}
;
}
} while (as <= aInProcess);
curconf = numwords0?0.0:conf/numwords;
prf("\n Response: %s(%s)[%.1f]\n",curtag.c_str,curwords.c_str,curconf);
as;
}

// ask for information
void QA::Ask
{
Boolean ok = FALSE;
ASRStatus as; SynStatus ss;
do {
as=Listen(prompt,ask->gname,ss);
(asaDone){
(curtag "command") {
(curwords "HELP") {
aio->SendMessage("tell(\""+help+"\")");
} (curwords "CANCEL"){
aio->SendMessage("tell(\"Cancelled\")");
ok = TRUE; status = cancelled;
}
}
(curtag name){
(curconf > minconf){
status = grounded;


}{
status = unconfirmed;
}
value = curtag+"("+curwords+")";
ok = TRUE;
}
} (asaTimeout) {
prf("Timeout\n");
aio->SendMessage("tell(\"Sorry, I didnt hear that!\")");
} (asaTerminated) {
terminated = TRUE;
}
} while (!ok && !terminated);
}

// confirm current slot value
void QA::Check
{
Boolean ok = FALSE;
ASRStatus as; SynStatus ss;
prompt;
do {
prompt = "Are sure you want "+GetValue+" ?";
as = Listen(prompt,chk->gname,ss);
(asaDone){
(curtag "command") {
(curwords "HELP") {
aio->SendMessage("tell(\"I am trying to confirm your last input.\")");
aio->SendMessage("tell(\"Please say Yes or No. If No, you can also give the correct value.\")");
} (curwords "CANCEL"){
ok = TRUE; status = cancelled;
}
}
(curtag "yes"){
ok = TRUE; status = grounded;
} (curtag name){
(curconf > minconf){
status = grounded;
}{
status = unconfirmed;
}
value = curtag+"("+curwords+")";
ok = TRUE;
} {
ok = TRUE; status = unknown; // user must have said No without correction
}
} (asaTimeout) {
aio->SendMessage("Sorry, I didnt hear that!");
} (asaTerminated) {
terminated = TRUE;
}
} while (!ok && !terminated);
}

void QA::GetSlot
{
do {
Ask;
while (status unconfirmed) Check;
}while (status != grounded && status != cancelled && !terminated);
}

QA::GetValue
{
n = value.find("(");
(n::npos) "";
n;
m = value.length - n -1;
val = value.substr(n,m);
for ( i = 0; i<M; rman- AGram(?GGram?,?global.net?); ggrm="" ADict(?ADict?); dict="" AHmms(?HmmSet?); h="" resources fixed global create ARMan; rman="" manager resource a ABuffer(?inChan?); inChan="" AIO from channel the { BuildRecogniser void } getchar; Continue\n\n?); to Return Press prf(?='\n\n");' microphone.\n\n?); by up picked not prf(?is output\n?); speech that ensure headphones prf(?Use microphone.\n?); open an uses demo this - prf(?\nWARNING \n?); Dialog Spoken Asynchronous ATK prf(?\nASDS: HTK_Error(9999); throw HTK\n?); initialise cannot HRError(9999,?ASDS: (InitHTK(argc,argv,asds_version)<SUCCESS){ *argv) char argc, Initialise( --------------------------- Code Initialisation ---------------------- val; val[i]="tolower(ch);" ch="val[i];" i){>StoreHMMs(h);
rman->StoreDict(dict);
rman->StoreGram(ggrm);
ResourceGroup * = rman->NewGroup("");
->AddHMMs(h); ->AddDict(dict); ->AddGram(ggrm);
// create the qa objects, these will create the resource groups
top = QA("topping",
"What topping would you like?",
"topping.net",
"I have a variety of toppings\n - try your favourite combination");
qty = QA("quantity",
"How many pizzas would you like?",
"howmany.net",
"I need to know how many pizzas to deliver");

// now we have resources, create aio
aio = AIO("aio",inChan,rman);
aio->DefineFiller("ER");
aio->DefineFiller("SIL");
aio->DefineFiller("OH");

// finally create Monitor and attach it to AIO
amon = AMonitor;
aio->AttachMonitor(amon);
}

void StartRecogniser
{
// Start up each component thread
amon->Start;
aio->Start;
}

void ShutDown
{
prf("Shutting down\n");
// wait till components shutdown
aio->SendMessage("closedown");
// then kill monitor
amon->Terminate;
HJoinMonitor;
}

// ------------------------- Application Code ---------------------------

void RunApplication
{
// Start recogniser running
StartRecogniser;

do{
top->GetSlot;
(!terminated && top->status grounded) qty->GetSlot;
(top->status grounded && qty->status grounded) {
order = "Your order is "+qty->GetValue+" "+top->GetValue;
(qty->GetValue "one")
order " pizza.";



order " pizzas.";
prf("Order: %s\n",order.c_str);
aio->SendMessage("tell(\""+order+"\")");
}
top->Re; qty->Re;
prf("\n\n=\n\n");
}while(!terminated);
ShutDown;
}

// --------------------------- Main Program ----------------------------

( argc, char *argv)
{
try {
Initialise(argc,argv);
BuildRecogniser;
RunApplication;
}
catch (ATK_Error e){
n = HRErrorCount;
prf("ATK Error %d\n",e.i);
for ( i=1; i<=n; i)
prf(" %d. %s\n",i,HRErrorGetMess(i));
}
catch (HTK_Error e){
n = HRErrorCount;
prf("HTK Error %d\n",e.i);
for ( i=1; i<=n; i)
prf(" %d. %s\n",i,HRErrorGetMess(i));
}
0;
}
Tags:  vc调用dll vs2005vc6.0 vc2005vc6.0 vc2005调用dll

延伸阅读

最新评论

发表评论