有没有人为iOS的Nuance Dragon移动语音SDK创build了一个MonoTouch绑定?

我有在Windows Phone 7上运行良好的龙移动SDK,我想获得适用于iOS的等效function。 由于SDK包装了麦克风,因此在我的MonoTouch项目中使用.NET程序集是不太可能的(即使我有源码)。 看来最好的办法是创build一个绑定库(如Miguel 在这里所描述的)。

它确实看起来像很多工作,但我很乐意重用,而不是重新发明轮子,如果有人已经做到了这一点… …

以下是我如何得到这个工作的更多细节。

  1. 我下载了绑定的样本 。 你可能会试图跳过这一步,但是如果你想让这个工作起作用,你真的必须从这个项目开始。
  2. 我用Xcode(我称之为SpeechKitLibrary)创build了一个Objective-C库,它有一个双重用途 – 一个是定义SpeechKitApplicationKey(这是SpeechKit需要的一个外部依赖):

    const unsigned char SpeechKitApplicationKey[] = {...}; 

    另一个是定义一个使用SpeechKit框架的类,并且与它链接。 (在Xcode中,将SpeechKit框架添加到项目的框架部分中)。

    我写的.m文件看起来像这样…(你可以找出.h文件 – 超级简单)。 我不是100%确定你需要所有这一切,但我想确保从这一步出来的静态归档库将导入正确的符号。 你或许可以避免这种情况,但在我的实验中,我发现我需要做这样的事情…

     // the SpeechKitWrapper isn't actually used - rather, it is a way to exercise all the API's that // the binding library needs from the SpeechKit framework, so that those can be linked into the generated .a file. @implementation SpeechKitWrapper @synthesize status; - (id)initWithDelegate:(id <SKRecognizerDelegate>)delegate { self = [super init]; if (self) { del = delegate; [self setStatus:@"initializing"]; SpeechKit setupWithID:@"NMDPTRIAL_ogazitt20120220010133" host:@"sandbox.nmdp.nuancemobility.net" port:443 useSSL:NO delegate:nil]; NSString *text = [NSString stringWithFormat:@"initialized. sessionid = %@", [SpeechKit sessionID]]; [self setStatus:text]; SKEarcon* earconStart = [SKEarcon earconWithName:@"beep.wav"]; [SpeechKit setEarcon:earconStart forType:SKStartRecordingEarconType]; voiceSearch = [[SKRecognizer alloc] initWithType:SKDictationRecognizerType detection:SKLongEndOfSpeechDetection language:@"en_US" delegate:delegate]; text = [NSString stringWithFormat:@"recognizer connecting. sessionid = %@", [SpeechKit sessionID]]; [self setStatus:text]; } return self; } @end 
  3. 然后我编译/链接了三种不同架构的静态存档 – i386,arm6和arm7。 BindingSample中的Makefile是如何执行此操作的模板。 但networking是你有三个库 – libSpeechKitLibrary- {i386,arm6,arm7} .a。 makefile然后使用OSX lipo(1)工具创build一个通用库(libSpeechKitLibraryUniversal.a)。

  4. 只有现在你准备好创build一个绑定库了。 您可以在绑定示例中重用AssemblyInfo.cs(将显示如何在通用库上为所有体系结构创build导入,并将驱动一些编译标志)。

     [assembly: LinkWith ("libSpeechKitLibraryUniversal.a", LinkTarget.Simulator | LinkTarget.ArmV6 | LinkTarget.ArmV7, ForceLoad = true)] 
  5. 你用btouch按照Makefile编译ApiDefinition.cs文件(我想我需要在StructsAndEnums.cs中重复一些信息来使其工作)。 注意 – 我没有去工作的唯一function是“SetEarcon”的东西 – 因为这是一个档案库,而不是一个框架,我不能捆绑一个WAV作为资源文件…我无法图了解如何让SetEarcon方法接受来自我的应用程序包的资源。

     using System; using MonoTouch.Foundation; namespace Nuance.SpeechKit { // SKEarcon.h public enum SKEarconType { SKStartRecordingEarconType = 1, SKStopRecordingEarconType = 2, SKCancelRecordingEarconType = 3, }; // SKRecognizer.h public enum SKEndOfSpeechDetection { SKNoEndOfSpeechDetection = 1, SKShortEndOfSpeechDetection = 2, SKLongEndOfSpeechDetection = 3, }; public static class SKRecognizerType { public static string SKDictationRecognizerType = "dictation"; public static string SKWebSearchRecognizerType = "websearch"; }; // SpeechKitErrors.h public enum SpeechKitErrors { SKServerConnectionError = 1, SKServerRetryError = 2, SKRecognizerError = 3, SKVocalizerError = 4, SKCancelledError = 5, }; // SKEarcon.h [BaseType(typeof(NSObject))] interface SKEarcon { [Export("initWithContentsOfFile:")] IntPtr Constructor(string path); [Static, Export("earconWithName:")] SKEarcon FromName(string name); } // SKRecognition.h [BaseType(typeof(NSObject))] interface SKRecognition { [Export("results")] string[] Results { get; } [Export("scores")] NSNumber[] Scores { get; } [Export("suggestion")] string Suggestion { get; } [Export("firstResult")] string FirstResult(); } // SKRecognizer.h [BaseType(typeof(NSObject))] interface SKRecognizer { [Export("audioLevel")] float AudioLevel { get; } [Export ("initWithType:detection:language:delegate:")] IntPtr Constructor (string type, SKEndOfSpeechDetection detection, string language, SKRecognizerDelegate del); [Export("stopRecording")] void StopRecording(); [Export("cancel")] void Cancel(); /* [Field ("SKSearchRecognizerType", "__Internal")] NSString SKSearchRecognizerType { get; } [Field ("SKDictationRecognizerType", "__Internal")] NSString SKDictationRecognizerType { get; } */ } [BaseType(typeof(NSObject))] [Model] interface SKRecognizerDelegate { [Export("recognizerDidBeginRecording:")] void OnRecordingBegin (SKRecognizer recognizer); [Export("recognizerDidFinishRecording:")] void OnRecordingDone (SKRecognizer recognizer); [Export("recognizer:didFinishWithResults:")] [Abstract] void OnResults (SKRecognizer recognizer, SKRecognition results); [Export("recognizer:didFinishWithError:suggestion:")] [Abstract] void OnError (SKRecognizer recognizer, NSError error, string suggestion); } // speechkit.h [BaseType(typeof(NSObject))] interface SpeechKit { [Static, Export("setupWithID:host:port:useSSL:delegate:")] void Initialize(string id, string host, int port, bool useSSL, [NullAllowed] SpeechKitDelegate del); [Static, Export("destroy")] void Destroy(); [Static, Export("sessionID")] string GetSessionID(); [Static, Export("setEarcon:forType:")] void SetEarcon(SKEarcon earcon, SKEarconType type); } [BaseType(typeof(NSObject))] [Model] interface SpeechKitDelegate { [Export("destroyed")] void Destroyed(); } [BaseType(typeof(NSObject))] interface SpeechKitWrapper { [Export("initWithDelegate:")] IntPtr Constructor(SKRecognizerDelegate del); [Export("status")] string Status { get; set; } } } 
  6. 您现在有一个程序集可以被monodouch应用程序项目引用。 现在最重要的事情就是记住要链接所有依赖关系的框架(不仅是SpeeckKit,还包括SK的依赖关系) – 通过传递mtouch一些额外的参数来实现:

     -gcc_flags "-F<insert_framework_path_here> -framework SpeechKit -framework SystemConfiguration -framework Security -framework AVFoundation -framework AudioToolbox" 

就这样,伙计们! 希望这是有帮助的…

如果有人(科斯或其他)获得SetEarcon方法的工作,请张贴解决scheme:-)

Nuance的SDK协议不足以让任何人甚至为其iOS SDK发布与MonoTouch一起使用的绑定。 但图书馆本身应该工作得很好。

这就是说,SDK只有less数types可以映射,而且对于其他人可能已经完成的工作来说,这样的工作是相当简单的。 您可以在这里查看如何使用参考指南来绑定程序集:

http://docs.xamarin.com/ios/advanced_topics/binding_objective-c_types

还有一个BindingSample项目,可以帮助用户更好地理解如何使用btouch绑定本地组件:

https://github.com/xamarin/monotouch-samples/tree/master/BindingSample

再次感谢Anuj您的回答。 我想我会留下一两个关于如何做到这一点。 绑定库不是很难build立(仍然调整,但它不是一个困难的任务)。

更隐晦的部分是搞清楚如何获得SpeechKit框架链接。 样本仅显示如何链接.a或.dylib。 在OSX的ld(1)手册页上花了一点时间之后,它看起来像用于链接框架的正确的ld(因此gcc)参数如下所示:

 -gcc_flags "-F<insert_framework_path_here> -framework SpeechKit" 

你把它放在项目属性的文本框中 – 在Build :: iPhone Build :: Additional mtouch参数下

请注意,-L不起作用,因为这不是一个库; 还要注意, 这里引用的-force_load和-ObjC并不需要,因为这是一个框架,而不是一个库。