[Mono-osx] P/invoking the OS X speech API?
Nolan Darilek
nolan at thewordnerd.info
Wed Feb 22 11:47:08 EST 2006
Ok, I've gotten rid of the segfault. Thanks for that tip.
I am, however, still not receiving speech, and I'm wondering if this
is perhaps due to the fact that I'm passing in a String where a void
* is expected, or perhaps there's some other magic I need to perform
to account for the fact that NewSpeechChannel accepts a pointer to a
SpeechChannel to populate whereas SpeakText expects the SpeechChannel
itself, and I'm using an IntPtr in both places. I initially tried
converting it to an Int32 (thinking that if the NewSpeechChannel
wanted a pointer to a struct and worked well with a pointer to an int
then perhaps a method that just wants the struct just might take an
int instead) but I suspected that was wrong even before I tried it,
and it doesn't appear to have worked besides. :)
Thoughts? Wrapping my mind around p/invoke is tying it into all kinds
of knots. :) Here's my new revision of the Channel class:
using System;
using System.Runtime.InteropServices;
namespace Meridian.Tts.Osx {
public class Channel {
private IntPtr _id;
protected const string _applicationServicesPath = "/System/Library/
Frameworks/ApplicationServices.framework/Versions/Current/
ApplicationServices";
[DllImport(_applicationServicesPath)]
private static extern short NewSpeechChannel(IntPtr voice, ref
IntPtr channel);
[DllImport(_applicationServicesPath)]
private static extern short SpeakText(IntPtr channel, String text,
long length);
public Channel() {
NewSpeechChannel((IntPtr)null, ref _id);
Speak("Hello, world.");
}
public bool Speak(String text) {
short rc = SpeakText(_id, text, (long)text.Length);
return (rc == 0);
}
}
}
On Feb 21, 2006, at 11:51 PM, kangaroo wrote:
> Nolan,
>
> It appears your problem is misunderstanding the C code (at least
> from my quick glance);
>
> SpeechChannel is a pointer to SpeechChannelRecord; meaning that the
> SpeechChannel* expected in NewSpeechChannel is in fact a
> SpeechChannelRecord** which you have collapsed to the structure.
>
> I'm also concerned about where the popuplation of the SpeechChannel
> is happening; I assume it is happening in native land in which case
> you probably want to use IntPtr and just pass the IntPtr around as
> needed rather than dealing with the structure. There is no point
> in bringing in that data if you dont need to.
>
> -kangaroo
>
> On 21-Feb-06, at 11:05 PM, Nolan Darilek wrote:
>
>> using System;
>> using System.Runtime.InteropServices;
>>
>> namespace Meridian.Tts.Osx {
>>
>> [StructLayout(LayoutKind.Sequential)]
>> struct SpeechChannel {
>> [MarshalAs(UnmanagedType.ByValArray, SizeConst=1)]
>> long[] data;
>> }
>>
>> public class Channel {
>>
>> private SpeechChannel _id;
>>
>> protected const string _applicationServicesPath = "/System/
>> Library/Frameworks/ApplicationServices.framework/Versions/Current/
>> ApplicationServices";
>>
>> [DllImport(_applicationServicesPath)]
>> private static extern short NewSpeechChannel(IntPtr voice, ref
>> SpeechChannel channel);
>>
>> [DllImport(_applicationServicesPath)]
>> private static extern short SpeakText(SpeechChannel channel,
>> String text, long length);
>>
>> public Channel() {
>> short rc = NewSpeechChannel((IntPtr)null, ref _id);
>> Console.WriteLine(rc);
>> Speak("Hello, world.");
>> }
>>
>> public bool Speak(String text) {
>> short rc = SpeakText(_id, text, (long)text.Length);
>> return (rc == 0);
>> }
>>
>> }
>> }
>
More information about the Mono-osx
mailing list