Dữ liệu cho gói nhận dạng giọng nói ngoại tuyến bằng tiếng Nga. Nhận dạng giọng nói bằng ứng dụng máy tính để bàn .NET. Cách tổng hợp lời nói

Sản phẩm và công nghệ:

Thư viện lời nói Visual Studio, C#, .NET

Bài viết thảo luận về:

  • thêm hỗ trợ nhận dạng giọng nói cho ứng dụng bảng điều khiển;
  • xử lý giọng nói được công nhận;
  • cài đặt thư viện nhận dạng giọng nói;
  • so sánh Microsoft.Speech và System.Speech;
  • Thêm hỗ trợ nhận dạng giọng nói vào ứng dụng Windows Forms.

Với sự ra đời của Windows Phone Cortana, một trợ lý cá nhân kích hoạt bằng giọng nói (cũng như một đối tác của công ty trái cây không thể nói vô ích), các ứng dụng hỗ trợ giọng nói ngày càng trở nên nổi bật trong quá trình phát triển phần mềm. Trong bài viết này, tôi sẽ chỉ cho bạn cách bắt đầu nhận dạng và tổng hợp giọng nói trong các ứng dụng bảng điều khiển Windows, ứng dụng Windows Forms và Windows Present Foundation (WPF).

Lưu ý rằng bạn cũng có thể thêm khả năng giọng nói vào ứng dụng Windows Phone, ứng dụng web ASP.NET, ứng dụng Windows Store, Windows RT và Xbox Kinect, nhưng các kỹ thuật này khác với những kỹ thuật được thảo luận trong bài viết này.

Một cách hay để biết chính xác nội dung bài viết này sẽ thảo luận là xem ảnh chụp màn hình của hai chương trình demo khác nhau trên cơm. 12 . Sau khi khởi chạy ứng dụng bảng điều khiển trên cơm. 1 ngay lập tức nói câu "Tôi thức rồi." Tất nhiên, bạn sẽ không thể nghe thấy ứng dụng demo khi đọc bài viết này nên nó sẽ hiển thị nội dung mà máy tính đang nói. Sau đó người dùng nói lệnh “Bật giọng nói”. Ứng dụng demo phản hồi bằng văn bản được nhận dạng, sau đó lắng nghe và phản hồi nội bộ các yêu cầu cộng hai số.

Cơm. 1. Nhận dạng và tổng hợp giọng nói trong ứng dụng bảng điều khiển


Cơm. 2. Nhận dạng giọng nói trong ứng dụng Windows Forms

Người dùng đã yêu cầu ứng dụng thêm một và hai, rồi hai và ba. Ứng dụng nhận dạng lệnh nói và đưa ra câu trả lời bằng giọng nói. Tôi sẽ mô tả những cách hữu ích hơn để sử dụng tính năng nhận dạng giọng nói sau.

Sau đó, người dùng nói “Tắt giọng nói”, một lệnh thoại vô hiệu hóa việc nghe các lệnh bổ sung nhưng không tắt hoàn toàn tính năng nhận dạng giọng nói. Sau lệnh bằng lời nói này, lệnh tiếp theo để thêm một và hai đã bị bỏ qua. Cuối cùng, người dùng bật lại lệnh nghe và thốt ra lệnh vô nghĩa “Klatu barada nikto”, lệnh này được ứng dụng nhận dạng là lệnh để tắt hoàn toàn tính năng nhận dạng giọng nói và tự chấm dứt.

TRÊN cơm. 2 hiển thị ứng dụng Windows Forms có hỗ trợ giọng nói giả. Ứng dụng này nhận dạng các lệnh nói nhưng không phản hồi chúng bằng đầu ra giọng nói. Khi bạn khởi chạy ứng dụng lần đầu tiên, hộp kiểm Bật giọng nói không được chọn, cho biết rằng tính năng nhận dạng giọng nói không hoạt động. Người dùng đã chọn hộp kiểm này và sau đó nói "Xin chào". Ứng dụng phản hồi bằng cách hiển thị văn bản được nhận dạng trong điều khiển ListBox ở cuối cửa sổ.

Sau đó, người dùng nói: “Đặt hộp văn bản 1 thành màu đỏ”. Ứng dụng đã nhận dạng giọng nói và trả lời: “Đặt hộp văn bản 1 màu đỏ”, gần như (nhưng không hoàn toàn) chính xác những gì người dùng đã nói. Mặc dù trên cơm. 2 Bạn không thể nhìn thấy nó, văn bản trong điều khiển TextBox ở đầu cửa sổ thực sự có màu đỏ.

Sau đó người dùng nói: “Vui lòng đặt hộp văn bản 1 thành màu trắng.” Ứng dụng đã nhận ra đây là "đặt hộp văn bản 1 màu trắng" và đã làm đúng như vậy. Người dùng kết thúc bằng cách nói: “Tạm biệt” và ứng dụng hiển thị văn bản đó nhưng không làm gì với Windows Forms, mặc dù chẳng hạn, nó có thể đã xóa hộp kiểm Speech On.

Sử dụng đối tượng tổng hợp khá đơn giản.

Trong các phần sau, tôi sẽ hướng dẫn bạn quy trình tạo cả hai chương trình demo, bao gồm cả việc cài đặt các thư viện giọng nói .NET cần thiết. Bài viết này giả định rằng bạn có ít nhất kỹ năng lập trình trung cấp nhưng không biết gì về nhận dạng và tổng hợp giọng nói.

Thêm hỗ trợ nhận dạng giọng nói vào ứng dụng bảng điều khiển

Để tạo bản demo được hiển thị trong cơm. 1, Tôi đã khởi chạy Visual Studio và tạo một ứng dụng bảng điều khiển C# mới có tên ConsoleSpeech. Tôi đã sử dụng thành công các công cụ giọng nói với Visual Studio 2010 và 2012, nhưng mọi phiên bản tương đối gần đây đều ổn. Sau khi tải mã mẫu vào trình chỉnh sửa, tôi đã đổi tên tệp Program.cs trong cửa sổ Solution Explorer thành ConsoleSpeechProgram.cs mang tính mô tả hơn và Visual Studio đã đổi tên lớp Chương trình cho tôi.

Tiếp theo, tôi đã thêm một liên kết đến tệp Microsoft.Speech.dll, nằm trong C:\ProgramFiles (x86)\Microsoft SDKs\Speech\v11.0\Assembly. DLL này bị thiếu trong máy tính của tôi và tôi phải tải xuống. Việc cài đặt các tệp cần thiết để thêm tính năng nhận dạng và tổng hợp giọng nói vào một ứng dụng không phải là điều đơn giản. Tôi sẽ giải thích chi tiết quá trình cài đặt trong phần tiếp theo, nhưng bây giờ hãy giả sử rằng Microsoft.Speech.dll có trên hệ thống của bạn.

Bằng cách thêm một tham chiếu đến DLL lời nói, tôi đã xóa tất cả các câu lệnh sử dụng khỏi đầu mã ngoại trừ câu lệnh trỏ đến không gian tên Hệ thống cấp cao nhất. Sau đó, tôi đã thêm các câu lệnh sử dụng cho các không gian tên Microsoft.Speech.Recognition, Microsoft.Speech.Synt tổng hợp và System.Globalization. Hai không gian tên đầu tiên được ánh xạ tới DLL lời nói. Lưu ý rằng cũng có các không gian tên như System.Speech.Recognition và System.Speech.Synt tổng hợp, có thể gây nhầm lẫn. Tôi sẽ giải thích sự khác biệt giữa chúng ngay sau đây. Không gian tên Toàn cầu hóa có sẵn theo mặc định và không yêu cầu thêm tham chiếu mới vào dự án.

Tất cả mã nguồn của ứng dụng bảng điều khiển demo được cung cấp tại cơm. 3 và cũng có sẵn trong gói nguồn đi kèm bài viết này. Tôi đã loại bỏ tất cả cách xử lý lỗi tiêu chuẩn để tránh che khuất các ý chính nhiều nhất có thể.

Cơm. 3. Mã nguồn ứng dụng bảng điều khiển demo

sử dụng Hệ thống; sử dụng Microsoft.Speech.Recognition; sử dụng Microsoft.Speech.Synt tổng hợp; sử dụng System.Globalization; không gian tên ConsoleSpeech ( class ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine ("\n(Đang nói: Tôi đang thức)"); ss.Speak("Tôi đang thức"); CultureInfo ci = new CultureInfo("en-us"); sre = new SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice( ; sre.Speechrecognized += sre_Speechrecognized; lựa chọn ch_startstopcommands = Lựa chọn mới (); ch_startstopcommands.add ("Bật giọng nói"); ch_startstopcommands.add ("S Peech Off "); ch_startStopcommands.add (" Klatu Barada Nikto "); Trình xây dựng ngữ pháp GB_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Ngữ pháp g_StartStop = new Grammar(gb_StartStop); Lựa chọn ch_Numbers = new Choices(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers. Add("3"); ch_Numbers.Add("4"); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Là gì"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("cộng"); gb_WhatIsXplusY.Append(ch_Numbers); Ngữ pháp g_WhatIsXplusY = Ngữ pháp mới(gb_WhatIsXplusY); sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple); while (xong == false) ( ; ) Console.WriteLine("\nHit< enter >để đóng shell\n"); Console.ReadLine(); ) bắt (Ngoại lệ cũ) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e ) ( string txt = e.Result.Text; float độ tin cậy = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (sự tự tin< 0.60) return; if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("Speech is ON"); speechOn = true; ) if (txt.IndexOf("speech off") >= 0) ( Console.WriteLine("Speech is OFF"); speechOn = false; ) if (speechOn == false) return; if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender). Công nhậnAsyncCancel(); done = true; Console.WriteLine("(Speaking: Chia tay)"); ss.Speak("Tạm biệt"); ) if (txt.IndexOf("What") >= 0 && txt.IndexOf("plus") >= 0) ( chuỗi từ = txt.Split(" "); int num1 = int.Parse(từ); int num2 = int.Parse(từ); int sum = num1 + num2; Console.WriteLine("(Nói: " + từ + " cộng " + từ + " bằng " + sum + ")"); ss.SpeakAsync(words + " plus " + Words + " bằng " + sum); ) ) // sre_SpeechRecognized ) // Program ) // ns

Sau câu lệnh sử dụng, mã demo bắt đầu như thế này:

không gian tên ConsoleSpeech ( class ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( ...

Đối tượng SpeechSynthesizer, ở cấp độ lớp, cho phép ứng dụng tổng hợp giọng nói. Đối tượng SpeechRecognitionEngine cho phép ứng dụng nghe và nhận dạng các từ hoặc cụm từ được nói. Biến boolean done xác định khi nào toàn bộ ứng dụng kết thúc. Biến boolean speechOn kiểm soát xem ứng dụng có nghe bất kỳ lệnh nào ngoài lệnh thoát khỏi chương trình hay không.

Ý tưởng ở đây là ứng dụng bảng điều khiển không chấp nhận đầu vào từ bàn phím nên nó luôn lắng nghe lệnh. Tuy nhiên, nếu speechOn sai thì chỉ có lệnh thoát khỏi chương trình được nhận dạng và thực thi; các lệnh khác được nhận dạng nhưng bị bỏ qua.

Phương thức Main bắt đầu như thế này:

thử ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine("\n(Nói: Tôi đang thức)"); ss.Speak("Tôi đang thức");

Một phiên bản của đối tượng SpeechSynthesizer đã được tạo khi nó được khai báo. Sử dụng đối tượng tổng hợp khá đơn giản. Phương thức SetOutputToDefaultAudioDevice gửi đầu ra tới loa được kết nối với máy tính của bạn (bạn cũng có thể gửi đầu ra tới một tệp). Phương thức Nói lấy một chuỗi rồi đọc chuỗi đó. Điều đó thật dễ dàng.

Nhận dạng giọng nói phức tạp hơn nhiều so với tổng hợp giọng nói. Phương thức Main tiếp tục bằng cách tạo một đối tượng trình phân giải:

CultureInfo ci = new CultureInfo("en-us"); sre = new SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized;

Đầu tiên, đối tượng CultureInfo chỉ định ngôn ngữ được công nhận, trong trường hợp này là tiếng Anh Mỹ. Đối tượng CultureInfo nằm trong không gian tên Toàn cầu hóa mà chúng tôi đã tham chiếu bằng câu lệnh sử dụng. Sau đó, sau khi gọi hàm tạo SpeechRecognitionEngine, đầu vào giọng nói sẽ được gán cho thiết bị âm thanh mặc định - thường là micrô. Lưu ý rằng hầu hết máy tính xách tay đều có micrô tích hợp, nhưng máy tính để bàn sẽ yêu cầu micrô bên ngoài (ngày nay thường được kết hợp với tai nghe).

Phương thức chính cho đối tượng nhận dạng là trình xử lý sự kiện SpeechRecognized. Khi sử dụng Visual Studio, nếu bạn nhập "sre.SpeechRecognized +=" và đợi trong tích tắc, IntelliSense sẽ tự động kết thúc biểu thức của bạn bằng tên trình xử lý sự kiện - sre_SpeechRecognized. Tôi khuyên bạn nên nhấn phím Tab để chấp nhận đề xuất và sử dụng tên này làm mặc định.

Lựa chọn ch_Numbers = Lựa chọn mới(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers.Add("3"); ch_Numbers.Add("4"); // theo quan điểm kỹ thuật, // đây là Add(new string ("4" )); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Là gì"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("cộng"); gb_WhatIsXplusY.Append(ch_Numbers); Ngữ pháp g_WhatIsXplusY = Ngữ pháp mới(gb_WhatIsXplusY);

Ba đối tượng chính ở đây là bộ Lựa chọn, mẫu GrammarBuilder và điều khiển Ngữ pháp. Khi tạo Ngữ pháp để nhận biết, tôi bắt đầu bằng việc liệt kê một số ví dụ cụ thể về những gì tôi cần nhận biết. Hãy nói: "Một cộng hai bằng bao nhiêu?" và “Ba cộng bốn bằng mấy?”

Sau đó tôi xác định mẫu chung tương ứng, ví dụ "Cái gì là thêm ?. Mẫu là một GrammarBuilder và các giá trị cụ thể được chuyển đến mẫu là một tập hợp các Lựa chọn. Đối tượng Ngữ pháp gói gọn mẫu và Lựa chọn.

Trong chương trình demo, tôi giới hạn các phần bổ sung từ 1 đến 4 và thêm chúng dưới dạng chuỗi vào bộ Lựa chọn. Cách tiếp cận hiệu quả hơn:

số chuỗi = chuỗi mới ("1", "2", "3", "4" ); Lựa chọn ch_Numbers = Lựa chọn mới(số);

Tôi đang trình bày một cách tiếp cận kém hiệu quả hơn để tạo bộ Lựa chọn vì hai lý do. Đầu tiên, thêm từng dòng một là cách tiếp cận duy nhất tôi từng thấy trong các ví dụ nhận dạng giọng nói khác. Thứ hai, bạn có thể nghĩ rằng việc thêm từng hàng một sẽ không có tác dụng gì cả; Visual Studio IntelliSense hiển thị trong thời gian thực rằng một trong các quá tải Thêm chấp nhận tham số của cụm từ chuỗi loại thông số. Nếu không chú ý đến từ khóa params, bạn có thể đã cho rằng phương thức Add chỉ chấp nhận mảng chuỗi chứ không chấp nhận một chuỗi. Nhưng điều này không phải vậy: anh ấy chấp nhận cả hai. Tôi khuyên bạn nên chuyển một mảng.

Việc tạo một tập hợp các Lựa chọn từ các số liên tiếp là một trường hợp đặc biệt và cho phép thực hiện một cách tiếp cận theo chương trình như:

số chuỗi = chuỗi mới; vì (int i = 0; tôi< 100; ++i) numbers[i] = i.ToString(); Choices ch_Numbers = new Choices(numbers);

Sau khi tạo Lựa chọn để lấp đầy các vị trí của GrammarBuilder, chương trình demo sẽ tạo GrammarBuilder và sau đó là Ngữ pháp kiểm soát:

GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Là gì"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("cộng"); gb_WhatIsXplusY.Append(ch_Numbers); Ngữ pháp g_WhatIsXplusY = Ngữ pháp mới(gb_WhatIsXplusY);

Chương trình demo sử dụng một mẫu tương tự để tạo Ngữ pháp cho lệnh bắt đầu và dừng:

Lựa chọn ch_StartStopCommands = Lựa chọn mới(); ch_StartStopCommands.Add("bật bài phát biểu"); ch_StartStopCommands.Add("tắt giọng nói"); ch_StartStopCommands.Add("Klatu barada nikto"); GrammarBuilder gb_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Ngữ pháp g_StartStop = Ngữ pháp mới(gb_StartStop);

Ngữ pháp có thể được định nghĩa rất linh hoạt. Ở đây các lệnh “bật giọng nói”, “tắt lời nói” và “klatu barada nikto” được đặt trong một ngữ pháp vì chúng có liên quan một cách logic. Ba lệnh này có thể được xác định theo ba ngữ pháp khác nhau hoặc các lệnh "bật giọng nói" và "tắt lời nói" có thể được đặt trong một ngữ pháp và lệnh "klatu barada nikto" trong một giây.

Khi bạn đã tạo tất cả các đối tượng Ngữ pháp, bạn đặt chúng vào trình nhận dạng giọng nói và tính năng nhận dạng giọng nói sẽ được kích hoạt:

sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple);

Đối số Công nhậnMode.Multiple là cần thiết khi bạn có nhiều hơn một ngữ pháp, điều này sẽ xảy ra trong tất cả các chương trình ngoại trừ các chương trình đơn giản nhất. Phương thức Main hoàn thành như sau:

Trong khi (xong == false) ( ; ) Console.WriteLine("\nHit< enter >để đóng shell\n"); Console.ReadLine(); ) bắt (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main

Một vòng lặp while trống trông có vẻ lạ cho phép bạn duy trì vỏ của ứng dụng bảng điều khiển đang chạy. Vòng lặp sẽ hoàn thành khi biến boolean cấp lớp done được trình xử lý sự kiện nhận dạng giọng nói đặt thành true.

Xử lý giọng nói được công nhận

Mã để xử lý các sự kiện nhận dạng giọng nói bắt đầu như sau:

static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float Niềm tin = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (sự tự tin< 0.60) return; ...

Văn bản được nhận dạng được lưu trữ trong thuộc tính Result.Text của đối tượng SpeechRecognizedEventArgs. Ngoài ra, bạn có thể sử dụng bộ Result.Words. Thuộc tính Result.Confidence lưu trữ một giá trị trong khoảng từ 0,0 đến 1,0. Giá trị này ước tính sơ bộ mức độ phù hợp của văn bản được nói với bất kỳ ngữ pháp nào được liên kết với trình nhận dạng. Chương trình demo hướng dẫn trình xử lý sự kiện bỏ qua văn bản có độ tin cậy thấp đối với văn bản được nhận dạng.

Giá trị độ tin cậy rất khác nhau tùy thuộc vào độ phức tạp của ngữ pháp, chất lượng micrô và các yếu tố khác. Ví dụ: nếu chương trình demo chỉ cần nhận dạng các số từ 1 đến 4 thì giá trị độ tin cậy trên máy tính của tôi thường vào khoảng 0,75. Tuy nhiên, nếu ngữ pháp phải nhận dạng các số từ 1 đến 100 thì giá trị độ tin cậy sẽ giảm xuống khoảng 0,25. Tóm lại, bạn thường nên thử nghiệm các giá trị độ tin cậy để đạt được kết quả nhận dạng giọng nói tốt.

if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("Speech is ON"); speechOn = true; ) if (txt.IndexOf("speech off") >= 0) ( Console .WriteLine("Bài phát biểu hiện đang TẮT"); speechOn = false; ) if (speechOn == false) return;

Mặc dù ban đầu nó có thể không hoàn toàn rõ ràng, nhưng logic này sẽ có ý nghĩa nếu bạn nghĩ về nó. Lệnh thoát bí mật sau đó được xử lý:

if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender).RecognizeAsyncCancel(); done = true; Console.WriteLine("(Speaking: Tạm biệt)"); ss.Speak("Tạm biệt"); )

Lưu ý rằng công cụ nhận dạng giọng nói thực sự có thể nhận ra những từ vô nghĩa. Nếu một đối tượng Grammar chứa các từ không có trong từ điển cài sẵn của đối tượng đó, Grammar sẽ cố gắng xác định những từ đó bằng cách sử dụng chẩn đoán ngữ nghĩa nếu có thể và thường khá thành công. Đó là lý do tại sao tôi sử dụng "klatu" thay vì "klaatu" chính xác (trong một bộ phim khoa học viễn tưởng cũ).

Ngoài ra, hãy lưu ý rằng bạn không bắt buộc phải xử lý tất cả văn bản được Ngữ pháp nhận dạng (“klatu barada nikto”) - bạn chỉ cần có đủ thông tin để xác định duy nhất cụm từ ngữ pháp (“klatu” và “barada”).

If (txt.IndexOf("What") >= 0 && txt.IndexOf("plus") >= 0) ( string word = txt.Split(" "); int num1 = int.Parse(words); int num2 = int.Parse(words); int sum = num1 + num2; Console.WriteLine("(Nói: " + từ + " cộng " + từ + " bằng " + tổng + ")"); ss.SpeakAsync(words + " cộng " + từ + " bằng " + tổng); ) ) // sre_SpeechRecognized ) // Chương trình ) // ns

Lưu ý rằng văn bản trong Results.Text phân biệt chữ hoa chữ thường ("Cái gì" và "cái gì"). Sau khi nhận ra một cụm từ, nó có thể được phân tích thành các từ cụ thể. Trong trường hợp này, văn bản được nhận dạng có dạng “X cộng y là gì”, do đó “Cái gì” được đặt trong các từ và hai số được thêm vào (dưới dạng chuỗi) được lưu trữ trong các từ và từ.

Cài đặt thư viện

Phần giải thích của chương trình demo giả định rằng tất cả các thư viện giọng nói cần thiết đã được cài đặt trên máy tính của bạn. Để tạo và chạy các chương trình demo, bạn cần cài đặt bốn gói: SDK (cung cấp khả năng tạo các bản demo trong Visual Studio), thời gian chạy (chạy các bản demo sau khi chúng được tạo) và các ngôn ngữ được nhận dạng và tổng hợp (phát âm).

Để cài đặt SDK, hãy tìm kiếm trên Internet “SDK nền tảng giọng nói 11”. Thao tác này sẽ đưa bạn đến đúng trang trong Trung tâm Tải xuống của Microsoft ( cơm. 4). Bằng cách nhấp vào nút Tải xuống, bạn sẽ thấy các tùy chọn được hiển thị trong cơm. 5. SDK có phiên bản 32 và 64 bit. Tôi thực sự khuyên bạn nên sử dụng phiên bản 32 bit bất kể kích thước bit của hệ thống của bạn. Phiên bản 64 bit không hoạt động với một số ứng dụng.


Cơm. 4. Trang cài đặt SDK chính trong Microsoft Download Center


Cơm. 5. Cài đặt SDK giọng nói

Bạn không cần bất cứ thứ gì ngoài một tệp .msi trong x86 (đối với hệ thống 32 bit). Bằng cách chọn tệp này và nhấp vào Tiếp theo, bạn có thể chạy trình cài đặt trực tiếp từ đây. Thư viện lời nói không đưa ra nhiều phản hồi về thời điểm quá trình cài đặt hoàn tất, vì vậy đừng tìm kiếm bất kỳ thông báo thành công nào.


Cơm. 6. Cài đặt môi trường thời gian chạy

Điều cực kỳ quan trọng là chọn cùng một phiên bản nền tảng (11 trong bản demo) và độ sâu bit (32 hoặc 64) làm SDK. Một lần nữa, tôi thực sự khuyên dùng phiên bản 32 bit, ngay cả khi bạn đang chạy trên hệ thống 64 bit.

Sau đó bạn có thể đặt ngôn ngữ nhận dạng. Trang tải xuống được cung cấp tại cơm. 7. Chương trình demo sử dụng tệp MSSpeech_SR_en-us_TELE.msi (Anh-Mỹ). SR là viết tắt của nhận dạng giọng nói và TELE là viết tắt của điện thoại; điều này có nghĩa là ngôn ngữ được nhận dạng được thiết kế để hoạt động với đầu vào âm thanh chất lượng thấp, chẳng hạn như từ điện thoại hoặc micrô trên máy tính để bàn.


Cơm. 7. Đặt ngôn ngữ được công nhận

Cuối cùng, bạn có thể đặt ngôn ngữ và giọng nói để tổng hợp giọng nói. Trang tải xuống được cung cấp tại cơm. số 8. Chương trình demo sử dụng tệp MSSpeech_TTS_en-us_Helen.msi. TTS (chuyển văn bản thành giọng nói) về cơ bản đồng nghĩa với tổng hợp giọng nói. Lưu ý hai giọng nói có sẵn tiếng Anh, Mỹ Có những giọng nói tiếng Anh khác, nhưng không phải tiếng Mỹ Tạo tập tin ngôn ngữ tổng hợp là một công việc rất khó khăn. Tuy nhiên, bạn có thể mua và cài đặt các giọng nói khác từ nhiều công ty khác nhau.


Cơm. 8. Cài đặt giọng nói và ngôn ngữ tổng hợp

Điều thú vị là, mặc dù ngôn ngữ nhận dạng giọng nói và ngôn ngữ tổng hợp giọng nói/giọng nói thực sự là những thứ hoàn toàn khác nhau nhưng cả hai gói đều là các tùy chọn trên cùng một trang tải xuống. Giao diện người dùng của Trung tâm tải xuống cho phép bạn kiểm tra cả ngôn ngữ nhận dạng và ngôn ngữ tổng hợp, nhưng việc cố gắng cài đặt chúng cùng lúc là một điều tai hại đối với tôi, vì vậy tôi khuyên bạn nên cài đặt chúng riêng biệt.

So sánh Microsoft.Speech với System.Speech

Nếu bạn là người mới làm quen với nhận dạng và tổng hợp giọng nói cho các ứng dụng Windows, bạn có thể dễ dàng bị nhầm lẫn bởi tài liệu này vì có nhiều nền tảng giọng nói. Cụ thể, ngoài thư viện Microsoft.Speech.dll được các chương trình demo trong bài viết này sử dụng, còn có một thư viện có tên System.Speech.dll là một phần của hệ điều hành Windows. Hai thư viện này giống nhau ở chỗ các API của chúng gần như giống hệt nhau nhưng không hoàn toàn. Do đó, nếu bạn tìm kiếm các ví dụ về xử lý giọng nói trên Internet và xem các đoạn mã thay vì các chương trình hoàn chỉnh, thì hoàn toàn không rõ ví dụ đó là System.Speech hay Microsoft.Speech.

Nếu bạn chưa quen với việc xử lý giọng nói, hãy sử dụng thư viện Microsoft.Speech thay vì System.Speech để thêm hỗ trợ giọng nói cho ứng dụng .NET của bạn.

Mặc dù cả hai thư viện đều có chung cơ sở mã lõi và các API tương tự nhưng chúng chắc chắn khác nhau. Một số khác biệt chính được tóm tắt trong bàn 1.

Bàn 1. Sự khác biệt chính giữa Microsoft.Speech và System.Speech

System.Speech DLL là một phần của HĐH nên nó được cài đặt trên mọi hệ thống Windows. Microsoft.Speech DLL (cùng thời gian chạy và ngôn ngữ liên quan của nó) phải được tải xuống và cài đặt trên hệ thống. Nhận dạng bằng System.Speech thường yêu cầu đào tạo cho một người dùng cụ thể khi người dùng đọc một số văn bản và hệ thống học cách hiểu đặc điểm phát âm của người dùng này. Tính năng nhận dạng bằng Microsoft.Speech hoạt động ngay lập tức đối với bất kỳ người dùng nào. System.Speech có thể nhận dạng hầu hết mọi từ (điều này được gọi là đọc chính tả miễn phí). Microsoft.Speech sẽ chỉ nhận dạng các từ và cụm từ có trong đối tượng Grammar được xác định trong chương trình.

Thêm hỗ trợ nhận dạng giọng nói vào ứng dụng Windows Forms

Quá trình thêm hỗ trợ nhận dạng và tổng hợp giọng nói vào ứng dụng Windows Forms hoặc WPF tương tự như quy trình dành cho ứng dụng bảng điều khiển. Để tạo chương trình demo được hiển thị trong cơm. 2, Tôi đã khởi chạy Visual Studio, tạo ứng dụng C# Windows Forms mới và đổi tên thành WinFormSpeech.

Sau khi tải mã mẫu vào trình chỉnh sửa, tôi đã thêm một liên kết đến tệp Microsoft.Speech.dll trong cửa sổ Solution Explorer - giống như tôi đã làm trong chương trình bảng điều khiển. Ở đầu mã nguồn, tôi đã loại bỏ các câu lệnh sử dụng không cần thiết, chỉ để lại các tham chiếu đến các không gian tên Hệ thống, Dữ liệu, Bản vẽ và Biểu mẫu. Sau đó, tôi đã thêm hai câu lệnh sử dụng cho các không gian tên Microsoft.Speech.Recognition và System.Globalization.

Bản demo dựa trên Windows Forms không sử dụng tính năng tổng hợp giọng nói nên tôi không liên kết tới thư viện Microsoft.Speech.Synt tổng hợp. Việc thêm tổng hợp giọng nói vào ứng dụng Windows Forms cũng giống như trong ứng dụng bảng điều khiển.

Trong Visual Studio ở chế độ thiết kế, tôi đã kéo các điều khiển TextBox, CheckBox và ListBox vào Biểu mẫu. Bấm đúp vào CheckBox và Visual Studio tự động tạo phương thức xử lý sự kiện CheckChanged khung xương.

Hãy nhớ lại rằng chương trình bảng điều khiển demo ngay lập tức bắt đầu nghe lệnh nói và tiếp tục làm như vậy cho đến khi kết thúc. Cách tiếp cận này có thể được sử dụng trong ứng dụng Windows Forms, nhưng thay vào đó, tôi quyết định cho phép người dùng bật và tắt tính năng nhận dạng giọng nói bằng cách sử dụng điều khiển CheckBox (tức là hộp kiểm).

Mã nguồn trong tệp Form1.cs của chương trình demo, nơi lớp một phần được xác định, được hiển thị tại cơm. 9. Một đối tượng công cụ nhận dạng giọng nói được khai báo và tạo dưới dạng thành viên Biểu mẫu. Trong hàm tạo của Biểu mẫu, tôi kết nối trình xử lý sự kiện SpeechRecognized, sau đó tạo và tải hai đối tượng Grammars:

public Form1() ( LaunchizeComponent(); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized; Grammar g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammar g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodby e);sre.LoadGrammarAsync(g_SetTextBox) ; // sre.RecognizeAsync() nằm // trong trình xử lý sự kiện CheckBox)

Cơm. 9. Thêm hỗ trợ nhận dạng giọng nói vào Windows Forms

sử dụng Hệ thống; sử dụng System.Data; sử dụng System.draw; sử dụng System.Windows.Forms; sử dụng Microsoft.Speech.Recognition; sử dụng System.Globalization; không gian tên WinFormSpeech ( public một phần lớp Form1: Form ( static CultureInfo ci = new CultureInfo("en-us"); static SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci); public Form1() ( LaunchizeComponent(); sre.SetInputToDefaultAudioDevice(); sre .SpeechRecognized += sre_SpeechRecognized; Ngữ pháp g_HelloGoodbye = GetHelloGoodbyeGrammar(); Ngữ pháp g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodbye); sre.LoadGrammarAsync(g_SetTextBox); // sre.Recognize Async() nằm // trong trình xử lý sự kiện CheckBox ) Ngữ pháp tĩnh GetHelloGoodbyeGrammar() ( Lựa chọn ch_HelloGoodbye = new Choices(); ch_HelloGoodbye.Add("hello"); ch_HelloGoodbye.Add("goodbye"); GrammarBuilder gb_result = new GrammarBuilder(ch_HelloGoodbye); Ngữ pháp g_result = new Grammar(gb_result) ; return g_result; ) Ngữ pháp tĩnh GetTextBox1TextGrammar() ( Lựa chọn ch_Colors = new Choices(); ch_Colors.Add(chuỗi mới ("đỏ", "trắng", "xanh")); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("đặt hộp văn bản 1"); gb_result.Append(ch_Colors); Ngữ pháp g_result = Ngữ pháp mới(gb_result); trả về g_result; ) riêng void checkBox1_CheckedChanged(object sender, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // đã tắt sre.RecognizeAsyncCancel(); ) void sre_SpeechRecognized(người gửi đối tượng, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; this.Invoke(new MethodInvoker(() =>( listBox1.Items.Add("Tôi nghe bạn nói: " + txt); ))); // WinForm chỉ định if (txt.IndexOf("text") >= 0 && txt.IndexOf("box") >= 0 && txt.IndexOf("1")>= 0) ( string word = txt.Split( " "); this.Invoke(new MethodInvoker(() => ( textBox1.Text =words; ))); // Chi tiết cụ thể của WinForm ) ) ) // Form ) // ns

Tôi có thể trực tiếp tạo hai đối tượng Ngữ pháp, như trong chương trình bảng điều khiển, nhưng thay vào đó, để làm cho mã rõ ràng hơn một chút, tôi đã xác định hai phương thức trợ giúp (GetHelloGoodbyeGrammar và GetTextBox1TextGrammar) để thực hiện công việc đó.

Ngữ pháp tĩnh GetTextBox1TextGrammar() ( Lựa chọn ch_Colors = new Choices(); ch_Colors.Add(chuỗi mới ("đỏ", "trắng", "xanh")); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("đặt văn bản ô 1"); gb_result.Append(ch_Colors); Ngữ pháp g_result = Ngữ pháp mới(gb_result); return g_result; )

Phương thức trợ giúp này sẽ nhận ra cụm từ "đặt hộp văn bản 1 màu đỏ". Tuy nhiên, người dùng không bắt buộc phải phát âm chính xác cụm từ này. Ví dụ: anh ấy có thể nói "Vui lòng đặt văn bản trong hộp văn bản 1 thành màu đỏ" và công cụ nhận dạng giọng nói vẫn sẽ nhận ra cụm từ là "đặt hộp văn bản 1 màu đỏ" - mặc dù có giá trị độ tin cậy thấp hơn giá trị khớp chính xác với Ngữ pháp bản mẫu. Nói cách khác, khi tạo đối tượng Ngữ pháp, bạn không bắt buộc phải tính đến tất cả các biến thể của một cụm từ. Điều này đơn giản hóa triệt để việc sử dụng nhận dạng giọng nói.

Trình xử lý sự kiện cho CheckBox được định nghĩa như sau:

riêng tư void checkBox1_CheckedChanged(object sender, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // bị vô hiệu hóa sre.RecognizeAsyncCancel(); )

Đối tượng công cụ nhận dạng giọng nói, sre (công cụ nhận dạng giọng nói), luôn tồn tại trong suốt vòng đời của ứng dụng Windows Forms. Đối tượng này được kích hoạt và hủy kích hoạt bằng các lệnh gọi đến các phương thức Nhận dạngAsync và Nhận dạngAsyncCancel khi người dùng chuyển đổi Hộp kiểm tương ứng.

Định nghĩa trình xử lý sự kiện SpeechRecognized bắt đầu bằng:

void sre_SpeechRecognized(người gửi đối tượng, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; ...

Bên cạnh các thuộc tính Result.Text và Result.Confidence được sử dụng ít nhiều liên tục, đối tượng Result còn có một số thuộc tính hữu ích khác nhưng phức tạp hơn mà bạn có thể muốn khám phá; ví dụ: Từ đồng âm và Đơn vị từ thay thế. Ngoài ra, công cụ nhận dạng giọng nói còn cung cấp một số sự kiện hữu ích như SpeechHypothesized.

this.Invoke((Action)(() => listBox1.Items.Add("Tôi nghe bạn nói: " + txt)));

Về lý thuyết, việc sử dụng ủy nhiệm MethodInvoker sẽ hiệu quả hơn một chút so với Action trong trường hợp này vì MethodInvoker là một phần của không gian tên Windows.Forms và do đó dành riêng cho các ứng dụng Windows Forms. Đại biểu hành động linh hoạt hơn. Ví dụ này cho thấy bạn hoàn toàn có thể thao tác với một ứng dụng Windows Forms thông qua công cụ nhận dạng giọng nói - đây là một tính năng cực kỳ mạnh mẽ và hữu ích.

Phần kết luận

Thông tin được trình bày trong bài viết này sẽ giúp bạn bắt đầu ngay nếu bạn muốn khám phá tính năng tổng hợp và nhận dạng giọng nói trong các ứng dụng .NET. Việc làm chủ công nghệ thật dễ dàng khi bạn vượt qua được những khó khăn trong quá trình học tập ban đầu và cài đặt thành phần. Thách thức thực sự trong việc tổng hợp và nhận dạng giọng nói là hiểu được khi nào nó thực sự hữu ích.

Với các chương trình bảng điều khiển, bạn có thể tạo các cuộc trò chuyện qua lại thú vị trong đó người dùng đặt câu hỏi và chương trình trả lời, dẫn đến một môi trường về cơ bản giống như Cortana. Bạn phải thận trọng vì khi giọng nói phát ra từ loa máy tính của bạn, nó sẽ được micrô thu lại và có thể được nhận dạng lại. Tôi đã thấy mình rơi vào một số tình huống khá buồn cười khi tôi đặt một câu hỏi, ứng dụng đã nhận ra câu hỏi đó và trả lời, nhưng câu trả lời bằng giọng nói đã kích hoạt sự kiện nhận dạng tiếp theo và tôi đã kết thúc bằng một vòng lặp lời nói vô tận hài hước.

Một cách sử dụng giọng nói khác có thể có trong chương trình bảng điều khiển là nhận dạng các lệnh như "Khởi chạy Notepad" và "Khởi chạy Word". Nói cách khác, một chương trình bảng điều khiển như vậy có thể được sử dụng trên máy tính của bạn để thực hiện các hành động đòi hỏi nhiều thao tác trên bàn phím và chuột.

James McCaffrey(Tiến sĩ James McCaffrey) làm việc cho Microsoft Research ở Redmond, Washington. Ông tham gia sáng tạo một số sản phẩm của Microsoft, bao gồm Internet Explorer và Bing. Anh ấy có thể liên lạc tại [email được bảo vệ].

Cảm ơn các chuyên gia Nghiên cứu của Microsoft Rob Gruen, Mark Marron và Curtis von Veh đã xem xét bài viết này.

) bằng cách sử dụng ví dụ Hello World thực tế về điều khiển thiết bị gia dụng.
Tại sao đồ gia dụng? Có, bởi vì nhờ ví dụ như vậy bạn có thể đánh giá cao điều đó tốc độ và độ chính xác có thể đạt được bằng cách sử dụng hoàn toàn cục bộ nhận dạng giọng nói không có máy chủ như ASR của Google hoặc Bộ bài phát biểu Yandex.
Tôi cũng đính kèm vào bài viết toàn bộ mã nguồn của chương trình và bản lắp ráp dành cho Android.

Tại sao đột nhiên?

Gần đây tôi đã biết điều này, tôi đã hỏi tác giả tại sao anh ấy muốn sử dụng tính năng nhận dạng giọng nói dựa trên máy chủ cho chương trình của mình (theo ý kiến ​​​​của tôi, điều này là không cần thiết và dẫn đến một số vấn đề). Để đạt được mục đích đó, tôi có thể mô tả chi tiết hơn việc sử dụng các phương pháp thay thế cho các dự án không cần phải nhận ra bất cứ điều gì và từ điển bao gồm một tập hợp các từ hữu hạn. Và thậm chí với một ví dụ về ứng dụng thực tế...

Tại sao chúng ta cần bất cứ thứ gì khác ngoài Yandex và Google?

Vì “ứng dụng thực tế” đó, tôi đã chọn chủ đề điều khiển giọng nói cho ngôi nhà thông minh.
Tại sao chính xác là ví dụ này? Bởi vì nó cho thấy một số lợi thế của việc nhận dạng giọng nói hoàn toàn cục bộ so với nhận dạng bằng giải pháp đám mây. Cụ thể là:
  • Tốc độ- chúng tôi không phụ thuộc vào máy chủ và do đó không phụ thuộc vào tính khả dụng, băng thông, v.v. các nhân tố
  • Sự chính xác- công cụ của chúng tôi chỉ hoạt động với từ điển mà ứng dụng của chúng tôi quan tâm, do đó nâng cao chất lượng nhận dạng
  • Giá- chúng tôi không phải trả tiền cho mỗi yêu cầu đến máy chủ
  • Kích hoạt bằng giọng nói- như một phần thưởng bổ sung cho những điểm đầu tiên - chúng tôi có thể liên tục “nghe chương trình phát sóng” mà không lãng phí lưu lượng truy cập và không tải máy chủ

Ghi chú

Hãy đặt chỗ ngay nhé những ưu điểm này có thể coi là ưu điểm chỉ dành cho một loại dự án nhất định, Chúng ta ở đâu chúng tôi biết chắc chắn trước, từ điển nào và ngữ pháp nào mà người dùng sẽ sử dụng. Nghĩa là khi chúng ta không cần nhận dạng văn bản tùy ý (ví dụ: tin nhắn SMS hoặc truy vấn tìm kiếm). Nếu không, nhận dạng đám mây là không thể thiếu.

Vì vậy, Android có thể nhận dạng giọng nói mà không cần Internet!
Vâng, vâng... Chỉ có trên JellyBean. Và chỉ từ nửa mét, không hơn. Và sự nhận biết này là cùng một cách diễn đạt, chỉ sử dụng một mô hình nhỏ hơn nhiều. Vì vậy, chúng tôi cũng không thể quản lý hoặc định cấu hình nó. Và những gì cô ấy sẽ trở lại với chúng tôi trong thời gian tới vẫn chưa được biết. Mặc dù chỉ phù hợp với SMS!

Chúng ta làm gì?

Chúng tôi sẽ triển khai điều khiển từ xa bằng giọng nói cho các thiết bị gia dụng, điều này sẽ hoạt động chính xác và nhanh chóng, từ vài mét và thậm chí trên điện thoại thông minh, máy tính bảng và đồng hồ Android rẻ tiền, tồi tàn, rất rẻ tiền.
Logic sẽ đơn giản nhưng rất thực tế. Chúng tôi kích hoạt micrô và nói một hoặc nhiều tên thiết bị. Ứng dụng nhận dạng chúng và bật và tắt chúng tùy thuộc vào trạng thái hiện tại. Hoặc anh ta nhận được một gia tài từ họ và phát âm nó bằng một giọng nữ dễ chịu. Ví dụ, nhiệt độ hiện tại trong phòng.

Ứng dụng thực tế rất nhiều

Buổi sáng, chưa kịp mở mắt, bạn đã vỗ tay lên màn hình điện thoại thông minh trên đầu giường và ra lệnh “Chào buổi sáng!” - kịch bản bắt đầu, máy pha cà phê bật và kêu vo vo, tiếng nhạc vui tai vang lên, rèm mở ra.
Hãy treo một chiếc điện thoại thông minh giá rẻ (2 nghìn, không hơn) lên tường trong mỗi phòng. Chúng tôi về nhà sau giờ làm việc và ra lệnh vào khoảng trống “Ngôi nhà thông minh! Đèn, tivi! - Tôi nghĩ không cần thiết phải nói điều gì sẽ xảy ra tiếp theo.

Phiên âm



Ngữ pháp mô tả cái gì người dùng có thể nói gì. Để Pocketsphinx biết, Làm sao anh ta sẽ phát âm nó, mỗi từ trong ngữ pháp cần phải viết nó phát âm như thế nào trong mô hình ngôn ngữ tương ứng. Đó là phiên mã mọi lời nói. Nó được gọi là từ điển.

Phiên âm được mô tả bằng một cú pháp đặc biệt. Ví dụ:
thông minh uu m n ay j nhà d oo m

Về nguyên tắc, không có gì phức tạp. Một nguyên âm đôi trong phiên âm biểu thị trọng âm. Phụ âm kép là phụ âm mềm theo sau là nguyên âm. Tất cả các kết hợp có thể có cho tất cả các âm thanh của tiếng Nga.

Rõ ràng là chúng tôi không thể mô tả trước tất cả các bản phiên âm trong ứng dụng của mình, vì chúng tôi không biết trước tên mà người dùng sẽ đặt cho thiết bị của họ. Do đó, chúng tôi sẽ tạo ra các phiên âm như vậy một cách “nhanh chóng” theo một số quy tắc ngữ âm tiếng Nga. Để thực hiện việc này, bạn có thể triển khai lớp PhonMapper sau, lớp này có thể nhận một chuỗi làm đầu vào và tạo bản phiên âm chính xác cho chuỗi đó.

Kích hoạt bằng giọng nói

Đây là khả năng của công cụ nhận dạng giọng nói luôn “nghe chương trình phát sóng” để phản ứng với một cụm từ (hoặc các cụm từ) được xác định trước. Đồng thời, tất cả các âm thanh và lời nói khác sẽ bị loại bỏ. Điều này không giống như việc mô tả ngữ pháp và chỉ bật micro. Tôi sẽ không trình bày ở đây lý thuyết về nhiệm vụ này và cơ chế hoạt động của nó. Hãy để tôi chỉ nói rằng gần đây các lập trình viên làm việc trên Pocketsphinx đã triển khai một chức năng như vậy và bây giờ nó đã có sẵn trong API.

Một điều chắc chắn đáng được đề cập. Đối với cụm từ kích hoạt, bạn không chỉ cần chỉ định phiên âm mà còn phải chọn cụm từ thích hợp giá trị ngưỡng độ nhạy. Giá trị quá nhỏ sẽ dẫn đến nhiều kết quả dương tính giả (đó là khi bạn không nói cụm từ kích hoạt nhưng hệ thống nhận ra). Và quá cao - đến khả năng miễn dịch. Vì vậy, cài đặt này có tầm quan trọng đặc biệt. Phạm vi giá trị gần đúng - từ 1e-1 đến 1e-40 tùy thuộc vào cụm từ kích hoạt.

Kích hoạt cảm biến tiệm cận

Nhiệm vụ này dành riêng cho dự án của chúng tôi và không liên quan trực tiếp đến việc công nhận. Mã có thể được nhìn thấy trực tiếp trong hoạt động chính.
Cô ấy thực hiện Trình nghe sự kiện cảm biến và tại thời điểm tiếp cận (giá trị cảm biến nhỏ hơn giá trị tối đa), nó sẽ bật bộ hẹn giờ, kiểm tra sau một độ trễ nhất định xem cảm biến có còn bị chặn hay không. Điều này được thực hiện để loại bỏ các kết quả dương tính giả.
Khi cảm biến không bị chặn nữa, chúng tôi sẽ dừng nhận dạng và nhận kết quả (xem mô tả bên dưới).

Hãy bắt đầu công nhận

Pocketsphinx cung cấp API thuận tiện để định cấu hình và chạy quy trình nhận dạng. Đây là những lớp học Trình nhận dạng SpechThiết lập nhận dạng giọng nói.
Cấu hình và khởi chạy nhận dạng trông như thế này:

PhonMapper phonMapper = new PhonMapper(getAssets().open("dict/ru/hotwords")); Ngữ pháp ngữ pháp = ngữ pháp mới(tên, phonMapper); ngữ pháp.addWords(từ nóng); DataFiles dataFiles = new DataFiles(getPackageName(), "ru"); Tệp hmmDir = Tệp mới(dataFiles.getHmm()); Tệp dict = Tệp mới(dataFiles.getDict()); Tệp jsgf = Tệp mới(dataFiles.getJsgf()); copyAssets(hmmDir); saveFile(jsgf, Grammar.getJsgf()); saveFile(dict, Grammar.getDict()); mRecognizer = SpeechRecognizerSetup.defaultSetup() .setAcousticModel(hmmDir) .setDictionary(dict) .setBoolean("-remove_noise", false) .setKeywordThreshold(1e-7f) .getRecognizer(); mRecognizer.addKeyphraseSearch(KWS_SEARCH, từ nóng); mRecognizer.addGrammarSearch(COMMAND_SEARCH, jsgf);

Ở đây, trước tiên chúng tôi sao chép tất cả các tệp cần thiết vào đĩa (Pocketpshinx yêu cầu mô hình âm thanh, ngữ pháp và từ điển có phiên âm trên đĩa). Sau đó, công cụ nhận dạng sẽ được cấu hình. Đường dẫn đến tệp mô hình và từ điển cũng như một số tham số (ngưỡng nhạy cảm cho cụm từ kích hoạt) được chỉ định. Tiếp theo, đường dẫn đến tệp ngữ pháp cũng như cụm từ kích hoạt được định cấu hình.

Như bạn có thể thấy từ mã này, một công cụ được cấu hình để nhận dạng cả ngữ pháp và cụm từ kích hoạt. Tại sao điều này được thực hiện? Để chúng ta có thể nhanh chóng chuyển đổi giữa những gì chúng ta hiện cần nhận biết. Quá trình bắt đầu nhận dạng cụm từ kích hoạt trông như thế này:

MRecognizer.startListening(KWS_SEARCH);
Và đây là cách nhận dạng lời nói theo một ngữ pháp nhất định:

MRecognizer.startListening(COMMAND_SEARCH, 3000);
Đối số thứ hai (tùy chọn) là số mili giây mà sau đó quá trình nhận dạng sẽ tự động kết thúc nếu không có ai nói gì.
Như bạn có thể thấy, bạn chỉ có thể sử dụng một động cơ để giải quyết cả hai vấn đề.

Làm thế nào để có được kết quả công nhận

Để có được kết quả nhận dạng, bạn cũng phải chỉ định một trình xử lý sự kiện triển khai giao diện Trình nghe công nhận.
Nó có một số phương thức được Pocketphinx gọi khi một trong các sự kiện xảy ra:
  • onBeginningOfSpeech- động cơ nghe thấy một số âm thanh, có thể đó là lời nói (hoặc có thể không)
  • onEndOfSpeech- âm thanh kết thúc
  • trênPartialResult- có kết quả nhận dạng trung gian. Đối với cụm từ kích hoạt, điều này có nghĩa là nó đã hoạt động. Lý lẽ giả thuyết
  • trênKết quả- kết quả cuối cùng của sự công nhận. Phương thức này sẽ được gọi sau khi phương thức được gọi dừng lại Tại Trình nhận dạng giọng nói. Lý lẽ giả thuyết chứa dữ liệu nhận dạng (chuỗi và điểm)

Bằng cách triển khai các phương thức onPartialResult và onResult theo cách này hay cách khác, bạn có thể thay đổi logic nhận dạng và thu được kết quả cuối cùng. Đây là cách nó được thực hiện trong trường hợp ứng dụng của chúng tôi:

@Override public void onEndOfSpeech() ( Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) ( mRecognizer.stop(); ) ) @Override public void onPartialResult(Giả thuyết giả thuyết) ( if (giả thuyết == null) return; Chuỗi văn bản = giả thuyết.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) ( startRecognition(); ) else ( Log.d(TAG, text); ) ) @Override public void onResult(Giả thuyết giả thuyết) ( mMicView.setBackgroundResource(R.drawable.background_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); Chuỗi văn bản = giả thuyết != null ?giả thuyết.getHypstr() : null; Log.d(TAG , "onResult " + text); if (COMMAND_SEARCH.equals(mRecognizer.getSearchName())) ( if (text != null) ( Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); process(text ); ) mRecognizer.startListening(KWS_SEARCH); ) )

Khi chúng tôi nhận được sự kiện onEndOfSpeech và nếu đồng thời chúng tôi nhận ra lệnh sẽ được thực thi thì chúng tôi cần dừng nhận dạng, sau đó onResult sẽ được gọi ngay lập tức.
OnResult cần kiểm tra những gì vừa được nhận dạng. Nếu đây là lệnh, thì bạn cần khởi chạy nó để thực thi và chuyển động cơ để nhận dạng cụm từ kích hoạt.
Trong onPartialResult chúng tôi chỉ quan tâm đến việc nhận dạng cụm từ kích hoạt. Nếu phát hiện ra, chúng tôi sẽ bắt đầu ngay quá trình nhận dạng lệnh. Đây là những gì nó trông giống như:

Đồng bộ riêng tư void startRecognition() ( if (mRecognizer == null || COMMAND_SEARCH.equals(mRecognizer.getSearchName())) return; mRecognizer.cancel(); new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME).startTone(ToneGenerator. TONE_CDMA_PIP, 200); post(400, new Runnable() ( @Override public void run() ( mMicView.setBackgroundResource(R.drawable.background_big_mic_green); mRecognizer.startListening(COMMAND_SEARCH, 3000); Log.d(TAG, "Nghe này command"); post(4000, mStopRecognitionCallback); ) )); )
Ở đây, trước tiên chúng tôi phát một tín hiệu nhỏ để thông báo cho người dùng rằng chúng tôi đã nghe thấy anh ấy và sẵn sàng nhận lệnh của anh ấy. Trong thời gian này, micro nên được tắt. Do đó, chúng tôi bắt đầu nhận dạng sau một khoảng thời gian chờ ngắn (dài hơn một chút so với thời lượng của tín hiệu để không nghe thấy tiếng vang của nó). Nó cũng bắt đầu một chuỗi sẽ buộc dừng nhận dạng nếu người dùng nói quá lâu. Trong trường hợp này là 3 giây.

Cách biến chuỗi được nhận dạng thành lệnh

Chà, mọi thứ ở đây đều dành riêng cho một ứng dụng cụ thể. Trong trường hợp ví dụ đơn giản, chúng tôi chỉ cần lấy tên thiết bị từ dòng, tìm kiếm thiết bị mong muốn và thay đổi trạng thái của thiết bị bằng cách sử dụng yêu cầu HTTP tới bộ điều khiển nhà thông minh hoặc báo cáo trạng thái hiện tại của thiết bị (như trong trường hợp của một bộ điều nhiệt). Logic này có thể được nhìn thấy trong lớp Controller.

Cách tổng hợp lời nói

Tổng hợp giọng nói là hoạt động nghịch đảo của nhận dạng. Ở đây thì ngược lại - bạn cần chuyển một dòng văn bản thành lời nói để người dùng có thể nghe thấy.
Trong trường hợp bộ điều chỉnh nhiệt, chúng ta phải làm cho thiết bị Android của mình đọc nhiệt độ hiện tại. Sử dụng API TextToSpeech việc này khá dễ thực hiện (cảm ơn Google đã cung cấp TTS nữ tuyệt vời cho tiếng Nga):

Private void speak(String text) ( được đồng bộ hóa (mSpeechQueue) ( ​​​​mRecognizer.stop(); mSpeechQueue.add(text); HashMap thông số = HashMap mới (2); params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UUID.randomUUID().toString()); params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC)); params.put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true"); mTextToSpeech.speak(văn bản, TextToSpeech.QUEUE_ADD, thông số); ) )

Có lẽ tôi sẽ nói điều gì đó tầm thường, nhưng trước quá trình tổng hợp, cần phải tắt tính năng nhận dạng. Trên một số thiết bị (ví dụ: tất cả các thiết bị Samsung), nhìn chung không thể nghe micrô và tổng hợp nội dung nào đó cùng một lúc.
Phần cuối của quá trình tổng hợp giọng nói (nghĩa là phần cuối của quá trình nói văn bản bằng bộ tổng hợp) có thể được theo dõi trong trình nghe:

Cuối cùng riêng tư TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() ( @Override public void onUtteranceCompleted(StringutteranceId) ( được đồng bộ hóa (mSpeechQueue) ( ​​​​ mSpeechQueue.poll(); if (mSpeechQueue.isEmpty()) ( mRecognizer.startListening( KWS_SEARCH) ; ) ) ) );

Trong đó, chúng tôi chỉ cần kiểm tra xem có gì khác trong hàng đợi tổng hợp hay không và bật nhận dạng cụm từ kích hoạt nếu không có gì khác.

Và đó là tất cả?

Đúng! Như bạn có thể thấy, việc nhận dạng giọng nói trực tiếp trên thiết bị một cách nhanh chóng và hiệu quả không hề khó chút nào nhờ sự hiện diện của những dự án tuyệt vời như Pocketsphinx. Nó cung cấp một API rất tiện lợi có thể được sử dụng để giải quyết các vấn đề liên quan đến nhận dạng lệnh thoại.

Trong ví dụ này, chúng tôi đã đính kèm sự công nhận cho một nhiệm vụ hoàn toàn cụ thể - điều khiển bằng giọng nói của thiết bị nhà thông minh. Nhờ sự công nhận của địa phương, chúng tôi đã đạt được tốc độ rất cao và giảm thiểu sai sót.
Rõ ràng là mã tương tự có thể được sử dụng cho các tác vụ khác liên quan đến giọng nói. Nó không nhất thiết phải là một ngôi nhà thông minh.

  • điều khiển giọng nói
  • công cụ giọng nói
  • Thêm thẻ

    Điện thoại này có nhận dạng giọng nói hoặc nhập liệu bằng giọng nói nhưng nó chỉ hoạt động qua Internet, kết nối với các dịch vụ của Google. Nhưng điện thoại có thể được dạy cách nhận dạng giọng nói mà không cần Internet, chúng ta sẽ xem cách kích hoạt tính năng nhận dạng tiếng Nga trong ngoại tuyến. Để phương pháp này hoạt động, bạn phải cài đặt hai ứng dụng Tìm kiếm bằng giọng nóiTìm kiếm của Google, mặc dù các chương trình này đã có sẵn trong chương trình cơ sở của nhà sản xuất.

    Đối với phần sụn

    Đi tới cài đặt điện thoại của bạn và chọn

    Chọn ngôn ngữ tiếng Nga và tải xuống.

    Đối với phần sụn 2.8B

    Trong phần sụn mới, mục menu " Nhận dạng giọng nói ngoại tuyến" vắng mặt.

    Nếu bạn đã cài đặt các gói ngoại tuyến trước khi cập nhật chương trình cơ sở và bạn không xóa (đặt lại cài đặt) trong quá trình cập nhật thì chúng đáng lẽ phải được giữ nguyên. Nếu không, bạn sẽ phải quay lại phần sụn 2.2 , cài đặt các gói thoại và chỉ sau đó cập nhật hệ thống lên 2,8B.

    Dành cho thiết bị Rev.B

    Chúng tôi cài đặt bản cập nhật thông qua khôi phục và tận hưởng tính năng nhận dạng giọng nói trong oyline.

    2. Tải xuống cơ sở dữ liệu cho bài phát biểu bằng tiếng Nga và sao chép nó vào thẻ SD

    Tải xuống Russian_offline.zip 1301

    3. Vào recovery bằng cách giữ (Volume + và On) khi điện thoại đã tắt.

    4. Chọn Áp dụng bản cập nhật từ bộ nhớ ngoài và chọn kho lưu trữ đã tải xuống.

    Không có chương trình nào có thể thay thế hoàn toàn công việc ghi âm giọng nói bằng tay. Tuy nhiên, có những giải pháp có thể tăng tốc đáng kể và tạo điều kiện thuận lợi cho việc dịch lời nói thành văn bản, tức là đơn giản hóa việc phiên âm.

    Phiên âm là việc ghi lại một tập tin âm thanh hoặc video ở dạng văn bản. Có những nhiệm vụ trả phí trên Internet khi người biểu diễn được trả một số tiền nhất định để sao chép văn bản.

    Dịch lời nói thành văn bản rất hữu ích

    • học sinh dịch các bài giảng bằng âm thanh hoặc video đã ghi thành văn bản,
    • các blogger điều hành các trang web và blog,
    • nhà văn, nhà báo để viết sách và văn bản,
    • các doanh nhân thông tin cần một văn bản sau hội thảo trên web, bài phát biểu của họ, v.v.,
    • những người gặp khó khăn khi đánh máy - họ có thể viết một lá thư và gửi cho gia đình hoặc bạn bè,
    • sự lựa chọn khác.

    Chúng tôi sẽ mô tả các công cụ hiệu quả nhất hiện có trên PC, ứng dụng di động và dịch vụ trực tuyến.

    1 Trang web speechpad.ru

    Đây là dịch vụ trực tuyến cho phép bạn dịch lời nói thành văn bản bằng trình duyệt Google Chrome. Dịch vụ này hoạt động với micrô và các tệp được tạo sẵn. Tất nhiên, chất lượng sẽ cao hơn rất nhiều nếu bạn sử dụng micro ngoài và tự đọc chính tả. Tuy nhiên, dịch vụ này hoạt động tốt ngay cả với video YouTube.

    Nhấp vào “Bật ghi âm”, trả lời câu hỏi về “Sử dụng micrô” - để thực hiện việc này, hãy nhấp vào “Cho phép”.

    Có thể thu gọn các hướng dẫn dài về cách sử dụng dịch vụ bằng cách nhấp vào nút 1 trong Hình. 3. Bạn có thể loại bỏ quảng cáo bằng cách hoàn tất đăng ký đơn giản.

    Cơm. 3. Dịch vụ Speechpad

    Kết quả hoàn thành rất dễ chỉnh sửa. Để thực hiện việc này, bạn cần sửa từ được đánh dấu theo cách thủ công hoặc đọc lại từ đó. Kết quả công việc được lưu trong tài khoản cá nhân của bạn, chúng cũng có thể được tải xuống máy tính của bạn.

    Danh sách video bài học làm việc với speechpad:

    Bạn có thể chép video từ Youtube hoặc từ máy tính, tuy nhiên bạn sẽ cần một mixer, chi tiết hơn:

    Video "Phiên âm âm thanh"

    Dịch vụ này hoạt động bằng bảy ngôn ngữ. Có một điểm trừ nhỏ. Thực tế là nếu bạn cần chép lại một tệp âm thanh đã hoàn thành, thì âm thanh của nó sẽ được nghe qua loa, điều này sẽ tạo thêm nhiễu dưới dạng tiếng vang.

    2 Dịch vụ dict.io

    Một dịch vụ trực tuyến tuyệt vời cho phép bạn dịch lời nói thành văn bản miễn phí và dễ dàng.

    Cơm. 4. Dịch vụ dict.io

    1 trong hình. 4 – Ngôn ngữ tiếng Nga có thể được chọn ở cuối trang. Trong trình duyệt Google Chrome, ngôn ngữ được chọn nhưng vì lý do nào đó trong Mozilla không có tùy chọn như vậy.

    Đáng chú ý là khả năng tự động lưu kết quả đã hoàn thành đã được triển khai. Điều này sẽ ngăn việc vô tình xóa do đóng tab hoặc trình duyệt. Dịch vụ này không nhận ra các tập tin đã hoàn thành. Hoạt động với micrô. Bạn cần đặt tên cho các dấu chấm câu khi đọc chính tả.

    Văn bản được nhận dạng khá chính xác, không có lỗi chính tả. Bạn có thể tự chèn dấu chấm câu từ bàn phím. Kết quả hoàn thành có thể được lưu trên máy tính của bạn.

    3 loa thật

    Chương trình này cho phép bạn dễ dàng dịch lời nói của con người thành văn bản. Nó được thiết kế để hoạt động trên các hệ thống khác nhau: Windows, Android, Linux, Mac. Với sự trợ giúp của nó, bạn có thể chuyển đổi giọng nói nghe được thành micrô (ví dụ: nó có thể được tích hợp vào máy tính xách tay), cũng như được ghi thành tệp âm thanh.

    Có thể hiểu được 13 ngôn ngữ trên thế giới. Có phiên bản beta của chương trình hoạt động như một dịch vụ trực tuyến:

    Bạn cần theo liên kết ở trên, chọn ngôn ngữ tiếng Nga, tải tệp âm thanh hoặc video của bạn lên dịch vụ trực tuyến và trả tiền cho phiên âm của nó. Sau khi phiên âm, bạn có thể sao chép văn bản kết quả. Tệp phiên âm càng lớn thì càng mất nhiều thời gian để xử lý, chi tiết hơn:

    Năm 2017 đã có tùy chọn chép lời miễn phí bằng RealSpeaker, nhưng năm 2018 thì không có tùy chọn này. Rất khó hiểu khi tất cả người dùng đều có thể tải xuống tệp phiên âm, có lẽ điều này sẽ được cải thiện.

    Bạn có thể tìm thấy thông tin liên hệ của nhà phát triển (VKontakte, Facebook, Youtube, Twitter, email, điện thoại) trên trang web của anh ấy (chính xác hơn là ở phần chân trang của trang web):

    4 Trình ghi lời nói

    Một giải pháp thay thế cho ứng dụng trước đây dành cho thiết bị di động chạy trên Android. Có sẵn miễn phí trong cửa hàng ứng dụng:

    Văn bản được chỉnh sửa tự động và dấu chấm câu được thêm vào. Rất thuận tiện cho việc ghi chép cho chính mình hoặc lập danh sách. Kết quả là văn bản sẽ có chất lượng rất tốt.

    5 câu thần chú rồng

    Đây là ứng dụng được phân phối miễn phí cho các thiết bị di động của Apple.

    Chương trình có thể hoạt động với 15 ngôn ngữ. Nó cho phép bạn chỉnh sửa kết quả và chọn các từ mong muốn từ danh sách. Bạn cần phát âm rõ ràng tất cả các âm, không ngắt quãng không cần thiết và tránh ngữ điệu. Đôi khi có lỗi ở phần cuối của từ.

    Ví dụ: ứng dụng Dragon Dictation được các chủ sở hữu sử dụng để ghi danh sách mua sắm trong cửa hàng khi di chuyển quanh căn hộ. Khi đến đó, tôi có thể xem nội dung trong ghi chú và không cần phải nghe.

    Dù bạn sử dụng chương trình nào trong quá trình luyện tập, hãy chuẩn bị kiểm tra kỹ kết quả và thực hiện một số điều chỉnh nhất định. Đây là cách duy nhất để có được một văn bản hoàn hảo không có lỗi.

    Ngoài ra còn có các dịch vụ hữu ích:

    Nhận các bài viết về kiến ​​thức máy tính mới nhất trực tiếp vào hộp thư đến của bạn.
    Đã nhiều hơn nữa 3.000 người đăng ký

    .