//----------------------------------------------------------------------------- // Purpose: Debugging, prints alternate list if one is created // Input : cpResult - // (*pfnPrint - //----------------------------------------------------------------------------- void PrintAlternates( ISpRecoResult* cpResult, void (*pfnPrint)( const char *fmt, ... ) ) { ISpPhraseAlt *rgPhraseAlt[ 32 ]; memset( rgPhraseAlt, 0, sizeof( rgPhraseAlt ) ); ULONG ulCount; ISpPhrase *phrase = ( ISpPhrase * )cpResult; if ( phrase ) { SPPHRASE *pElements; if ( SUCCEEDED( phrase->GetPhrase( &pElements ) ) ) { if ( pElements->Rule.ulCountOfElements > 0 ) { HRESULT hr = cpResult->GetAlternates( pElements->Rule.ulFirstElement, pElements->Rule.ulCountOfElements, 32, rgPhraseAlt, &ulCount); Assert( !FAILED( hr ) ); for ( ULONG r = 0 ; r < ulCount; r++ ) { CSpDynamicString dstrText; hr = rgPhraseAlt[ r ]->GetText( (ULONG)SP_GETWHOLEPHRASE, (ULONG)SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL); Assert( !FAILED( hr ) ); pfnPrint( "[ ALT ]" ); pfnPrint( dstrText.CopyToChar() ); pfnPrint( "\r\n" ); } } } } for ( int i = 0; i < 32; i++ ) { if ( rgPhraseAlt[ i ] ) { rgPhraseAlt[ i ]->Release(); rgPhraseAlt[ i ] = NULL; } } }
/***************************************************************************** * CPhraseReplacement::Initialize * *--------------------------------* * Description: * Gets the phrase from the ISpPhrase object and calls SetUpMaps(). * This initialization routine can be called either from a * client with a new CPhraseReplacement object or * when an alternate is committed (or the recoresult has * otherwise changed). * Return: * Return value of ISpRecoResult::GetPhrase() * Return value of CPhraseReplacement::SetUpMaps() *******************************************************************************/ HRESULT CPhraseReplacement::Initialize( ISpPhrase &rPhrase ) { // Get (or re-get) the phrase if ( m_pPhrase ) { ::CoTaskMemFree( m_pPhrase ); } HRESULT hr = rPhrase.GetPhrase( &m_pPhrase ); if ( FAILED( hr ) ) { return hr; } hr = SetUpMaps(); m_fSuccessfulSetup = SUCCEEDED( hr ); m_fUseMaps = (S_OK == hr); return hr; } /* CPhraseReplacement::Initialize */
//----------------------------------------------------------------------------- // 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); }