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. Firesuiry

    Firesuiry

    Joined:
    Jun 14, 2016
    Posts:
    4
    Have you solve this problem?I have the same problem
     
  2. RavenMikal

    RavenMikal

    Joined:
    Oct 18, 2014
    Posts:
    144
    are you running a 32 or 64 bit machine? Im running a 32 bit, so I had to make some minor changes and recompile the .dll...
     
  3. Harlock1980

    Harlock1980

    Joined:
    Sep 22, 2015
    Posts:
    4
    Hi, I'm having problems with the spanish voice.
    I have installed the spanish language (my entire OS) and Spanish Helena as a default voice.
    SAPI.cpl says everithing correct but, when I put accents like the word "más" Unity only says "m s", can you help me?
    Thank you
     
  4. Vortavasail

    Vortavasail

    Joined:
    Apr 22, 2016
    Posts:
    44
    this is working fine for me anyway to get this to work on and audio source ?
     
  5. Harlock1980

    Harlock1980

    Joined:
    Sep 22, 2015
    Posts:
    4
    Are you using spanish voices?
     
  6. LonK

    LonK

    Joined:
    Nov 24, 2012
    Posts:
    2
    @Harlock1980 I've figured out about your question, also using some other character languages can't get correct voice problem.
    The way to solve these speech incorrectly problem is..........

    1st. if you're using Windows 10, you can go your control panel, select about Speech function, to check your language pack has already download Speech voice resource completely.

    2nd. Make sure correct voice name, maybe the voice name is "Helena"
    you can also run that unitypackage above, open TestVoice.cs line23, remove remark label, it will also show correct voice full name.

    3rd. the language ID should be correct, such as Spanish's Language-Culture Code is "es-ES" and Language ID is "40a"

    4th. if your speech text is a string, you have to make a transfer your string encoding from ANSI to UTF-8. an easier way is to make a .txt file.

    5th. your text file should be like this...
    <lang langid='40a'><voice required='Name=Microsoft Hanhan Desktop'>Hola, Cómo lo haces</lang>

    6th. if you have made a .txt file, than the say function should be change to
    vm.SayEX(sayFilename,12);
    12 meas that string is a file name and have to include path.

    and then... press RUN and enjoy your correct language.

    I have succeed to make this say English, Spanish, French, Japanese and some other language.

    This dll is a really excellent resource, I'm very grateful the author sharing for us.

    the Only thing makes me upset is... Microsoft doesn't support South East Asia Country languages, I need Indonesian and Vietnamese Voice pack, still find nothing... =.="
     
  7. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Thanks.
    And Thanks for the hot-line. :cool:
     
    LonK likes this.
  8. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    I'm not 100% certain but I think this is bombing 5.6f03 - I've bug reported a few times - let's see what happens.

    EDIT: Yup, something about the Close it doesn't like in the strapped c lib looks like.
    Or some new intricacy/requirement/goof/breaking change in Unity's interop handling
    Or something even more random like needed to be built specifically for windows 10 64
    Or the stars are out of alignment.

    So

    Code (csharp):
    1. extern "C" void EXPORT_API Uni_Voice_Close()  
    2. // Release voice
    3. {   pVoice->lpVtbl->Release(pVoice);
    4.    // Finish COM
    5.    CoUninitialize();
    6. }
    7.  
    is
    Code (csharp):
    1.  
    2. ========== OUTPUTING STACK TRACE ==================
    3.  
    4. 0x00007FFD730C1201 (SAPI_UNITY_DLL) Uni_Voice_Close
    5. 0x0000000005884AB6 (Mono JIT Code) (wrapper managed-to-native) VoiceManager:Uni_Voice_Close ()
    6. 0x0000000005884A19 (Mono JIT Code) VoiceManager:OnApplicationQuit ()
    7. 0x000000000584F36B (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    8. 0x00007FFD5CC65703 (mono) mono_set_defaults
    9. 0x00007FFD5CBB8425 (mono) mono_runtime_invoke
    10.   ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF634F7FBC4)
    11. 0x00007FF634F7FBC4 (Klock)
    12.  
    for now

    Code (csharp):
    1.  
    2.     void OnApplicationQuit()
    3.     {
    4.     //    Uni_Voice_Close();
    5.     }
    6.  
    will stifle the errors and probably just leak a bit...
     
    Last edited: Apr 7, 2017
  9. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Case 899179 confirms that the issue is the DLL closing.
    (Many thanks Gytis for your quick repsonse)

    I have forwarded the details of this post and the code to that case.
    In the interim, can confirm that bypassing the proper close out will stop the bombing for now. (and the editor)
     
  10. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Very fast, indeed. Thanks. :cool:
     
  11. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Test case was tiny. Lots of detail. Never hurts. Might reach out to you. Here's hoping.
     
    ZJP likes this.
  12. nicokirb

    nicokirb

    Joined:
    Dec 1, 2016
    Posts:
    1
    Hi ZJP

    Is it possible to skip or end the speech while the voice is speaking?
    If yes, may I ask how do you implement it?
     
    WinterboltGames likes this.
  13. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    I need to know how this can be done too!

    If you found anything please send the info to me here at ARadwan620@gmail.com

    Thanks in advance!
     
  14. ZJP

    ZJP

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

    This DLL is based on the Microsoft SAPI. Something like , maybe. But the source need to be modified and this function need to be added.

    Or....

    With SayEX (Extended with Xml ) the flag SVSFPurgeBeforeSpeak : 'Purges all pending speak requests prior to this speak call' can help. Never try it before. So...
     
  15. Saikat_2016

    Saikat_2016

    Joined:
    Dec 21, 2016
    Posts:
    10
    Still showing "DllNotFoundException: Voice_speaker.dll error"....my Unity version is 5.3.4f1 my OS is Win7_64Bit, I already paste the Voice_speaker.dll in the C:\Windows\SysWOW64 folder...How is it possible
     
  16. ZJP

    ZJP

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

    New version here. :

    a) Can be compiled with the free DevCPP IDE (32 and 64B output). Add the ole32.lib to the project : >> Project >>
    Project Options >>> Parameters >> Linker >>> Add Lib...
    - Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32/libole32.a (32B)
    - Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib/libole32.a (64B)
    to prevent these compilations error :
    - undefined reference to `__imp_CoInitializeEx'
    - undefined reference to `__imp_CoCreateInstance'
    - undefined reference to `__imp_CoUninitialize'
    - undefined reference to `__imp_CoUninitialize'


    b) All problems with accents are solved. (Something to do with string, LPWSTR and Marshalling on C#) :D

    Source C++
    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. extern "C" int EXPORT_API Uni_Voice_Init(){
    13.     CoInitializeEx(NULL, COINIT_MULTITHREADED);
    14.    // Create SAPI voice
    15.    if(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice)){
    16.         // Couldn't create voice.
    17.         CoUninitialize();
    18.         return 1;
    19.    }
    20.    return 0;
    21. }
    22.  
    23. extern "C" int EXPORT_API Uni_Voice_Speak(LPWSTR texte)   {
    24.    if(pVoice->lpVtbl->Speak(pVoice,  texte, SPF_ASYNC|SPF_IS_XML, NULL)){
    25.  
    26.        return 1;
    27.    }
    28.    return 0;
    29. }
    30.  
    31. extern "C" int EXPORT_API Uni_Voice_SpeakEX(LPWSTR texte, int voiceFlag){
    32.    if(pVoice->lpVtbl->Speak(pVoice, texte, voiceFlag, NULL)){
    33.        return 1;
    34.    }
    35.    return 0;
    36. }
    37.  
    38. extern "C" int EXPORT_API Uni_Voice_Status(int stat){
    39.    pVoice->lpVtbl->GetStatus(pVoice, &eventStatus, NULL );
    40.    ULONG voiceStat;
    41.  
    42.    switch ( stat )   {
    43.         case 0:
    44.             voiceStat = eventStatus.dwRunningState; // 2 = speak is running
    45.             break;
    46.         case 1:
    47.             voiceStat = (eventStatus.ulInputWordPos) + 1; // start position of the actual speaked word
    48.             break;
    49.         case 2:
    50.             voiceStat = (eventStatus.ulLastStreamQueued); // The number of the last stream queued.
    51.             break;
    52.         case 3:
    53.             voiceStat = (eventStatus.ulCurrentStream); //The number of the current stream being synthesized or receiving output
    54.             break;
    55.  
    56.         default:
    57.              voiceStat = eventStatus.dwRunningState; // 2 = speak is running
    58.             break;
    59.     }
    60.    return (int)voiceStat;
    61. }
    62.  
    63. extern "C" int EXPORT_API Uni_Voice_Pause(){
    64.    pVoice->lpVtbl->Pause(pVoice);
    65.    return 0;
    66. }
    67.  
    68. extern "C" int EXPORT_API Uni_Voice_Resume(){
    69.    pVoice->lpVtbl->Resume(pVoice);
    70.    return 0;
    71. }
    72.  
    73.  
    74. extern "C" int EXPORT_API Uni_Voice_Rate(int rate){
    75.    pVoice->lpVtbl->SetRate(pVoice, rate );
    76.    return 0;
    77. }
    78.  
    79. extern "C" int EXPORT_API Uni_Voice_Volume(int volume){
    80.    pVoice->lpVtbl->SetVolume(pVoice, volume );
    81.    return 0;
    82. }
    83.  
    84.  
    85.  
    86. extern "C" void EXPORT_API Uni_Voice_Close(){
    87.    pVoice->lpVtbl->Release(pVoice);
    88.    // Finish COM
    89.    CoUninitialize();
    90. }
    91. // *****************************************************************
    92. // Voice to Unity3D DLL (c) ZJP
    93. // *****************************************************************
    94.  
    95.  

    The SAPI.H
    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.  
    296.  

    C# UNITY MANAGER
    Code (csharp):
    1.  
    2. // **************************************************************************
    3. //                Unity Text To Speech V2.2 ZJP. Voice Manager script
    4. // **************************************************************************
    5.  
    6. using UnityEngine;
    7. using System.Collections;
    8. using Microsoft.Win32;
    9. using System.Runtime.InteropServices;
    10.  
    11. public class VoiceManager : MonoBehaviour
    12. {
    13.    private int VoiceInit  = 0;
    14.    public int VoiceNumber = 0;
    15.    public string[] VoiceNames;
    16.  
    17.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Init();
    18.    [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Close();
    19.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Status(int voiceStat);
    20.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Speak([MarshalAs(UnmanagedType.LPWStr)]string TextToSpeech); // SPF_ASYNC & SPF_IS_XML
    21.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_SpeakEX([MarshalAs(UnmanagedType.LPWStr)]string TextToSpeech, int voiceFlag); // CUSTOM FLAG
    22.  
    23.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Volume(int volume); //  zero to 100
    24.    [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Rate(int rate); // -10 to 10
    25.  
    26.    [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Pause();
    27.    [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Resume();
    28.  
    29.  
    30.    // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    31.    /* 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
    32.  
    33.    SPF_DEFAULT
    34.        Specifies that the default settings should be used.  The defaults are:
    35.            * Speak the given text string synchronously
    36.            * Not purge pending speak requests
    37.            * Parse the text as XML only if the first character is a left-angle-bracket (<)
    38.            * Not persist global XML state changes across speak calls
    39.            * Not expand punctuation characters into words.
    40.        To override this default, use the other flag values given below.
    41.  
    42.    SPF_ASYNC
    43.        Specifies that the Speak call should be asynchronous. That is, it will return immediately after the speak request is queued.
    44.    SPF_PURGEBEFORESPEAK
    45.        Purges all pending speak requests prior to this speak call.
    46.    SPF_IS_FILENAME
    47.        The string passed to Uni_Voice_Speak is a file name, and the file text should be spoken.
    48.    SPF_IS_XML
    49.        The input text will be parsed for XML markup.
    50.    SPF_IS_NOT_XML
    51.        The input text will not be parsed for XML markup.
    52.    SPF_PERSIST_XML
    53.        Global state changes in the XML markup will persist across speak calls.
    54.    SPF_NLP_SPEAK_PUNC
    55.        Punctuation characters should be expanded into words (e.g. "This is a sentence." would become "This is a sentence period").
    56.    SPF_PARSE_SAPI
    57.        Force XML parsing As MS SAPI.
    58.    SPF_PARSE_SSML
    59.        Force XML parsing As W3C SSML.
    60.    */
    61.  
    62.    const int SPF_DEFAULT          = 0;
    63.    const int SPF_ASYNC            = 1;
    64.    const int SPF_PURGEBEFORESPEAK = 2;
    65.    const int SPF_IS_FILENAME      = 4;
    66.    const int SPF_IS_XML           = 8;
    67.    const int SPF_IS_NOT_XML       = 16;
    68.    const int SPF_PERSIST_XML      = 32;
    69.    const int SPF_NLP_SPEAK_PUNC   = 64;
    70.    const int SPF_PARSE_SAPI       = 128;
    71.    const int SPF_PARSE_SSML       = 256;
    72.    // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    73.  
    74.    // Use this for initialization
    75.    public int Init()
    76.    {
    77.        // Info (64Bits OS):
    78.        // Executing Windows\sysWOW64\speech\SpeechUX\SAPI.cpl brings up a Window that displays (!) all of the 32 bit Voices
    79.        // and the current single 64 bit Voice "Anna".
    80.      
    81.        // HKEY_LOCAL_MACHINE\\SOFTWARE\Microsoft\Speech\\Voices\\Tokens\\xxxVOICExxxINSTALLEDxxx\\Attributes >>> (Name)
    82.        const string speechTokens = "Software\\Microsoft\\Speech\\Voices\\Tokens";
    83.      
    84.        using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(speechTokens))
    85.        {
    86.            VoiceNumber = registryKey.SubKeyCount; // key found not mean true voice number !!!
    87.            VoiceNames  = new string[VoiceNumber + 1];
    88.            VoiceNumber = 0;
    89.            foreach (var regKeyFound in registryKey.GetSubKeyNames())
    90.            {
    91.                //Debug.Log(regKeyFound);
    92.                string finalKey = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\" + regKeyFound + "\\Attributes";
    93.                //Debug.Log(finalKey);
    94.                string gotchaVoiceName = "";
    95.                gotchaVoiceName = (string)Registry.GetValue (finalKey, "Name", "");
    96.                if (gotchaVoiceName != "")
    97.                {
    98.                    //Debug.Log("Langage Name = " + gotchaVoiceName);
    99.                    VoiceNumber++; // increase the real voice number..
    100.                    VoiceNames[VoiceNumber ] = gotchaVoiceName;
    101.                }
    102.            }
    103.        }
    104.        // return 0 >>> Init ok
    105.        if (VoiceNumber != 0)
    106.        {
    107.            VoiceInit =  Uni_Voice_Init();
    108.        } else VoiceInit = 1;
    109.        return VoiceInit;
    110.    }
    111.  
    112.  
    113.    public int Say(string textToSay)
    114.    {
    115.        // https://msdn.microsoft.com/en-us/library/ms717077(v=vs.85).aspx
    116.  
    117.        // "This is <emph>very</emph> important!  This sounds normal <pitch middle = '+40'/> but the pitch drops half way through"
    118.        // "This is <emph>very</emph> important!. This is very important! "
    119.        // "<volume level="Level">  Text to be spoken</volume>"
    120.        // "<rate speed="-5">This text should be spoken at rate zero.</rate>" -10 to +10
    121.        // "<silence msec='1000'/>"
    122.        // "I will spell the word <spell>Love</spell> for you."
    123.        // "<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"
    124.        // "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!!!"
    125.        return Uni_Voice_Speak(textToSay);
    126.    }
    127.  
    128.    public int SayEX(string textToSay, int flagOfSpeak)
    129.    {
    130.        return Uni_Voice_SpeakEX(textToSay, flagOfSpeak );
    131.    }
    132.  
    133.    public int Status(int statToCheck)
    134.    {
    135.        // statToCheck = 0 >> return '2' for a running speak. '0' or '1' in other case.
    136.        // statToCheck = 1 >> return the position of the actual spoken word in the textToSay string. ;)
    137.        //        ex for "Hello my friend" can return the position of H >> 1, m >> 7 and f >> 10
    138.        // statToCheck = 2 >> return Total speak stream
    139.        // statToCheck = 3 >> return Actual speak stream
    140.        return (Uni_Voice_Status(statToCheck));
    141.    }
    142.  
    143.    public void Volume(int vol)
    144.    {
    145.        Uni_Voice_Volume(vol); //  zero to 100
    146.    }
    147.  
    148.    public void Rate(int rat)
    149.    {
    150.        Uni_Voice_Rate(rat); // -10 to 10
    151.    }
    152.  
    153.    public void Pause()
    154.    {
    155.        Uni_Voice_Pause();
    156.    }
    157.  
    158.    public void Resume()
    159.    {
    160.        Uni_Voice_Resume();
    161.    }
    162.  
    163.  
    164.  
    165.    void OnApplicationQuit()
    166.    {
    167.        Uni_Voice_Close();
    168.    }
    169. }
    170. // **************************************************************************
    171. //               Unity Text To Speech V2 ZJP. Voice Manager
    172. // **************************************************************************
    173.  
    174.  
    175.  

    C# TEST CODE

    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 numVoice;
    10.    public int voiceOK;
    11.    public string voiceName;
    12.    public VoiceManager vm;
    13.  
    14.    public string textesay;
    15.  
    16.    void Start (){
    17.        vm = GetComponent<VoiceManager>();
    18.        voiceOK = vm.Init();
    19.        if (voiceOK != 1){
    20.            //voiceName = vm.VoiceNames[1];
    21.            //Debug.Log("Voice number " + vm.VoiceNumber + " " + voiceName );
    22.            //textesay = "Hello. My name is Anna, and i am a woman. It's nice to meet you. Have a nice day and goodbye.";
    23.            //vm.Say (textesay);
    24.            //vm.SayEX("Funny, it's the same voice again", 1+8);
    25.            textesay = "<voice required='Name=Bernard'> bonjour, je suis Bernard. Léger, là-bas, expliqué <voice required='Name=Juliette'> Et moi, je me nome Juliette.";
    26.            vm.Say (textesay);
    27.        }
    28.    }
    29.    // Update is called once per frame
    30.    void Update (){
    31.        if (voiceOK != 1 && vm.Status(0) == 2 ) // a speech is running
    32.        {
    33.            Debug.Log(" Total Stream  > " + vm.Status(2));
    34.            Debug.Log(" Actual stream <<<<<<<<<<<<<<<<<<<<<<<<<<<<<> " + vm.Status(3));
    35.            Debug.Log(" Position of the actual spoken word in the actual stream > " + vm.Status(1));
    36.        }
    37.    }
    38.  
    39. }
    40.  
    41.  

    Manager and test (or final) script can be placed on the same GameObject.for this, do not forgot to change the Script Execution Order of the Manager : before the other ones.


    This DLL works on Windows 7, 8, 8.1, 10, 32 and 64B and on Unity 5.x, 2017.x


    Sorry for the late response. :confused:


    Your are free to include this DLL in any app or project you want.
    You are free to modify and change anything you want. Yes, even the copyright and my name. :p



    Have fun.
     

    Attached Files:

    Last edited: Jan 3, 2018
    myownbot and Pulas like this.
  17. WalterK2

    WalterK2

    Joined:
    Apr 24, 2016
    Posts:
    2
    Thank You!
     
  18. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
  19. myownbot

    myownbot

    Joined:
    Mar 30, 2017
    Posts:
    29
  20. myownbot

    myownbot

    Joined:
    Mar 30, 2017
    Posts:
    29
    Then I copied the DLL into the asset folder as well, and voila! THE ERROR was GONE!
    And the Voice manager finds installed languages. The first entry is empty though, but I don't care much.
    As you can see my notebook speaks Japanese as default language. I can use the English language as well.

    I'D LIKE TO THANK ZJP FOR SHARING THIS ASSET!!!!

    Screenshot_5.png Screenshot_6.png Screenshot_7.png
     
  21. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
  22. myownbot

    myownbot

    Joined:
    Mar 30, 2017
    Posts:
    29
    Hello!

    I did not like the idea of having the initialization stuff of the Voice manager sit on a certain game object. Others would have to search for it to be able to use.

    I put it into a singleton class whereas the Init() function is called on awake. if init was successful, the instance is created, if not, the instance stays null and the NullReferenceException will be thown on runtime.

    This allows for creating a prefab out of this for easier referencing in the code (no hussle with GetComponent<VoiceManager>()).

    to make a prefab and use it, do the following (nothing fancy)

    1. create empty object and attach this script to it
    2. pull this game object into a folder of your choice in Project folder => a prefab will be created
    3. delete the game object in the hierarchy
    4. drop the prefab into Hierarchy
    5. access like TTS.VoiceManager.Instance.Say ("hello world!"); from where ever you are!


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Serialization;
    5.  
    6. using Microsoft.Win32;
    7. using System.Runtime.InteropServices;
    8.  
    9. namespace TTS
    10. {
    11.     public class VoiceManager : MonoBehaviour
    12.     {
    13.         private int VoiceInit  = 0;
    14.         public int VoiceNumber = 0;
    15.         public string[] VoiceNames;
    16.         public bool initOK;
    17.  
    18.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Init();
    19.         [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Close();
    20.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Status(int voiceStat);
    21.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Speak([MarshalAs(UnmanagedType.LPWStr)]string TextToSpeech); // SPF_ASYNC & SPF_IS_XML
    22.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_SpeakEX([MarshalAs(UnmanagedType.LPWStr)]string TextToSpeech, int voiceFlag); // CUSTOM FLAG
    23.  
    24.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Volume(int volume); //  zero to 100
    25.         [DllImport ("SAPI_UNITY_DLL")] private static extern int  Uni_Voice_Rate(int rate); // -10 to 10
    26.  
    27.         [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Pause();
    28.         [DllImport ("SAPI_UNITY_DLL")] private static extern void Uni_Voice_Resume();
    29.  
    30.  
    31.         // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    32.         /* 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
    33.    SPF_DEFAULT
    34.        Specifies that the default settings should be used.  The defaults are:
    35.            * Speak the given text string synchronously
    36.            * Not purge pending speak requests
    37.            * Parse the text as XML only if the first character is a left-angle-bracket (<)
    38.            * Not persist global XML state changes across speak calls
    39.            * Not expand punctuation characters into words.
    40.        To override this default, use the other flag values given below.
    41.    SPF_ASYNC
    42.        Specifies that the Speak call should be asynchronous. That is, it will return immediately after the speak request is queued.
    43.    SPF_PURGEBEFORESPEAK
    44.        Purges all pending speak requests prior to this speak call.
    45.    SPF_IS_FILENAME
    46.        The string passed to Uni_Voice_Speak is a file name, and the file text should be spoken.
    47.    SPF_IS_XML
    48.        The input text will be parsed for XML markup.
    49.    SPF_IS_NOT_XML
    50.        The input text will not be parsed for XML markup.
    51.    SPF_PERSIST_XML
    52.        Global state changes in the XML markup will persist across speak calls.
    53.    SPF_NLP_SPEAK_PUNC
    54.        Punctuation characters should be expanded into words (e.g. "This is a sentence." would become "This is a sentence period").
    55.    SPF_PARSE_SAPI
    56.        Force XML parsing As MS SAPI.
    57.    SPF_PARSE_SSML
    58.        Force XML parsing As W3C SSML.
    59.    */
    60.  
    61.         const int SPF_DEFAULT          = 0;
    62.         const int SPF_ASYNC            = 1;
    63.         const int SPF_PURGEBEFORESPEAK = 2;
    64.         const int SPF_IS_FILENAME      = 4;
    65.         const int SPF_IS_XML           = 8;
    66.         const int SPF_IS_NOT_XML       = 16;
    67.         const int SPF_PERSIST_XML      = 32;
    68.         const int SPF_NLP_SPEAK_PUNC   = 64;
    69.         const int SPF_PARSE_SAPI       = 128;
    70.         const int SPF_PARSE_SSML       = 256;
    71.         // CUSTOM VOICE FLAG !!! ******************************************************************************************************************
    72.  
    73.         private static VoiceManager _instance;
    74.         public static VoiceManager Instance {
    75.             get {
    76.                 UnityEngine.Assertions.Assert.IsNotNull(_instance, "The static variable for Instance has not been set. Did you do this call before Awake() has finished or unchecked \"Is Singleton\" maybe?");
    77.                 return _instance;
    78.             }
    79.         }
    80.  
    81.         protected void Awake()
    82.         {
    83.             UnityEngine.Assertions.Assert.IsNull(_instance, "_intance was not null. Do you maybe have several Speech Bubble Managers in your scene, all trying to be singletons?");
    84.  
    85.             int res = Init ();
    86.             if (res != 1)
    87.             {
    88.                 _instance = this;
    89.             }
    90.             else
    91.             {
    92.                 _instance = null;
    93.             }
    94.         }
    95.  
    96.         // Use this for initialization
    97.         public int Init()
    98.         {
    99.             // Info (64Bits OS):
    100.             // Executing Windows\sysWOW64\speech\SpeechUX\SAPI.cpl brings up a Window that displays (!) all of the 32 bit Voices
    101.             // and the current single 64 bit Voice "Anna".
    102.  
    103.             // HKEY_LOCAL_MACHINE\\SOFTWARE\Microsoft\Speech\\Voices\\Tokens\\xxxVOICExxxINSTALLEDxxx\\Attributes >>> (Name)
    104.             const string speechTokens = "Software\\Microsoft\\Speech\\Voices\\Tokens";
    105.  
    106.             using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(speechTokens))
    107.             {
    108.                 VoiceNumber = registryKey.SubKeyCount; // key found not mean true voice number !!!
    109.                 VoiceNames  = new string[VoiceNumber + 1];
    110.                 VoiceNumber = 0;
    111.                 foreach (var regKeyFound in registryKey.GetSubKeyNames())
    112.                 {
    113.                     //Debug.Log(regKeyFound);
    114.                     string finalKey = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\" + regKeyFound + "\\Attributes";
    115.                     //Debug.Log(finalKey);
    116.                     string gotchaVoiceName = "";
    117.                     gotchaVoiceName = (string)Registry.GetValue (finalKey, "Name", "");
    118.                     if (gotchaVoiceName != "")
    119.                     {
    120.                         //Debug.Log("Langage Name = " + gotchaVoiceName);
    121.                         VoiceNumber++; // increase the real voice number..
    122.                         VoiceNames[VoiceNumber ] = gotchaVoiceName;
    123.                     }
    124.                 }
    125.             }
    126.             // return 0 >>> Init ok
    127.             if (VoiceNumber != 0)
    128.             {
    129.                 VoiceInit =  Uni_Voice_Init();
    130.             }
    131.             else VoiceInit = 1;
    132.  
    133.             return VoiceInit;
    134.         }
    135.  
    136.  
    137.         public int Say(string textToSay)
    138.         {
    139.             // https://msdn.microsoft.com/en-us/library/ms717077(v=vs.85).aspx
    140.  
    141.             // "This is <emph>very</emph> important!  This sounds normal <pitch middle = '+40'/> but the pitch drops half way through"
    142.             // "This is <emph>very</emph> important!. This is very important! "
    143.             // "<volume level="Level">  Text to be spoken</volume>"
    144.             // "<rate speed="-5">This text should be spoken at rate zero.</rate>" -10 to +10
    145.             // "<silence msec='1000'/>"
    146.             // "I will spell the word <spell>Love</spell> for you."
    147.             // "<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"
    148.             // "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!!!"
    149.             return Uni_Voice_Speak(textToSay);
    150.         }
    151.  
    152.         public int SayEX(string textToSay, int flagOfSpeak)
    153.         {
    154.             return Uni_Voice_SpeakEX(textToSay, flagOfSpeak );
    155.         }
    156.  
    157.         public int Status(int statToCheck)
    158.         {
    159.             // statToCheck = 0 >> return '2' for a running speak. '0' or '1' in other case.
    160.             // statToCheck = 1 >> return the position of the actual spoken word in the textToSay string. ;)
    161.             //        ex for "Hello my friend" can return the position of H >> 1, m >> 7 and f >> 10
    162.             // statToCheck = 2 >> return Total speak stream
    163.             // statToCheck = 3 >> return Actual speak stream
    164.             return (Uni_Voice_Status(statToCheck));
    165.         }
    166.  
    167.         public void Volume(int vol)
    168.         {
    169.             Uni_Voice_Volume(vol); //  zero to 100
    170.         }
    171.  
    172.         public void Rate(int rat)
    173.         {
    174.             Uni_Voice_Rate(rat); // -10 to 10
    175.         }
    176.  
    177.         public void Pause()
    178.         {
    179.             Uni_Voice_Pause();
    180.         }
    181.  
    182.         public void Resume()
    183.         {
    184.             Uni_Voice_Resume();
    185.         }
    186.  
    187.         void OnApplicationQuit()
    188.         {
    189.             Uni_Voice_Close();
    190.         }
    191.  
    192.     // **************************************************************************
    193.     //               Unity Text To Speech V2 ZJP. Voice Manager
    194.     // **************************************************************************
    195.     }
    196. }
    197.  
     

    Attached Files:

    RavenMikal likes this.
  23. Lumaan

    Lumaan

    Joined:
    Aug 1, 2015
    Posts:
    1
    I whis this file was maned "Voice_speaker.dll" then I be able to use it with "Wasteland 2 Director's Cut", it's 64bits.
    The "Wasteland 2" I can use the 1st one and 32bits, but I will rather the 64bits version (And looks better).

     
  24. RavenMikal

    RavenMikal

    Joined:
    Oct 18, 2014
    Posts:
    144
    Its been a good while since I've messed with it, but I remember having to change a few references in regards to 32bit to 64bit and built as a 64 bit and it worked...Don't remember the details, but I do remember being surprised at how easy it was, like seriously it was a first try type of thing.
     
  25. DaveStrs

    DaveStrs

    Joined:
    Mar 28, 2024
    Posts:
    1
    Your are free to include this DLL in any app or project you want.
    You are free to modify and change anything you want. Yes, even the copyright and my name. :p

    no bro you are legend

    i look around like every corners for specific dll which i can use in github in every forums but you are legend i got what i was looking for thanks a lot man if i release my mods ill credit you you are the best
     
  26. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,487
    Please use the "Like" button to show appreciation. Please do not necropost on these forums.

    Thanks.
     
Thread Status:
Not open for further replies.