123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- // Copyright (c) 2023 Xiaomi Corporation (authors: Fangjun Kuang)
- using System.Runtime.InteropServices;
- using System;
- using System.Text;
- namespace SherpaNcnn
- {
- [StructLayout(LayoutKind.Sequential)]
- public struct TransducerModelConfig
- {
- [MarshalAs(UnmanagedType.LPStr)]
- public string EncoderParam;
- [MarshalAs(UnmanagedType.LPStr)]
- public string EncoderBin;
- [MarshalAs(UnmanagedType.LPStr)]
- public string DecoderParam;
- [MarshalAs(UnmanagedType.LPStr)]
- public string DecoderBin;
- [MarshalAs(UnmanagedType.LPStr)]
- public string JoinerParam;
- [MarshalAs(UnmanagedType.LPStr)]
- public string JoinerBin;
- [MarshalAs(UnmanagedType.LPStr)]
- public string Tokens;
- public int UseVulkanCompute;
- public int NumThreads;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct TransducerDecoderConfig
- {
- [MarshalAs(UnmanagedType.LPStr)]
- public string DecodingMethod;
- public int NumActivePaths;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct FeatureConfig
- {
- public float SampleRate;
- public int FeatureDim;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct OnlineRecognizerConfig
- {
- public FeatureConfig FeatConfig;
- public TransducerModelConfig ModelConfig;
- public TransducerDecoderConfig DecoderConfig;
- public int EnableEndpoint;
- public float Rule1MinTrailingSilence;
- public float Rule2MinTrailingSilence;
- public float Rule3MinUtteranceLength;
- [MarshalAs(UnmanagedType.LPStr)]
- public string HotwordsFile;
- public float HotwordsScore;
- }
- // please see
- // https://www.mono-project.com/docs/advanced/pinvoke/#gc-safe-pinvoke-code
- // https://www.mono-project.com/docs/advanced/pinvoke/#properly-disposing-of-resources
- public class OnlineRecognizer : IDisposable
- {
- public OnlineRecognizer(OnlineRecognizerConfig config)
- {
- IntPtr h = CreateOnlineRecognizer(ref config);
- _handle = new HandleRef(this, h);
- }
- public OnlineStream CreateStream()
- {
- IntPtr p = CreateOnlineStream(_handle.Handle);
- return new OnlineStream(p);
- }
- public bool IsReady(OnlineStream stream)
- {
- return IsReady(_handle.Handle, stream.Handle) != 0;
- }
- public bool IsEndpoint(OnlineStream stream)
- {
- return IsEndpoint(_handle.Handle, stream.Handle) != 0;
- }
- public void Reset(OnlineStream stream)
- {
- Reset(_handle.Handle, stream.Handle);
- }
- public void Decode(OnlineStream stream)
- {
- Decode(_handle.Handle, stream.Handle);
- }
- public OnlineRecognizerResult GetResult(OnlineStream stream)
- {
- IntPtr h = GetResult(_handle.Handle, stream.Handle);
- OnlineRecognizerResult result = new OnlineRecognizerResult(h);
- DestroyResult(h);
- return result;
- }
- public void Dispose()
- {
- Cleanup();
- // Prevent the object from being placed on the
- // finalization queue
- System.GC.SuppressFinalize(this);
- }
- ~OnlineRecognizer()
- {
- Cleanup();
- }
- private void Cleanup()
- {
- DestroyOnlineRecognizer(_handle.Handle);
- // Don't permit the handle to be used again.
- _handle = new HandleRef(this, IntPtr.Zero);
- }
- private HandleRef _handle;
- private const string dllName = "sherpa-ncnn-c-api";
- [DllImport(dllName, EntryPoint = "CreateRecognizer")]
- private static extern IntPtr CreateOnlineRecognizer(ref OnlineRecognizerConfig config);
- [DllImport(dllName, EntryPoint = "DestroyRecognizer")]
- private static extern void DestroyOnlineRecognizer(IntPtr handle);
- [DllImport(dllName, EntryPoint = "CreateStream")]
- private static extern IntPtr CreateOnlineStream(IntPtr handle);
- [DllImport(dllName)]
- private static extern int IsReady(IntPtr handle, IntPtr stream);
- [DllImport(dllName)]
- private static extern int IsEndpoint(IntPtr handle, IntPtr stream);
- [DllImport(dllName)]
- private static extern void Reset(IntPtr handle, IntPtr stream);
- [DllImport(dllName, EntryPoint = "Decode")]
- private static extern void Decode(IntPtr handle, IntPtr stream);
- [DllImport(dllName)]
- private static extern IntPtr GetResult(IntPtr handle, IntPtr stream);
- [DllImport(dllName)]
- private static extern void DestroyResult(IntPtr result);
- }
- public class OnlineStream : IDisposable
- {
- public OnlineStream(IntPtr p)
- {
- _handle = new HandleRef(this, p);
- }
- public void AcceptWaveform(float sampleRate, float[] samples)
- {
- AcceptWaveform(Handle, sampleRate, samples, samples.Length);
- }
- public void InputFinished()
- {
- InputFinished(Handle);
- }
- ~OnlineStream()
- {
- Cleanup();
- }
- public void Dispose()
- {
- Cleanup();
- // Prevent the object from being placed on the
- // finalization queue
- System.GC.SuppressFinalize(this);
- }
- private void Cleanup()
- {
- DestroyOnlineStream(Handle);
- // Don't permit the handle to be used again.
- _handle = new HandleRef(this, IntPtr.Zero);
- }
- private HandleRef _handle;
- public IntPtr Handle => _handle.Handle;
- private const string dllName = "sherpa-ncnn-c-api";
- [DllImport(dllName, EntryPoint = "DestroyStream")]
- private static extern void DestroyOnlineStream(IntPtr handle);
- [DllImport(dllName)]
- private static extern void AcceptWaveform(IntPtr handle, float sampleRate, float[] samples, int n);
- [DllImport(dllName)]
- private static extern void InputFinished(IntPtr handle);
- }
- public class OnlineRecognizerResult
- {
- public OnlineRecognizerResult(IntPtr handle)
- {
- Impl impl = (Impl)Marshal.PtrToStructure(handle, typeof(Impl));
- // PtrToStringUTF8() requires .net standard 2.1
- // _text = Marshal.PtrToStringUTF8(impl.Text);
- int length = 0;
- unsafe
- {
- byte* buffer = (byte*)impl.Text;
- while (*buffer != 0)
- {
- ++buffer;
- }
- length = (int)(buffer - (byte*)impl.Text);
- }
- byte[] stringBuffer = new byte[length];
- Marshal.Copy(impl.Text, stringBuffer, 0, length);
- _text = Encoding.UTF8.GetString(stringBuffer);
- }
- [StructLayout(LayoutKind.Sequential)]
- struct Impl
- {
- public IntPtr Text;
- public IntPtr Tokens;
- public IntPtr Timestamps;
- int Count;
- }
- private String _text;
- public String Text => _text;
- }
- }
|