最近进行语音识别的项目,由于受网络等因素的影响,找了下找到一个离线版本的语音识别Vosk,系统自带的语音识别效果比较差,百度和讯飞之类的需要通过网络进行识别,也需要费用
由于Vosk只有netstandard2.0版本,所以至少使用Framework4.6.1及以上版本兼容,
从https://alphacephei.com/vosk/models 下载模型,中文识别的,也可以通过自己训练模型得到
以下具体示例代码:
1 using NAudio.Wave; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows; 8 using System.Windows.Controls; 9 using System.Windows.Data; 10 using System.Windows.Documents; 11 using System.Windows.Input; 12 using System.Windows.Media; 13 using System.Windows.Media.Imaging; 14 using System.Windows.Navigation; 15 using System.Windows.Shapes; 16 using Vosk; 17 18 namespace NAudioTest 19 { 20 /// <summary> 21 /// MainWindow.xaml 的交互逻辑 22 /// </summary> 23 public partial class MainWindow : Window 24 { 25 public MainWindow() 26 { 27 InitializeComponent(); 28 } 29 30 private Model model = new Model("modelcn");//程序根目录下 31 32 private WaveIn waveIn;//WasapiLoopbackCapture 系统音频卡输出语音,我们使用外部输入语音 33 34 private VoskRecognizer rec; 35 36 private void InitRec() 37 { 38 waveIn = new WaveIn();//WasapiLoopbackCapture 39 waveIn.WaveFormat = new WaveFormat(16000,16, 1);//44100 采样率16K就可以,太高会导致识别率下降,百度也使用16K 40 waveIn.DataAvailable += WaveIn_DataAvailable; 41 42 rec = new VoskRecognizer(model, waveIn.WaveFormat.SampleRate);//加载模型 43 rec.SetMaxAlternatives(0);//设置备选项 44 rec.SetWords(false);//设置是否显示时间 45 } 46 47 private void btnStart_Click(object sender, RoutedEventArgs e) 48 { 49 try 50 { 51 if(waveIn != null) 52 { 53 waveIn.StartRecording(); 54 } 55 else 56 { 57 InitRec(); 58 } 59 } 60 catch 61 { 62 } 63 } 64 65 private void WaveIn_DataAvailable(object sender, WaveInEventArgs e) 66 { 67 //int recLen = e.BytesRecorded; 68 //byte[] data = new byte[recLen]; 69 //Array.Copy(e.Buffer, data, recLen); 70 if (rec.AcceptWaveform(e.Buffer, e.BytesRecorded)) 71 { 72 Console.WriteLine(rec.Result()); 73 } 74 else 75 { 76 //Console.WriteLine(rec.FinalResult());//不要片段去分析,不然因为语义太少分析不出来 77 //Console.WriteLine("---------"); 78 } 79 } 80 81 private void btnStop_Click(object sender, RoutedEventArgs e) 82 { 83 try 84 { 85 if (waveIn != null) 86 { 87 waveIn.StopRecording(); 88 } 89 } 90 catch 91 { 92 } 93 } 94 95 private void Window_Loaded(object sender, RoutedEventArgs e) 96 { 97 InitRec(); 98 } 99 } 100 }
前面部分识别错误,后面都是正确的,还进行了语义分割
第二种方法
1 using System; 2 using System.IO; 3 using Vosk; 4 5 public class VoskDemo 6 { 7 public static void DemoBytes(Model model) 8 { 9 // Demo byte buffer 10 VoskRecognizer rec = new VoskRecognizer(model, 16000.0f); 11 rec.SetMaxAlternatives(0); 12 rec.SetWords(true); 13 using(Stream source = File.OpenRead("test.wav")) { 14 byte[] buffer = new byte[4096]; 15 int bytesRead; 16 while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) { 17 if (rec.AcceptWaveform(buffer, bytesRead)) { 18 Console.WriteLine(rec.Result()); 19 } else { 20 Console.WriteLine(rec.PartialResult()); 21 } 22 } 23 } 24 Console.WriteLine(rec.FinalResult()); 25 } 26 27 public static void DemoFloats(Model model) 28 { 29 // Demo float array 30 VoskRecognizer rec = new VoskRecognizer(model, 16000.0f); 31 using(Stream source = File.OpenRead("test.wav")) { 32 byte[] buffer = new byte[4096]; 33 int bytesRead; 34 while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) { 35 float[] fbuffer = new float[bytesRead / 2]; 36 for (int i = 0, n = 0; i < fbuffer.Length; i++, n+=2) { 37 fbuffer[i] = BitConverter.ToInt16(buffer, n); 38 } 39 if (rec.AcceptWaveform(fbuffer, fbuffer.Length)) { 40 Console.WriteLine(rec.Result()); 41 } else { 42 Console.WriteLine(rec.PartialResult()); 43 } 44 } 45 } 46 Console.WriteLine(rec.FinalResult()); 47 } 48 49 public static void DemoSpeaker(Model model) 50 { 51 // Output speakers 52 SpkModel spkModel = new SpkModel("model-spk"); 53 VoskRecognizer rec = new VoskRecognizer(model, 16000.0f); 54 rec.SetSpkModel(spkModel); 55 56 using(Stream source = File.OpenRead("test.wav")) { 57 byte[] buffer = new byte[4096]; 58 int bytesRead; 59 while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) { 60 if (rec.AcceptWaveform(buffer, bytesRead)) { 61 Console.WriteLine(rec.Result()); 62 } else { 63 Console.WriteLine(rec.PartialResult()); 64 } 65 } 66 } 67 Console.WriteLine(rec.FinalResult()); 68 } 69 70 public static void Main() 71 { 72 // You can set to -1 to disable logging messages 73 Vosk.Vosk.SetLogLevel(0); 74 75 Model model = new Model("model"); 76 DemoBytes(model); 77 DemoFloats(model); 78 DemoSpeaker(model); 79 } 80 }