Text-to_Speech MS Agent Question

Hi,
  I am using MS Agent to develop my application

I write the following subroutine

int SpeakOut_Japanese(const CKBehaviorContext& BehContext)

{

      CKBehavior* beh = BehContext.Behavior;

        char sIP[300];
     beh->GetInputParameterValue(0, sIP);
     beh->SetOutputParameterValue(0,sIP);
     TCHAR wsIP[300];
     MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);

      
    static const LPWSTR kpwzCharacterOld=L"";
    static const LPTSTR kpszAppTitle="";
      
      HRESULT                        hRes;
      _TCHAR                        szError[256];
      VARIANT                        vPath;
      BSTR                        bszSpeak;
      long                        lCharID;
      long                        lRequestID;
      IAgentEx               *pAgentEx;
      IAgentCharacterEx  *pCharacterEx = NULL;

      hRes = CoCreateInstance(CLSID_AgentServer,
                                          NULL,
                                          CLSCTX_SERVER,
                                          IID_IAgentEx,
                                          (LPVOID *)&pAgentEx);


      

            // First try to load the default character

            VariantInit(&vPath);
            vPath.vt = VT_EMPTY;

            hRes = pAgentEx->Load(vPath, &lCharID, &lRequestID);
        hRes = pAgentEx->GetCharacterEx(lCharID, &pCharacterEx);
            hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
            hRes = pCharacterEx->Show(FALSE, &lRequestID);
            
            //bszSpeak = SysAllocString(L"Hello World!");
            //bszSpeak = SysAllocString(LsIP);
            hRes = pCharacterEx->Speak((LPWSTR)wsIP, NULL, &lRequestID);
            
            //SysFreeString(bszSpeak);
            Sleep(30000);
      
      return CKBR_OK;
}


hRes = pCharacterEx->Speak((LPWSTR)wsIP, NULL, &lRequestID);
This line supposes can speak out by the agent where (LPWSTR)wsIP is the input string by user in unicode.

But it doesn;t speak out.  any hints?  the agent can appear successfully.

gorexyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gorexyAuthor Commented:
anyone can help this ?
0
gorexyAuthor Commented:
seems it is quite hard...so I try to increase the point.

this code
MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);

will store the input array sIP into wsIP which will become unicode and so it can store chinese/japanese/ etc.

then
this code
hRes = pCharacterEx->Speak((LPWSTR)wsIP, NULL, &lRequestID);

will speak out the data from wsIP array.

but fail.
0
chip3dCommented:
>hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
this will set the speaker to english, thats why it fails to speak japanese...
hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL));

well, you also need a japanese voice: http://www.microsoft.com/msagent/downloads/user.asp#tts
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

gorexyAuthor Commented:
yes I donwload the agent alreay
and I can fix the input string
for example
bszSpeak = SysAllocString(L"2005年度 第4四半期 業績説明会");

it can speak a bit because the Japense cannot be read properly and so cannot speak well.  But at least it can produces sound

BUt I want to let user input their strings
so I wrote

MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);
so the input array will be encoded into unicode
then I pass wsIP into
hRes = pCharacterEx->Speak((LPWSTR)wsIP, NULL, &lRequestID);

fail to produce sound



0
chip3dCommented:
well, your string will not read any japanese character you want, cuz the decimalvalues you give will not be interpreted as one character
0
gorexyAuthor Commented:
oh..how come
it is not the numeric....it is japanese character in my file!
0
chip3dCommented:
hmm, ok, than i dont have the japanese font installed...
 
0
gorexyAuthor Commented:
ok ignore the japanese issue first may go back later
why
hRes = pCharacterEx->Speak((LPWSTR)wsIP, NULL, &lRequestID);
doesn't work even in English character?

0
chip3dCommented:
hmmm, i tried to send a wchar_t string directly to speak:
wchar_t text[] = L"Hello World!";
hRes = pCharacterEx->Speak(text, NULL, &lRequestID);
but this will return an out of memory error...
It seems that you have to allocate the string with SysAllocString
so try
bszSpeak = SysAllocString(wsIP);
hRes = pCharacterEx->Speak(bszSpeak, NULL, &lRequestID);
0
gorexyAuthor Commented:
so it works for you if you assign the memory?
0
chip3dCommented:
for english, yes
0
gorexyAuthor Commented:
so the final statement will be like this, right?

MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);
bszSpeak = SysAllocString(wsIP);
hRes = pCharacterEx->Speak(bszSpeak, NULL, &lRequestID);

Do you think the MultiByteToWiderChar can successfully make the input string into UNICODE so that it can display correctly?
0
gorexyAuthor Commented:
good news then....i really hope this can work on 2-byte characters as well so it can speak different languages.  

Will you go to test 2-byte char as well?

Highly appreciate and I learn a alots from you.
0
chip3dCommented:
ok, i got it...
yes 2byte characters are working well
but the agent need a localization file and a tts file for the language you want to use...
for japanese you need the lhttsjpj-3.exe (tts)
and the AgtX0411.exe (localization)
you will find both at http://www.microsoft.com/msagent/downloads/user.asp
just select japanese in the comboboxes and press downloadlink....

to aktivate the agent to be japanese, use
hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL));
before you call speak...

also inetresting could be
http://www.microsoft.com/msagent/support/user/tts.asp

If you want to speak english text you have so switch the langid again. The agent doesn't automatically detect the language for you...

this is my test, wich is working...
...
          hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL));

          if (FAILED(hRes))
               __leave;

          // Show the character.  The first parameter tells Microsoft
          // Agent to show the character by playing an animation.

          hRes = pCharacterEx->Show(FALSE, &lRequestID);
         
          if (FAILED(hRes))
               __leave;

          // Make the character speak
         
          wchar_t text[] = L"ユニセフ";
          bszSpeak = SysAllocString(text);
          hRes = pCharacterEx->Speak(bszSpeak, NULL, &lRequestID);

          SysFreeString(bszSpeak);
...
0
gorettiCommented:
oh....2 questions.
1. hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL));

why not
hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE));

2.  wchar_t text[] = L"ユニセフ";
          bszSpeak = SysAllocString(text);
          hRes = pCharacterEx->Speak(bszSpeak, NULL, &lRequestID);

why don't need to make it as UNICODE?

Also, did you see the Japanese characters in your wizard?  In my case, some a Jpanese and some are ???????  .

so that's why I think we need to use UNICODE instead.
0
gorexyAuthor Commented:
sorry..just try to use another account to login and reply question.
The above answer is from mine
0
chip3dCommented:
1) SUBLANG_JAPANESE doens't exist, cuz there is no sublanguage like enlish_us or english_gb...

2)  L"ユニセフ";  this is a unicode string, the website is porting the characters to xml variables.... So just use your string u hav e posted at the beginnig... or use wchar_t text1[] = {24180,24230,31532,22235,21322,21322,26399,26989,32318,35500,26126,20250,0}; as decimal input for a wchar_t string...

I can see the japanese characters in my wizard. You must have installed the localizationfile as i told you before and need to activate japanesesupport for windows: systemcontrol->region and language options->extended->10001 (MAC - japanese)
0
gorexyAuthor Commented:
>I can see the japanese characters in my wizard. You must have installed the localizationfile as >i told you before and need to activate japanesesupport for windows: systemcontrol->region >and language options->extended->10001 (MAC - japanese)

this is funny.

If I use my program to run, I cannot see the whole Japense, just some words are Japense but some are in quotation mark ???

then I try to run some sample on web and it works and I don't need to change the setting of the region.



0
gorexyAuthor Commented:
Also, what is the "L" used in
wchar_t text[] = L"Hello World!";    ??

can it still work if I write without "L"?

MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);
bszSpeak = SysAllocString(wsIP);
hRes = pCharacterEx->Speak(bszSpeak, NULL, &lRequestID);

0
chip3dCommented:
this L indicates that the following string is a two byte string...
this wsIP, what kind of string is it? char, wchar_t?

if i dont change the region, the agent says nothing and i got only |||||||||||| in the text window. If you look in the documetation for the agent or on the web in the agent faq, then all will tell you, you have to set the localiztion...
show me the sample on web...
wchar_t text1[] = {24180,24230,31532,22235,21322,21322,26399,26989,32318,35500,26126,20250,0};
this is the text you have wanted to speak in your first post... it working well the way i do it...

You will not find a agent doing automatically switching language for you. This is not very easy cuz for many languages you have to do complex frequent analyses, cuz for example, english, germen, french... all usinge the same characters...
0
gorexyAuthor Commented:
I use
MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);  to convert the input array sIP which was declared as char sIP[100] then make it as widechar (UNICODE? am I right?) and display the 2-byte string  Pls correct me if I am wrong


http://www.microsoft.com/msagent/dev/code/TryMSAgent.asp

you can put Japense inside and it will speak Japanese and the Japanese text display properly in the wizard


>>if i dont change the region, the agent says nothing and i got only |||||||||||| in the text
in my case, I didn';t change region, it can still speak Japanese but not the whole.  It can speak the Chinese like Japanese only. and the real Japanese will become ?????.

>You will not find a agent doing automatically switching language
NO I don't need this complicate.  I just use the whole sentence for 1 language only.  So I can fix that language.
0
chip3dCommented:
well, i can't read any japanes signs with the demo from microsoft...
mybe your systemdefaults are japanese and the default tts also

so, just set the langid you want to use, than the agent will choose the right voice, if he find one.
i can't say if the voice really says all correct in japanese, cuz i can't speak japanese :)

>MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);
You have to specify the correct codepage, or is this a real multibyte format you get?
does sIP have a valid sting?

I don't know anything about the CKBehaviorContext object? Is this a object fom windows lib? Is there any documentation?
0
gorettiCommented:
>mybe your systemdefaults are japanese and the default tts also
NO my default is Chinese.  when I put Japanese, it shows Japanese and when I put Chinese, it shows chinese..

>so, just set the langid you want to use, than the agent will choose the right voice, if he find >one.
yes but the problem is the input string will become ????? so it cannot speak properly.  That's why I want to use UNICODE.

does sIP have a valid sting?>
hm..yes it may not....so any suggestion to allow me to make sure the input string is unicdoe?

>KBehaviorContext object
this is from Virtools Dev.  
0
gorexyAuthor Commented:
Below is what I declare

char sIP[300];
beh->GetInputParameterValue(0, sIP); //  get input string and store in sIP Virtools Dev method
TCHAR wsIP[300];
MultiByteToWideChar(CP_ACP, 0, sIP, -1,  (LPWSTR)wsIP, 300);
0
gorexyAuthor Commented:
sorry one more question

>>if i dont change the region, the agent says nothing an

if in case, it really need to change region, is there any that VC++ can do so?
So I can make sure it is in the correct region

sorry to ask too many
0
chip3dCommented:
I think the MultiByteToWideChar will insert '?' if it cannot convert the string or when you use a wrong codepage to convert to unicode
with changing region i mean the langid for the agent:
hRes = pCharacterEx->SetLanguageID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE));
You must know what kind of language your unicodestring has and must set the correct langid before the agent can speak it correctly
0
gorexyAuthor Commented:
hi,
  I tried your code

wchar_t text[] = L"ユニセフ";
bszSpeak = SysAllocString(text);

but the wizard shows ??????? only

seems cannot display properly.
0
gorexyAuthor Commented:
it is funny.....the sampel page can display properly but why our code doesn;t
0
gorexyAuthor Commented:
oh..finally it displays properly
0
chip3dCommented:
what have you done to get the proper result?
0
chip3dCommented:
one thing to the problem why it is not speaking all letters correctly...

well i think its a problem of the sapi4, the agent is using. Sapi4 does not support unicode. So i think the agent will convert the 2byte string to a normal string via a codepage (it depends on the langid you have set). This means you have only less than 256 values for the letters. I far as i know you can only take a subset of the japanese letters for this table... Same for Chinese.
0
gorexyAuthor Commented:
now I do a trick to  "disable" the MS Agent to come out
I create my own character without display itself and the ballon.

Also, I don't use multibyte function and load the text directly from a text file (seems as user input is not working).  so it can displays properly.  and it can speak many different languages!

many thanks for your help so far!

now i face another unicode problem...but not related to VC++ (related to excel and MySQL)

the whole picture is user enter their own language (Japanese/chiense/french...) into Excel and data will be sent to MySQL to store.

When some data retrieve, the MS Agent will speak the corresponding language.

but I still figure out how Excel store UNICODE and MYSQL in order to feed into the MS Agent.

If you like to help, pls let me know.  anyway I learnt a lots from you here.  Thanks
0
chip3dCommented:
nice, good idea with the custom character :)

Do you open a unicode file? Does the agent automatically switch the languages?

Well i don't know for sure, but i think exel will save in two byte characters and MYSQL is using the UTF8 format. UTF8 is a multibyte unicode format.
0
gorexyAuthor Commented:
yes I open an unicode file and no it wll not switch langaue and I need to specify.  But it is ok to me, my applicaiton allow me to specifiy the object to speak different language.

so you mean EXCEL to MySQL will not work, right?
0
chip3dCommented:
well, no, maybe there are some export or import functions, but i do not know very much about excel and mysql... sorry.
0
gorexyAuthor Commented:
no problem it is ok
you help a lots already
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual C++.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.