void CDialogueManager::LoadDialogue(const char *szFilename) { int scriptNum; int sentenceNum; int strLen; char* buffer; // Load in all the dialogue from file at beginning of game ifstream in; in.open(szFilename,ios_base::in | ios_base::binary); if( in.is_open() ) { in.read((char*)&scriptNum,sizeof(int)); for( int script = 0; script < scriptNum; script++ ) { in.read((char*)&strLen,sizeof(int)); buffer = new char[strLen+1]; in.read(buffer,strLen); buffer[strLen] = '\0'; string szName = buffer; CScript* newScript = new CScript(szName); delete[] buffer; in.read((char*)&sentenceNum,sizeof(int)); for( int sentence = 0; sentence < sentenceNum; sentence++ ) { in.read((char*)&strLen,sizeof(int)); buffer = new char[strLen+1]; in.read(buffer,strLen); buffer[strLen] = '\0'; string szSentence = buffer; delete[] buffer; in.read((char*)&strLen,sizeof(int)); buffer = new char[strLen+1]; in.read(buffer,strLen); buffer[strLen] = '\0'; string szTrigger = buffer; delete[] buffer; CSentence* newSentence = new CSentence(szSentence,szTrigger); if( strLen < 1 ) newSentence->SetEventBool(false); else newSentence->SetEventBool(true); newScript->AddSentence(newSentence); } m_vScripts.push_back(newScript); } } in.close(); }
bool CSoundCombiner::IsCombinedFileChecksumValid( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) { unsigned int computedChecksum = CheckSumWork( filesystem, info ); char fullpath[ MAX_PATH ]; Q_strncpy( fullpath, outfile, sizeof( fullpath ) ); filesystem->GetLocalPath( outfile, fullpath, sizeof( fullpath ) ); CSentence sentence; bool valid = false; if ( LoadSentenceFromWavFile( fullpath, sentence ) ) { unsigned int diskFileEmbeddedChecksum = sentence.GetDataCheckSum(); valid = computedChecksum == diskFileEmbeddedChecksum; if ( !valid ) { Warning( " checksum computed %u, disk %u\n", computedChecksum, diskFileEmbeddedChecksum ); } } else { Warning( "CSoundCombiner::IsCombinedFileChecksumValid: Unabled to load %s\n", fullpath ); } CleanupWork(); return valid; }
static int GetConjProperties(const CSentence& S, int WordNo, ConjFromWhatList& FromWhere,int& iConjIndex, int UpperBorder) { if( (WordNo == -1) || (WordNo >= UpperBorder) ) return -1; int OborotNo = S.m_Words[WordNo].GetOborotNo(); if ( OborotNo != -1 && S.GetOpt()->m_pOborDic->m_Entries[OborotNo].HasPartOfSpeech(S.GetOpt()->m_Conjunction) ) { for(size_t i = WordNo ; i < UpperBorder; i++ ) if( S.m_Words[i].HasOborot2()) { FromWhere = FROM_OBOR_DIC; iConjIndex = OborotNo; return WordNo + 1; } } iConjIndex = S.m_Words[WordNo].m_SubordinateConjNo; int HomonymNo; if ( (iConjIndex != -1 ) && !S.IsRelativSentencePronoun(0, WordNo, HomonymNo) ) { FromWhere = FROM_SUB_CONJ; return WordNo+1; } return -1; }
void CSentence::Append( float starttime, const CSentence& src ) { #if PHONEME_EDITOR int i; // Combine for ( i = 0 ; i < src.m_Words.Size(); i++ ) { CWordTag *word = src.m_Words[ i ]; CWordTag *newWord = new CWordTag( *word ); newWord->m_flStartTime += starttime; newWord->m_flEndTime += starttime; // Offset times int c = newWord->m_Phonemes.Count(); for ( int i = 0; i < c; ++i ) { CPhonemeTag *tag = newWord->m_Phonemes[ i ]; tag->AddStartTime( starttime ); tag->AddEndTime( starttime ); } AddWordTag( newWord ); } if ( src.GetText()[ 0 ] ) { char fulltext[ 4096 ]; if ( GetText()[ 0 ] ) { Q_snprintf( fulltext, sizeof( fulltext ), "%s %s", GetText(), src.GetText() ); } else { Q_strncpy( fulltext, src.GetText(), sizeof( fulltext ) ); } SetText( fulltext ); } int c = src.m_EmphasisSamples.Size(); for ( i = 0; i < c; i++ ) { CEmphasisSample s = src.m_EmphasisSamples[ i ]; s.time += starttime; m_EmphasisSamples.AddToTail( s ); } // Or in voice duck settings m_bShouldVoiceDuck |= src.m_bShouldVoiceDuck; #else Assert( 0 ); #endif }
string GetNodeGrmStr(const CSentence& Sentence, const CRelationsIterator& RelIt, int GroupNo, int WordNo, string& Lemma) { Lemma = ""; if (GroupNo != -1) return ""; else { size_t ClauseNo = Sentence.GetMinClauseByWordNo(WordNo); const CClause& Clause = Sentence.GetClause(ClauseNo); const CMorphVariant* pSynVar = &*Clause.GetSynVariantByNo(0); int UnitNo = pSynVar->UnitNoByWordNo(WordNo); const CSynUnit& U = pSynVar->m_SynUnits[UnitNo]; Lemma = Sentence.GetWords()[WordNo].GetHomonym(U.m_iHomonymNum)->m_strLemma; return Sentence.GetOpt()->GetGramTab()->GrammemsToStr(U.m_iGrammems | U.m_TypeGrammems); } }
bool CSoundCombiner::LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io ) { sentence.Reset(); InFileRIFF riff( wavfile, io ); // UNDONE: Don't use printf to handle errors if ( riff.RIFFName() != RIFF_WAVE ) { return false; } // set up the iterator for the whole file (root RIFF is a chunk) IterateRIFF walk( riff, riff.RIFFSize() ); // This chunk must be first as it contains the wave's format // break out when we've parsed it bool found = false; while ( walk.ChunkAvailable() && !found ) { switch( walk.ChunkName() ) { case WAVE_VALVEDATA: { found = true; CSoundCombiner::ParseSentence( sentence, walk ); } break; } walk.ChunkNext(); } return true; }
void GetGroups(const CSentence& Sentence, const CAgramtab& A, string& Res) { int nClausesCount = Sentence.GetClausesCount(); for (int ClauseNo = 0; ClauseNo<nClausesCount; ClauseNo++) { const CClause& Clause = Sentence.GetClause(ClauseNo); int nCvar = Clause.m_SynVariants.size(); if (Clause.m_SynVariants.empty()) continue; int nVmax = Clause.m_SynVariants.begin()->m_iWeight; for (CSVI pSynVar = Clause.m_SynVariants.begin(); pSynVar != Clause.m_SynVariants.end(); pSynVar++) { if (pSynVar->m_iWeight < nVmax) break; const CMorphVariant& V = *pSynVar; Res += Format("\t<synvar>\n"); // print the clause { int ClauseType = (V.m_ClauseTypeNo == -1) ? UnknownSyntaxElement : Clause.m_vectorTypes[V.m_ClauseTypeNo].m_Type;; string Type; if (ClauseType != UnknownSyntaxElement) Type = (const char*)A.GetClauseNameByType(ClauseType); else Type = "EMPTY"; Res += Format("\t\t<clause type=\"%s\">%s</clause>\n", Type.c_str(), GetWords(Sentence, Clause).c_str()); } for (int GroupNo = 0; GroupNo < V.m_vectorGroups.GetGroups().size(); GroupNo++) { const CGroup& G = V.m_vectorGroups.GetGroups()[GroupNo]; Res += Format("\t\t<group type=\"%s\">%s</group>\n", Sentence.GetOpt()->GetGroupNameByIndex(G.m_GroupType), GetWords(Sentence, G).c_str()); }; Res += Format("\t</synvar>\n"); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : store - //----------------------------------------------------------------------------- void CSoundCombiner::StoreValveDataChunk( CSentence& sentence ) { // Buffer and dump data CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); sentence.SaveToBuffer( buf ); // Copy into store m_pOutIterator->ChunkWriteData( buf.Base(), buf.TellPut() ); }
//----------------------------------------------------------------------------- // Purpose: // Input : &walk - //----------------------------------------------------------------------------- void CSoundCombiner::ParseSentence( CSentence& sentence, IterateRIFF &walk ) { CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); buf.EnsureCapacity( walk.ChunkSize() ); walk.ChunkRead( buf.Base() ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() ); sentence.InitFromDataChunk( buf.Base(), buf.TellPut() ); }
void GetRelations(const CSentence& Sentence, string& Result) { CRelationsIterator RelIt; RelIt.SetSentence(&Sentence); for (int i = 0; i<Sentence.m_vectorPrClauseNo.size(); i++) RelIt.AddClauseNoAndVariantNo(Sentence.m_vectorPrClauseNo[i], 0); RelIt.BuildRelations(); for (long RelNo = 0; RelNo < RelIt.GetRelations().size(); RelNo++) { const CSynOutputRelation& piRel = RelIt.GetRelations()[RelNo]; string RelName = Sentence.GetOpt()->GetGroupNameByIndex(piRel.m_Relation.type); string Src = GetNodeStr(Sentence, RelIt, piRel.m_iSourceGroup, piRel.m_Relation.m_iFirstWord); string Trg = GetNodeStr(Sentence, RelIt, piRel.m_iTargetGroup, piRel.m_Relation.m_iLastWord); string SrcLemma, TrgLemma; string SrcGrm = GetNodeGrmStr(Sentence, RelIt, piRel.m_iSourceGroup, piRel.m_Relation.m_iFirstWord, SrcLemma); string TrgGrm = GetNodeGrmStr(Sentence, RelIt, piRel.m_iTargetGroup, piRel.m_Relation.m_iLastWord, TrgLemma); string GramRel = Sentence.GetOpt()->GetGramTab()->GrammemsToStr(piRel.m_Relation.m_iGrammems); Result += Format("\t<rel name=\"%s\" gramrel=\"%s\" lemmprnt=\"%s\" grmprnt=\"%s\" lemmchld=\"%s\" grmchld=\"%s\" > %s -> %s </rel>\n", RelName.c_str(), GramRel.c_str(), SrcLemma.c_str(), SrcGrm.c_str(), TrgLemma.c_str(), TrgGrm.c_str(), Src.c_str(), Trg.c_str()); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *phonemes - //----------------------------------------------------------------------------- void LogPhonemes( CSentence& sentence ) { return; Log( "Phonemecount == %i\n", sentence.CountPhonemes() ); for ( int i = 0; i < sentence.m_Words.Size(); i++ ) { const CWordTag *w = sentence.m_Words[ i ]; for ( int j = 0; j < w->m_Phonemes.Size(); j++ ) { const CPhonemeTag *p = w->m_Phonemes[ j ]; Log( "Phoneme %s %u to %u\n", p->GetTag(), p->m_uiStartByte, p->m_uiEndByte ); } } }
bool CSentencesCollection::ReadAndProcessSentences(const CPlmLineCollection* piPlmLine) { const size_t LinesCount = piPlmLine->m_Items.size(); if( !m_pSyntaxOptions->IsValid()) return false; if (m_bEnableProgressBar) printf ("Starting Syntax\n"); time_t t1; time (&t1); for (size_t LineNo = 0; LineNo < LinesCount; ) { if (m_bEnableProgressBar) printf ("%i of %i \r", LineNo, LinesCount); CSentence* S = m_pSyntaxOptions->NewSentence(); if (!S) { m_pSyntaxOptions->OutputErrorString("Cannot allocate space for the new sentence!"); return false; }; try { S->m_pSyntaxOptions = m_pSyntaxOptions; bool bResult = S->ReadNextFromPlmLines(piPlmLine,LineNo); if (m_bLogProcessedSentence) { FILE * fp = fopen ("last_read_sentence.log", "w"); fprintf (fp, "%s\n",S->GetSentenceBeginStr().c_str()); fclose(fp); }; if( !bResult ) { // a parse error occurs delete S; return false; }; } catch (...) { m_pSyntaxOptions->OutputErrorString("Cannot read a sentence from Mapost"); delete S; return false; }; if( S->m_Words.empty() ) { // no not-empty sentence can be found, we are at the end of the text delete S; break; } try { bool bRes = S->BuildClauses(); if( !bRes ) { delete S; return false; }; S->CalculatePrimitiveClausesCount(); if (m_bEnableProgressBar) { if (S->m_bPanicMode) printf (" found a \"panic\" sentence\n"); }; m_vectorSents.push_back(S); } catch (...) { if (m_bEnableProgressBar) { printf ("\n"); if (!S->m_Words.empty()) printf ("exception at offset %i\n", S->m_Words[0].m_GraphematicalUnitOffset); }; delete S; m_pSyntaxOptions->OutputErrorString("An exception in Synan occurred!"); return false; }; } if (m_bEnableProgressBar) { time_t t2; time (&t2); printf ("Finish \n"); int seconds = t2-t1; printf ("Time : %i\n", seconds); printf ("Count of tokens : %i\n", LinesCount); if (seconds > 0) printf ("The speed is %i tokens pro second\n", LinesCount/seconds); }; return true; }
//----------------------------------------------------------------------------- // Purpose: Given a wave file and a string of words "text", creates a CFG from the // sentence and stores the resulting words/phonemes in CSentence // Input : *wavname - // text - // sentence - // (*pfnPrint - // Output : SR_RESULT //----------------------------------------------------------------------------- SR_RESULT ExtractPhonemes( const char *wavname, CSpDynamicString& text, CSentence& sentence, void (*pfnPrint)( const char *fmt, ...) ) { // Assume failure SR_RESULT result = SR_RESULT_ERROR; if ( text.Length() <= 0 ) { pfnPrint( "Error: no rule / text specified\n" ); return result; } USES_CONVERSION; HRESULT hr; CUtlVector < WORDRULETYPE > wordRules; CComPtr<ISpStream> cpInputStream; CComPtr<ISpRecognizer> cpRecognizer; CComPtr<ISpRecoContext> cpRecoContext; CComPtr<ISpRecoGrammar> cpRecoGrammar; CComPtr<ISpPhoneConverter> cpPhoneConv; // Create basic SAPI stream object // NOTE: The helper SpBindToFile can be used to perform the following operations hr = cpInputStream.CoCreateInstance(CLSID_SpStream); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Stream object not installed?\n" ); return result; } CSpStreamFormat sInputFormat; // setup stream object with wav file MY_WAVE_AUDIO_FILENAME // for read-only access, since it will only be access by the SR engine hr = cpInputStream->BindToFile( T2W(wavname), SPFM_OPEN_READONLY, NULL, sInputFormat.WaveFormatExPtr(), SPFEI_ALL_EVENTS ); if ( FAILED( hr ) ) { pfnPrint( "Error: couldn't open wav file %s\n", wavname ); return result; } // Create in-process speech recognition engine hr = cpRecognizer.CoCreateInstance(CLSID_SpInprocRecognizer); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 In process recognizer object not installed?\n" ); return result; } // Create recognition context to receive events hr = cpRecognizer->CreateRecoContext(&cpRecoContext); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to create recognizer context\n" ); return result; } // Create a grammar hr = cpRecoContext->CreateGrammar( EP_GRAM_ID, &cpRecoGrammar ); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to create recognizer grammar\n" ); return result; } LANGID englishID = 0x409; // 1033 decimal bool userSpecified = false; LANGID langID = SpGetUserDefaultUILanguage(); // Allow commandline override if ( CommandLine()->FindParm( "-languageid" ) != 0 ) { userSpecified = true; langID = CommandLine()->ParmValue( "-languageid", langID ); } // Create a phoneme converter ( so we can convert to IPA codes ) hr = SpCreatePhoneConverter( langID, NULL, NULL, &cpPhoneConv ); if ( FAILED( hr ) ) { if ( langID != englishID ) { if ( userSpecified ) { pfnPrint( "Warning: SAPI 5.1 Unable to create phoneme converter for command line override -languageid %i\n", langID ); } else { pfnPrint( "Warning: SAPI 5.1 Unable to create phoneme converter for default UI language %i\n",langID ); } // Try english!!! langID = englishID; hr = SpCreatePhoneConverter( langID, NULL, NULL, &cpPhoneConv ); } if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to create phoneme converter for English language id %i\n", langID ); return result; } else { pfnPrint( "Note: SAPI 5.1 Falling back to use english -languageid %i\n", langID ); } } else if ( userSpecified ) { pfnPrint( "Note: SAPI 5.1 Using user specified -languageid %i\n",langID ); } SPSTATEHANDLE hStateRoot; // create/re-create Root level rule of grammar hr = cpRecoGrammar->GetRule(L"Root", 0, SPRAF_TopLevel | SPRAF_Active, TRUE, &hStateRoot); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to create root rule\n" ); return result; } // Inactivate it so we can alter it hr = cpRecoGrammar->SetRuleState( NULL, NULL, SPRS_INACTIVE ); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to deactivate grammar rules\n" ); return result; } // Create the rule set from the words in text { CSpDynamicString currentWord; WCHAR *pos = ( WCHAR * )text; WCHAR str[ 2 ]; str[1]= 0; while ( *pos ) { if ( *pos == L' ' /*|| *pos == L'.' || *pos == L'-'*/ ) { // Add word to rule set if ( currentWord.Length() > 0 ) { AddWordRule( cpRecoGrammar, &hStateRoot, &wordRules, currentWord ); currentWord.Clear(); } pos++; continue; } // Skip anything that's inside a [ xxx ] pair. if ( *pos == L'[' ) { while ( *pos && *pos != L']' ) { pos++; } if ( *pos ) { pos++; } continue; } str[ 0 ] = *pos; currentWord.Append( str ); pos++; } if ( currentWord.Length() > 0 ) { AddWordRule( cpRecoGrammar, &hStateRoot, &wordRules, currentWord ); } if ( wordRules.Size() <= 0 ) { pfnPrint( "Error: Text %s contained no usable words\n", text ); return result; } // Build all word to word transitions in the grammar if ( !BuildRules( cpRecoGrammar, &hStateRoot, &wordRules ) ) { pfnPrint( "Error: Rule set for %s could not be generated\n", text ); return result; } } // check for recognitions and end of stream event const ULONGLONG ullInterest = SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM) | SPFEI(SPEI_FALSE_RECOGNITION) | SPFEI(SPEI_PHRASE_START ) | SPFEI(SPEI_HYPOTHESIS ) | SPFEI(SPEI_INTERFERENCE) ; hr = cpRecoContext->SetInterest( ullInterest, ullInterest ); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to set interest level\n" ); return result; } // use Win32 events for command-line style application hr = cpRecoContext->SetNotifyWin32Event(); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to set win32 notify event\n" ); return result; } // connect wav input to recognizer // SAPI will negotiate mismatched engine/input audio formats using system audio codecs, so second parameter is not important - use default of TRUE hr = cpRecognizer->SetInput(cpInputStream, TRUE); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to associate input stream\n" ); return result; } // Activate the CFG ( rather than using dictation ) hr = cpRecoGrammar->SetRuleState( NULL, NULL, SPRS_ACTIVE ); if ( FAILED( hr ) ) { switch ( hr ) { case E_INVALIDARG: pfnPrint( "pszName is invalid or bad. Alternatively, pReserved is non-NULL\n" ); break; case SP_STREAM_UNINITIALIZED: pfnPrint( "ISpRecognizer::SetInput has not been called with the InProc recognizer\n" ); break; case SPERR_UNINITIALIZED: pfnPrint( "The object has not been properly initialized.\n"); break; case SPERR_UNSUPPORTED_FORMAT: pfnPrint( "Audio format is bad or is not recognized. Alternatively, the device driver may be busy by another application and cannot be accessed.\n" ); break; case SPERR_NOT_TOPLEVEL_RULE: pfnPrint( "The rule pszName exists, but is not a top-level rule.\n" ); break; default: pfnPrint( "Unknown error\n" ); break; } pfnPrint( "Error: SAPI 5.1 Unable to activate rule set\n" ); return result; } // while events occur, continue processing // timeout should be greater than the audio stream length, or a reasonable amount of time expected to pass before no more recognitions are expected in an audio stream BOOL fEndStreamReached = FALSE; while (!fEndStreamReached && S_OK == cpRecoContext->WaitForNotifyEvent( SR_WAVTIMEOUT )) { CSpEvent spEvent; // pull all queued events from the reco context's event queue while (!fEndStreamReached && S_OK == spEvent.GetFrom(cpRecoContext)) { // Check event type switch (spEvent.eEventId) { case SPEI_INTERFERENCE: { SPINTERFERENCE interference = spEvent.Interference(); switch ( interference ) { case SPINTERFERENCE_NONE: pfnPrint( "[ I None ]\r\n" ); break; case SPINTERFERENCE_NOISE: pfnPrint( "[ I Noise ]\r\n" ); break; case SPINTERFERENCE_NOSIGNAL: pfnPrint( "[ I No Signal ]\r\n" ); break; case SPINTERFERENCE_TOOLOUD: pfnPrint( "[ I Too Loud ]\r\n" ); break; case SPINTERFERENCE_TOOQUIET: pfnPrint( "[ I Too Quiet ]\r\n" ); break; case SPINTERFERENCE_TOOFAST: pfnPrint( "[ I Too Fast ]\r\n" ); break; case SPINTERFERENCE_TOOSLOW: pfnPrint( "[ I Too Slow ]\r\n" ); break; default: break; } } break; case SPEI_PHRASE_START: pfnPrint( "Phrase Start\r\n" ); sentence.MarkNewPhraseBase(); break; case SPEI_HYPOTHESIS: case SPEI_RECOGNITION: case SPEI_FALSE_RECOGNITION: { CComPtr<ISpRecoResult> cpResult; cpResult = spEvent.RecoResult(); CSpDynamicString dstrText; if (spEvent.eEventId == SPEI_FALSE_RECOGNITION) { dstrText = L"(Unrecognized)"; result = SR_RESULT_FAILED; // It's possible that the failed recog might have more words, so see if that's the case EnumeratePhonemes( cpPhoneConv, cpResult, sentence ); } else { // Hypothesis or recognition success cpResult->GetText( (ULONG)SP_GETWHOLEPHRASE, (ULONG)SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL); EnumeratePhonemes( cpPhoneConv, cpResult, sentence ); if ( spEvent.eEventId == SPEI_RECOGNITION ) { result = SR_RESULT_SUCCESS; } pfnPrint( va( "%s%s\r\n", spEvent.eEventId == SPEI_HYPOTHESIS ? "[ Hypothesis ] " : "", dstrText.CopyToChar() ) ); } cpResult.Release(); } break; // end of the wav file was reached by the speech recognition engine case SPEI_END_SR_STREAM: fEndStreamReached = TRUE; break; } // clear any event data/object references spEvent.Clear(); }// END event pulling loop - break on empty event queue OR end stream }// END event polling loop - break on event timeout OR end stream // Deactivate rule hr = cpRecoGrammar->SetRuleState( NULL, NULL, SPRS_INACTIVE ); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to deactivate rule set\n" ); return result; } // close the input stream, since we're done with it // NOTE: smart pointer will call SpStream's destructor, and consequently ::Close, but code may want to check for errors on ::Close operation hr = cpInputStream->Close(); if ( FAILED( hr ) ) { pfnPrint( "Error: SAPI 5.1 Unable to close input stream\n" ); return result; } return result; }
//----------------------------------------------------------------------------- // Purpose: Walk list of words and phonemes and create phoneme tags in CSentence object // FIXME: Right now, phonemes are assumed to evenly space out across a word. // Input : *converter - // result - // sentence - //----------------------------------------------------------------------------- void EnumeratePhonemes( ISpPhoneConverter *converter, const ISpRecoResult* result, CSentence& sentence ) { USES_CONVERSION; // Grab access to element container ISpPhrase *phrase = ( ISpPhrase * )result; if ( !phrase ) return; SPPHRASE *pElements; if ( !SUCCEEDED( phrase->GetPhrase( &pElements ) ) ) return; // Only use it if it's better/same size as what we already had on-hand if ( pElements->Rule.ulCountOfElements > 0 ) //(unsigned int)( sentence.m_Words.Size() - sentence.GetWordBase() ) ) { sentence.ResetToBase(); // Walk list of words for ( ULONG i = 0; i < pElements->Rule.ulCountOfElements; i++ ) { unsigned int wordstart, wordend; // Get start/end sample index wordstart = pElements->pElements[i].ulAudioStreamOffset + (unsigned int)pElements->ullAudioStreamPosition; wordend = wordstart + pElements->pElements[i].ulAudioSizeBytes; // Create word tag CWordTag *w = new CWordTag( W2T( pElements->pElements[i].pszDisplayText ) ); Assert( w ); w->m_uiStartByte = wordstart; w->m_uiEndByte = wordend; sentence.AddWordTag( w ); // Count # of phonemes in this word SPPHONEID pstr[ 2 ]; pstr[ 1 ] = 0; WCHAR wszPhoneme[ SP_MAX_PRON_LENGTH ]; const SPPHONEID *current; SPPHONEID phoneme; current = pElements->pElements[i].pszPronunciation; float total_weight = 0.0f; while ( 1 ) { phoneme = *current++; if ( !phoneme ) break; pstr[ 0 ] = phoneme; wszPhoneme[ 0 ] = L'\0'; converter->IdToPhone( pstr, wszPhoneme ); total_weight += WeightForPhoneme( W2A( wszPhoneme ) ); } current = pElements->pElements[i].pszPronunciation; // Decide # of bytes/phoneme weight float psize = 0; if ( total_weight ) { psize = ( wordend - wordstart ) / total_weight; } int number = 0; // Re-walk the phoneme list and create true phoneme tags float startWeight = 0.0f; while ( 1 ) { phoneme = *current++; if ( !phoneme ) break; pstr[ 0 ] = phoneme; wszPhoneme[ 0 ] = L'\0'; converter->IdToPhone( pstr, wszPhoneme ); CPhonemeTag *p = new CPhonemeTag( W2A( wszPhoneme ) ); Assert( p ); float weight = WeightForPhoneme( W2A( wszPhoneme ) ); p->m_uiStartByte = wordstart + (int)( startWeight * psize ); p->m_uiEndByte = p->m_uiStartByte + (int)( psize * weight ); startWeight += weight; // Convert to IPA phoneme code p->SetPhonemeCode( TextToPhoneme( p->GetTag() ) ); sentence.AddPhonemeTag( w, p ); number++; } } } // Free memory ::CoTaskMemFree(pElements); }
int CSentence::CanLinkSimpleSimilar(int CommaWordNo) { try { /* if comma is at the very beginning of ath the end, then exit */ if ( (CommaWordNo == 0) || (CommaWordNo + 1 >= m_Words.size() ) ) return -1; if (GetOpt()->m_Language == morphGerman) { // we can use CSentence::m_GroupsUnion if Tomita is enabled for (size_t i=0; i< m_GroupsUnion.GetGroups().size(); i++) { const CGroup& group = m_GroupsUnion.GetGroups()[i]; // ignore groups which contain only three words and the second word is // a comma (a clause delimiter) if (group.size() == 3) if (m_Words[group.m_iFirstWord+1].m_bComma) continue; if ( (group.m_iFirstWord < CommaWordNo) && (group.m_iLastWord > CommaWordNo) ) return group.m_iLastWord; }; return -1; }; const int Radius = (GetOpt()->m_Language == morphGerman)? 10 : 6; int StartClauseWordNo = max(0, CommaWordNo - Radius); CSentence* pSent = GetOpt()->NewSentence(); if (!pSent) throw CExpc ("Cannot create sentence"); for (int i = StartClauseWordNo; i < min((int)m_Words.size(), CommaWordNo + Radius); i++) pSent->m_Words.push_back(m_Words[i]); CClause C(pSent, 0, pSent->m_Words.size() - 1); pSent->AddClause(C); pSent->m_bShouldUseTwoPotentialRule = false; pSent->RunSyntaxInClauses(SimpleSimilarRules); int Result = -1; const CClause& prClause = pSent->m_Clauses[0]; for (CSVI it = prClause.m_SynVariants.begin(); (Result == -1)&& (it!=prClause.m_SynVariants.end()); it++) for (size_t i=0; i< it->m_vectorGroups.GetGroups().size(); i++) { const CGroup& group = it->m_vectorGroups.GetGroups()[i]; // ignore groups which contain only three words and the second word is // a comma (a clause delimiter) if (group.size() == 3) { const CSynUnit& U = it->m_SynUnits[group.m_iFirstWord+1]; if (pSent->m_Words[U.m_SentPeriod.m_iFirstWord].m_bComma) continue; }; if ( (group.m_iFirstWord+StartClauseWordNo < CommaWordNo) && (group.m_iLastWord+StartClauseWordNo > CommaWordNo) ) { Result = group.m_iLastWord + StartClauseWordNo; break; }; } delete pSent; return Result; } catch(...) { OutputErrorString("Failed RunSyntaxInClause(CanLinkSimpleSimilar)"); return -1; } }
//----------------------------------------------------------------------------- // Purpose: // Input : drawHelper - // rcWorkSpace - //----------------------------------------------------------------------------- void PhonemeEditor::CloseCaption_Redraw( CChoreoWidgetDrawHelper& drawHelper, RECT& rcWorkSpace, CSentence& sentence ) { if ( GetMode() != MODE_CLOSECAPTION ) return; float starttime = m_nLeftOffset / GetPixelsPerSecond(); float endtime = w2() / GetPixelsPerSecond() + starttime; RECT rcCC; CloseCaption_GetTrayTopBottom( rcCC ); int ypos = rcCC.top; const char *fontName = "Arial Unicode MS"; RECT rcTitle = rcCC; OffsetRect( &rcTitle, 0, -20 ); rcTitle.left = 15; rcTitle.right = w2(); drawHelper.DrawColoredText( "Arial", 15, FW_BOLD, PEColor( COLOR_PHONEME_CC_TEXT ), rcTitle, "Close caption..." ); drawHelper.DrawColoredLine( PEColor( COLOR_PHONEME_CC_TAG_FILLER_NORMAL ), PS_SOLID, 1, 0, rcCC.top-1, w2(), rcCC.top-1 ); drawHelper.DrawColoredLine( PEColor( COLOR_PHONEME_CC_TAG_FILLER_NORMAL ), PS_SOLID, 1, 0, rcCC.bottom, w2(), rcCC.bottom ); bool drawselected; for ( int pass = 0; pass < 2 ; pass++ ) { drawselected = pass == 0 ? false : true; int count = sentence.GetCloseCaptionPhraseCount( CC_ENGLISH ); for (int k = 0; k < count; k++) { CCloseCaptionPhrase *phrase = sentence.GetCloseCaptionPhrase( CC_ENGLISH, k ); if ( !phrase ) continue; if ( phrase->GetSelected() != drawselected ) continue; float t1 = phrase->GetStartTime(); float t2 = phrase->GetEndTime(); // Tag it float frac = ( t1 - starttime ) / ( endtime - starttime ); int xpos = ( int )( frac * rcWorkSpace.right ); //if ( frac <= 0.0 ) // xpos = 0; // Draw duration float frac2 = ( t2 - starttime ) / ( endtime - starttime ); if ( frac2 < 0.0 ) continue; int xpos2 = ( int )( frac2 * rcWorkSpace.right ); // Draw line and vertical ticks RECT rcPhrase; CloseCaption_GetPhraseRect( phrase, rcPhrase ); /* rcPhrase.left = xpos; rcPhrase.right = xpos2; rcPhrase.top = ypos; rcPhrase.bottom = ypos + m_nTickHeight - 1; */ drawHelper.DrawFilledRect( PEColor( phrase->GetSelected() ? COLOR_PHONEME_CC_TAG_SELECTED : COLOR_PHONEME_CC_TAG_FILLER_NORMAL ), rcPhrase ); COLORREF border = PEColor( phrase->GetSelected() ? COLOR_PHONEME_CC_TAG_BORDER_SELECTED : COLOR_PHONEME_CC_TAG_BORDER ); drawHelper.DrawOutlinedRect( border, PS_SOLID, 1, rcPhrase ); //if ( frac >= 0.0 && frac <= 1.0 ) { int fontsize = 9; RECT rcText; rcText.left = xpos; rcText.right = xpos2; rcText.top = rcCC.top; rcText.bottom = rcCC.bottom; int availw = xpos2 - xpos; int tokenCount = phrase->CountTokens(); if ( tokenCount >= 1 ) { int pixelsPerToken = availw / tokenCount; rcText.right = rcText.left + pixelsPerToken; for ( int i = 0; i < tokenCount; i++ ) { wchar_t const *token = phrase->GetToken( i ); if ( token && token[ 0 ] ) { int texw = drawHelper.CalcTextWidthW( fontName, fontsize, FW_NORMAL, L"%s", token ); RECT rcOutput = rcText; if ( texw < pixelsPerToken ) { rcOutput.left += ( pixelsPerToken - texw ) / 2; } if ( i != tokenCount - 1 ) { // Draw divider drawHelper.DrawColoredLine( border, PS_SOLID, 1, rcText.right, rcText.top + 5, rcText.right, rcText.bottom - 5 ); } drawHelper.DrawColoredTextW( fontName, fontsize, FW_NORMAL, PEColor( phrase->GetSelected() ? COLOR_PHONEME_CC_TAG_TEXT_SELECTED : COLOR_PHONEME_CC_TAG_TEXT ), rcOutput, L"%s", token ); } OffsetRect( &rcText, pixelsPerToken, 0 ); } } } } } RECT rcOutput; CloseCaption_GetCCAreaRect( rcOutput ); CloseCaption_DrawCCArea( drawHelper, rcOutput ); }
//----------------------------------------------------------------------------- // Purpose: Given a wavfile and a list of inwords, determines the word/phonene // sample counts for the sentce // Input : *wavfile - // *inwords - // *outphonemes{ text.Clear( - // Output : SR_RESULT //----------------------------------------------------------------------------- static SR_RESULT SAPI_ExtractPhonemes( const char *wavfile, int numsamples, void (*pfnPrint)( const char *fmt, ... ), CSentence& inwords, CSentence& outwords ) { LogReset(); USES_CONVERSION; CSpDynamicString text; text.Clear(); HKEY hkwipe; LONG lResult = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft\\Speech\\RecoProfiles", 0, KEY_ALL_ACCESS, &hkwipe ); if ( lResult == ERROR_SUCCESS ) { RecursiveRegDelKey( hkwipe ); RegCloseKey( hkwipe ); } if ( strlen( inwords.GetText() ) <= 0 ) { inwords.SetTextFromWords(); } // Construct a string from the inwords array text.Append( T2W( inwords.GetText() ) ); // Assume failure SR_RESULT result = SR_RESULT_ERROR; if ( text.Length() > 0 ) { CSentence sentence; pfnPrint( "Processing...\r\n" ); // Give it a try result = ExtractPhonemes( wavfile, text, sentence, pfnPrint ); pfnPrint( "Finished.\r\n" ); // PrintWordsAndPhonemes( sentence, pfnPrint ); // Copy results to outputs outwords.Reset(); outwords.SetText( inwords.GetText() ); Log( "Starting\n" ); LogWords( inwords ); if ( SR_RESULT_ERROR != result ) { int i; Log( "Hypothesized\n" ); LogWords( sentence ); for( i = 0 ; i < sentence.m_Words.Size(); i++ ) { CWordTag *tag = sentence.m_Words[ i ]; if ( tag ) { // Skip '...' tag if ( stricmp( tag->GetWord(), "..." ) ) { CWordTag *newTag = new CWordTag( *tag ); outwords.m_Words.AddToTail( newTag ); } } } // Now insert unrecognized/skipped words from original list // int frompos = 0, topos = 0; while( 1 ) { // End of source list if ( frompos >= inwords.m_Words.Size() ) break; const CWordTag *fromTag = inwords.m_Words[ frompos ]; // Reached end of destination list, just copy words over from from source list until // we run out of source words if ( topos >= outwords.m_Words.Size() ) { // Just copy words over CWordTag *newWord = new CWordTag( *fromTag ); // Remove phonemes while ( newWord->m_Phonemes.Size() > 0 ) { CPhonemeTag *kill = newWord->m_Phonemes[ 0 ]; newWord->m_Phonemes.Remove( 0 ); delete kill; } outwords.m_Words.AddToTail( newWord ); frompos++; topos++; continue; } // Destination word const CWordTag *toTag = outwords.m_Words[ topos ]; // Words match, just skip ahead if ( !stricmp( fromTag->GetWord(), toTag->GetWord() ) ) { frompos++; topos++; continue; } // The only case we handle is that something in the source wasn't in the destination // Find the next source word that appears in the destination int skipAhead = frompos + 1; bool found = false; while ( skipAhead < inwords.m_Words.Size() ) { const CWordTag *sourceWord = inwords.m_Words[ skipAhead ]; if ( !stricmp( sourceWord->GetWord(), toTag->GetWord() ) ) { found = true; break; } skipAhead++; } // Uh oh destination has words that are not in source, just skip to next destination word? if ( !found ) { topos++; } else { // Copy words from from source list into destination // int skipCount = skipAhead - frompos; while ( --skipCount>= 0 ) { const CWordTag *sourceWord = inwords.m_Words[ frompos++ ]; CWordTag *newWord = new CWordTag( *sourceWord ); // Remove phonemes while ( newWord->m_Phonemes.Size() > 0 ) { CPhonemeTag *kill = newWord->m_Phonemes[ 0 ]; newWord->m_Phonemes.Remove( 0 ); delete kill; } outwords.m_Words.InsertBefore( topos, newWord ); topos++; } frompos++; topos++; } } Log( "\nDone simple check\n" ); LogWords( outwords ); LogPhonemes( outwords ); ComputeMissingByteSpans( numsamples, outwords ); Log( "\nFinal check\n" ); LogWords( outwords ); LogPhonemes( outwords ); } } else { pfnPrint( "Input sentence is empty!\n" ); } // Return results return result; }