Jump to content

Help with the eSpeak synthesizer DLL


Recommended Posts

Hello,

As I commented in this thread:

 

This link

 

I am trying to work with the eSpeak voice synthesizer.

It turns out that when I try to start the synthesizer, with the "espeak_Initialize" function, the program in AutoIT slams shut down without showing errors or anything.

The DLL is 32-bit, and I'm trying to use it on 64-bit Windows, with the 32-bit version of AutoIT (I know it works on 64-bit Windows, because there are applications that use this synthesizer on 64-bit Windows, such as NVDA:

 

Link of NVDA website

 

This is what appears in the eSpeak API header file, regarding the "espeak_Initialize" function

 

Quote

ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
/* Must be called before any synthesis functions are called.
output: the audio data can either be played by eSpeak or passed back by the SynthCallback function.
buflength:  The length in mS of sound buffers passed to the SynthCallback function.
Value=0 gives a default of 60mS.
This parameter is only used for AUDIO_OUTPUT_RETRIEVAL and AUDIO_OUTPUT_SYNCHRONOUS modes.
path: The directory which contains the espeak-ng-data directory, or NULL for the default location.
options: bit 0:  1=allow espeakEVENT_PHONEME events.
 bit 1:  1= espeakEVENT_PHONEME events give IPA phoneme names, not eSpeak phoneme names
 bit 15: 1=don't exit if espeak_data is not found (used for --help)
Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR).

 

I think the problem may be in the last parameter ("options"), that I must not be passing it right (although I have tried different ways) but I don't get along well with working at bit level.

In any case, I have tried passing a value as "int" and it doesn't work. As "byte" either, either one value or several, with BitOr()...

This is the code I have done. So that it is not so long, in the post I only put the AutoIT code. But I attach compressed, the same code including the eSpeak API header file so that you can have it at hand, and the eSpeak DLL, with the data directory, necessary for the voices.

 

Global Const $_eSpeak_API_Revision=12

      Global Const $_eSpeakRate_Minimum=80
      Global Const $_eSpeakRate_Maximum=450
      Global Const $_eSpeakRate_Normal=175

      Global Const $_eSpeakInitialize_Phoneme_Events=0x0001
      Global Const $_eSpeakInitialize_Phoneme_IPA=0x0002
      Global Const $_eSpeakInitialize_Dont_Exit=0x8000


      Global Const Enum Step +1 _ ;eSpeak_Event_Type
       $_eSpeakEvent_List_Terminated=0, _
       $_eSpeakEvent_Word=1, _
       $_eSpeakEvent_Sentence=2, _
       $_eSpeakEvent_Mark=3, _
       $_eSpeakEvent_Play=4, _
       $_eSpeakEvent_End=5, _
       $_eSpeakEvent_MSG_Terminated=6, _
       $_eSpeakEvent_Phoneme=7, _
       $_eSpeakEvent_SampleRate=8

      Global Const Enum Step +1 _ ;espeak_POSITION_TYPE
       $_Pos_Character=1, _
       $_Pos_Word, _
       $_Pos_Sentence

      Global Const Enum Step +1 _ ;espeak_AUDIO_OUTPUT
       $_Audio_Output_Playback, _
       $_Audio_Output_Retrieval, _
       $_Audio_Output_Synchronous, _
       $_Audio_Output_Synch_Playback _

      Global Const Enum Step +1 _ ;espeak_ERROR
       $_EE_OK=0, _
       $_EE_Internal_Error=-1, _
       $_EE_Buffer_Full=1, _
       $_EE_Not_Found=2


msgbox(0, "", "Starting eSpeak...")
MSGBox(0, "", "eSpeak API library returns:  "&eSpeak_Initialize())
Exit


   Func eSpeak_Initialize($ArgOutput=$_Audio_Output_Playback, $ArgBufLength=0, $ArgPath="")


      Local $BuffRetDLL
      Local $DLLHandle

     If ((Not IsNumber($ArgOutput) Or StringIsDigit($ArgOutput)==0) _
      Or (Not IsNumber($ArgBufLength) Or StringIsDigit($ArgBufLength)==0) _
      Or ($ArgPath<>"" And Not FileExists($ArgPath))) Then Return -1
     If $ArgPath=="" Then
      $ArgPath=@ScriptDir&"\espeak-ng-data"
     EndIf
     $DLLHandle=DLLOpen(@ScriptDir&"\espeak.dll")
      If $DLLHandle==-1 Then Return -1
     $BuffRetDLL=DLLCall($DLLHandle, _
      "int", "espeak_Initialize", _
      "int", $ArgOutput, _
      "int", $ArgBufLength, _
      "str", $ArgPath, _
      "int", BitOr($_eSpeakInitialize_Phoneme_Events, $_eSpeakInitialize_Phoneme_IPA))
     Return $BuffRetDLL

   EndFunc

 

eSpeak.rar

Thanks to anyone who can help me with this!

 

Link to comment
Share on other sites

You do not have any error handling on your code.  How do you expect finding a solution without knowing what went wrong ?  Please add messages about returned values and @error after each statement.

Make sure that if you run x86 you use 32bits DLL. And likewise, if you run x64, ensure you use 64bits DLL.

Link to comment
Share on other sites

Can you supply the console output from an execution of your script in the scite editor?

Where did you get the 32bit eSpeak DLL?  Did you build it yourself?

Edited by TheXman
Link to comment
Share on other sites

The eSpeak DLL along with the data directory I attached, I have taken it from NVDA, which I referenced in the first post: that's why I know it works, and it's not a problem running the DLL on 64-bit Windows. Because with NVDA (which is a screen reader) it works without problem.

The ideal would be to recompile the DLL for 64 bits. But I imagine that this DLL is not really eSpeak, but an interface to use the synthesizer. And I have not found the code for this DLL.
Anyway, I don't think it would be as easy to recompile the DLL for 64 bits, as to compile it again, without touching any code: I imagine that it would be necessary to make changes in the library code, and I don't have so much level of C++ as for that.

I don't use Scite. That's why I didn't put the console output: I usually program in notepad and compile directly with Au2exe.

I don't have any reference in the code to the DLL output, because it wouldn't do any good: the problem is that the AutoIT program closes, as soon as DLLCall is executed, so AutoIT doesn't have time to return anything.
So I'm afraid that even if I used Scite I wouldn't get any output from the console either.

if the code worked, the MSGBox() that invokes the eSpeak initialization function should be executed, even if it didn't return the DLL return; but at least it would mean that AutoIT is communicating correctly with the DLL.

Link to comment
Share on other sites

If you want to debate the need to supply the requested information or you just choose not to, that's fine.  Good luck!  Hopefully, others will provide the kind of "help" you're looking for.  :bye:

Edited by TheXman
Link to comment
Share on other sites

If providing console output from a script execution can help, even if the program shuts down abruptly, I have no problem doing so.
How do I get the console output from the script execution in Scite.

Thanks

Link to comment
Share on other sites

I finally managed to solve the problem with this DLL.

It was silly, but it took me days to figure it out, because I hadn't thought of it.

The problem was in the directory path of the eSpeak data, which must be passed to the espeak_Initialize() function. The path had an accent, since it is in Spanish; and that made that when calling espeak_Initialize() in the DLL, this one was closed suddenly.

Removing the accent to the route, it works without problem (although I have not coded all the functions yet). But at least it doesn't close the program, and espeak_Initialize() returns a value that seems to be correct.

Thanks for your help

Link to comment
Share on other sites

At the time that I had requested the the output from scite, I had already fixed the errors in your script and had it workingIn the script that you posted above, there's more than one error and none of those errors that I found had anything to do with the path to the eSpeak data files.  Maybe the accent in the path is another error, but it is definitely not the biggest one.

What was really silly was you not providing the information that I requested so that I could have confirmed what I needed to confirm and you could've moved on to getting additional help and finding out what the issues were with your script.  So you have apparently wasted several days still not finding the other errors in your example script and you are getting back what "seems" to be a correct value (meaning you don't even know for sure),  Why?  Because you didn't want to supply the answer to a simple request (which you never did by the way).   All you managed to do was piss off someone that had helped you before, was trying to help you again, and probably won't help you in the future. That's just brilliant...said no one!

Here's some advice for the future:  If you come here looking for help and want to ask questions, you can expect to have to answer a few too.  Otherwise, you can get ignored and waste a lot of time coming to conclusions that only "seem" correct (but most likely aren't). 

 

Edited by TheXman
Link to comment
Share on other sites

Well, I'm sorry that you got so angry, but:

 

If providing console output from a script execution can help, even if the program shuts down abruptly, I have no problem doing so.
How do I get the console output from the script execution in Scite.
Thanks

 

 

And I didn't get a response.

 

As I said, I don't use Scite, so I don't know how to do what you were asking me to do; it's not that I didn't want to provide the information you were asking for.

Anyway, I understand if you don't want to help me again, because no one is forcing you to do it.


And I appreciate that you helped me with the binding for this DLL, in another thread.

 

Best regards

 

Link to comment
Share on other sites

  • 9 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...