KeywordSpotter.cs
4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/// Copyright (c) 2024 Xiaomi Corporation (authors: Fangjun Kuang)
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace SherpaOnnx
{
// 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 KeywordSpotter : IDisposable
{
public KeywordSpotter(KeywordSpotterConfig config)
{
IntPtr h = SherpaOnnxCreateKeywordSpotter(ref config);
_handle = new HandleRef(this, h);
}
public OnlineStream CreateStream()
{
IntPtr p = SherpaOnnxCreateKeywordStream(_handle.Handle);
return new OnlineStream(p);
}
public OnlineStream CreateStream(string keywords)
{
byte[] utf8Bytes = Encoding.UTF8.GetBytes(keywords);
byte[] utf8BytesWithNull = new byte[utf8Bytes.Length + 1]; // +1 for null terminator
Array.Copy(utf8Bytes, utf8BytesWithNull, utf8Bytes.Length);
utf8BytesWithNull[utf8Bytes.Length] = 0; // Null terminator
IntPtr p = SherpaOnnxCreateKeywordStreamWithKeywords(_handle.Handle, utf8BytesWithNull);
return new OnlineStream(p);
}
/// Return true if the passed stream is ready for decoding.
public bool IsReady(OnlineStream stream)
{
return IsReady(_handle.Handle, stream.Handle) != 0;
}
/// You have to ensure that IsReady(stream) returns true before
/// you call this method
public void Decode(OnlineStream stream)
{
Decode(_handle.Handle, stream.Handle);
}
public void Reset(OnlineStream stream)
{
Reset(_handle.Handle, stream.Handle);
}
// The caller should ensure all passed streams are ready for decoding.
public void Decode(IEnumerable<OnlineStream> streams)
{
// TargetFramework=net20 does not support System.Linq
// IntPtr[] ptrs = streams.Select(s => s.Handle).ToArray();
List<IntPtr> list = new List<IntPtr>();
foreach (OnlineStream s in streams)
{
list.Add(s.Handle);
}
IntPtr[] ptrs = list.ToArray();
Decode(_handle.Handle, ptrs, ptrs.Length);
}
public KeywordResult GetResult(OnlineStream stream)
{
IntPtr h = GetResult(_handle.Handle, stream.Handle);
KeywordResult result = new KeywordResult(h);
DestroyResult(h);
return result;
}
public void Dispose()
{
Cleanup();
// Prevent the object from being placed on the
// finalization queue
System.GC.SuppressFinalize(this);
}
~KeywordSpotter()
{
Cleanup();
}
private void Cleanup()
{
SherpaOnnxDestroyKeywordSpotter(_handle.Handle);
// Don't permit the handle to be used again.
_handle = new HandleRef(this, IntPtr.Zero);
}
private HandleRef _handle;
[DllImport(Dll.Filename)]
private static extern IntPtr SherpaOnnxCreateKeywordSpotter(ref KeywordSpotterConfig config);
[DllImport(Dll.Filename)]
private static extern void SherpaOnnxDestroyKeywordSpotter(IntPtr handle);
[DllImport(Dll.Filename)]
private static extern IntPtr SherpaOnnxCreateKeywordStream(IntPtr handle);
[DllImport(Dll.Filename)]
private static extern IntPtr SherpaOnnxCreateKeywordStreamWithKeywords(IntPtr handle, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1)] byte[] utf8Keywords);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxIsKeywordStreamReady")]
private static extern int IsReady(IntPtr handle, IntPtr stream);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxDecodeKeywordStream")]
private static extern void Decode(IntPtr handle, IntPtr stream);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxResetKeywordStream")]
private static extern void Reset(IntPtr handle, IntPtr stream);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxDecodeMultipleKeywordStreams")]
private static extern void Decode(IntPtr handle, IntPtr[] streams, int n);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxGetKeywordResult")]
private static extern IntPtr GetResult(IntPtr handle, IntPtr stream);
[DllImport(Dll.Filename, EntryPoint = "SherpaOnnxDestroyKeywordResult")]
private static extern void DestroyResult(IntPtr result);
}
}