Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Speech / Src / Internal / Synthesis / TTSEngineProxy.cs / 1 / TTSEngineProxy.cs
//------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Contains either a reference to an audio audioStream or a list of
// text fragments.
//
// History:
// 2/1/2005 jeanfp Created from the Sapi Managed code
//-----------------------------------------------------------------
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Speech.Internal.ObjectTokens;
using System.Speech.Synthesis.TtsEngine;
using System.Text;
using System.Threading;
namespace System.Speech.Internal.Synthesis
{
abstract class ITtsEngineProxy
{
internal ITtsEngineProxy (int lcid)
{
_alphabetConverter = new AlphabetConverter (lcid);
}
abstract internal IntPtr GetOutputFormat (IntPtr targetFormat);
abstract internal void AddLexicon (Uri lexicon, string mediaType);
abstract internal void RemoveLexicon (Uri lexicon);
abstract internal void Speak (List frags, byte [] wfx);
abstract internal void ReleaseInterface ();
abstract internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet);
abstract internal AlphabetType EngineAlphabet { get; }
internal AlphabetConverter AlphabetConverter { get { return _alphabetConverter; } }
#if SPEECHSERVER || PROMPT_ENGINE
abstract internal void BackupVoice (IPromptEngine pe);
#endif
protected AlphabetConverter _alphabetConverter;
}
internal class TtsProxySsml : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//*******************************************************************
#region Constructors
internal TtsProxySsml (TtsEngineSsml ssmlEngine, ITtsEngineSite site, int lcid)
: base (lcid)
{
_ssmlEngine = ssmlEngine;
_site = site;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr targetFormat)
{
return _ssmlEngine.GetOutputFormat (SpeakOutputFormat.WaveFormat, targetFormat);
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
_ssmlEngine.AddLexicon (lexicon, mediaType, _site);
}
override internal void RemoveLexicon (Uri lexicon)
{
_ssmlEngine.RemoveLexicon (lexicon, _site);
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
_ssmlEngine.Speak (frags.ToArray (), waveFormat, _site);
}
finally
{
gc.Free ();
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return phones;
}
else
{
return _alphabetConverter.SapiToIpa (phones);
}
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Ipa;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice ((ITtsEngineSsml) new ProxyComSsml (_ssmlEngine, _site));
}
///
/// Maps the ITtsEngineSsml interface to the sapi ITtsEngine interface
///
class ProxyComSsml : ITtsEngineSsml
{
internal ProxyComSsml (TtsEngineSsml sapiEngine, ITtsEngineSite site)
{
_ssmlEngine = sapiEngine;
_site = site;
}
#region ITtsEngineSsml implementation
void ITtsEngineSsml.GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
waveHeader = _ssmlEngine.GetOutputFormat (speakOutputFormat, targetWaveFormat);
}
///
/// Add a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// media type
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.AddLexicon (string location, string mediaType, IntPtr site)
{
_ssmlEngine.AddLexicon (new Uri (location, UriKind.RelativeOrAbsolute), mediaType, _site);
}
///
/// Removes a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.RemoveLexicon (string location, IntPtr site)
{
_ssmlEngine.RemoveLexicon (new Uri (location, UriKind.RelativeOrAbsolute), _site);
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
/// Text fragment with SSML
/// attributes information
/// Number of elements in fragment
/// Wave format header
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.Speak (IntPtr fragments, int count, IntPtr waveFormat, IntPtr site)
{
TextFragment [] textFragments = Converter.PtrToFragments (fragments, count);
_ssmlEngine.Speak (textFragments, waveFormat, _site);
}
private TtsEngineSsml _ssmlEngine;
private ITtsEngineSite _site;
#endregion
}
#endif
#endregion
//********************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private TtsEngineSsml _ssmlEngine;
private ITtsEngineSite _site;
#endregion
}
///
///
///
internal class TtsProxyCom : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//********************************************************************
#region Constructors
internal TtsProxyCom (ITtsEngineSsml comEngine, IntPtr iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
_comEngine = comEngine;
}
#endregion
//*******************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr targetFormat)
{
IntPtr waveFormatEx;
_comEngine.GetOutputFormat (targetFormat != IntPtr.Zero ? SpeakOutputFormat.WaveFormat : SpeakOutputFormat.Text, targetFormat, out waveFormatEx);
return waveFormatEx;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
_comEngine.AddLexicon (lexicon.ToString (), mediaType, _iSite);
}
override internal void RemoveLexicon (Uri lexicon)
{
_comEngine.RemoveLexicon (lexicon.ToString (), _iSite);
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
// Marshal all the Text fragments data into unmanaged memory
Collection memoryBlocksAllocated = new Collection ();
// Keep the list of all the memory blocks allocated by Marshal.CoTaskMemAlloc
IntPtr fragmentInterop = TextFragmentInterop.FragmentToPtr (frags, memoryBlocksAllocated);
try
{
_comEngine.Speak (fragmentInterop, frags.Count, waveFormat, _iSite);
}
finally
{
// Release all the allocated memory
foreach (IntPtr ptr in memoryBlocksAllocated)
{
Marshal.FreeCoTaskMem (ptr);
}
}
}
finally
{
gc.Free ();
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
Marshal.ReleaseComObject (_comEngine);
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Ipa;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return phones;
}
else
{
return _alphabetConverter.SapiToIpa (phones);
}
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice (_comEngine);
}
#endif
#endregion
//*******************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private ITtsEngineSsml _comEngine;
// This variable is stored here but never created or deleted
private IntPtr _iSite;
#endregion
}
///
///
///
internal class TtsProxySapi : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//********************************************************************
#region Constructors
internal TtsProxySapi (ITtsEngine sapiEngine, IntPtr iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
_sapiEngine = sapiEngine;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr preferedFormat)
{
// Initialize TTS Engine
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
Guid guidNull = new Guid ();
IntPtr coMem = IntPtr.Zero;
_sapiEngine.GetOutputFormat (ref formatId, preferedFormat, out guidNull, out coMem);
return coMem;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
// SAPI: Ignore
}
override internal void RemoveLexicon (Uri lexicon)
{
// SAPI: Ignore
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
GCHandle spvTextFragment = new GCHandle ();
if (ConvertTextFrag.ToSapi (frags, ref spvTextFragment))
{
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
try
{
_sapiEngine.Speak (0, ref formatId, waveFormat, spvTextFragment.AddrOfPinnedObject (), _iSite);
}
finally
{
ConvertTextFrag.FreeTextSegment (ref spvTextFragment);
}
}
}
finally
{
gc.Free ();
}
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Sapi;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return _alphabetConverter.IpaToSapi (phones);
}
else
{
return phones;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
Marshal.ReleaseComObject (_sapiEngine);
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
ITtsEngineSsml proxy = (ITtsEngineSsml) new ProxyComSapi (_sapiEngine);
pe.SetBackupVoice (proxy);
}
#endif
#endregion
//********************************************************************
//
// Private Fields
//
//*******************************************************************
#region private Fields
private ITtsEngine _sapiEngine;
// This variable is stored here but never created or deleted
private IntPtr _iSite;
#endregion
#if SPEECHSERVER || PROMPT_ENGINE
///
/// Maps the ITtsEngineSsml interface to the sapi ITtsEngine interface
///
class ProxyComSapi : ITtsEngineSsml
{
internal ProxyComSapi (ITtsEngine sapiEngine)
{
_sapiEngine = sapiEngine;
}
#region ITtsEngineSsml implementation
void ITtsEngineSsml.GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
// Initialize TTS Engine
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
Guid guidNull = new Guid ();
IntPtr coMem = IntPtr.Zero;
_sapiEngine.GetOutputFormat (ref formatId, targetWaveFormat, out guidNull, out coMem);
waveHeader = coMem;
}
///
/// Add a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// media type
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.AddLexicon (string location, string mediaType, IntPtr site)
{
}
///
/// Removes a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.RemoveLexicon (string location, IntPtr site)
{
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
/// Text fragment with SSML
/// attributes information
/// Number of elements in fragment
/// Wave format header
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.Speak (IntPtr fragments, int count, IntPtr waveFormat, IntPtr site)
{
GCHandle spvTextFragment = new GCHandle ();
TextFragment [] textFragments = Converter.PtrToFragments (fragments, count);
ConvertTextFrag.ToSapi (new List (textFragments), ref spvTextFragment);
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
try
{
_sapiEngine.Speak (0, ref formatId, waveFormat, spvTextFragment.AddrOfPinnedObject (), site);
}
finally
{
ConvertTextFrag.FreeTextSegment (ref spvTextFragment);
}
}
#endregion
private ITtsEngine _sapiEngine;
}
#endif
}
#if SPEECHSERVER || PROMPT_ENGINE
///
///
///
internal class TextEngine : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//*******************************************************************
#region Constructors
internal TextEngine (ITtsEngineSite iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr preferedFormat)
{
return IntPtr.Zero;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
// Ignore
}
override internal void RemoveLexicon (Uri lexicon)
{
// Ignore
}
override internal void Speak (List frags, byte [] wfx)
{
TextEngineSsml.WriteTextFragments (_iSite, frags);
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Sapi;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return _alphabetConverter.IpaToSapi (phones);
}
else
{
return phones;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
}
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice (new TextEngineSsml (_iSite));
}
#endregion
//********************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private ITtsEngineSite _iSite;
#endregion
//*******************************************************************
//
// Private Types
//
//********************************************************************
#region private Types
class TextEngineSsml : ITtsEngineSsml
{
internal TextEngineSsml (ITtsEngineSite iSite)
{
_iSite = iSite;
}
///
/// Queries the engine about a specific output format.
/// The engine should examine the requested output format,
/// and return the closest format that it supports.
///
public void GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
WAVEFORMATEX waveFormatEx = WAVEFORMATEX.Default;
byte [] abHeader = waveFormatEx.ToBytes ();
waveHeader = Marshal.AllocCoTaskMem (abHeader.Length);
Marshal.Copy (abHeader, 0, waveHeader, abHeader.Length);
}
///
/// Add a lexicon to the engine collection of lexicons
///
public void AddLexicon (string location, string mediaType, IntPtr site)
{
}
///
/// Removes a lexicon to the engine collection of lexicons
///
public void RemoveLexicon (string location, IntPtr site)
{
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
public void Speak (IntPtr fragments, int count, IntPtr waveHeader, IntPtr site)
{
WriteTextFragments (_iSite, new List (Converter.PtrToFragments (fragments, count)));
}
public static void WriteTextFragments (ITtsEngineSite iSite, List frags)
{
foreach (TextFragment frag in frags)
{
if (frag.State.Action == TtsEngineAction.Speak)
{
string s = "0:TTS:" + frag.TextToSpeak + "\0";
GCHandle gc = GCHandle.Alloc (s, GCHandleType.Pinned);
try
{
iSite.Write (gc.AddrOfPinnedObject (), (frag.TextLength + 7) * 2);
}
finally
{
gc.Free ();
}
}
}
}
private ITtsEngineSite _iSite;
}
#endregion
}
#endif
#if SPEECHSERVER || PROMPT_ENGINE
class Converter
{
internal static TextFragment [] PtrToFragments (IntPtr fragments, int count)
{
TextFragment [] textFragments = new TextFragment [count];
TextFragmentInterop fragInterop = new TextFragmentInterop ();
int sizeOfFrag = Marshal.SizeOf (fragInterop);
for (int i = 0; i < count; i++)
{
Marshal.PtrToStructure ((IntPtr) ((ulong) fragments + (ulong) (i * sizeOfFrag)), fragInterop);
textFragments [i] = new TextFragment ();
if (fragInterop._textToSpeak != null && fragInterop._textToSpeak.Length > 0)
textFragments [i].TextToSpeak = fragInterop._textToSpeak;
textFragments [i].TextOffset = fragInterop._textOffset;
textFragments [i].TextLength = fragInterop._textLength;
textFragments [i].State = fragInterop._state.PtrToFragmentState ();
}
return textFragments;
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class TextFragmentInterop
{
internal FragmentStateInterop _state;
[MarshalAs (UnmanagedType.LPWStr)]
internal string _textToSpeak;
internal int _textOffset;
internal int _textLength;
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class FragmentStateInterop
{
internal TtsEngineAction _action;
internal int _langId;
internal int _emphasis;
internal int _duration;
internal IntPtr _sayAs;
internal IntPtr _prosody;
internal IntPtr _phoneme;
FragmentStateInterop () { _action = TtsEngineAction.BeginPromptEngineOutput; _langId = _emphasis = _duration = 0; _sayAs = _phoneme = _prosody = IntPtr.Zero; }
internal FragmentState PtrToFragmentState ()
{
FragmentState fragmentState = new FragmentState ();
fragmentState.Action = _action;
fragmentState.LangId = _langId;
fragmentState.Emphasis = _emphasis;
fragmentState.Duration = _duration;
if (_sayAs != IntPtr.Zero)
{
fragmentState.SayAs = new SayAs ();
Marshal.PtrToStructure (_sayAs, fragmentState.SayAs);
}
if (_phoneme != IntPtr.Zero)
{
StringBuilder phones = new StringBuilder ();
int i = 0;
char phone = ' ';
do
{
Marshal.WriteInt16 (new IntPtr ((long) _phoneme + i * 2), phone);
phones.Append (unchecked ((char) phone));
}
while (phones [i++] != 0);
fragmentState.Phoneme = phones.ToString().ToCharArray ();
}
if (_prosody != IntPtr.Zero)
{
ProsodyInterop prosodyInterop = new ProsodyInterop ();
Marshal.PtrToStructure (_prosody, prosodyInterop);
fragmentState.Prosody = prosodyInterop.PtrToProsody ();
}
return fragmentState;
}
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class ProsodyInterop
{
internal ProsodyNumber _pitch;
internal ProsodyNumber _range;
internal ProsodyNumber _rate; // can be casted to a Prosody Rate
internal int _duration;
internal ProsodyNumber _volume;
internal IntPtr _contourPoints;
internal Prosody PtrToProsody ()
{
Prosody prosody = new Prosody ();
prosody.Pitch = _pitch;
prosody.Range = _range;
prosody.Rate = _rate;
prosody.Duration = _duration;
prosody.Volume = _volume;
//
if (prosody.GetContourPoints () != null)
{
List points = new List ();
int i = 0;
ContourPoint point = new ContourPoint ();
int sizeOfPoint = Marshal.SizeOf (points [0]);
do
{
Marshal.PtrToStructure (new IntPtr ((long) _contourPoints + i * sizeOfPoint), point);
points.Add (point);
}
while (point.Start != 100f);
prosody.SetContourPoints (points.ToArray ());
}
return prosody;
}
}
}
#endif
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Contains either a reference to an audio audioStream or a list of
// text fragments.
//
// History:
// 2/1/2005 jeanfp Created from the Sapi Managed code
//-----------------------------------------------------------------
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Speech.Internal.ObjectTokens;
using System.Speech.Synthesis.TtsEngine;
using System.Text;
using System.Threading;
namespace System.Speech.Internal.Synthesis
{
abstract class ITtsEngineProxy
{
internal ITtsEngineProxy (int lcid)
{
_alphabetConverter = new AlphabetConverter (lcid);
}
abstract internal IntPtr GetOutputFormat (IntPtr targetFormat);
abstract internal void AddLexicon (Uri lexicon, string mediaType);
abstract internal void RemoveLexicon (Uri lexicon);
abstract internal void Speak (List frags, byte [] wfx);
abstract internal void ReleaseInterface ();
abstract internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet);
abstract internal AlphabetType EngineAlphabet { get; }
internal AlphabetConverter AlphabetConverter { get { return _alphabetConverter; } }
#if SPEECHSERVER || PROMPT_ENGINE
abstract internal void BackupVoice (IPromptEngine pe);
#endif
protected AlphabetConverter _alphabetConverter;
}
internal class TtsProxySsml : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//*******************************************************************
#region Constructors
internal TtsProxySsml (TtsEngineSsml ssmlEngine, ITtsEngineSite site, int lcid)
: base (lcid)
{
_ssmlEngine = ssmlEngine;
_site = site;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr targetFormat)
{
return _ssmlEngine.GetOutputFormat (SpeakOutputFormat.WaveFormat, targetFormat);
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
_ssmlEngine.AddLexicon (lexicon, mediaType, _site);
}
override internal void RemoveLexicon (Uri lexicon)
{
_ssmlEngine.RemoveLexicon (lexicon, _site);
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
_ssmlEngine.Speak (frags.ToArray (), waveFormat, _site);
}
finally
{
gc.Free ();
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return phones;
}
else
{
return _alphabetConverter.SapiToIpa (phones);
}
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Ipa;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice ((ITtsEngineSsml) new ProxyComSsml (_ssmlEngine, _site));
}
///
/// Maps the ITtsEngineSsml interface to the sapi ITtsEngine interface
///
class ProxyComSsml : ITtsEngineSsml
{
internal ProxyComSsml (TtsEngineSsml sapiEngine, ITtsEngineSite site)
{
_ssmlEngine = sapiEngine;
_site = site;
}
#region ITtsEngineSsml implementation
void ITtsEngineSsml.GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
waveHeader = _ssmlEngine.GetOutputFormat (speakOutputFormat, targetWaveFormat);
}
///
/// Add a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// media type
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.AddLexicon (string location, string mediaType, IntPtr site)
{
_ssmlEngine.AddLexicon (new Uri (location, UriKind.RelativeOrAbsolute), mediaType, _site);
}
///
/// Removes a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.RemoveLexicon (string location, IntPtr site)
{
_ssmlEngine.RemoveLexicon (new Uri (location, UriKind.RelativeOrAbsolute), _site);
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
/// Text fragment with SSML
/// attributes information
/// Number of elements in fragment
/// Wave format header
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.Speak (IntPtr fragments, int count, IntPtr waveFormat, IntPtr site)
{
TextFragment [] textFragments = Converter.PtrToFragments (fragments, count);
_ssmlEngine.Speak (textFragments, waveFormat, _site);
}
private TtsEngineSsml _ssmlEngine;
private ITtsEngineSite _site;
#endregion
}
#endif
#endregion
//********************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private TtsEngineSsml _ssmlEngine;
private ITtsEngineSite _site;
#endregion
}
///
///
///
internal class TtsProxyCom : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//********************************************************************
#region Constructors
internal TtsProxyCom (ITtsEngineSsml comEngine, IntPtr iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
_comEngine = comEngine;
}
#endregion
//*******************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr targetFormat)
{
IntPtr waveFormatEx;
_comEngine.GetOutputFormat (targetFormat != IntPtr.Zero ? SpeakOutputFormat.WaveFormat : SpeakOutputFormat.Text, targetFormat, out waveFormatEx);
return waveFormatEx;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
_comEngine.AddLexicon (lexicon.ToString (), mediaType, _iSite);
}
override internal void RemoveLexicon (Uri lexicon)
{
_comEngine.RemoveLexicon (lexicon.ToString (), _iSite);
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
// Marshal all the Text fragments data into unmanaged memory
Collection memoryBlocksAllocated = new Collection ();
// Keep the list of all the memory blocks allocated by Marshal.CoTaskMemAlloc
IntPtr fragmentInterop = TextFragmentInterop.FragmentToPtr (frags, memoryBlocksAllocated);
try
{
_comEngine.Speak (fragmentInterop, frags.Count, waveFormat, _iSite);
}
finally
{
// Release all the allocated memory
foreach (IntPtr ptr in memoryBlocksAllocated)
{
Marshal.FreeCoTaskMem (ptr);
}
}
}
finally
{
gc.Free ();
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
Marshal.ReleaseComObject (_comEngine);
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Ipa;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return phones;
}
else
{
return _alphabetConverter.SapiToIpa (phones);
}
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice (_comEngine);
}
#endif
#endregion
//*******************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private ITtsEngineSsml _comEngine;
// This variable is stored here but never created or deleted
private IntPtr _iSite;
#endregion
}
///
///
///
internal class TtsProxySapi : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//********************************************************************
#region Constructors
internal TtsProxySapi (ITtsEngine sapiEngine, IntPtr iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
_sapiEngine = sapiEngine;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr preferedFormat)
{
// Initialize TTS Engine
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
Guid guidNull = new Guid ();
IntPtr coMem = IntPtr.Zero;
_sapiEngine.GetOutputFormat (ref formatId, preferedFormat, out guidNull, out coMem);
return coMem;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
// SAPI: Ignore
}
override internal void RemoveLexicon (Uri lexicon)
{
// SAPI: Ignore
}
override internal void Speak (List frags, byte [] wfx)
{
GCHandle gc = GCHandle.Alloc (wfx, GCHandleType.Pinned);
try
{
IntPtr waveFormat = gc.AddrOfPinnedObject ();
GCHandle spvTextFragment = new GCHandle ();
if (ConvertTextFrag.ToSapi (frags, ref spvTextFragment))
{
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
try
{
_sapiEngine.Speak (0, ref formatId, waveFormat, spvTextFragment.AddrOfPinnedObject (), _iSite);
}
finally
{
ConvertTextFrag.FreeTextSegment (ref spvTextFragment);
}
}
}
finally
{
gc.Free ();
}
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Sapi;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return _alphabetConverter.IpaToSapi (phones);
}
else
{
return phones;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
Marshal.ReleaseComObject (_sapiEngine);
}
#if SPEECHSERVER || PROMPT_ENGINE
override internal void BackupVoice (IPromptEngine pe)
{
ITtsEngineSsml proxy = (ITtsEngineSsml) new ProxyComSapi (_sapiEngine);
pe.SetBackupVoice (proxy);
}
#endif
#endregion
//********************************************************************
//
// Private Fields
//
//*******************************************************************
#region private Fields
private ITtsEngine _sapiEngine;
// This variable is stored here but never created or deleted
private IntPtr _iSite;
#endregion
#if SPEECHSERVER || PROMPT_ENGINE
///
/// Maps the ITtsEngineSsml interface to the sapi ITtsEngine interface
///
class ProxyComSapi : ITtsEngineSsml
{
internal ProxyComSapi (ITtsEngine sapiEngine)
{
_sapiEngine = sapiEngine;
}
#region ITtsEngineSsml implementation
void ITtsEngineSsml.GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
// Initialize TTS Engine
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
Guid guidNull = new Guid ();
IntPtr coMem = IntPtr.Zero;
_sapiEngine.GetOutputFormat (ref formatId, targetWaveFormat, out guidNull, out coMem);
waveHeader = coMem;
}
///
/// Add a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// media type
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.AddLexicon (string location, string mediaType, IntPtr site)
{
}
///
/// Removes a lexicon to the engine collection of lexicons
///
/// A path or a Uri
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.RemoveLexicon (string location, IntPtr site)
{
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
/// Text fragment with SSML
/// attributes information
/// Number of elements in fragment
/// Wave format header
/// Engine site (ITtsEngineSite)
void ITtsEngineSsml.Speak (IntPtr fragments, int count, IntPtr waveFormat, IntPtr site)
{
GCHandle spvTextFragment = new GCHandle ();
TextFragment [] textFragments = Converter.PtrToFragments (fragments, count);
ConvertTextFrag.ToSapi (new List (textFragments), ref spvTextFragment);
Guid formatId = SAPIGuids.SPDFID_WaveFormatEx;
try
{
_sapiEngine.Speak (0, ref formatId, waveFormat, spvTextFragment.AddrOfPinnedObject (), site);
}
finally
{
ConvertTextFrag.FreeTextSegment (ref spvTextFragment);
}
}
#endregion
private ITtsEngine _sapiEngine;
}
#endif
}
#if SPEECHSERVER || PROMPT_ENGINE
///
///
///
internal class TextEngine : ITtsEngineProxy
{
//*******************************************************************
//
// Constructors
//
//*******************************************************************
#region Constructors
internal TextEngine (ITtsEngineSite iSite, int lcid)
: base (lcid)
{
_iSite = iSite;
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
override internal IntPtr GetOutputFormat (IntPtr preferedFormat)
{
return IntPtr.Zero;
}
override internal void AddLexicon (Uri lexicon, string mediaType)
{
// Ignore
}
override internal void RemoveLexicon (Uri lexicon)
{
// Ignore
}
override internal void Speak (List frags, byte [] wfx)
{
TextEngineSsml.WriteTextFragments (_iSite, frags);
}
override internal AlphabetType EngineAlphabet
{
get
{
return AlphabetType.Sapi;
}
}
override internal char [] ConvertPhonemes (char [] phones, AlphabetType alphabet)
{
if (alphabet == AlphabetType.Ipa)
{
return _alphabetConverter.IpaToSapi (phones);
}
else
{
return phones;
}
}
///
/// Release the COM interface for COM object
///
override internal void ReleaseInterface ()
{
}
override internal void BackupVoice (IPromptEngine pe)
{
pe.SetBackupVoice (new TextEngineSsml (_iSite));
}
#endregion
//********************************************************************
//
// Private Fields
//
//********************************************************************
#region private Fields
private ITtsEngineSite _iSite;
#endregion
//*******************************************************************
//
// Private Types
//
//********************************************************************
#region private Types
class TextEngineSsml : ITtsEngineSsml
{
internal TextEngineSsml (ITtsEngineSite iSite)
{
_iSite = iSite;
}
///
/// Queries the engine about a specific output format.
/// The engine should examine the requested output format,
/// and return the closest format that it supports.
///
public void GetOutputFormat (SpeakOutputFormat speakOutputFormat, IntPtr targetWaveFormat, out IntPtr waveHeader)
{
WAVEFORMATEX waveFormatEx = WAVEFORMATEX.Default;
byte [] abHeader = waveFormatEx.ToBytes ();
waveHeader = Marshal.AllocCoTaskMem (abHeader.Length);
Marshal.Copy (abHeader, 0, waveHeader, abHeader.Length);
}
///
/// Add a lexicon to the engine collection of lexicons
///
public void AddLexicon (string location, string mediaType, IntPtr site)
{
}
///
/// Removes a lexicon to the engine collection of lexicons
///
public void RemoveLexicon (string location, IntPtr site)
{
}
///
/// Renders the specified text fragments array in the
/// specified output format.
///
public void Speak (IntPtr fragments, int count, IntPtr waveHeader, IntPtr site)
{
WriteTextFragments (_iSite, new List (Converter.PtrToFragments (fragments, count)));
}
public static void WriteTextFragments (ITtsEngineSite iSite, List frags)
{
foreach (TextFragment frag in frags)
{
if (frag.State.Action == TtsEngineAction.Speak)
{
string s = "0:TTS:" + frag.TextToSpeak + "\0";
GCHandle gc = GCHandle.Alloc (s, GCHandleType.Pinned);
try
{
iSite.Write (gc.AddrOfPinnedObject (), (frag.TextLength + 7) * 2);
}
finally
{
gc.Free ();
}
}
}
}
private ITtsEngineSite _iSite;
}
#endregion
}
#endif
#if SPEECHSERVER || PROMPT_ENGINE
class Converter
{
internal static TextFragment [] PtrToFragments (IntPtr fragments, int count)
{
TextFragment [] textFragments = new TextFragment [count];
TextFragmentInterop fragInterop = new TextFragmentInterop ();
int sizeOfFrag = Marshal.SizeOf (fragInterop);
for (int i = 0; i < count; i++)
{
Marshal.PtrToStructure ((IntPtr) ((ulong) fragments + (ulong) (i * sizeOfFrag)), fragInterop);
textFragments [i] = new TextFragment ();
if (fragInterop._textToSpeak != null && fragInterop._textToSpeak.Length > 0)
textFragments [i].TextToSpeak = fragInterop._textToSpeak;
textFragments [i].TextOffset = fragInterop._textOffset;
textFragments [i].TextLength = fragInterop._textLength;
textFragments [i].State = fragInterop._state.PtrToFragmentState ();
}
return textFragments;
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class TextFragmentInterop
{
internal FragmentStateInterop _state;
[MarshalAs (UnmanagedType.LPWStr)]
internal string _textToSpeak;
internal int _textOffset;
internal int _textLength;
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class FragmentStateInterop
{
internal TtsEngineAction _action;
internal int _langId;
internal int _emphasis;
internal int _duration;
internal IntPtr _sayAs;
internal IntPtr _prosody;
internal IntPtr _phoneme;
FragmentStateInterop () { _action = TtsEngineAction.BeginPromptEngineOutput; _langId = _emphasis = _duration = 0; _sayAs = _phoneme = _prosody = IntPtr.Zero; }
internal FragmentState PtrToFragmentState ()
{
FragmentState fragmentState = new FragmentState ();
fragmentState.Action = _action;
fragmentState.LangId = _langId;
fragmentState.Emphasis = _emphasis;
fragmentState.Duration = _duration;
if (_sayAs != IntPtr.Zero)
{
fragmentState.SayAs = new SayAs ();
Marshal.PtrToStructure (_sayAs, fragmentState.SayAs);
}
if (_phoneme != IntPtr.Zero)
{
StringBuilder phones = new StringBuilder ();
int i = 0;
char phone = ' ';
do
{
Marshal.WriteInt16 (new IntPtr ((long) _phoneme + i * 2), phone);
phones.Append (unchecked ((char) phone));
}
while (phones [i++] != 0);
fragmentState.Phoneme = phones.ToString().ToCharArray ();
}
if (_prosody != IntPtr.Zero)
{
ProsodyInterop prosodyInterop = new ProsodyInterop ();
Marshal.PtrToStructure (_prosody, prosodyInterop);
fragmentState.Prosody = prosodyInterop.PtrToProsody ();
}
return fragmentState;
}
}
///
/// TODOC
///
[StructLayout (LayoutKind.Sequential)]
internal class ProsodyInterop
{
internal ProsodyNumber _pitch;
internal ProsodyNumber _range;
internal ProsodyNumber _rate; // can be casted to a Prosody Rate
internal int _duration;
internal ProsodyNumber _volume;
internal IntPtr _contourPoints;
internal Prosody PtrToProsody ()
{
Prosody prosody = new Prosody ();
prosody.Pitch = _pitch;
prosody.Range = _range;
prosody.Rate = _rate;
prosody.Duration = _duration;
prosody.Volume = _volume;
//
if (prosody.GetContourPoints () != null)
{
List points = new List ();
int i = 0;
ContourPoint point = new ContourPoint ();
int sizeOfPoint = Marshal.SizeOf (points [0]);
do
{
Marshal.PtrToStructure (new IntPtr ((long) _contourPoints + i * sizeOfPoint), point);
points.Add (point);
}
while (point.Start != 100f);
prosody.SetContourPoints (points.ToArray ());
}
return prosody;
}
}
}
#endif
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlWrappingReader.cs
- PropertyGridEditorPart.cs
- ThicknessAnimationUsingKeyFrames.cs
- SoapSchemaExporter.cs
- MouseCaptureWithinProperty.cs
- MediaPlayerState.cs
- DateTimeOffsetAdapter.cs
- SequentialUshortCollection.cs
- HttpListenerPrefixCollection.cs
- SuppressMessageAttribute.cs
- FormatterServices.cs
- QilInvoke.cs
- TextServicesLoader.cs
- OperationFormatter.cs
- RefreshPropertiesAttribute.cs
- DbParameterCollection.cs
- GlobalizationAssembly.cs
- JournalEntryStack.cs
- SizeFConverter.cs
- Error.cs
- NativeMethods.cs
- EmptyEnumerable.cs
- StringFreezingAttribute.cs
- TextOptionsInternal.cs
- XmlSchemaAttribute.cs
- ping.cs
- Component.cs
- CopyEncoder.cs
- Single.cs
- RecommendedAsConfigurableAttribute.cs
- FileLoadException.cs
- PTUtility.cs
- SingleConverter.cs
- EndEvent.cs
- DynamicAttribute.cs
- WebAdminConfigurationHelper.cs
- ServiceOperationParameter.cs
- ExceptionRoutedEventArgs.cs
- SafeLocalMemHandle.cs
- CompoundFileStorageReference.cs
- StringInfo.cs
- RoutingExtension.cs
- ProxyElement.cs
- CookieHandler.cs
- Shape.cs
- ActivationServices.cs
- StringInfo.cs
- SecurityRuntime.cs
- PageTheme.cs
- ManagementExtension.cs
- Odbc32.cs
- AffineTransform3D.cs
- DataControlExtensions.cs
- AbsoluteQuery.cs
- QueryContinueDragEventArgs.cs
- MobileUserControlDesigner.cs
- AuthorizationRuleCollection.cs
- EventWaitHandleSecurity.cs
- ListItemCollection.cs
- MetafileHeader.cs
- TraceUtils.cs
- SqlAggregateChecker.cs
- UICuesEvent.cs
- updateconfighost.cs
- TraceShell.cs
- GenericTypeParameterBuilder.cs
- ViewEvent.cs
- InvalidPrinterException.cs
- SiteIdentityPermission.cs
- FieldAccessException.cs
- InkCanvasAutomationPeer.cs
- FieldAccessException.cs
- TextParaClient.cs
- TextElementEnumerator.cs
- PrintPreviewGraphics.cs
- StdValidatorsAndConverters.cs
- FactoryId.cs
- DataControlFieldHeaderCell.cs
- MachineKey.cs
- SamlSecurityTokenAuthenticator.cs
- IOException.cs
- ValueExpressions.cs
- RelatedPropertyManager.cs
- WorkflowQueueInfo.cs
- Trigger.cs
- WSSecurityOneDotZeroSendSecurityHeader.cs
- GeometryHitTestResult.cs
- MemberPath.cs
- RecommendedAsConfigurableAttribute.cs
- TabControl.cs
- WebPartMovingEventArgs.cs
- StatusBarPanel.cs
- Opcode.cs
- SchemaElement.cs
- DriveInfo.cs
- PackWebResponse.cs
- SizeAnimationBase.cs
- Int32Converter.cs
- StylusPointProperties.cs
- MetadataPropertyvalue.cs