diff -r 8ce15fced3a6 -r cad71a31b7fc srsf/devtts/src/devttsalgorithmmanager.cpp --- a/srsf/devtts/src/devttsalgorithmmanager.cpp Thu Aug 19 09:56:14 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1235 +0,0 @@ -/* -* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Implementations for CTTSAlgorithmManager methods. -* -*/ - - -// INCLUDE FILES -#include -#include -#include -#include -#include -#include -#include "devttsalgorithmmanager.h" -#include "rubydebug.h" - -#ifdef _DEBUG -#include -#endif - -// CONSTANTS -_LIT( KResourceFileName, "nssdevtts.rsc" ); - -// Default audio priority -const TInt KDefaultPriority = KAudioPriorityVoiceDial; - -#ifdef DEVTTS_AUDIOBUFFER_TO_FILE -const TFileName KAudioBufferFileName( _L( "c:\\documents\\devttsaudio" ) ); -const TFileName KAudioBufferFileNameExtension( _L( ".raw" ) ); -#endif - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::CTTSAlgorithmManager -// C++ default constructor can NOT contain any code, that -// might leave. -// ----------------------------------------------------------------------------- -// -CTTSAlgorithmManager::CTTSAlgorithmManager( MDevTTSObserver& aObserver ): - iPaused( EFalse ), - iObserver( aObserver ), - iAudio( NULL ), - iAudioState( ETTSAudioPlayerNotInitialized ), - iHw( NULL ), - iError( KErrNone ), - iState( EDevTTSNotInitialized ), - iMode( EDevTTSSoundDeviceMode ), - iLastBufferFromTts( EFalse ), - iTtpHw( NULL ), -#ifdef DEVTTS_3DB_HACK - iApplyGain( ETrue ), -#endif - iNlp( NULL ), - iNlpInitialized( EFalse ) - { - // Nothing - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::ConstructL(/*CConsoleBase* console*/) - { - RUBY_DEBUG_BLOCK( "CTTSAlgorithmManager::ConstructL" ); - - TBool boolStereo( EFalse ); - TUint intStereo( 0 ); - TUint bitsPerSample( 16 ); - TUint samplingRate( 16000 ); - TUint bufferSize( 4096 ); - TInt defaultPriority( 0 ); - - // Try to find resource file first from MMC, then from C-drive and only - // after that from flash - // letters for drives in search order - const TBuf<2> KResourceDrives = _L("cz"); - - // load resources - RResourceFile resourceFile; - RFs fs; - User::LeaveIfError( fs.Connect() ); - CleanupClosePushL( fs ); - - TFileName name; - TInt i( 0 ); - // try to find from the first driver - name.Append( KResourceDrives[i] ); - name.Append( ':' ); - name.Append( KDC_RESOURCE_FILES_DIR ); - name.Append( KResourceFileName ); - - TBool found( EFalse ); - - while ( !found && i < KResourceDrives.Length() ) - { - name[0] = KResourceDrives[i++]; - - if ( BaflUtils::FileExists(fs, name) ) - { - // open resource - resourceFile.OpenL( fs, name ); - CleanupClosePushL( resourceFile ); - found = ETrue; - } - } - - if ( !found ) - { - User::Leave( KErrNotFound ); - } - - HBufC8* configurations = resourceFile.AllocReadLC( R_DEVTTS_CONFIGURATIONS ); - - TResourceReader resReader; - resReader.SetBuffer( configurations ); - - // Sampling rate - samplingRate = resReader.ReadUint32(); - - // Bits per sample - bitsPerSample = resReader.ReadUint32(); - - // Mono / Stereo - intStereo = resReader.ReadUint32(); - - // Buffer size - bufferSize = resReader.ReadUint32(); - -#ifdef __WINS__ - // CMMFDevSound uses currently buffer size of 16384 in emulator. - RUBY_DEBUG0( "CTTSAlgorithmManager::ConstructL - Hard coded buffer size in use!" ); - bufferSize = 16384; -#endif - - // Priority - defaultPriority = KDefaultPriority; - - if ( intStereo == 0 ) - { - boolStereo = EFalse; - } - else - { - boolStereo = ETrue; - } - - // Cleanup configurations, resourceFile, fs - CleanupStack::PopAndDestroy( configurations ); - CleanupStack::PopAndDestroy( &resourceFile ); - CleanupStack::PopAndDestroy( &fs ); - - // Create new TtsHwDevice instance - iHw = CTtsHwDevice::NewL( *this, samplingRate, bufferSize ); - - // Create audio playback instance - iAudio = CDevTTSAudio::NewL( *this, defaultPriority ); - - iState = EDevTTSStopped; - - // Start audio device initialization process - iAudio->InitializeL(); - - // Wait for callback only if it is asynchronous - // (state will be something else if it is synchronous) - if ( iAudioState == ETTSAudioPlayerNotInitialized ) - { - if ( !iAudioWait.IsStarted() ) - { - RUBY_DEBUG0( "CTTSAlgorithmManager::ConstructL iAudioWait.Start()" ); - iAudioWait.Start(); - } - } - - iAudio->ConfigL( samplingRate, bitsPerSample, boolStereo, bufferSize); - - // Create & initialize TtpHwDevice - iTtpHw = CASRSTtpHwDevice::NewL( *this ); - iTtpHw->InitializeL(); - iTtpHw->SetPhonemeNotationL( _L( "NIPA8" ) ); - - // Create NlpHwDevice - TRAPD( error, iNlp = CNlpHwDevice::NewL( *this ) ); - if ( error == KErrNone ) - { - iNlp->InitializeL(); - iNlpInitialized = ETrue; - } - else - { - iNlpInitialized = EFalse; - } - -#ifdef DEVTTS_AUDIOBUFFER_TO_FILE - User::LeaveIfError( iSession.Connect() ); - iFileOpen = EFalse; - iFileCounter = 0; -#endif - - RUBY_DEBUG1( "CTTSAlgorithmManager config, sampling rate: %d", samplingRate ); - RUBY_DEBUG1( "CTTSAlgorithmManager config, bits per sample: %d", bitsPerSample); - RUBY_DEBUG1( "CTTSAlgorithmManager config, mono/stereo: %d", intStereo); - RUBY_DEBUG1( "CTTSAlgorithmManager config, buffer size: %d", bufferSize); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -CTTSAlgorithmManager* CTTSAlgorithmManager::NewL( MDevTTSObserver& aObserver/*, CConsoleBase* console*/ ) - { - CTTSAlgorithmManager* self = new( ELeave ) CTTSAlgorithmManager(aObserver); - - CleanupStack::PushL( self ); - self->ConstructL( /*console*/ ); - CleanupStack::Pop( self ); - - return self; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::~CTTSAlgorithmManager -// Destructor. -// ----------------------------------------------------------------------------- -// -CTTSAlgorithmManager::~CTTSAlgorithmManager() - { - if ( iAudio ) - { - iAudio->Clear(); - delete iAudio; - iAudio = NULL; - } - if ( iHw ) - { - delete iHw; - iHw = NULL; - } - if ( iTtpHw ) - { - iTtpHw->Clear(); - delete iTtpHw; - iTtpHw = NULL; - } - if ( iNlp ) - { - iNlp->Clear(); - delete iNlp; - iNlp = NULL; - } -#ifdef DEVTTS_AUDIOBUFFER_TO_FILE - iSession.Close(); -#endif - } - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::AddStyleL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -TTtsStyleID CTTSAlgorithmManager::AddStyleL( const TTtsStyle& aStyle ) - { - return iHw->AddStyleL( aStyle ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::Balance -// Forwards call to the CDevTTSAudio. -// ----------------------------------------------------------------------------- -// -TInt CTTSAlgorithmManager::Balance() - { - return iAudio->Balance(); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::BufferProcessed -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::BufferProcessed( const TDesC8& aBuffer ) - { - // Client should call this only when buffers are provided to client - if ( iMode == EDevTTSClientMode ) - { - iHw->BufferProcessed( aBuffer ); - } - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::CustomInterface -// Not in use currently. Now returns NULL. -// ----------------------------------------------------------------------------- -// -TAny* CTTSAlgorithmManager::CustomInterface( TUid /*aInterfaceID*/ ) - { - return NULL; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::DeleteStyleL -// Forwards call to the actual implementation object. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::DeleteStyleL( TTtsStyleID aStyleID ) - { - iHw->DeleteStyleL( aStyleID ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::GetPositionL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::GetPositionL( TTimeIntervalMicroSeconds& aTime ) const - { - iHw->GetPositionL( aTime ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::GetPositionL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::GetPositionL( TTtsSegment& aSegment, TInt& aWordIndex ) const - { - iHw->GetPositionL( aSegment, aWordIndex ); - } - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::IsLanguageSupported -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -TBool CTTSAlgorithmManager::IsLanguageSupported( TLanguage aLanguage ) const - { - return iHw->IsLanguageSupported( aLanguage ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MaxVolume -// Forwards call to the CDevTTSAudio. -// ----------------------------------------------------------------------------- -// -TInt CTTSAlgorithmManager::MaxVolume() - { - return iAudio->MaxVolume(); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::NumberOfStyles -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -TUint16 CTTSAlgorithmManager::NumberOfStyles() const - { - return iHw->NumberOfStyles(); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::Pause -// Pauses synthesis process in TtsHwDevice and also audio playback if needed. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::Pause() - { - // Do nothing if not synthesizing currently - if ( iState != EDevTTSSynthesizing ) - { - return; - } - - // Stop synthesis and playback - iHw->Pause(); - - if( iMode == EDevTTSSoundDeviceMode ) - { - // Do a complete stop to the audio player instead of pause. - // Pausing and resuming after that leads to the situation where all of - // the data won't be played... - iAudio->Stop(); - iAudioState = ETTSAudioPlayerPaused; - } - - iState = EDevTTSPrimed; - iPaused = ETrue; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::PrimeSynthesisL -// Prepares a synthesizing process, data will be read from client using a -// stream. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::PrimeSynthesisL( MTtsSegmentStream& aStream ) - { - // Not yet in use, leave every time - // @todo: Remove this when functionality is available - User::Leave( KErrNotSupported ); - - // Do the state check - if ( iState == EDevTTSNotInitialized ) - { - User::Leave( KErrNotReady ); - } - - if ( iState != EDevTTSStopped ) - { - User::Leave( KErrInUse ); - } - - iHw->PrimeSynthesisL( aStream ); - - iState = EDevTTSPrimed; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::PrimeSynthesisL -// Prepares a synthesizing process. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::PrimeSynthesisL( CTtsParsedText& aText ) - { - RUBY_DEBUG_BLOCK( "CTTSAlgorithmManager::PrimeSynthesisL" ); - - // Do the state check - - if ( iState == EDevTTSNotInitialized ) - { - User::Leave( KErrNotReady ); - } - - if (iState != EDevTTSStopped) - { - User::Leave( KErrInUse ); - } - - // 1. Analyze structure if no segments in the parsed text object - if ( aText.NumberOfSegments() == 0 ) - { - iHw->AnalyzeStructureL( aText ); - } - - // 2. Call NLP if there is written text - if ( ( aText.Text() != KNullDesC16 ) && iNlpInitialized ) - { - - TBool useNlp( ETrue ); - TInt counter( 0 ); - - // Loop through content types of segments to find out if NLP should be used - for ( counter = 0; counter < aText.NumberOfSegments(); counter++ ) - { - TTtsSegment segment = aText.SegmentL( counter ); - TTtsStyleID styleID = segment.StyleID(); - TTtsStyle& style = StyleL( styleID ); - - if ( !style.iNlp ) - { - useNlp = EFalse; - } - } - - if ( useNlp ) - { - // If language is not specified, run LID before NLP - for ( counter = 0; counter < aText.NumberOfSegments(); counter++ ) - { - TTtsSegment segment = aText.SegmentL( counter ); - TTtsStyleID styleID = segment.StyleID(); - TTtsStyle& style = StyleL( styleID ); - - if ( style.iLanguage == ELangOther ) - { - RArray languages; - RArray scores; - - // Only one result is needed - iTtpHw->LanguageIdentificationL( segment.TextPtr(), 1, languages, scores ); - - if ( languages.Count() == 0 ) - { - languages.Close(); - scores.Close(); - User::Leave( KErrGeneral ); - } - - style.iLanguage = languages[0]; - - RUBY_DEBUG1( "CTTSAlgorithmManager::PrimeSynthesisL called LID [lang id: %d] before NLP", style.iLanguage ); - - languages.Close(); - scores.Close(); - } - } - } - - if ( useNlp ) - { - iNlp->NormalizeTextL( aText ); - } - } - - // Set the phoneme notation which is given within parsed text into TTP - // Do this only if no phonemesequence is given and if notation is something - // else than the default - if ( ( aText.PhonemeNotation() != KNullDesC16 ) && ( aText.PhonemeSequence() == KNullDesC8 ) ) - { - iTtpHw->SetPhonemeNotationL( aText.PhonemeNotation() ); - } - - // 3. Do the TTP if phoneme sequence not available - if ( aText.PhonemeSequence() == KNullDesC8 ) - { - // If also text is NULL, argument is not ok - if ( aText.Text() == KNullDesC16 ) - { - User::Leave( KErrArgument ); - } - -#ifdef __SIND_MULTIPLE_SEGMENTS - RArray segmentPhonemeLengths; - CleanupClosePushL(segmentPhonemeLengths); -#endif // __SIND_MULTIPLE_SEGMENTS - // Find the style attached to each segment - for ( TInt i = 0; i < aText.NumberOfSegments(); i++ ) - { - TTtsSegment segment = aText.SegmentL( i ); - TTtsStyleID styleID = segment.StyleID(); - TTtsStyle& style = StyleL( styleID ); - - RUBY_DEBUG1( "CTTSAlgorithmManager::PrimeSynthesisL calling TTP with lang id [%d]", style.iLanguage ); - - HBufC8* phonemeBuffer = iTtpHw->ConvertTextL( segment.TextPtr(), style.iLanguage ); - - if ( phonemeBuffer == NULL ) - { - RUBY_DEBUG0( "CTTSAlgorithmManager::PrimeSynthesisL TTP returned NULL, calling again with ELangOther" ); - - // Try with another approach, use ELangOther as language and let - // the LID to do the job - if ( style.iLanguage != ELangOther ) - { - style.iLanguage = ELangOther; - phonemeBuffer = iTtpHw->ConvertTextL( segment.TextPtr(), style.iLanguage ); - RUBY_DEBUG1( "CTTSAlgorithmManager::PrimeSynthesisL LID returned lang id [%d]", style.iLanguage ); - if ( phonemeBuffer == NULL ) - { - User::Leave( KErrGeneral ); - } - } - else - { - User::Leave( KErrGeneral ); - } - } - - CleanupStack::PushL( phonemeBuffer ); - -#ifdef __SIND_MULTIPLE_SEGMENTS - // Append segment's phone sequence to CTtsparsedText's phoneme sequence - HBufC8* phonemeSeq = HBufC8::NewLC( aText.PhonemeSequence().Length() + phonemeBuffer->Des().Length() ); - phonemeSeq->Des().Append( aText.PhonemeSequence() ); - phonemeSeq->Des().Append( phonemeBuffer->Des() ); - // Set new phoneme sequence - aText.SetPhonemeSequenceL( *phonemeSeq ); - CleanupStack::PopAndDestroy( phonemeSeq ); - - // Save the length of segment's phoneme sequence - segmentPhonemeLengths.AppendL( phonemeBuffer->Des().Length() ); - -#else - aText.SetPhonemeSequenceL( phonemeBuffer->Des() ); - - segment.SetPhonemeSequencePtr( aText.PhonemeSequence() ); - // Add modified segment to parsed text - aText.DeleteSegmentL( i ); - aText.AddSegmentL( segment, i ); -#endif // __SIND_MULTIPLE_SEGMENTS - - // phonemeBuffer - CleanupStack::PopAndDestroy( phonemeBuffer ); - } - -#ifdef __SIND_MULTIPLE_SEGMENTS - // Put pointers of the whole phone sequence in CTtsParsedText - // to their respective segments - TInt position( 0 ); - for ( TInt i = 0; i < aText.NumberOfSegments(); i++ ) - { - TTtsSegment segment = aText.SegmentL( i ); - segment.SetPhonemeSequencePtr( aText.PhonemeSequence().Mid( position, segmentPhonemeLengths[i] ) ); - // Add modified segment to parsed text - aText.DeleteSegmentL( i ); - aText.AddSegmentL( segment, i ); - // Move the position to next segments starting position - position += segmentPhonemeLengths[i]; - } - - // Release resources allocated by RArray - CleanupStack::PopAndDestroy( &segmentPhonemeLengths ); -#endif // __SIND_MULTIPLE_SEGMENTS - - } - -#ifdef DEVTTS_3DB_HACK - iApplyGain = ETrue; -#endif - - - // 4. Analyze prosody - iHw->AnalyzeProsodyL( aText ); - - // 5. Prime TtsHwDevice - iHw->PrimeSynthesisL( aText ); - - iState = EDevTTSPrimed; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetAudioPriority -// Forwards call to the CDevTTSAudio -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetAudioPriority( TInt aPriority, TDevTTSAudioPreference aPref ) - { - iAudio->SetAudioPriority( aPriority, aPref ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetAudioOutputL -// Forwards call to the CDevTTSAudio -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetAudioOutputL( TInt aAudioOutput ) - { - iAudio->SetAudioOutputL( aAudioOutput ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetBalance -// Forwards call to the CDevTTSAudio -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetBalance( TInt aBalance ) - { - iAudio->SetBalance( aBalance ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetPositionL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetPositionL( const TTimeIntervalMicroSeconds& aTime ) - { - iHw->SetPositionL( aTime ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetPositionL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetPositionL( const TTtsSegment& aSegment, - TInt aWordIndex ) - { - iHw->SetPositionL( aSegment, aWordIndex ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetVolume -// Forwards call to the CDevTTSAudio -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetVolume( TInt aVolume ) - { - iAudio->SetVolume( aVolume ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SetVolumeRamp -// Forwards call to the CDevTTSAudio -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SetVolumeRamp( const TTimeIntervalMicroSeconds& aRampDuration ) - { - iAudio->SetVolumeRamp( aRampDuration ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::Stop -// Stop synthesis process as well as audio playback if running. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::Stop() - { - if ( iState == EDevTTSNotInitialized ) - { - // Just to play it safe, do nothing if not initialized - return; - } - - if ( iAudioState == ETTSAudioPlayerPlaying ) - { - iAudio->Stop(); - iAudioState = ETTSAudioPlayerIdle; - } - if ( iState == EDevTTSSynthesizing || iState == EDevTTSPrimed ) - { - iHw->Stop(); - } - - iState = EDevTTSStopped; - - // Clear paused flag. might be that we are stopping after pausing - iPaused = EFalse; - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::StyleL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -TTtsStyle& CTTSAlgorithmManager::StyleL( TTtsStyleID aStyleID ) const - { - return iHw->StyleL( aStyleID ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::StyleL -// Forwards call to TtsHwDevice -// ----------------------------------------------------------------------------- -// -TTtsStyle& CTTSAlgorithmManager::StyleL( TUint16 aIndex ) const - { - return iHw->StyleL( aIndex ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::SynthesizeL -// Starts or resumes synthesis process. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::SynthesizeL( TDevTTSOutputMode aOutputMode ) - { - - if ( (iState == EDevTTSNotInitialized) || (iState == EDevTTSStopped) ) - { - User::Leave( KErrNotReady ); - } - - if ( iState != EDevTTSPrimed ) - { - User::Leave( KErrInUse ); - } - - // If iPaused flag is set, we know that there is an - // ongoing synthesis process and we should resume that instead of starting - // a new one. - if ( iPaused ) - { - // Resume synthesis by calling hwdevice - iHw->SynthesizeL(); - - if ( iMode == EDevTTSSoundDeviceMode ) - { - iAudio->PlayInitL(); - - iAudioState = ETTSAudioPlayerPlaying; - } - iState = EDevTTSSynthesizing; - iPaused = EFalse; - return; - } - - iMode = aOutputMode; - - // Start synthesizing by calling hwdevice - iHw->SynthesizeL(); - iLastBufferFromTts = EFalse; - - if ( iMode == EDevTTSSoundDeviceMode ) - { - // Check the audio player state - if ( iAudioState == ETTSAudioPlayerNotInitialized || - iAudioState == ETTSAudioPlayerError ) - { - User::Leave( KErrNotReady ); - } - - if ( iAudioState == ETTSAudioPlayerPlaying ) - { - User::Leave( KErrInUse ); - } - - // Initialize audio device so that it is ready for playback - iAudio->PlayInitL(); - - iAudioState = ETTSAudioPlayerPlaying; - } - - iState = EDevTTSSynthesizing; - - RUBY_DEBUG0( "CTTSAlgorithmManager::SynthesizeL started" ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::Volume -// Forwards call to the CDevTTSAudio. -// ----------------------------------------------------------------------------- -// -TInt CTTSAlgorithmManager::Volume() - { - return iAudio->Volume(); - } - - -// ========================== CALLBACKS FROM DEVTTSAUDIO ======================= - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::InitializeComplete -// Audio has been initialized. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MdtaoInitializeComplete(TInt aError) - { - if ( aError == KErrNone ) - { - iAudioState = ETTSAudioPlayerIdle; - RUBY_DEBUG0( "CTTSAlgorithmManager::InitializeComplete ok" ); - } - else - { - iAudioState = ETTSAudioPlayerError; - RUBY_DEBUG0( "CTTSAlgorithmManager::InitializeComplete ERROR" ); - } - - if ( iAudioWait.IsStarted() ) - { - RUBY_DEBUG0( "DEVTTS iAudioWait.AsyncStop()" ); - iAudioWait.AsyncStop(); - } - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MdtaoBufferToBeFilled -// Audio player wants a new buffer so that it can be played. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MdtaoBufferToBeFilled( TDes8& aBuffer, - TInt aSizeRequested ) - { - RUBY_DEBUG1( "CTTSAlgorithmManager::MdtaoBufferToBeFilled size of wanted audio buffer: %d bytes", aSizeRequested ); - - // Sometimes it might happen that we get still one callback even though - // DevSound is not anymore playing - if ( iAudioState != ETTSAudioPlayerPlaying ) - { - RUBY_DEBUG0( "CTTSAlgorithmManager::MdtaoBufferToBeFilled called even though iAudioState != ETTSAudioPlayerPlaying" ); - return; - } - - const TUint8* buffer = iPlaybackBuffer.Ptr(); - - if ( iStartPoint >= iStopPoint ) - { - // Underflow, nothing to be sent to audio out - aBuffer.FillZ( aSizeRequested ); - aBuffer.SetLength( aSizeRequested ); - - iAudio->PlayData( iLastBufferFromTts ); - return; - } - - TInt copyLength = 0; - // Tells if the whole buffer given by TtsHwDevice has been played - TBool last = EFalse; - - if ( ( iStartPoint + aSizeRequested ) >= iStopPoint ) - { - // We get to the end of the data that needs to be played - last = ETrue; - copyLength = iStopPoint - iStartPoint + 1; - - // Empty buffer - aBuffer.FillZ(); - } - else - { - // Fill the whole requested size - copyLength = aSizeRequested; - } - - // Copy data to audio out buffer - aBuffer.Copy( &buffer[iStartPoint], copyLength); - -#ifdef DEVTTS_3DB_HACK - if( iApplyGain ) - { - const TInt32 KSqrt2FXP = 0x00002d41L; - const TInt32 KSqrt2Shift = 13; - TPtr16 audioData((TUint16*)(aBuffer.Ptr()), copyLength/2, copyLength/2); - for( int i=0; i> KSqrt2Shift; - if(newvalue > 0x7fffL | newvalue < -0x8000L) - { - - iApplyGain = EFalse; - break; - } - audioData[i] = newvalue; - } - } -#endif - - // Notify TtsHwDevice - if ( last ) - { - iHw->BufferProcessed( iPlaybackBuffer ); - } - - RUBY_DEBUG1( "CTTSAlgorithmManager::MdtaoBufferToBeFilled Audio buffer size filled: %d bytes\n", aBuffer.Length() ); - - iStartPoint = iStartPoint + copyLength; - - iAudio->PlayData( iLastBufferFromTts ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::PlayFinished -// Checks the incoming error code and sets the audio state accordingly. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MdtaoPlayFinished( TInt aError ) - { - iAudioState = ETTSAudioPlayerIdle; - - if ( aError == KErrNone ) - { - // Don't put error code to aError since MthdTtsCompleted can - // be called with error code before this function is called - RUBY_DEBUG0( "CTTSAlgorithmManager::MdtaoPlayFinished ok" ); - } - else - { - // Audio is interrupted by something with higher priority. - // Keep idle state for audio player since application might - // try again with better luck. (When there is no other apps trying - // to access audio out.) - iError = aError; - - // Stop TTS Hw device too - iHw->Stop(); - - RUBY_DEBUG0( "CTTSAlgorithmManager::MdtaoPlayFinished audio interrupted" ); - } - - // Move automatically to stopped state - iState = EDevTTSStopped; - - // Call the client - iObserver.MdtoEvent( EDevTTSEventComplete, iError ); - } - - - -// ========================== CALLBACKS FROM TtsHwDevice ======================= - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MthdTtsCompleted -// Called by TtsHwDevice when synthesis has completed -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MthdTtsCompleted( TInt aStatus ) - { - iState = EDevTTSStopped; - - // Mark that previous received buffer is the last one - iLastBufferFromTts = ETrue; - - iError = aStatus; - - // Do the callback to client, handled by MdtaoPlayFinished if in sound device mode - if ( iMode == EDevTTSClientMode ) - { - iObserver.MdtoEvent( EDevTTSEventComplete, aStatus ); - } - -#ifdef DEVTTS_AUDIOBUFFER_TO_FILE - iFile.Close(); - iFileOpen = EFalse; -#endif - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MthdCustomEvent -// Custom event from TtsHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MthdCustomEvent( TInt /*aEvent*/, TInt /*aStatus*/, - const TDesC8& /*aParameter*/ ) - { - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MthdProcessBuffer -// Prepares buffer for playback or forwards callback to client, depends on the -// operation mode. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MthdProcessBuffer( const TDesC8& aBuffer ) - { - RUBY_DEBUG0( "CTTSAlgorithmManager::MthdProcessBuffer" ); - -#ifdef DEVTTS_AUDIOBUFFER_TO_FILE - if ( iFileOpen == EFalse ) - { - TFileName filename; - filename.Append( KAudioBufferFileName ); - filename.AppendNum( iFileCounter ); - filename.Append( KAudioBufferFileNameExtension ); - - iFile.Replace( iSession, filename, EFileWrite ); - iFileOpen = ETrue; - iFileCounter++; - } - TInt size( 0 ); - iFile.Size( size ); - iFile.Seek( ESeekEnd, size ); - iFile.Write( aBuffer ); -#endif - - // Handle buffer internally if in sound device mode, otherwise just - // forward the callback to client - if ( iMode == EDevTTSSoundDeviceMode ) - { - // Store pointer to buffer - iPlaybackBuffer.Set( aBuffer ); - // Mark start and stop points for the audio playback - iStartPoint = 0; - iStopPoint = aBuffer.Size() - 1; - } - else - { - iObserver.MdtoProcessBuffer( aBuffer ); - } - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MthdoConfigurationData -// Forwards callback to client. -// ----------------------------------------------------------------------------- -// -HBufC8* CTTSAlgorithmManager::MthdoConfigurationData( TUint32 aPackageType, - TUint32 aPackageID, - TUint32 aStartPosition, - TUint32 aEndPosition ) - { - return iObserver.MdtoConfigurationData( aPackageType, aPackageID, - aStartPosition, aEndPosition ); - } - - -// ====================== CALLBACKS FROM MASRSTtpHwDeviceObserver ============== - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MathdoConfigurationData -// Forwards callback to client. -// ----------------------------------------------------------------------------- -// -HBufC8* CTTSAlgorithmManager::MathdoConfigurationData( TUint32 aPackageType, - TUint32 aPackageID, - TUint32 aStartPosition, - TUint32 aEndPosition ) - { - return iObserver.MdtoConfigurationData( aPackageType, aPackageID, - aStartPosition, aEndPosition ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MathdoWordListReady -// Should not be called since we always use synchrnous TTP. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MathdoWordListReady( const TInt /*aError*/ ) - { - // Do nothing - } - - - -// ====================== CALLBACKS FROM MNlpHwDeviceObserver ================== - - -// ----------------------------------------------------------------------------- -// MNlpHwDeviceObserver::MnhdNlpCompleted -// Called when asynchronous NLP processing has been completed -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::MnhdoNlpCompleted( TInt /*aStatus*/ ) - { - // Should not be called currently since NLP is handled synchronously - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MnhdoConfigurationData -// NLP calls when it needs its configuration data to be loaded -// ----------------------------------------------------------------------------- -// -HBufC8* CTTSAlgorithmManager::MnhdoConfigurationData( TUint32 aPackageType, - TUint32 aPackageID, - TUint32 aStartPosition, - TUint32 aEndPosition ) - { - return iObserver.MdtoConfigurationData( aPackageType, aPackageID, - aStartPosition, aEndPosition ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::MnhdoStyleL -// Called when NLP needs style information -// ----------------------------------------------------------------------------- -// -const TTtsStyle& CTTSAlgorithmManager::MnhdoStyleL( TTtsStyleID styleID ) - { - // Call TtsHwDevice to get the wanted style - return iHw->StyleL( styleID ); - } - - -// ====================== New additions for SIND inc3 ========================== - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::LanguageIdentificationL -// Does language identification. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::LanguageIdentificationL( CTtsParsedText& aText, - TInt aNumberOfGuesses, - RArray& aLanguages, - RArray& aScores ) - { - CheckStateL(); - - // Check that at least some text is given - if ( aText.Text() == KNullDesC16 ) - { - User::Leave( KErrArgument); - } - - // Call TtpHwDevice - iTtpHw->LanguageIdentificationL( aText.Text(), aNumberOfGuesses, aLanguages, aScores ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::NormalizeTextL -// Normalizes text using NLPHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::NormalizeTextL( CTtsParsedText& aText ) - { - if ( iNlp == NULL || !iNlpInitialized ) - { - User::Leave( KErrNotSupported ); - } - - CheckStateL(); - - iNlp->NormalizeTextL( aText ); - } - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::NormalizeAndSegmentTextL -// Normalizes and segments the text using NLPHwDevice -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::NormalizeAndSegmentTextL( CTtsParsedText& aText ) - { - if ( iNlp == NULL || !iNlpInitialized ) - { - User::Leave( KErrNotSupported ); - } - - CheckStateL(); - - iNlp->NormalizeAndSegmentTextL( aText ); - } - - -// ========================== PRIVATE FUNCTIONS ================================ - - -// ----------------------------------------------------------------------------- -// CTTSAlgorithmManager::CheckStateL -// Checks that state of DevTTS is idle. -// ----------------------------------------------------------------------------- -// -void CTTSAlgorithmManager::CheckStateL() - { - if ( iState == EDevTTSNotInitialized ) - { - User::Leave( KErrNotReady ); - } - - if ( iState != EDevTTSStopped ) - { - User::Leave( KErrInUse ); - } - } - - -// End of File