Search Unity

Text to Speech [Dll] for Windows Desktop.

Discussion in 'Scripting' started by ZJP, Jul 31, 2010.

Thread Status:
Not open for further replies.
  1. sdf

    sdf

    Joined:
    Sep 6, 2012
    Posts:
    13
    good dll,why without viseme.......???
     
  2. ng_min_teck

    ng_min_teck

    Joined:
    Apr 30, 2014
    Posts:
    33
    i also have this issue, the program pronoun wrongly in Chinese and anyone have any idea instead using voice_nb number, i want use the voice name

    now my voice_nb so far

    voice_nb 0 = default microsoft anna
    voice_nb 1 = microsoft Lili-chinese
    voice_nb 2 = emily
     
    Last edited: May 5, 2014
  3. ng_min_teck

    ng_min_teck

    Joined:
    Apr 30, 2014
    Posts:
    33
  4. Evil-Dog

    Evil-Dog

    Joined:
    Oct 4, 2011
    Posts:
    134
    Very neat! I get a crash on Voice 2, any idea?
     
  5. ng_min_teck

    ng_min_teck

    Joined:
    Apr 30, 2014
    Posts:
    33
    comment out Application.Quit (); will prevent the program close if you only have 1 voice

    actually i plan to make the change voice option to combo box drop down list, which allow user choose which voice they prefer. It will look something like this $Capture.JPG
     
    Last edited: May 9, 2014
  6. ng_min_teck

    ng_min_teck

    Joined:
    Apr 30, 2014
    Posts:
    33
    I have problem that the code won't auto update the setup until i click 1 gui button
    $Capture.JPG
    $Capture2.JPG

    Code (csharp):
    1. void start ()
    2.     {
    3.         if (VoiceAvailable () > 0)
    4.         {  
    5.             InitVoice (); // init the engine
    6.  
    7.             if (voice_nb > GetVoiceCount ())
    8.                 voice_nb = 0;
    9.            
    10.             if (voice_nb < 0)
    11.                 voice_nb = 0;
    12.  
    13.             // get all the installed name
    14.             for(int i =0; i < GetVoiceCount(); i++)
    15.             {
    16.                 IntPtr pStr = GetVoiceName(i);
    17.                 string str = Marshal.PtrToStringAnsi(pStr);
    18.                 voiceName.Add(str);
    19.             }
    20. }
     
  7. ng_min_teck

    ng_min_teck

    Joined:
    Apr 30, 2014
    Posts:
    33
    nvm solved, btw my combo box been cutoff any idea how to fix it
     
  8. jholland404

    jholland404

    Joined:
    Aug 14, 2012
    Posts:
    2

    If you need TTS for Macintosh try https://www.assetstore.unity3d.com/en/#!/content/4115.

    It is inexpensive, only $15.00 currently.

    Uses built in Mac voices. Apple has tons of downloads to add new voices.


    enjoy ;)

    jholland
     
  9. jiangjiang

    jiangjiang

    Joined:
    Feb 17, 2014
    Posts:
    6
    i had solved it.it can speak chinese now. If anyone want it ,email me! 271809781@qq.com
     
  10. floatingBen

    floatingBen

    Joined:
    Jun 6, 2014
    Posts:
    2
    I want to add a child voice to this, does anyone know how to do this?
     
  11. floatingBen

    floatingBen

    Joined:
    Jun 6, 2014
    Posts:
    2
    Also only one voice (a women) works for me, do you know why?
     
  12. Endrick

    Endrick

    Joined:
    Feb 2, 2014
    Posts:
    40
    hello there, can i change the voice to male voice?
    how to edit the voice on .dll file?

    the link does'n work
     
  13. MohammadM

    MohammadM

    Joined:
    Jun 8, 2014
    Posts:
    28
    is there a way to have a child voice ?
     
  14. MohammadM

    MohammadM

    Joined:
    Jun 8, 2014
    Posts:
    28
    Hello. i had the same problem and did what u said . the voice plays for a second but then the program just crashed every time. any idea?
     
  15. dcarrigg

    dcarrigg

    Joined:
    May 21, 2014
    Posts:
    24
    Is the source code for this dll available online anywhere, or if it would be possible to get a copy?

    The dll so far is great, but there's a bug that's been mentioned here with writing the data to a file where it always uses the default voice.

    If I could get my hands on the source code, I'd love to provide a couple updates:
    - A function that returns a byte[] so that it could directly be put into a Unity AudioClip
    - Fix the bug with SpeakToFile always using the default voice
     
    jmitchell_ufg likes this.
  16. Abios

    Abios

    Joined:
    Aug 18, 2014
    Posts:
    1
    Hi. How can I install more voices? I've tried the ones in this page but the system doesn't recognize them.

    I need help with this.
     
  17. g0tNoodles

    g0tNoodles

    Joined:
    Nov 28, 2010
    Posts:
    193
    @MohammadM Sorry for taking so long to reply. Did you get the problem sorted? If not, can you post your code?
     
  18. jmitchell_ufg

    jmitchell_ufg

    Joined:
    Sep 17, 2014
    Posts:
    1
    I'm having the same issue. Is the source available at all now? If not I'll just have to write my own DLL, but it's so very close to being exactly what I need!
     
  19. jlcra

    jlcra

    Joined:
    Jan 27, 2014
    Posts:
    13
    Great utility! Thanks so much ZJP!

    Does anyone know how to get this working when exporting a build, though? I'm not sure what to do with the dll. Do I need to place the dll in the correct folder on each computer I run the build from?

    I guess I would need an installer to place the dll file in the correct place automatically?
     
  20. RajindR

    RajindR

    Joined:
    Nov 19, 2014
    Posts:
    1
    Is there any chance that you could post the source of voice_speaker.dll I'm trying to write speech recognition application with unity. I want to write such dll that use SAPI to connect it with unity.
     
  21. Hellium

    Hellium

    Joined:
    Sep 25, 2014
    Posts:
    43
    Just to say that the dll and the script are compatible with Unity 5 ! :D
    Thank you ZJP !

    By the way, do you use the System.Speech.Synthesis namespace ? I was not able to use it in an Unity project, but your solution works, so it's fine ! :)
     
    ZJP likes this.
  22. lucashaley

    lucashaley

    Joined:
    May 26, 2006
    Posts:
    8
    Hello!

    I am trying to get this to work in Unity5/Windows8, and I'm having some difficulties. Here's what I've done so far:

    1) Downloaded the DLL and installed it in SysWOW64.
    2) Added the basic script to an empty gameObject.
    3) Added the DLL from SysWOW64 into Assets/Plugins in Unity
    4) Restart computer and Unity

    I get a DllNotFoundException: Voice_speaker.dll error, both on start and stop.

    Is there anything else I need to do? Install anything in the system itself?

    Thank you for any help!

    -Lucas
     
  23. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
    I'm having the same problem lucashaley is having. I followed the same steps he did, too. I've also tried putting the DLL in only SysWOW64 (not in Unity), only in system32, in both, and in each directory individually along with the DLL in Unity (in essence, every combination with a reboot inbetween).

    I've also tried modifying the basic script to not use the "EntryPoint" part of the DllImport attribute since the function names matched. (I didn't really expect this to work, but it was something else to try.)

    Am I missing an obvious step from somewhere?

    I'm running Unity 5 on Windows 8.1 (64-bit).
     
  24. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
    I was able to integrate Intel's RealSense speech synthesis into Unity. There is a C# example in the SDK that's easy to copy. I ended up having to read the sentences in a separate thread, but it works and the voice is pretty good.
     
  25. w4ffl35

    w4ffl35

    Joined:
    May 30, 2015
    Posts:
    2
    Do you have a link to documentation on integrating RealSense with Unity? I'm also looking for a text to speech synthesis solution

    edit: herp derp - first two links on google that i skimmed over

    installation
    https://software.intel.com/en-us/blogs/2015/02/13/add-realsense-to-unity

    usage
    https://software.intel.com/en-us/blogs/2015/02/17/12-steps-to-apply-realsense-toolkit-in-unity
     
    Last edited: May 30, 2015
  26. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
    Are you looking for a Windows-only solution that doesn't require the end-user to install anything? If so, my partner just made a DLL that connects to Windows's built-in text-to-speech, and I'll look into uploading it. Let me know!
     
  27. PixelPoet

    PixelPoet

    Joined:
    Jun 12, 2015
    Posts:
    1
    That would certainly be wonderful! I am having trouble integrating this one (I am using Unity5 with Windows 8.1). Can you help me out?
     
  28. RavenMikal

    RavenMikal

    Joined:
    Oct 18, 2014
    Posts:
    144
    I'm having issues with it two. I've literally put a copy of the .dll everywhere I can find .dll's on my cpu, unity included, and when I'm in mono, it doesn't seem to recognize it's existence. I don't get it, annoying as hell, as it doesn't seem to have an issue with the UMA.dll. I'm sure I'm missing something, I just don't know what...lol
     
  29. DigitalAdam

    DigitalAdam

    Joined:
    Jul 18, 2007
    Posts:
    1,204
    I would love to see this!
     
  30. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
  31. josivan88

    josivan88

    Joined:
    Dec 24, 2012
    Posts:
    4
    Hey people, who want a simple code for speech in windows without any DLL?

    Code (CSharp):
    1.  
    2. //Add this on uses;
    3. using System;
    4. using System.IO;
    5. using System.Diagnostics;
    6. using System.Text;
    7.  
    8.     //Function to speak in default windows voice
    9.     public static void Speak(string texto)
    10.     {
    11.         //create the containing folder
    12.         if (!Directory.Exists ("C:/TempSpeak")) {
    13.             System.IO.Directory.CreateDirectory ("C:/TempSpeak");
    14.             var di = new DirectoryInfo("C:/TempSpeak");
    15.             di.Attributes = FileAttributes.Hidden;
    16.         }
    17.  
    18.         string Rand = UnityEngine.Random.Range (000000, 999999).ToString ("D6");
    19.         UnityEngine.Debug.Log(Rand);
    20.         //Create Temp.vbs
    21.         String Voice = "C:/TempSpeak/Temp"+Rand+".vbs";
    22.         AddTextToFile (Voice, "\r\nCreateObject(\"SAPI.Spvoice\").Speak\"" + texto + "\"");
    23.         AddTextToFile (Voice, "Set obj = CreateObject(\"Scripting.FileSystemObject\")");
    24.         AddTextToFile (Voice, "obj.DeleteFile(\"C:\\TempSpeak\\Temp"+Rand+".vbs\")");
    25.                 //     Call the vbs file
    26.                 Process scriptProc = new Process ();
    27.                 scriptProc.StartInfo.FileName = @"cscript";
    28.                 //        scriptProc.StartInfo.WorkingDirectory = @"c:\scripts\"; //<---very important
    29.                 scriptProc.StartInfo.Arguments = "//B //Nologo " + "C://TempSpeak//Temp"+Rand+".vbs";
    30.                 scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //evita de mostrar a janela de prompt
    31.                 scriptProc.Start ();
    32.                 //Voila
    33.     }
    34.  
    35.     //Add text to text files
    36.     public static void AddTextToFile(string adress,string value)
    37.     {
    38.         FileStream fs=new FileStream(adress, FileMode.Append, FileAccess.Write, FileShare.Write);
    39.         fs.Close();
    40.         StreamWriter sw=new StreamWriter(adress, true, Encoding.Unicode);
    41.         string NextLine="\r\n"+value;
    42.         sw.Write(NextLine);
    43.         sw.Close();
    44.     }
    45.  
    46. //Simply use
    47.  
    48. Speak("Something");
    The code create and execute .vbs files to call windows voice.


    Any problem contact me: josivan_silva@hotmail.com
     
  32. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
    I can't recommend your solution, josivan88. It assumes a "C" drive, it creates a new directory outside of its own directory and outside of the Application Data directory, plus it relies on not generating two identical random numbers while a speech process is running.

    I'd like to point out that the solution I posted above does use a DLL, but it provides several benefits:
    • It only initializes the Speech API once.
    • It automatically queues up requests and puts a programmer-defined delay between the phrases.
    • If the next phrase to speak is equal to the one currently being spoken, it is discarded.
    • It's been used in several released games.
    The DLL is tiny at 286 kilobytes and Unity makes it is trivial to add them to your project. If you don't trust the DLL, all of the code is available for you to view and compile yourself with the included project file.
     
  33. josivan88

    josivan88

    Joined:
    Dec 24, 2012
    Posts:
    4

    William, C drive is the default drive for windows, i've never see a Computer without a C drive. The path is only a example you can change for anywhere you want. the numbers generated have 1 000 000 of possiblities, 1 in 1 million a guess that is dificult to have two identical files.
    i not disagree with the DLL solution, i am only offering a diferent solution, use only if you want or the DLL dont work ... few free.
    (Sorry for my bad english)
     
  34. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Hi,

    I'm working (but not really time for) on a new version. I have (for the moment) some troubles with the 64B version.

    Sapi.h light version
    Code (csharp):
    1.  
    2. // ********************************************************************************************************* //
    3. // SAPI MINGW VERSION ************************************************************************************** //
    4. // ********************************************************************************************************* //
    5.  
    6. #ifndef SAPI_SIMPLE_H
    7. #define SAPI_SIMPLE_H
    8.  
    9. // COM objects
    10. #include <Objbase.h>
    11.  
    12. // GUIDs
    13. const GUID CLSID_SpVoice = {0x96749377, 0x3391, 0x11d2, 0x9e,0xe3, 0x00,0xc0,0x4f,0x79,0x73,0x96};
    14. const GUID IID_ISpVoice  = {0x6c44df74, 0x72b9, 0x4992, 0xa1,0xec, 0xef,0x99,0x6e,0x04,0x22,0xd4};
    15.  
    16. // Enums
    17. typedef enum SPEAKFLAGS
    18. {
    19.    SPF_DEFAULT    = 0,
    20.    SPF_ASYNC    = ( 1L << 0 ) ,
    21.    SPF_PURGEBEFORESPEAK = ( 1L << 1 ) ,
    22.    SPF_IS_FILENAME    = ( 1L << 2 ) ,
    23.    SPF_IS_XML    = ( 1L << 3 ) ,
    24.    SPF_IS_NOT_XML    = ( 1L << 4 ) ,
    25.    SPF_PERSIST_XML    = ( 1L << 5 ) ,
    26.    SPF_NLP_SPEAK_PUNC    = ( 1L << 6 ) ,
    27.    SPF_PARSE_SAPI    = ( 1L << 7 ) ,
    28.    SPF_PARSE_SSML    = ( 1L << 8 ) ,
    29.    SPF_PARSE_AUTODETECT = 0,
    30.    SPF_NLP_MASK   = SPF_NLP_SPEAK_PUNC,
    31.    SPF_PARSE_MASK   = ( SPF_PARSE_SAPI | SPF_PARSE_SSML ) ,
    32.    SPF_VOICE_MASK   = ( ( ( ( ( ( ( SPF_ASYNC | SPF_PURGEBEFORESPEAK )  | SPF_IS_FILENAME )  | SPF_IS_XML )  | SPF_IS_NOT_XML )  | SPF_NLP_MASK )  | SPF_PERSIST_XML )  | SPF_PARSE_MASK ) ,
    33.    SPF_UNUSED_FLAGS   = ~SPF_VOICE_MASK
    34. }    SPEAKFLAGS;
    35.  
    36. // Enum dummies
    37. typedef enum{SPVPRIORITY_X} SPVPRIORITY;
    38. typedef enum{SPEVENTENUM_X} SPEVENTENUM;
    39.  
    40. // Interface dummies
    41. typedef void ISpNotifySink;
    42. typedef void SPNOTIFYCALLBACK;
    43. typedef void ISpNotifyCallback;
    44. typedef void SPEVENT;
    45. typedef void SPEVENTSOURCEINFO;
    46. typedef void ISpObjectToken;
    47. typedef void ISpStreamFormat;
    48. //typedef void SPVOICESTATUS; // ZJP  MODIF !!!
    49.  
    50. typedef WCHAR SPPHONEID;
    51. typedef enum SPVISEMES
    52. {
    53.    // English examples
    54.    //------------------
    55.   SP_VISEME_0,  // silence
    56.   SP_VISEME_1,  // ae, ax, ah
    57.   SP_VISEME_2,  // aa
    58.   SP_VISEME_3,  // ao
    59.   SP_VISEME_4,  // ey, eh, uh
    60.   SP_VISEME_5,  // er
    61.   SP_VISEME_6,  // y, iy, ih, ix
    62.   SP_VISEME_7,  // w, uw
    63.   SP_VISEME_8,  // ow
    64.   SP_VISEME_9,  // aw
    65.   SP_VISEME_10,  // oy
    66.   SP_VISEME_11,  // ay
    67.   SP_VISEME_12,  // h
    68.   SP_VISEME_13,  // r
    69.   SP_VISEME_14,  // l
    70.   SP_VISEME_15,  // s, z
    71.   SP_VISEME_16,  // sh, ch, jh, zh
    72.   SP_VISEME_17,  // th, dh
    73.   SP_VISEME_18,  // f, v
    74.   SP_VISEME_19,  // d, t, n
    75.   SP_VISEME_20,  // k, g, ng
    76.   SP_VISEME_21  // p, b, m
    77. } SPVISEMES;
    78. typedef struct SPVOICESTATUS
    79. {
    80.   ULONG  ulCurrentStream;
    81.   ULONG  ulLastStreamQueued;
    82.   HRESULT  hrLastResult;
    83.   DWORD  dwRunningState;
    84.   ULONG  ulInputWordPos;
    85.   ULONG  ulInputWordLen;
    86.   ULONG  ulInputSentPos;
    87.   ULONG  ulInputSentLen;
    88.   LONG  lBookmarkId;
    89.   SPPHONEID  PhonemeId;
    90.   SPVISEMES  VisemeId;
    91.   DWORD  dwReserved1;
    92.   DWORD  dwReserved2;
    93. } SPVOICESTATUS;
    94. // Voice class (C-style)
    95. typedef interface ISpVoice ISpVoice;
    96.  
    97. typedef struct ISpVoiceVtbl
    98. {
    99.    BEGIN_INTERFACE
    100.  
    101.    // COM *******************************************************************************************
    102.    HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
    103.     ISpVoice * This,
    104.     /* [in] */ REFIID riid,
    105.     /* [annotation][iid_is][out] */
    106.     /*__RPC__deref_out */  void **ppvObject); /* ZJP MODIF */
    107. //     LPVOID FAR  void **ppvObject);
    108.  
    109.    ULONG ( STDMETHODCALLTYPE *AddRef )(
    110.     ISpVoice * This);
    111.  
    112.    ULONG ( STDMETHODCALLTYPE *Release )(
    113.     ISpVoice * This);
    114.  
    115.    // NOTIFY ****************************************************************************************
    116.    HRESULT ( STDMETHODCALLTYPE *SetNotifySink )(
    117.     ISpVoice * This,
    118.     /* [in] */ ISpNotifySink *pNotifySink);
    119.  
    120.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyWindowMessage )(
    121.     ISpVoice * This,
    122.     /* [in] */ HWND hWnd,
    123.     /* [in] */ UINT Msg,
    124.     /* [in] */ WPARAM wParam,
    125.     /* [in] */ LPARAM lParam);
    126.  
    127.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyCallbackFunction )(
    128.     ISpVoice * This,
    129.     /* [in] */ SPNOTIFYCALLBACK *pfnCallback,
    130.     /* [in] */ WPARAM wParam,
    131.     /* [in] */ LPARAM lParam);
    132.  
    133.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyCallbackInterface )(
    134.     ISpVoice * This,
    135.     /* [in] */ ISpNotifyCallback *pSpCallback,
    136.     /* [in] */ WPARAM wParam,
    137.     /* [in] */ LPARAM lParam);
    138.  
    139.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyWin32Event )(
    140.     ISpVoice * This);
    141.  
    142.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *WaitForNotifyEvent )(
    143.     ISpVoice * This,
    144.     /* [in] */ DWORD dwMilliseconds);
    145.  
    146.    /* [local] */ HANDLE ( STDMETHODCALLTYPE *GetNotifyEventHandle )(
    147.     ISpVoice * This);
    148.  
    149.    // EVENT ************************************************************************************************
    150.    HRESULT ( STDMETHODCALLTYPE *SetInterest )(
    151.     ISpVoice * This,
    152.     /* [in] */ ULONGLONG ullEventInterest,
    153.     /* [in] */ ULONGLONG ullQueuedInterest);
    154.  
    155.    HRESULT ( STDMETHODCALLTYPE *GetEvents )(
    156.     ISpVoice * This,
    157.     /* [in] */ ULONG ulCount,
    158.     /* [size_is][out] */ SPEVENT *pEventArray,
    159.     /* [out] */ ULONG *pulFetched);
    160.  
    161.    HRESULT ( STDMETHODCALLTYPE *GetInfo )(
    162.     ISpVoice * This,
    163.     /* [out] */ SPEVENTSOURCEINFO *pInfo);
    164.  
    165.    // ********************************************************************************************************* //
    166.    // SPVOICE ************************************************************************************************* //
    167.    // ********************************************************************************************************* //
    168.    HRESULT ( STDMETHODCALLTYPE *SetOutput )(
    169.     ISpVoice * This,
    170.     /* [in] */ IUnknown *pUnkOutput,
    171.     /* [in] */ BOOL fAllowFormatChanges);
    172.  
    173.    HRESULT ( STDMETHODCALLTYPE *GetOutputObjectToken )(
    174.     ISpVoice * This,
    175.     /* [out] */ ISpObjectToken **ppObjectToken);
    176.  
    177.    HRESULT ( STDMETHODCALLTYPE *GetOutputStream )(
    178.     ISpVoice * This,
    179.     /* [out] */ ISpStreamFormat **ppStream);
    180.  
    181.    HRESULT ( STDMETHODCALLTYPE *Pause )(
    182.     ISpVoice * This);
    183.  
    184.    HRESULT ( STDMETHODCALLTYPE *Resume )(
    185.     ISpVoice * This);
    186.  
    187.    HRESULT ( STDMETHODCALLTYPE *SetVoice )(
    188.     ISpVoice * This,
    189.     /* [in] */ ISpObjectToken *pToken);
    190.  
    191.    HRESULT ( STDMETHODCALLTYPE *GetVoice )(
    192.     ISpVoice * This,
    193.     /* [out] */ ISpObjectToken **ppToken);
    194.  
    195.    HRESULT ( STDMETHODCALLTYPE *Speak )(
    196.     ISpVoice * This,
    197.     /* [string][in][annotation] */
    198.     LPCWSTR pwcs,
    199.     /* [in] */ DWORD dwFlags,
    200.     /* [out][annotation] */
    201.     ULONG *pulStreamNumber);
    202.  
    203.    HRESULT ( STDMETHODCALLTYPE *SpeakStream )(
    204.     ISpVoice * This,
    205.     /* [in] */ IStream *pStream,
    206.     /* [in] */ DWORD dwFlags,
    207.     /* [out][annotation] */
    208.     ULONG *pulStreamNumber);
    209.  
    210.    HRESULT ( STDMETHODCALLTYPE *GetStatus )(
    211.     ISpVoice * This,
    212.     /* [out] */ SPVOICESTATUS *pStatus,
    213.     /* [out] */ LPWSTR *ppszLastBookmark);
    214.  
    215.    HRESULT ( STDMETHODCALLTYPE *Skip )(
    216.     ISpVoice * This,
    217.     /* [string][in] */ LPCWSTR pItemType,
    218.     /* [in] */ long lNumItems,
    219.     /* [out] */ ULONG *pulNumSkipped);
    220.  
    221.    HRESULT ( STDMETHODCALLTYPE *SetPriority )(
    222.     ISpVoice * This,
    223.     /* [in] */ SPVPRIORITY ePriority);
    224.  
    225.    HRESULT ( STDMETHODCALLTYPE *GetPriority )(
    226.     ISpVoice * This,
    227.     /* [out] */ SPVPRIORITY *pePriority);
    228.  
    229.    HRESULT ( STDMETHODCALLTYPE *SetAlertBoundary )(
    230.     ISpVoice * This,
    231.     /* [in] */ SPEVENTENUM eBoundary);
    232.  
    233.    HRESULT ( STDMETHODCALLTYPE *GetAlertBoundary )(
    234.     ISpVoice * This,
    235.     /* [out] */ SPEVENTENUM *peBoundary);
    236.  
    237.    HRESULT ( STDMETHODCALLTYPE *SetRate )(
    238.     ISpVoice * This,
    239.     /* [in] */ long RateAdjust);
    240.  
    241.    HRESULT ( STDMETHODCALLTYPE *GetRate )(
    242.     ISpVoice * This,
    243.     /* [out] */ long *pRateAdjust);
    244.  
    245.    HRESULT ( STDMETHODCALLTYPE *SetVolume )(
    246.     ISpVoice * This,
    247.     /* [in] */ USHORT usVolume);
    248.  
    249.    HRESULT ( STDMETHODCALLTYPE *GetVolume )(
    250.     ISpVoice * This,
    251.     /* [out] */ USHORT *pusVolume);
    252.  
    253.    HRESULT ( STDMETHODCALLTYPE *WaitUntilDone )(
    254.     ISpVoice * This,
    255.     /* [in] */ ULONG msTimeout);
    256.  
    257.    HRESULT ( STDMETHODCALLTYPE *SetSyncSpeakTimeout )(
    258.     ISpVoice * This,
    259.     /* [in] */ ULONG msTimeout);
    260.  
    261.    HRESULT ( STDMETHODCALLTYPE *GetSyncSpeakTimeout )(
    262.     ISpVoice * This,
    263.     /* [out] */ ULONG *pmsTimeout);
    264.  
    265.    /* [local] */ HANDLE ( STDMETHODCALLTYPE *SpeakCompleteEvent )(
    266.     ISpVoice * This);
    267.  
    268.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *IsUISupported )(
    269.     ISpVoice * This,
    270.     /* [in] */ LPCWSTR pszTypeOfUI,
    271.     /* [in] */ void *pvExtraData,
    272.     /* [in] */ ULONG cbExtraData,
    273.     /* [out] */ BOOL *pfSupported);
    274.  
    275.    /* [local] */ HRESULT ( STDMETHODCALLTYPE *DisplayUI )(
    276.     ISpVoice * This,
    277.     /* [in] */ HWND hwndParent,
    278.     /* [in] */ LPCWSTR pszTitle,
    279.     /* [in] */ LPCWSTR pszTypeOfUI,
    280.     /* [in] */ void *pvExtraData,
    281.     /* [in] */ ULONG cbExtraData);
    282.    // ********************************************************************************************************* //
    283.    // SPVOICE ************************************************************************************************* //
    284.    // ********************************************************************************************************* //
    285.  
    286. END_INTERFACE
    287. } ISpVoiceVtbl;
    288.  
    289. interface ISpVoice
    290. {
    291.    CONST_VTBL struct ISpVoiceVtbl *lpVtbl;
    292. };
    293.  
    294. #endif   // SAPI_SIMPLE_H
    295.  
    CPP. Project build with Code::Block
    Code (csharp):
    1.  
    2. // *****************************************************************
    3. // Voice to Unity3D DLL (c) ZJP
    4. // *****************************************************************
    5. #define EXPORT_API __declspec(dllexport)
    6. #include <sapi.h>
    7. #include <stdio.h>
    8.  
    9. ISpVoice* pVoice;
    10. SPVOICESTATUS eventStatus;
    11.  
    12.  
    13. LPWSTR CharToLPWSTR (const char * szString)
    14. {
    15.   //If you want to turn from char *, then the function parameters const removed.
    16.   //If you want to transfer from the string argument c_str () function is turned on, as shown below.
    17.   // string msg = "Hello";
    18.   // CharToLPWSTR (msg.c_str ());
    19.  
    20.   int dwLen = strlen (szString) + 1;
    21.   int nwLen = MultiByteToWideChar (CP_ACP, 0, szString, dwLen, NULL, 0) ;
    22.   LPWSTR lpszPath = new WCHAR [dwLen];
    23.   MultiByteToWideChar (CP_ACP, 0, szString, dwLen, lpszPath, nwLen);
    24.   return lpszPath;
    25. }
    26.  
    27. extern "C" int EXPORT_API Uni_Voice_Init()
    28. {
    29.   CoInitializeEx(NULL, COINIT_MULTITHREADED);
    30.    // Create SAPI voice
    31.    if(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice))
    32.   {
    33.   // Couldn't create voice.
    34.   CoUninitialize();
    35.   return 1;
    36.    }
    37.    return 0;
    38. }
    39.  
    40. extern "C" int EXPORT_API Uni_Voice_Speak(const char* texte)   // Speak with voice
    41. {
    42.    if(pVoice->lpVtbl->Speak(pVoice, CharToLPWSTR (texte), SPF_ASYNC|SPF_IS_XML, NULL))
    43.    //if(pVoice->lpVtbl->Speak(pVoice, L"good morning peter. one two three four five six", SPF_ASYNC|SPF_IS_XML, NULL))
    44.    {
    45.      // Couldn't speak with voice.
    46.      //pVoice->lpVtbl->Release(pVoice);
    47.      //CoUninitialize();
    48.      return 1;
    49.    }
    50.    return 0;
    51. //     if(pVoice->lpVtbl->Speak(pVoice, L"This is <emph>very</emph> important!  This sounds normal <pitch middle = '+40'/> but the pitch drops half way through", SPF_IS_XML, NULL))
    52. //     if(pVoice->lpVtbl->Speak(pVoice, L"This is <emph>very</emph> important!. This is very important! ", SPF_IS_XML, NULL))
    53. //<volume level="Level">  Text to be spoken</volume>
    54. //<rate speed="-5">This text should be spoken at rate zero.</rate> -10 to +10
    55. //<silence msec="2000"/>
    56. // <voice required="Language=409"> A U.S. English voice should speak this.</voice> <lang langid="409">  A U.S. English voice should speak this.</lang>
    57. //     if(pVoice->lpVtbl->Speak(pVoice, L"I will spell the word <spell>Love</spell> for you.", SPF_IS_XML, NULL))
    58. //     if(pVoice->lpVtbl->Speak(pVoice, L" <voice required='Gender=Female'> <lang langid='40C'> Bonjour je suis Virginie.</lang>  <lang langid='409'> Hello my name is Anna.</lang> <voice required='Gender=Male'> <lang langid='40C'> et moi Sebastien.</lang>", SPF_IS_XML, NULL))
    59.    //   if(pVoice->lpVtbl->Speak(pVoice, L"<voice required='Name=ScanSoft Sebastien_Full_22kHz'> Bonjour je suis Sebastien", SPF_IS_XML, NULL))
    60.  
    61. }
    62.  
    63. extern "C" int EXPORT_API Uni_Voice_SpeakEX(const char* texte, int voiceFlag)   // Speak with voice
    64. {
    65.    if(pVoice->lpVtbl->Speak(pVoice, CharToLPWSTR (texte), voiceFlag, NULL))
    66.    //if(pVoice->lpVtbl->Speak(pVoice, L"good morning peter. one two three four five six", SPF_ASYNC|SPF_IS_XML, NULL))
    67.    {
    68.      // Couldn't speak with voice.
    69.      //pVoice->lpVtbl->Release(pVoice);
    70.      //CoUninitialize();
    71.      return 1;
    72.    }
    73.    return 0;
    74. }
    75.  
    76. extern "C" int EXPORT_API Uni_Voice_Status(int stat) // Status
    77. {
    78.    pVoice->lpVtbl->GetStatus(pVoice, &eventStatus, NULL );
    79.    ULONG voiceStat;
    80.  
    81.    switch ( stat )
    82.    {
    83.   case 0:
    84.   voiceStat = eventStatus.dwRunningState; // 2 = speak is running
    85.   break;
    86.   case 1:
    87.   voiceStat = (eventStatus.ulInputWordPos) + 1; // start position of the actual speaked word
    88.   break;
    89.   case 2:
    90.   voiceStat = (eventStatus.ulLastStreamQueued); // The number of the last stream queued.
    91.   break;
    92.   case 3:
    93.   voiceStat = (eventStatus.ulCurrentStream); //The number of the current stream being synthesized or receiving output
    94.   break;
    95.  
    96.   default:
    97.   voiceStat = eventStatus.dwRunningState; // 2 = speak is running
    98.   break;
    99.   }
    100.    return (int)voiceStat;
    101. }
    102.  
    103. extern "C" void EXPORT_API Uni_Voice_Close()   // Release voice
    104. {
    105.    pVoice->lpVtbl->Release(pVoice);
    106.    // Finish COM
    107.    CoUninitialize();
    108. }
    109. // *****************************************************************
    110. // Voice to Unity3D DLL (c) ZJP
    111. // *****************************************************************
    112.  
    Unity C# Voice Manager
    Code (csharp):
    1.  
    2. // **************************************************************************
    3. // Unity Text To Speech V2 ZJP. Voice Manager
    4. // **************************************************************************
    5. // DO NOT FORGET TO CHANGE THE EXECUTION ORDER OF THIS CLASSE/SCRIPT ( - 100)
    6. // **************************************************************************
    7.  
    8. using UnityEngine;
    9. using System.Collections;
    10. using Microsoft.Win32;
    11. using System.Runtime.InteropServices;
    12.  
    13. public class VoiceManager : MonoBehaviour
    14. {
    15.    public int VoiceInit = 0;
    16.    public int VoiceNumber = 0;
    17.    public string[] VoiceNames;
    18.  
    19.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Init();
    20.    [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Close();
    21.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Status(int voiceStat);
    22.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Speak(string TextToSpeech); // SPF_ASYNC & SPF_IS_XML
    23.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_SpeakEX(string TextToSpeech, int voiceFlag); // CUSTOM FLAG
    24.    // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    25.    /* https://msdn.microsoft.com/en-us/library/ee431843%28v=vs.85%29.aspx & https://msdn.microsoft.com/en-us/library/ms717077%28v=vs.85%29.aspx
    26.    SPF_DEFAULT
    27.      Specifies that the default settings should be used.  The defaults are:
    28.        * Speak the given text string synchronously
    29.        * Not purge pending speak requests
    30.        * Parse the text as XML only if the first character is a left-angle-bracket (<)
    31.        * Not persist global XML state changes across speak calls
    32.        * Not expand punctuation characters into words.
    33.      To override this default, use the other flag values given below.
    34.    SPF_ASYNC
    35.      Specifies that the Speak call should be asynchronous. That is, it will return immediately after the speak request is queued.
    36.    SPF_PURGEBEFORESPEAK
    37.      Purges all pending speak requests prior to this speak call.
    38.    SPF_IS_FILENAME
    39.      The string passed to Uni_Voice_Speak is a file name, and the file text should be spoken.
    40.    SPF_IS_XML
    41.      The input text will be parsed for XML markup.
    42.    SPF_IS_NOT_XML
    43.      The input text will not be parsed for XML markup.
    44.    SPF_PERSIST_XML
    45.      Global state changes in the XML markup will persist across speak calls.
    46.    SPF_NLP_SPEAK_PUNC
    47.      Punctuation characters should be expanded into words (e.g. "This is a sentence." would become "This is a sentence period").
    48.    SPF_PARSE_SAPI
    49.      Force XML parsing As MS SAPI.
    50.    SPF_PARSE_SSML
    51.      Force XML parsing As W3C SSML.
    52.    */
    53.    const int SPF_DEFAULT  = 0;
    54.    const int SPF_ASYNC  = 1;
    55.    const int SPF_PURGEBEFORESPEAK = 2;
    56.    const int SPF_IS_FILENAME  = 4;
    57.    const int SPF_IS_XML  = 8;
    58.    const int SPF_IS_NOT_XML  = 16;
    59.    const int SPF_PERSIST_XML  = 32;
    60.    const int SPF_NLP_SPEAK_PUNC  = 64;
    61.    const int SPF_PARSE_SAPI  = 128;
    62.    const int SPF_PARSE_SSML  = 256;
    63.    // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    64.  
    65.    // Use this for initialization
    66.    void Start()
    67.    {
    68.      // Info (64Bits OS):
    69.      // Executing Windows\sysWOW64\speech\SpeechUX\SAPI.cpl brings up a Window that displays (!) all of the 32 bit Voices
    70.      // and the current single 64 bit Voice "Anna".
    71.  
    72.      // HKEY_LOCAL_MACHINE\\SOFTWARE\Microsoft\Speech\\Voices\\Tokens\\xxxVOICExxxINSTALLEDxxx\\Attributes >>> (Name)
    73.      const string speechTokens = "Software\\Microsoft\\Speech\\Voices\\Tokens";
    74.  
    75.      using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(speechTokens))
    76.      {
    77.        VoiceNumber = registryKey.SubKeyCount; // key found not mean true voice number !!!
    78.        VoiceNames  = new string[VoiceNumber + 1];
    79.        VoiceNumber = 0;
    80.        foreach (var regKeyFound in registryKey.GetSubKeyNames())
    81.        {
    82.          //Debug.Log(regKeyFound);
    83.          string finalKey = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\" + regKeyFound + "\\Attributes";
    84.          //Debug.Log(finalKey);
    85.          string gotchaVoiceName = "";
    86.          gotchaVoiceName = (string)Registry.GetValue (finalKey, "Name", "");
    87.          if (gotchaVoiceName != "")
    88.          {
    89.            //Debug.Log("Langage Name = " + gotchaVoiceName);
    90.            VoiceNumber++; // increase the real voice number..
    91.            VoiceNames[VoiceNumber ] = gotchaVoiceName;
    92.          }
    93.        }
    94.      }
    95.      // return 0 >>> Init ok
    96.      if (VoiceNumber != 0)
    97.      {
    98.        VoiceInit =  Uni_Voice_Init();
    99.      } else VoiceInit = 1;
    100.  
    101.    }
    102.  
    103.  
    104.    public int Say(string textToSay)
    105.    {
    106.      // "This is <emph>very</emph> important!  This sounds normal <pitch middle = '+40'/> but the pitch drops half way through"
    107.      // "This is <emph>very</emph> important!. This is very important! "
    108.      // "<volume level="Level">  Text to be spoken</volume>"
    109.      // "<rate speed="-5">This text should be spoken at rate zero.</rate>" -10 to +10
    110.      // <silence msec='1000'/>
    111.      // "I will spell the word <spell>Love</spell> for you."
    112.      // "<voice required='Name=Microsoft Anna'> Hello i'm Anna. Have a nice day. <voice required='Name=IVONA 2 Amy'> It's Amy here. Good day too"
    113.      // "All system <emph>ready</emph>. Engine online, weapons online. We are ready. 9<silence msec='1000'/>8<silence msec='1000'/>7<silence msec='1000'/>6<silence msec='1000'/>5<silence msec='1000'/>4<silence msec='1000'/>3<silence msec='1000'/>2<silence msec='1000'/>1<silence msec='1000'/>0. Take off!!!"
    114.  
    115.      return Uni_Voice_Speak(textToSay);
    116.    }
    117.  
    118.    public int SayEX(string textToSay, int flagOfSpeak)
    119.    {
    120.      return Uni_Voice_SpeakEX(textToSay,flagOfSpeak );
    121.    }
    122.  
    123.    public int Status(int statToCheck)
    124.    {
    125.      // statToCheck = 0 >> return '2' for a running speak. '0' or '1' in other case.
    126.      // statToCheck = 1 >> return the position of the actual spoken word in the textToSay string. ;)
    127.      // ex for "Hello my friend" can return the position of H >> 1, m >> 7 and f >> 10
    128.  
    129.      // statToCheck = 2 >> return Total speak stream
    130.      // statToCheck = 3 >> return Actual speak stream  
    131.  
    132.      return (Uni_Voice_Status(statToCheck));
    133.    }
    134.  
    135.    void OnApplicationQuit()
    136.    {
    137.      Uni_Voice_Close();
    138.   }
    139. }
    140. // **************************************************************************
    141. // Unity Text To Speech V2 ZJP. Voice Manager
    142. // **************************************************************************
    143.  
    Unity C# Test
    Code (csharp):
    1.  
    2. // **************************************************************************
    3. // Unity Text To Speech V2 ZJP. Test Voice
    4. // **************************************************************************
    5. using UnityEngine;
    6.  
    7. public class TestVoice : MonoBehaviour
    8. {
    9.    public int voiceOk;
    10.    public int numVoice;
    11.    public string voiceName;
    12.    public VoiceManager vm;
    13.  
    14.    public string textesay;
    15.  
    16.    void Start ()
    17.    {
    18.      vm = GameObject.Find("VoiceManager").GetComponent<VoiceManager>();
    19.      numVoice  = vm.VoiceNumber;
    20.      voiceName = vm.VoiceNames[0];
    21.      Debug.Log("Voice number " + vm.VoiceNumber);
    22.      // textesay = "<voice required='" + voiceName + "'>" + sayThisText;
    23.      // textesay = "<voice required='" + vm.VoiceNames[i] + "'>" + sayThisText;
    24.      textesay = "<voice required='Name=Microsoft Anna'> Hello i'm Microsoft Anna. Have a nice day.";
    25.      vm.Say(textesay); // start a speech
    26.      //vm.SayEX("c:/text.txt",12);
    27.      //vm.SayEX("Hello, this is the default voice. The one", 1+8);
    28.      //vm.SayEX("<voice required='Name=" + voiceName + "'>" + "Hello, this is the voice 2", 1+8+32);
    29.      //vm.SayEX("Funny, it's the voice 2 again", 1+8);
    30.    }
    31.  
    32.    // Update is called once per frame
    33.    void Update ()
    34.    {
    35.      if (vm.Status(0) == 2 ) // a speech is running
    36.      {
    37.        Debug.Log(" Total Stream  > " + vm.Status(2));
    38.        Debug.Log(" Actual stream <<<<<<<<<<<<<<<<<<<<<<<<<<<<<> " + vm.Status(3));
    39.        Debug.Log(" Position of the actual spoken word in the actual stream > " + vm.Status(1));
    40.      }
    41.    }
    42.  
    43. }
    44.  
    45.  
     

    Attached Files:

    Last edited: Dec 7, 2015
    RavenMikal likes this.
  35. mipecr

    mipecr

    Joined:
    Dec 10, 2015
    Posts:
    5

    I got your code, and I created a DLL for 64bits and it works correctly.

    Here it is a unity package working.

    Thank you.
     

    Attached Files:

    ZJP, odival and RavenMikal like this.
  36. RavenMikal

    RavenMikal

    Joined:
    Oct 18, 2014
    Posts:
    144
    oooo....whats new in the new version? =)

    Never had a chance to thank you for the original, besides for what you made it for, it gave me a solid example of a dll that works with unity and making a c# wrapper for it ^_^
     
    ZJP likes this.
  37. KnightRiderGuy

    KnightRiderGuy

    Joined:
    Nov 23, 2014
    Posts:
    515
    Are there any kind of instructions on how to use this because it does not appear to do anything. I get a error message that says:
    Code (CSharp):
    1. DllNotFoundException: SAPI_UNITY_DLL
    2. VoiceManager.OnApplicationQuit () (at Assets/scripts/With SAPI DLL/VoiceManager.cs:136)
     
  38. mipecr

    mipecr

    Joined:
    Dec 10, 2015
    Posts:
    5

    I'v just tried in another computer and it works without doing anything, just pressing play in editor. I'm using Windows 8.1 x64.
    When you press play button, if you select "voiceManager", you can see a voice name list which are installed in your computer. Then you have to go to line 21 of TestVoice.cs and change the name of the voice, you have to write one of the list.
    However, your problem is different, your Unity doesn't find de DLL, but I don't know why.
     
  39. KnightRiderGuy

    KnightRiderGuy

    Joined:
    Nov 23, 2014
    Posts:
    515
    I'm using a Mac mipecr, maybe that might have something to do with it?
    I can click play and it does not give any kind of error that prevents from going into play mode, but thats as far as I can get with it. :(
     
  40. mipecr

    mipecr

    Joined:
    Dec 10, 2015
    Posts:
    5
    It's only for Windows but in Mac, I think there are other solutions.
     
  41. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    You're welcome.

    Thank to you. :cool:
    How have you solved the probleme?. Compiling with a 64B version of the...compiler?!.

    Bad news. It's for Windows OS. Sorry.
     
  42. KnightRiderGuy

    KnightRiderGuy

    Joined:
    Nov 23, 2014
    Posts:
    515
    Figures that was the problem, I should hook a monitor up to my backup PC and give it a try, thanks man :)
     
  43. mipecr

    mipecr

    Joined:
    Dec 10, 2015
    Posts:
    5
    I created a new solution in Visual Studio and I set the version to x64.
     
    ZJP likes this.
  44. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    ;) Of course.. :D
     
  45. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Last edited: Dec 18, 2015
  46. Southgarden116

    Southgarden116

    Joined:
    Oct 6, 2013
    Posts:
    1
    Thank you so much ZJP for this! I have a question though, somehow with this newer version I can't find the installed german voice Steffi. It worked with your first Version, but I can't get it to work with Unity 5, so I have to use this newer one of yours.
     
  47. thompsem

    thompsem

    Joined:
    Jan 4, 2016
    Posts:
    1
    Hi Guys,

    I know this is an old post, but I was hoping to get some help. This seems to be a pretty good working solutions for me, but is there anyway to save the voice sample to a .wav or .mp3 to be used later? The audio I am synthesizing is only temporary before our voice actor records, and I want to have my system set up to just drop the new audio files in when that time comes. Having audio files instead of run-time generation also helps out with some of the platforms we are working on. Any help of point in the right direction would be appreciated.
     
  48. WalterK2

    WalterK2

    Joined:
    Apr 24, 2016
    Posts:
    2
    Hi ZLP,
    I use your dll successfully, thank you for your work!
    I mainly do not write in Unity, but in XProfan, another programming language where your dll can be easily integrated too. Now I want to make the dll better known and usable by other XProfan users, but I also would like to use it in freeware programs and perhaps in commercial programs too. So my question: Is your dll freeware and can it be used in conjunction with own programms without limitations or are there any conditions?
    Thanks
    WalterK2
     
  49. pan-master

    pan-master

    Joined:
    Nov 11, 2013
    Posts:
    127
    can you do something Like Speak.Stop(); in the middle of talk.These Dll dont have Pause(), or Dispose() I guess?
     
    Last edited: May 25, 2016
  50. William_Lee_Sims

    William_Lee_Sims

    Joined:
    Oct 11, 2014
    Posts:
    40
    I use a free program like Audacity, poke through the various "microphone" options for recording your Windows audio and simply record while your program goes through all of the game's phrases.
     
Thread Status:
Not open for further replies.