davidm / luacom

Microsoft Component Object Model (COM) binding for Lua
http://lua-users.org/wiki/LuaCom
Other
116 stars 51 forks source link

"Member not found" error trying to change SAPI voice #13

Open fiendish opened 8 years ago

fiendish commented 8 years ago

Mimicing the invocation to change SAPI voice shown in https://msdn.microsoft.com/en-us/library/ms723614%28v=vs.85%29.aspx

require "luacom"
talk = luacom.CreateObject("SAPI.SpVoice")
talk.Voice = talk:GetVoices():Item(0)

Gives error

COM error:(.\src\library\tLuaCOM.cpp,403):Member not found.

Thoughts on what might be wrong?

ignacio commented 8 years ago

Can we split the code to see where it is failing?

local luacom = require "luacom"
local talk = luacom.CreateObject("SAPI.SpVoice")
local voices = talk:GetVoices()
local voice = voices:Item(0)
talk.Voice = voice

Please provide the full stack trace of the error, to see the line in Lua code that triggers the error.

fiendish commented 8 years ago

GetVoices and Item both work fine. You can see by doing print(talk.Voice:GetDescription(), "--" , talk:GetVoices():Item(0):GetDescription())

On my machine e.g. this shows

Microsoft Mary -- Microsoft Mary

I'll have to look into maybe different build options to get more stack trace. All I have right now is:

stack traceback:

stdin:1: in main chunk

:/

fiendish commented 8 years ago

Sorry. I should clarify. I did this before and the failure seems to be at the final assignment to talk.Voice On Feb 25, 2016 6:17 PM, "Ignacio Burgueño" notifications@github.com wrote:

Can we split the code to see where it is failing?

local luacom = require "luacom" local talk = luacom.CreateObject("SAPI.SpVoice") local voices = talk:GetVoices() local voice = voices:Item(0) talk.Voice = voice

Please provide the full stack trace of the error, to see the line in Lua code that triggers the error.

— Reply to this email directly or view it on GitHub https://github.com/davidm/luacom/issues/13#issuecomment-188885193.

ignacio commented 8 years ago

Great. Voice is a property. When you read the value of a property, one method is called. When you assign something to it, a different method is called. This is usually handled transparently, until it is not :)

However, from what I could gather by using OleView (a tool that comes with Visual Studio, I think, that shows information about COM interfaces and so on), this should be handled correctly.

This is the interface:

interface ISpeechVoice : IDispatch {
        [id(0x00000001), propget, helpstring("Status")]
        HRESULT Status([out, retval] ISpeechVoiceStatus** Status);
        [id(0x00000002), propget, helpstring("Voice")]
        HRESULT Voice([out, retval] ISpeechObjectToken** Voice);
        [id(0x00000002), propputref, helpstring("Voice")]
        HRESULT Voice([in] ISpeechObjectToken* Voice);

(snip)

So, the 'Voice' property should work ok. Can you test if talk.Voice = nil gives an error too?

I would try the following: talk.SetVoice = talk:GetVoices():Item(0)

or talk.setVoice = talk:GetVoices():Item(0)

ignacio commented 8 years ago

By the way, which LuaCOM version are you using?

Anyway, I feel that propputref is not supported by luacom.

Does this work? talk.Rate = 10

fiendish commented 8 years ago

talk.Rate = 10 does work and alters the speech appropriately.

And this works! Which is what I'll use. talk:setVoice(talk:GetVoices():Item(0)) -- talk.Voice = fails so use :setVoice()

Thanks for that idea. I don't know that it closes the issue, but it solves my particular problem at least.

ignacio commented 8 years ago

It's great to hear that it worked :relieved:

From what I understand from the code (it's been years since I looked at it, though) is that the "set" in "setVoice" hints as to what to do with that function call (ie, strip the set prefix and treat Voice as a property).

Dealing with properties directly is already supported (the talk.Rate = 10 thing), so it seems to me that propputref properties don't work without these hints. It may be a matter of adding the relevant code. I don't have a working luacom build here with me so I cannot test. I'll leave this issue open, though.

Thanks a lot for the confirmation!