.NET masaüstü uygulamalarını kullanarak konuşma tanıma. Gerçek bir örnek kullanarak sunucular olmadan ultra hızlı konuşma tanıma Android 6.0'da çevrimdışı konuşma tanıma

) ev aletleri kontrolünde gerçek bir Merhaba Dünya örneği kullanarak.
Neden ev aletleri? Evet, çünkü böyle bir örnek sayesinde bunu takdir edebilirsiniz. hız ve doğruluk kullanılarak elde edilebilecek tamamen yerli gibi sunucular olmadan konuşma tanıma Google ASR'si veya Yandex Konuşma Kiti.
Ayrıca makaleye programın tüm kaynak kodunu ve Android için derlemenin kendisini de ekliyorum.

Neden aniden?

Son zamanlarda bununla karşılaştıktan sonra yazara, programı için neden sunucu tabanlı konuşma tanımayı kullanmak istediğini sordum (bence bu gereksizdi ve bazı sorunlara yol açtı). Bu amaçla, hiçbir şeyin tanınmasına gerek olmayan ve sözlüğün sınırlı sayıda kelimeden oluştuğu projeler için alternatif yöntemlerin kullanımını daha ayrıntılı olarak anlatabilir miyim? Ve hatta pratik bir uygulama örneğiyle...

Neden Yandex ve Google dışında başka bir şeye ihtiyacımız var?

Bu çok “pratik uygulama” için konuyu seçtim akıllı ev için ses kontrolü.
Neden tam olarak bu örnek? Çünkü tamamen yerel konuşma tanımanın, bulut çözümlerini kullanarak tanımaya göre çeşitli avantajlarını gösterir. Yani:
  • Hız- sunuculara bağlı değiliz ve bu nedenle onların kullanılabilirliğine, bant genişliğine vb. bağlı değiliz. faktörler
  • Kesinlik- motorumuz yalnızca uygulamamızı ilgilendiren sözlükle çalışır, böylece tanınma kalitesi artar
  • Fiyat- sunucuya yapılan her istek için ödeme yapmak zorunda değiliz
  • Ses aktivasyonu- ilk noktalara ek bir bonus olarak - trafiğimizi boşa harcamadan ve sunucuları yüklemeden sürekli "yayını dinleyebiliriz"

Not

Bu avantajların avantaj sayılabilmesi için hemen rezervasyon yaptırayım. yalnızca belirli bir proje sınıfı için, Neredeyiz önceden kesin olarak biliyoruz, kullanıcının hangi sözlükle ve hangi gramerle çalışacağı. Yani, rastgele metni (örneğin bir SMS mesajı veya bir arama sorgusu) tanımamıza gerek olmadığında. Aksi takdirde bulut tanıma vazgeçilmezdir.

Böylece Android, İnternet olmadan da konuşmayı tanıyabilir!
Evet, evet... Yalnızca JellyBean'de. Ve sadece yarım metreden fazlası yok. Ve bu tanıma aynı diktedir, sadece çok daha küçük bir model kullanılarak. Yani onu da yönetemiyoruz veya yapılandıramıyoruz. Ve bir dahaki sefere bize ne döneceği bilinmiyor. Her ne kadar SMS için doğru olsa da!

Biz ne yaptık?

Ev aletleri için birkaç metreden, hatta ucuz, berbat, çok ucuz Android akıllı telefon, tablet ve saatlerde doğru ve hızlı çalışacak sesli uzaktan kumandayı hayata geçireceğiz.
Mantık basit ama çok pratik olacak. Mikrofonu etkinleştirip bir veya daha fazla cihaz adını söylüyoruz. Uygulama bunları tanır ve mevcut duruma göre açıp kapatır. Veya onlardan bir servet alır ve bunu hoş bir kadın sesiyle söyler. Örneğin odadaki mevcut sıcaklık.

Pratik uygulamalar çoktur

Sabah gözlerinizi açmadan avucunuzu komodinin üzerindeki akıllı telefon ekranına vurup "Günaydın!" komutunu verdiniz. - senaryo başlar, kahve makinesi açılır ve mırıldanır, hoş bir müzik duyulur, perdeler açılır.
Her odanın duvarına ucuz (2 bin, artık yok) bir akıllı telefon asalım. İşten sonra eve gidiyoruz ve boşluğa “Akıllı Ev! Işıklar, televizyon! - Bundan sonra ne olacağını söylemeye gerek olduğunu düşünmüyorum.

Transkripsiyonlar



Dilbilgisi neyi açıklar kullanıcının söyleyebilecekleri. Pocketsphinx'in bilmesi için, Nasıl telaffuz edecekse, dilbilgisindeki her kelimenin karşılık gelen dil modelinde nasıl ses çıkardığını yazması gerekir. Yani transkripsiyon her kelime. denir sözlük.

Transkripsiyonlar özel bir sözdizimi kullanılarak açıklanmaktadır. Örneğin:
akıllı uu m n ay j ev d oo m

Prensip olarak karmaşık bir şey yok. Transkripsiyondaki çift sesli harf vurguyu gösterir. Çift ünsüz, yumuşak bir ünsüz ve onu takip eden bir sesli harftir. Rus dilinin tüm sesleri için olası tüm kombinasyonlar.

Uygulamamızdaki tüm transkripsiyonları önceden tanımlayamayacağımız açıktır çünkü kullanıcının cihazlarına vereceği isimleri önceden bilmiyoruz. Bu nedenle, bu tür transkripsiyonları Rus fonetiğinin bazı kurallarına göre "anında" oluşturacağız. Bunu yapmak için, girdi olarak bir dize alabilen ve bunun için doğru transkripsiyonu oluşturabilen aşağıdaki PhonMapper sınıfını uygulayabilirsiniz.

Ses aktivasyonu

Bu, konuşma tanıma motorunun önceden belirlenmiş bir ifadeye (veya ifadelere) tepki vermek için her zaman "yayını dinleme" yeteneğidir. Aynı zamanda diğer tüm sesler ve konuşmalar da silinecektir. Bu, dil bilgisini anlatıp sadece mikrofonu açmakla aynı şey değil. Burada bu görevin teorisini ve nasıl çalıştığının mekaniğini sunmayacağım. Pocketsphinx üzerinde çalışan programcıların son zamanlarda böyle bir işlevi hayata geçirdiklerini ve artık API'de kullanıma hazır olduğunu söylemeliyim.

Bir şeyi kesinlikle belirtmeye değer. Bir aktivasyon ifadesi için yalnızca transkripsiyonu belirtmeniz değil, aynı zamanda uygun olanı da seçmeniz gerekir. hassasiyet eşik değeri. Çok küçük bir değer birçok hatalı pozitif sonuca yol açacaktır (bu, etkinleştirme ifadesini söylemediğiniz halde sistemin bunu tanıdığı durumdur). Ve çok yüksek - dokunulmazlık için. Bu nedenle bu ayar özellikle önemlidir. Yaklaşık değer aralığı - 1e-1'den 1e-40'a kadar aktivasyon ifadesine bağlı olarak.

Yakınlık sensörü aktivasyonu

Bu görev projemize özeldir ve doğrudan tanınma ile ilgili değildir. Kod doğrudan ana aktivitede görülebilir.
O uygular SensörEventListener ve yaklaşma anında (sensör değeri maksimumun altında) zamanlayıcıyı açarak belirli bir gecikmeden sonra sensörün hala engellenip engellenmediğini kontrol eder. Bu, yanlış pozitifleri ortadan kaldırmak için yapılır.
Sensör tekrar bloke edilmediğinde, sonucu alarak tanımayı durdururuz (aşağıdaki açıklamaya bakın).

Tanıma işlemine başlayalım

Pocketsphinx, tanıma sürecini yapılandırmak ve çalıştırmak için kullanışlı bir API sağlar. Bunlar sınıflar Özel Tanıyıcı Ve Konuşma Tanıyıcı Kurulumu.
Tanıma yapılandırması ve başlatılması şöyle görünür:

PhonMapper phonMapper = new PhonMapper(getAssets().open("dict/ru/hotwords")); Gramer grameri = new Gramer(isimler, phonMapper); grammar.addWords(özel kelime); DataFiles dataFiles = new DataFiles(getPackageName(), "ru"); Dosya hmmDir = yeni Dosya(dataFiles.getHmm()); Dosya dict = new Dosya(dataFiles.getDict()); Dosya jsgf = yeni Dosya(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, özel kelime); mRecognizer.addGrammarSearch(COMMAND_SEARCH, jsgf);

Burada öncelikle gerekli tüm dosyaları diske kopyalıyoruz (Pocketpshinx, diskte olması için bir akustik model, gramer ve transkripsiyonlu sözlük gerektirir). Daha sonra tanıma motorunun kendisi yapılandırılır. Modele ve sözlük dosyalarına giden yollar ve bazı parametreler (etkinleştirme ifadesi için hassasiyet eşiği) belirtilir. Daha sonra, dil bilgisinin yanı sıra etkinleştirme ifadesinin bulunduğu dosyanın yolu yapılandırılır.

Bu koddan görebileceğiniz gibi, bir motor hem dilbilgisi hem de aktivasyon ifadesi tanıma için yapılandırılmıştır. Bu neden yapılıyor? Böylece şu anda tanımamız gerekenler arasında hızlı bir şekilde geçiş yapabiliriz. Etkinleştirme ifadesi tanıma sürecini başlatmak şu şekilde görünür:

MRecognizer.startListening(KWS_SEARCH);
Ve belirli bir dilbilgisine göre konuşma şu şekilde tanınır:

MRecognizer.startListening(COMMAND_SEARCH, 3000);
İkinci argüman (isteğe bağlı), kimse bir şey söylemediğinde tanımanın otomatik olarak sona ereceği milisaniye sayısıdır.
Gördüğünüz gibi her iki sorunu da çözmek için yalnızca bir motor kullanabilirsiniz.

Tanıma sonucu nasıl alınır?

Tanıma sonucunu almak için arayüzü uygulayan bir olay dinleyicisini de belirtmeniz gerekir. TanımaDinleyici.
Olaylardan biri meydana geldiğinde Pocketsphinx tarafından çağrılan birkaç yöntem vardır:
  • onKonuşmanın Başlangıcında- motor bir ses duydu, belki konuşmaydı (ya da belki değildi)
  • onEndOfSpeech- ses biter
  • onKısmiSonuç- ara tanıma sonuçları var. Bir aktivasyon ifadesi için bu, işe yaradığı anlamına gelir. Argüman Hipotez
  • sonuç üzerinde- tanınmanın nihai sonucu. Bu yöntem, yöntem çağrıldıktan sonra çağrılacaktır. durmak en Konuşma Tanıyıcı. Argüman Hipotez tanıma verilerini içerir (dize ve puan)

onPartialResult ve onResult yöntemlerini bir şekilde uygulayarak tanıma mantığını değiştirebilir ve nihai sonucu elde edebilirsiniz. Bizim başvurumuzda bu şu şekilde yapılıyor:

@Override public void onEndOfSpeech() ( Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) ( mRecognizer.stop(); )) @Override public void onPartialResult(Hipotez hipotezi) ( if (hipotez == null) return; String text = hipotez.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) ( startRecognition(); ) else ( Log.d(TAG, text); ) ) @Override public void onResult(Hipotez hipotezi) ( mMicView.setBackgroundResource(R.drawable.background_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); String text = hipotez != null ? hipotez.getHypstr() : null; Log.d(TAG , "onResult " + metin); if (COMMAND_SEARCH.equals(mRecognizer.getSearchName())) ( if (text != null) ( Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); proses(metin) ); ) mRecognizer.startListening(KWS_SEARCH);

onEndOfSpeech olayını aldığımızda ve aynı zamanda yürütülecek komutu tanırsak, tanımayı durdurmamız gerekir, ardından onResult hemen çağrılacaktır.
onResult'ta yeni neyin tanındığını kontrol etmeniz gerekir. Bu bir komutsa, onu yürütmek için başlatmanız ve motoru etkinleştirme ifadesini tanıyacak şekilde değiştirmeniz gerekir.
onPartialResult'ta yalnızca aktivasyon ifadesini tanımakla ilgileniyoruz. Eğer tespit edersek hemen komut tanıma işlemini başlatıyoruz. İşte neye benziyor:

Özel senkronize 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, "Dinle komutlar"); post(4000, mStopRecognitionCallback); ) )); )
Burada öncelikle kullanıcıya onu duyduğumuzu ve komutuna hazır olduğumuzu bildirmek için küçük bir sinyal çalıyoruz. Bu süre zarfında mikrofon kapatılmalıdır. Bu nedenle, kısa bir zaman aşımından sonra (yankısını duymamak için sinyalin süresinden biraz daha uzun) tanımaya başlarız. Ayrıca, kullanıcının çok uzun süre konuşması durumunda tanımayı zorla durduracak bir ileti dizisi başlatır. Bu durumda 3 saniyedir.

Tanınan dize komutlara nasıl dönüştürülür?

Buradaki her şey belirli bir uygulamaya özeldir. Çıplak örnekte, cihaz adlarını hattan çıkarırız, istenen cihazı ararız ve ya akıllı ev denetleyicisine bir HTTP isteği kullanarak durumunu değiştiririz ya da mevcut durumunu bildiririz (örneğin, bir termostat). Bu mantık Controller sınıfında görülebilir.

Konuşma nasıl sentezlenir

Konuşma sentezi tanımanın ters işlemidir. Burada durum tam tersidir; kullanıcının duyabilmesi için bir metin satırını konuşmaya dönüştürmeniz gerekir.
Termostat söz konusu olduğunda Android cihazımızın mevcut sıcaklığı konuşmasını sağlamalıyız. API'yi kullanma Konuşma metni bunu yapmak oldukça kolaydır (Rus dili için harika kadın TTS'si için Google'a teşekkürler):

Özel void konuşma(String text) ( synchronized (mSpeechQueue) ( ​​mRecognizer.stop(); mSpeechQueue.add(text); HashMap parametreler = yeni HashMap (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(metin, TextToSpeech.QUEUE_ADD, parametreler); ))

Muhtemelen banal bir şey söyleyeceğim ama sentez işleminden önce tanımayı devre dışı bırakmak gerekir. Bazı cihazlarda (örneğin tüm Samsung cihazlarında), mikrofonu dinlemek ve aynı anda bir şeyler sentezlemek genellikle imkansızdır.
Konuşma sentezinin sonu (yani, bir sentezleyici tarafından metnin seslendirilmesi sürecinin sonu) dinleyicide takip edilebilir:

Özel final TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() ( @Override public void onUtteranceCompleted(String utteranceId) ( synchronized (mSpeechQueue) ( ​​mSpeechQueue.poll(); if (mSpeechQueue.isEmpty()) ( mRecog nizer.startListening( KWS_SEARCH) ) ) ));

Burada, sentez kuyruğunda başka bir şey olup olmadığını kontrol ediyoruz ve başka bir şey yoksa aktivasyon ifadesi tanımayı etkinleştiriyoruz.

Peki hepsi bu mu?

Evet! Gördüğünüz gibi, Pocketsphinx gibi harika projelerin varlığı sayesinde konuşmayı doğrudan cihazda hızlı ve verimli bir şekilde tanımak hiç de zor değil. Sesli komutların tanınmasıyla ilgili sorunların çözümünde kullanılabilecek oldukça kullanışlı bir API sağlar.

Bu örnekte, tanınmayı tamamen spesifik bir göreve ekledik - akıllı ev cihazlarının ses kontrolü. Yerel tanınırlık sayesinde çok yüksek hızlara ulaştık ve hataları minimuma indirdik.
Aynı kodun sesle ilgili diğer görevler için de kullanılabileceği açıktır. Akıllı bir ev olması gerekmiyor.

  • ses kontrolü
  • ses motoru
  • Etiket ekle

    Hiçbir program, kaydedilen konuşmanın yazıya geçirilmesi şeklindeki manuel çalışmanın yerini tamamen alamaz. Ancak konuşmanın metne çevrilmesini önemli ölçüde hızlandırabilen ve kolaylaştırabilen, yani transkripsiyonu basitleştirebilen çözümler vardır.

    Transkripsiyon, bir ses veya video dosyasının metin biçiminde kaydedilmesidir. İnternette, metni yazıya dökmek için sanatçıya belirli bir miktar para ödendiğinde ücretli ücretli görevler vardır.

    Konuşmadan metne çeviri faydalıdır

    • öğrencilerin kayıtlı sesli veya görüntülü dersleri metne çevirmeleri,
    • web siteleri ve bloglar çalıştıran blog yazarları,
    • Kitap ve metin yazan yazarlar, gazeteciler,
    • Web semineri, konuşma vb. sonrasında bir metne ihtiyaç duyan bilgi işadamları,
    • Yazmakta zorluk çeken kişiler - bir mektubu yazdırıp bunu ailelerine veya arkadaşlarına gönderebilirler,
    • diğer seçenekler.

    PC'lerde, mobil uygulamalarda ve çevrimiçi hizmetlerde bulunan en etkili araçları anlatacağız.

    1 Web sitesi konuşmapad.ru

    Bu, Google Chrome tarayıcısını kullanarak konuşmayı metne çevirmenize olanak tanıyan çevrimiçi bir hizmettir. Hizmet bir mikrofon ve hazır dosyalarla çalışır. Elbette harici bir mikrofon kullanıp kendiniz dikte ederseniz kalite çok daha yüksek olacaktır. Ancak hizmet, YouTube videolarında bile iyi bir iş çıkarıyor.

    "Kaydı etkinleştir" seçeneğini tıklayın, "Mikrofon kullanma" sorusunu yanıtlayın - bunu yapmak için "İzin Ver" seçeneğini tıklayın.

    Hizmetin kullanımına ilişkin uzun talimatlar, Şekil 1'deki düğme 1'e tıklanarak daraltılabilir. 3. Basit bir kayıt işlemini tamamlayarak reklamlardan kurtulabilirsiniz.

    Pirinç. 3. Konuşma paneli hizmeti

    Bitmiş sonucun düzenlenmesi kolaydır. Bunu yapmak için, vurgulanan kelimeyi manuel olarak düzeltmeniz veya tekrar dikte etmeniz gerekir. Çalışmanın sonuçları kişisel hesabınıza kaydedilir, ayrıca bilgisayarınıza da indirilebilir.

    Konuşma paneliyle çalışmaya ilişkin video derslerinin listesi:

    Youtube'dan veya bilgisayarınızdan videoları yazabilirsiniz, ancak bir miksere ve daha fazla ayrıntıya ihtiyacınız olacak:

    Video "ses transkripsiyonu"

    Hizmet yedi dilde faaliyet göstermektedir. Küçük bir eksi var. Bitmiş bir ses dosyasını kopyalamanız gerekiyorsa, sesinin hoparlörler aracılığıyla duyulacağı ve bu da yankı şeklinde ek parazit yaratacağı gerçeğinde yatmaktadır.

    2 Hizmet dictation.io

    Konuşmayı ücretsiz ve kolay bir şekilde metne çevirmenize olanak tanıyan harika bir çevrimiçi hizmet.

    Pirinç. 4. Hizmet dictation.io

    Şekil 1'de 1. 4 – Sayfa sonunda Rusça dili seçilebilmektedir. Google Chrome tarayıcısında dil seçili ancak Mozilla'da nedense böyle bir seçenek yok.

    Bitmiş sonucu otomatik olarak kaydetme yeteneğinin uygulanması dikkat çekicidir. Bu, bir sekmenin veya tarayıcının kapatılması sonucunda yanlışlıkla silinmeyi önleyecektir. Bu hizmet tamamlanmış dosyaları tanımıyor. Mikrofonla çalışır. Dikte ederken noktalama işaretlerini belirtmeniz gerekir.

    Metin oldukça doğru bir şekilde tanınıyor, yazım hatası yok. Noktalama işaretlerini klavyeden kendiniz ekleyebilirsiniz. Bitmiş sonuç bilgisayarınıza kaydedilebilir.

    3 GerçekHoparlör

    Bu program insan konuşmasını kolayca metne çevirmenizi sağlar. Farklı sistemlerde çalışacak şekilde tasarlanmıştır: Windows, Android, Linux, Mac. Onun yardımıyla, duyulan konuşmayı bir mikrofona (örneğin, bir dizüstü bilgisayara yerleştirilebilir) ve ayrıca ses dosyalarına kaydedilebilir.

    13 dünya dilini anlayabilir. Programın çevrimiçi hizmet olarak çalışan bir beta sürümü vardır:

    Yukarıdaki bağlantıyı takip etmeniz, Rusça dilini seçmeniz, ses veya video dosyanızı çevrimiçi hizmete yüklemeniz ve transkripsiyonunu ödemeniz gerekir. Transkripsiyondan sonra ortaya çıkan metni kopyalayabilirsiniz. Transkripsiyon dosyası ne kadar büyük olursa, işlenmesi o kadar uzun sürer, daha fazla ayrıntı:

    2017'de RealSpeaker'ı kullanarak ücretsiz bir transkripsiyon seçeneği vardı, ancak 2018'de böyle bir seçenek yok. Yazıya aktarılan dosyanın tüm kullanıcılar tarafından indirilebilmesi oldukça kafa karıştırıcıdır; belki bu durum iyileştirilecektir.

    Programın geliştiricisinin (VKontakte, Facebook, Youtube, Twitter, e-posta, telefon) iletişim bilgileri web sitesinin sayfasında (daha doğrusu sitenin altbilgisinde) bulunabilir:

    4 Konuşma Kaydedici

    Android'de çalışan mobil cihazlar için önceki uygulamaya bir alternatif. Uygulama mağazasında ücretsiz olarak mevcuttur:

    Metin otomatik olarak düzenlenir ve noktalama işaretleri eklenir. Kendinize not dikte etmek veya liste yapmak için çok kullanışlıdır. Sonuç olarak, metin çok iyi kalitede olacaktır.

    5 Ejderha Diktesi

    Bu, Apple'ın mobil cihazları için ücretsiz olarak dağıtılan bir uygulamadır.

    Program 15 dilde çalışabilmektedir. Sonucu düzenlemenize ve listeden istediğiniz kelimeleri seçmenize olanak tanır. Tüm sesleri net bir şekilde telaffuz etmeniz, gereksiz duraklamalar yapmamanız ve tonlamadan kaçınmanız gerekir. Bazen kelimelerin sonlarında hatalar olabiliyor.

    Dragon Dictation uygulaması, örneğin mülk sahipleri tarafından, dairede dolaşırken bir mağazadaki alışveriş listesini dikte etmek için kullanılır. Oraya vardığımda nottaki metne bakabiliyorum ve dinlemek zorunda kalmıyorum.

    Uygulamanızda hangi programı kullanırsanız kullanın, sonuçları tekrar kontrol etmeye ve bazı ayarlamalar yapmaya hazır olun. Hatasız, kusursuz bir metin elde etmenin tek yolu budur.

    Ayrıca yararlı hizmetler:

    En son bilgisayar okuryazarlığı makalelerini doğrudan gelen kutunuza alın.
    Zaten daha fazlası 3.000 abone

    .

    Ürünler ve teknolojiler:

    Visual Studio, C#, .NET Konuşma Kitaplıkları

    Makale şunları tartışıyor:

    • konsol uygulamasına konuşma tanıma desteğinin eklenmesi;
    • tanınan konuşmanın işlenmesi;
    • konuşma tanıma kütüphanelerinin kurulumu;
    • Microsoft.Speech ve System.Speech'in karşılaştırılması;
    • Windows Forms uygulamasına konuşma tanıma desteği ekleme.

    Konuşmayla etkinleştirilen bir kişisel asistan olan Windows Phone Cortana'nın (aynı zamanda hakkında boşuna konuşulamayacak bir meyve şirketi muadili) ortaya çıkışıyla birlikte, konuşma etkin uygulamalar yazılım geliştirmede giderek daha fazla öne çıkıyor. Bu makalede size Windows konsol uygulamalarında, Windows Forms uygulamalarında ve Windows Sunum Vakfı'nda (WPF) konuşma tanıma ve sentezlemeye nasıl başlayacağınızı göstereceğim.

    Windows Phone uygulamalarına, ASP.NET web uygulamalarına, Windows Mağazası uygulamalarına, Windows RT'ye ve Xbox Kinect'e de konuşma özellikleri ekleyebileceğinizi ancak tekniklerin bu makalede açıklananlardan farklı olduğunu unutmayın.

    Bu makalenin tam olarak neyi tartışacağına dair bir fikir edinmenin iyi bir yolu, iki farklı demo programının ekran görüntülerine bakmaktır. pirinç. 1 Ve 2 . Konsol uygulamasını başlattıktan sonra pirinç. 1 hemen “uyanığım” cümlesini söylüyor. Elbette bu yazıyı okurken demo uygulamasını duyamayacaksınız, dolayısıyla bilgisayarın söylediği metni görüntülüyor. Daha sonra kullanıcı “Konuşma açık” komutunu söyler. Demo uygulaması tanınan metinle yanıt verir ve ardından dahili olarak iki sayı ekleme isteklerini dinler ve yanıt verir.

    Pirinç. 1. Konsol uygulamasında konuşma tanıma ve sentezleme


    Pirinç. 2. Windows Forms uygulamasında konuşma tanıma

    Kullanıcı, uygulamadan bir ve ikiyi, ardından iki ve üçü eklemesini istedi. Uygulama konuşulan komutları tanıdı ve sesli yanıtlar verdi. Konuşma tanımayı kullanmanın daha kullanışlı yollarını daha sonra anlatacağım.

    Kullanıcı daha sonra, ek komutların dinlenmesini devre dışı bırakan ancak konuşma tanımayı tamamen devre dışı bırakmayan bir sesli komut olan "Konuşmayı kapat" dedi. Bu sözlü komutun ardından bir ve ikinin eklenmesi yönündeki komut dikkate alınmadı. Son olarak kullanıcı komut dinlemeyi tekrar açtı ve uygulamanın konuşma tanımayı tamamen devre dışı bırakıp kendini sonlandırmaya yönelik bir komut olarak tanıdığı anlamsız "Klatu barada nikto" komutunu söyledi.

    Açık pirinç. 2 sahte konuşma özellikli bir Windows Forms uygulamasını gösterir. Bu uygulama sözlü komutları tanır ancak bunlara ses çıkışıyla yanıt vermez. Uygulamayı ilk başlattığınızda Konuşma Tanıma'nın etkin olmadığını gösteren Konuşma Açık onay kutusu işaretlenmemişti. Kullanıcı bu onay kutusunu işaretledi ve ardından "Merhaba" dedi. Uygulama, tanınan metni pencerenin altındaki ListBox denetiminde görüntüleyerek yanıt verdi.

    Kullanıcı daha sonra "Metin kutusu 1'i kırmızıya ayarla" dedi. Uygulama konuşmayı tanıdı ve yanıt verdi: "Metin kutusu 1'i kırmızıya ayarla", bu neredeyse (ama tam olarak değil) kullanıcının söylediği şeydi. açık olmasına rağmen pirinç. 2 Göremezsiniz, pencerenin üst kısmındaki TextBox kontrolünde bulunan metin gerçekten kırmızıdır.

    Daha sonra kullanıcı şöyle dedi: "Lütfen metin kutusu 1'i beyaza ayarlayın." Uygulama bunu "metin kutusu 1'i beyaza ayarla" olarak tanıdı ve tam da bunu yaptı. Kullanıcı "Güle güle" diyerek bitirdi ve uygulama bu metni görüntüledi ancak Windows Forms ile hiçbir şey yapmadı; ancak örneğin Konuşma Açık onay kutusunun işareti kaldırılabilirdi.

    Sentezleyici nesnesini kullanmak oldukça basittir.

    Aşağıdaki bölümlerde, gerekli .NET konuşma kitaplıklarının kurulumu da dahil olmak üzere, her iki demo programını oluşturma sürecinde size yol göstereceğim. Bu makale, en azından orta düzeyde programlama becerilerine sahip olduğunuzu ancak konuşma tanıma ve sentezleme hakkında hiçbir şey bilmediğinizi varsaymaktadır.

    Konsol uygulamasına konuşma tanıma desteği ekleme

    Gösterilen demoyu oluşturmak için pirinç. 1, Visual Studio'yu başlattım ve ConsoleSpeech adında yeni bir C# konsol uygulaması oluşturdum. Konuşma araçlarını Visual Studio 2010 ve 2012'de başarılı bir şekilde kullandım, ancak nispeten yeni sürümlerin herhangi biri sorun yaratmayacaktır. Şablon kodunu düzenleyiciye yükledikten sonra Solution Explorer penceresindeki Program.cs dosyasını daha açıklayıcı ConsoleSpeechProgram.cs olarak yeniden adlandırdım ve Visual Studio benim için Program sınıfını yeniden adlandırdı.

    Daha sonra, C:\ProgramFiles (x86)\Microsoft SDKs\Speech\v11.0\Assembly konumunda bulunan Microsoft.Speech.dll dosyasına bir bağlantı ekledim. Bu DLL bilgisayarımda eksikti ve indirmem gerekiyordu. Bir uygulamaya konuşma tanıma ve sentez eklemek için gereken dosyaları yüklemek o kadar da önemsiz değildir. Kurulum işlemini bir sonraki bölümde detaylı olarak anlatacağım ancak şimdilik sisteminizde Microsoft.Speech.dll dosyasının bulunduğunu varsayalım.

    Konuşma DLL'sine bir referans ekleyerek, üst düzey Sistem ad alanına işaret eden dışındaki tüm kullanma ifadelerini kodun üst kısmından kaldırdım. Daha sonra Microsoft.Speech.Recognition, Microsoft.Speech.Synthesis ve System.Globalization ad alanları için kullanma ifadelerini ekledim. İlk iki ad alanı konuşma DLL'sine eşlenir. System.Speech.Recognition ve System.Speech.Synthesis gibi kafa karıştırıcı olabilecek ad alanlarının da bulunduğunu unutmayın. Aralarındaki farkı kısaca anlatacağım. Globalization ad alanı varsayılan olarak mevcuttu ve projeye yeni bir referans eklenmesini gerektirmiyordu.

    Demo konsol uygulamasına ilişkin tüm kaynak kodları şu adreste sağlanmaktadır: pirinç. 3 ve bu makaleye eşlik eden kaynak paketinde de mevcuttur. Ana fikirlerin mümkün olduğunca bulanıklaşmasını önlemek için tüm standart hata işlemeyi kaldırdım.

    Pirinç. 3. Demo konsol uygulaması kaynak kodu

    Sistemi kullanarak; Microsoft.Speech.Recognition'ı kullanma; Microsoft.Speech.Synthesis kullanarak; System.Globalization'ı kullanarak; namespace ConsoleSpeech ( class ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool bitti = false; static bool konuşmaOn = true; static void Main(string args) ( try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine ("\n(Konuşuyorum: Uyanığım)"); ss.Speak("Uyanığım"); CultureInfo ci = new CultureInfo("en-us"); SpeechRecognized += sre_SpeechRecognized; Choices ch_StartStopCommands = new Choices(); ch_StartStopCommands.Add("speech on"); ch_StartStopCommands.Add("speech off"); ch_StartStopCommands.Add("klatu barada nikto"); GrammarBuilder gb_StartStop = new GrammarBuilder( ); gb_StartStopCommands); Dilbilgisi g_StartStop = new Dilbilgisi(gb_StartStop); Seçimler ch_Numbers(); ch_Numbers.Add("4"); gb_WhatIsXplusY.Append("Nedir"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("artı"); gb_WhatIsXplusY.Append(ch_Numbers); Dilbilgisi g_WhatIsXplusY = new Dilbilgisi(gb_WhatIsXplusY); sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple); while (done == false) ( ; ) Console.WriteLine("\nHit< enter >kabuğu kapatmak için\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Ana statik void sre_SpeechRecognized(nesne gönderen, SpeechRecognizedEventArgs e ) ( string txt = e.Result.Text; float güven = e.Result.Confidence; Console.WriteLine("\nTanınan: " + txt); if (güven< 0.60) return; if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("Konuşma artık AÇIK"); konuşmaOn = true; ) if (txt.IndexOf("konuşma kapalı") >= 0) ( Console.WriteLine("Konuşma artık KAPALI"); konuşmaOn = false ) if (speechOn == false) return; if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender). RecognizeAsyncCancel(); done = true; Console.WriteLine("(Konuşma: Elveda)"); ss.Speak("Elveda"); ) if (txt.IndexOf("Ne") >= 0 && txt.IndexOf("artı") >= 0) ( string words = txt.Split(" "); int sayi1 = int.Parse(kelimeler); int sayi2 = int.Parse(kelimeler); int toplam = sayi1 + sayi2; Console.WriteLine("(Konuşma: " + kelimeler + " artı " + kelimeler + " eşittir " + toplam + ")"); ss.SpeakAsync(words + " plus " +words + " eşittir " + toplam); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Use ifadelerinden sonra demo kodu şu şekilde başlar:

    ad alanı ConsoleSpeech ( class ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; statik bool bitti = false; statik bool konuşmaOn = doğru; statik void Main(string args) ( ...

    SpeechSynthesizer nesnesi, sınıf düzeyinde, bir uygulamanın konuşmayı sentezlemesini sağlar. SpeechRecognitionEngine nesnesi, bir uygulamanın konuşulan kelimeleri veya cümleleri dinlemesine ve tanımasına olanak tanır. Boolean değişkeni, uygulamanın tamamının ne zaman sonlandırılacağını belirler. SpeakingOn boolean değişkeni, uygulamanın programdan çıkma komutu dışında herhangi bir komutu dinleyip dinlemediğini kontrol eder.

    Buradaki fikir, konsol uygulamasının klavye girişini kabul etmemesi, dolayısıyla her zaman komutları dinlemesidir. Ancak, eğer konuşmaOn yanlışsa, yalnızca programdan çıkma komutu tanınır ve yürütülür; diğer komutlar tanınır ancak göz ardı edilir.

    Main yöntemi şu şekilde başlar:

    try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine("\n(Konuşma: Uyanığım)"); ss.Speak("Uyanığım");

    SpeechSynthesizer nesnesinin bir örneği, bildirildiğinde oluşturuldu. Sentezleyici nesnesini kullanmak oldukça basittir. SetOutputToDefaultAudioDevice yöntemi, çıktıyı bilgisayarınıza bağlı hoparlörlere gönderir (çıktıyı bir dosyaya da gönderebilirsiniz). Speak yöntemi bir dize alır ve ardından onu söyler. İşte bu kadar kolay.

    Konuşma tanıma, konuşma sentezinden çok daha karmaşıktır. Main yöntemi bir çözümleyici nesnesi oluşturarak devam eder:

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

    İlk olarak CultureInfo nesnesi tanınacak dili (bu durumda Amerika Birleşik Devletleri İngilizcesi) belirtir. CultureInfo nesnesi, bir use ifadesiyle başvurduğumuz Globalization ad alanındadır. Ardından, SpeechRecognitionEngine yapıcısını çağırdıktan sonra, ses girişi varsayılan ses cihazına (çoğunlukla mikrofona) atanır. Çoğu dizüstü bilgisayarın yerleşik bir mikrofona sahip olduğunu, ancak masaüstü bilgisayarların harici bir mikrofona ihtiyaç duyacağını unutmayın (bugünlerde genellikle kulaklıklarla birlikte kullanılıyor).

    Tanıyıcı nesnenin anahtar yöntemi SpeechRecognized olay işleyicisidir. Visual Studio'yu kullanırken "sre.SpeechRecognized +=" yazıp bir saniye beklerseniz IntelliSense, ifadenizi otomatik olarak olay işleyici adı olan sre_SpeechRecognized ile sonlandıracaktır. Öneriyi kabul etmek ve bu adı varsayılan olarak kullanmak için Sekme tuşuna basmanızı öneririm.

    Seçimler ch_Numbers = yeni Seçimler(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers.Add("3"); ch_Numbers.Add("4"); // teknik açıdan bakıldığında, // bu Add(new string ( "4" )); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Nedir"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("artı"); gb_WhatIsXplusY.Append(ch_Numbers); Dilbilgisi g_WhatIsXplusY = new Dilbilgisi(gb_WhatIsXplusY);

    Buradaki üç ana nesne, Seçimler kümesi, GrammarBuilder şablonu ve Grammar denetimidir. Tanıma için bir Dilbilgisi oluşturduğumda, tanımam gereken şeylerin bazı spesifik örneklerini listeleyerek başlıyorum. "Bir artı iki kaç eder?" diyelim. ve “Üç artı dört kaç eder?”

    Daha sonra karşılık gelen genel şablonu tanımlarım, örneğin "Nedir? artı ?. Şablon bir GrammarBuilder'dır ve şablona iletilen belirli değerler bir Seçimler kümesidir. Dilbilgisi nesnesi şablonu ve Seçimleri kapsar.

    Demo programında eklemeleri 1'den 4'e kadar sınırlandırıyorum ve bunları String olarak Choices setine ekliyorum. Daha verimli yaklaşım:

    dize numaraları = yeni dize ("1", "2", "3", "4"); Seçimler ch_Numbers = new Seçimler(sayılar);

    İki nedenden dolayı Seçimler kümesi oluşturmaya yönelik daha az etkili bir yaklaşım sunuyorum. Öncelikle diğer konuşma tanıma örneklerinde gördüğüm tek yaklaşım her seferinde bir satır eklemekti. İkinci olarak, her defasında bir satır eklemenin hiç işe yaramayacağını düşünebilirsiniz; Visual Studio IntelliSense, Ekle aşırı yüklemelerinden birinin tür parametreleri dize ifadelerinden oluşan bir parametreyi kabul ettiğini gerçek zamanlı olarak gösterir. Params anahtar sözcüğünü fark etmediyseniz, Add yönteminin tek bir dizeyi değil yalnızca dize dizilerini kabul ettiğini varsaymış olabilirsiniz. Ama durum böyle değil; ikisini de kabul ediyor. Bir dizi geçirmenizi öneririm.

    Sıralı sayılardan bir dizi Seçim oluşturmak biraz özel bir durumdur ve aşağıdaki gibi programlı bir yaklaşıma izin verir:

    dize numaraları = yeni dize; for (int i = 0; i< 100; ++i) numbers[i] = i.ToString(); Choices ch_Numbers = new Choices(numbers);

    GrammarBuilder yuvalarını doldurmak için Seçimler oluşturduktan sonra demo programı bir GrammarBuilder ve ardından kontrol eden bir Grammar oluşturur:

    GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Nedir"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("artı"); gb_WhatIsXplusY.Append(ch_Numbers); Dilbilgisi g_WhatIsXplusY = new Dilbilgisi(gb_WhatIsXplusY);

    Demo programı, başlatma ve durdurma komutlarına yönelik Dilbilgisini oluşturmak için benzer bir şablon kullanır:

    Seçimler ch_StartStopCommands = new Seçimler(); ch_StartStopCommands.Add("konuşma açık"); ch_StartStopCommands.Add("konuşma kapalı"); ch_StartStopCommands.Add("her şey yolunda"); GrammarBuilder gb_StartStop = yeni GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Dilbilgisi g_StartStop = yeni Dilbilgisi(gb_StartStop);

    Dilbilgisi çok esnek bir şekilde tanımlanabilir. Burada "konuşma açık", "konuşma kapalı" ve "klatu barada nikto" komutları mantıksal olarak ilişkili oldukları için tek bir dilbilgisine yerleştirilmiştir. Bu üç komut üç farklı gramerde tanımlanabilir ya da "speech on" ve "speech off" komutları bir gramerde, "klatu barada nikto" komutu da bir saniyede yerleştirilebilir.

    Tüm Gramer nesnelerini oluşturduktan sonra bunları konuşma tanıyıcıya yerleştirirsiniz ve konuşma tanıma etkinleştirilir:

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

    RecognizeMode.Multiple argümanı, birden fazla dilbilgisine sahip olduğunuzda gereklidir; bu, en basit programların dışındaki tüm programlarda geçerli olacaktır. Main yöntemi şu şekilde tamamlanır:

    While (done == false) ( ; ) Console.WriteLine("\nHit< enter >kabuğu kapatmak için\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main

    Tuhaf görünümlü boş while döngüsü, bir konsol uygulamasının kabuğunu çalışır durumda tutmanıza olanak tanır. Döngü, sınıf düzeyindeki boolean değişkeni, konuşma tanıma olay işleyicisi tarafından true olarak ayarlandığında tamamlanacaktır.

    Tanınan konuşma işleme

    Konuşma tanıma olaylarını işlemeye yönelik kod şu şekilde başlar:

    static void sre_SpeechRecognized(nesne gönderen, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float güven = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (güven< 0.60) return; ...

    Tanınan metin, SpeechRecognizedEventArgs nesnesinin Result.Text özelliğinde depolanır. Alternatif olarak Result.Words setini kullanabilirsiniz. Result.Confidence özelliği, konuşulan metnin tanıyıcıyla ilişkili herhangi bir gramerle ne kadar iyi eşleştiğine dair kaba bir tahmin olan 0,0 ile 1,0 arasında bir değer saklar. Demo programı, olay işleyicisine tanınan metne olan güveni düşük olan metni yok sayması talimatını verir.

    Güven değerleri dilbilginizin karmaşıklığına, mikrofon kalitesine ve diğer faktörlere bağlı olarak büyük ölçüde değişir. Örneğin demo programının yalnızca 1'den 4'e kadar olan sayıları tanıması gerekiyorsa bilgisayarımdaki güven değerleri genellikle 0,75 civarındadır. Ancak gramerin 1'den 100'e kadar sayıları tanıması gerekiyorsa güven değerleri yaklaşık 0,25'e düşer. Özetle, iyi konuşma tanıma sonuçları elde etmek için genellikle güven değerleriyle denemeler yapmalısınız.

    if (txt.IndexOf("konuşma açık") >= 0) ( Console.WriteLine("Konuşma artık AÇIK"); konuşmaOn = true; ) if (txt.IndexOf("konuşma kapalı") >= 0) ( Konsol .WriteLine("Konuşma artık KAPALI"); konuşmaOn = false; if (speechOn == false) return;

    Her ne kadar ilk başta tamamen açık olmasa da, eğer düşünürseniz bu mantık mantıklı gelmelidir. Daha sonra gizli çıkış komutu işlenir:

    if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) ( ((SpeechRecognitionEngine)sender).RecognizeAsyncCancel(); done = true; Console.WriteLine("(Konuşma: Elveda)"); ss.Speak("Elveda"); )

    Konuşma tanıma motorunun aslında anlamsız kelimeleri tanıyabildiğini unutmayın. Bir Dilbilgisi nesnesi, nesnenin yerleşik sözlüğünde bulunmayan sözcükler içeriyorsa, Dilbilgisi mümkünse semantik buluşsal yöntemi kullanarak bu sözcükleri tanımlamaya çalışır ve genellikle oldukça başarılı olur. Bu yüzden (eski bir bilim kurgu filminden) doğru "klaatu" yerine "klatu" kullandım.

    Ayrıca, Dilbilgisi tarafından tanınan metnin tamamını ("klatu barada nikto") işlemeniz gerekmediğini unutmayın; yalnızca dilbilgisel ifadeyi ("klatu" ve "barada") benzersiz bir şekilde tanımlamak için yeterli bilgiye sahip olmanız gerekir.

    If (txt.IndexOf("Ne") >= 0 && txt.IndexOf("plus") >= 0) ( string words = txt.Split(" "); int num1 = int.Parse(words); int num2 = int.Parse(kelimeler); int toplam = sayı1 + sayı2; Console.WriteLine("(Konuşma: " + kelimeler + " artı " + kelimeler + " eşittir " + toplam + ")"); " eşittir " + toplam); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Results.Text'teki metnin büyük/küçük harfe duyarlı olduğunu unutmayın ("Ne" ve "ne"). Bir cümleyi tanıdıktan sonra belirli kelimelere ayrıştırılabilir. Bu durumda, tanınan metin "x artı y nedir" biçimindedir, dolayısıyla "Ne" sözcüklere yerleştirilir ve eklenen iki sayı (dizeler olarak) sözcüklerde ve sözcüklerde saklanır.

    Kitaplıkları yükleme

    Demo programının açıklamasında gerekli tüm konuşma kitaplıklarının bilgisayarınızda kurulu olduğu varsayılmaktadır. Demo programları oluşturmak ve çalıştırmak için dört paket yüklemeniz gerekir: SDK (Visual Studio'da demo oluşturma yeteneği sağlar), çalışma zamanı (demoları oluşturulduktan sonra çalıştırır) ve tanınan ve sentezlenen (telaffuz edilen) diller.

    SDK'yı yüklemek için İnternette "Konuşma Platformu 11 SDK'sı" ifadesini arayın. Bu sizi Microsoft İndirme Merkezi'ndeki doğru sayfaya götürecektir ( pirinç. 4). İndir düğmesini tıklattığınızda, gösterilen seçenekleri göreceksiniz. pirinç. 5. SDK'nın 32 ve 64 bit sürümleri mevcuttur. Sisteminizin bit boyutundan bağımsız olarak 32 bit sürümünü kullanmanızı şiddetle tavsiye ederim. 64 bit sürümü bazı uygulamalarla çalışmaz.


    Pirinç. 4. Microsoft İndirme Merkezi'ndeki ana SDK kurulum sayfası


    Pirinç. 5. Konuşma SDK'sını yükleyin

    X86 altında (32 bit sistemler için) tek bir .msi dosyasından başka bir şeye ihtiyacınız yoktur. Bu dosyayı seçip İleri'ye tıklayarak yükleyiciyi doğrudan buradan çalıştırabilirsiniz. Konuşma kitaplıkları kurulumun ne zaman tamamlandığı konusunda çok fazla geri bildirimde bulunmaz, bu nedenle herhangi bir başarı mesajı aramayın.


    Pirinç. 6. Çalışma zamanı ortamının kurulumu

    SDK ile aynı platform sürümünü (demoda 11) ve bit derinliğini (32 veya 64) seçmek son derece önemlidir. Bir kez daha, 64 bit bir sistemde çalışıyor olsanız bile 32 bit sürümünü şiddetle tavsiye ediyorum.

    Daha sonra tanıma dilini ayarlayabilirsiniz. İndirme sayfası şu adreste verilmiştir: pirinç. 7. Demo programı MSSpeech_SR_en-us_TELE.msi (İngilizce-ABD) dosyasını kullanır. SR, konuşma tanıma anlamına gelir ve TELE, telefon anlamına gelir; bu, tanınan dilin, telefon veya masaüstü mikrofonu gibi düşük kaliteli ses girişleriyle çalışacak şekilde tasarlandığı anlamına gelir.


    Pirinç. 7. Tanınan bir dilin ayarlanması

    Son olarak konuşma sentezi için dili ve sesi ayarlayabilirsiniz. İndirme sayfası şu adreste verilmiştir: pirinç. 8. Demo programı MSSpeech_TTS_en-us_Helen.msi dosyasını kullanır. TTS (metinden konuşmaya) aslında konuşma senteziyle eşanlamlıdır. Mevcut iki sese dikkat edin: İngilizce, ABD. Başka İngilizce sesler de var ama ABD'de yok. Sentez dili dosyaları oluşturmak çok zor bir iştir. Ancak diğer sesleri çeşitli şirketlerden satın alıp kurabilirsiniz.


    Pirinç. 8. Sesi ve sentez dilini ayarlama

    İlginç bir şekilde, konuşma tanıma dili ve ses/konuşma sentezi dili aslında tamamen farklı şeyler olmasına rağmen, her iki paket de aynı indirme sayfasındaki seçeneklerdir. İndirme Merkezi kullanıcı arayüzü, hem tanıma dilini hem de sentez dilini kontrol etmenize olanak tanır, ancak bunları aynı anda yüklemeye çalışmak benim için felaketti, bu yüzden bunları ayrı ayrı yüklemenizi öneririm.

    Microsoft.Speech'i System.Speech ile Karşılaştırma

    Windows uygulamaları için konuşma tanıma ve sentezleme konusunda yeniyseniz, birden fazla konuşma platformu olduğundan belgeler kolayca kafanızı karıştırabilir. Özellikle bu makaledeki demo programların kullandığı Microsoft.Speech.dll kütüphanesine ek olarak Windows işletim sisteminin bir parçası olan System.Speech.dll adlı bir kütüphane bulunmaktadır. İki kitaplık, API'lerinin tamamen olmasa da neredeyse aynı olması açısından benzerdir. Bu nedenle, internette konuşma işleme örnekleri ararsanız ve tam programlar yerine kod parçacıkları görürseniz, örneğin System.Speech mi yoksa Microsoft.Speech mi olduğu hiç de açık değildir.

    Konuşma işleme konusunda yeniyseniz, .NET uygulamanıza konuşma desteği eklemek için System.Speech yerine Microsoft.Speech kitaplığını kullanın.

    Her iki kitaplık da ortak bir çekirdek kod tabanını ve benzer API'leri paylaşsa da kesinlikle farklıdırlar. Bazı temel farklılıklar aşağıda özetlenmiştir. masa 1.

    Masa 1. Microsoft.Speech ve System.Speech arasındaki temel farklar

    System.Speech DLL işletim sisteminin bir parçasıdır, dolayısıyla her Windows sistemine yüklenir. Microsoft.Speech DLL'si (ve ilgili çalışma zamanı ve dilleri) sisteme indirilmeli ve kurulmalıdır. System.Speech kullanarak tanıma genellikle belirli bir kullanıcı için eğitim gerektirir; kullanıcı bir metni okuduğunda sistem bu kullanıcının telaffuz özelliğini anlamayı öğrenir. Microsoft.Speech'i kullanarak tanıma, herhangi bir kullanıcı için hemen çalışır. System.Speech hemen hemen her kelimeyi tanıyabilir (buna serbest dikte denir). Microsoft.Speech yalnızca programda tanımlanan Dilbilgisi nesnesindeki sözcükleri ve tümcecikleri tanıyacaktır.

    Windows Forms uygulamasına konuşma tanıma desteği ekleme

    Windows Forms veya WPF uygulamasına konuşma tanıma ve sentez desteği ekleme süreci, konsol uygulamasına benzer. Gösterilen demo programını oluşturmak için pirinç. 2, Visual Studio'yu başlattım, yeni bir C# Windows Forms uygulaması oluşturdum ve onu WinFormSpeech olarak yeniden adlandırdım.

    Şablon kodunu editöre yükledikten sonra, tıpkı konsol programında yaptığım gibi Solution Explorer penceresinde Microsoft.Speech.dll dosyasına bir bağlantı ekledim. Kaynak kodunun üst kısmında, gereksiz kullanım ifadelerini kaldırdım ve yalnızca Sistem, Veri, Çizim ve Form ad alanlarına referansları bıraktım. Daha sonra Microsoft.Speech.Recognition ve System.Globalization ad alanları için iki adet use ifadesi ekledim.

    Windows Forms tabanlı demo konuşma sentezini kullanmadığından Microsoft.Speech.Synthesis kitaplığına bağlantı vermiyorum. Windows Forms uygulamasına konuşma sentezi eklemek, konsol uygulamasındakiyle aynıdır.

    Visual Studio'da tasarım modunda, bir TextBox, CheckBox ve ListBox kontrollerini Form'a sürükledim. CheckBox'a çift tıklandığında Visual Studio otomatik olarak CheckChanged olay işleyici yönteminin iskeletini oluşturdu.

    Demo konsol programının hemen sözlü komutları dinlemeye başladığını ve sonlandırılıncaya kadar bunu yapmaya devam ettiğini hatırlayın. Bu yaklaşım bir Windows Forms uygulamasında kullanılabilir, ancak bunun yerine kullanıcının bir CheckBox denetimi (yani bir onay kutusu) kullanarak konuşma tanımayı açıp kapatmasına izin vermeye karar verdim.

    Demo programının kısmi sınıfın tanımlandığı Form1.cs dosyasındaki kaynak kodu şu adreste gösterilmektedir: pirinç. 9. Bir konuşma tanıma motoru nesnesi Form üyesi olarak bildirilir ve oluşturulur. Formun yapıcısında SpeechRecognized olay işleyicisini bağladım ve ardından iki Grammars nesnesi oluşturup yükledim:

    public Form1() (InitializeComponent(); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized; Gramer g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammar g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodby) e); sre.LoadGrammarAsync(g_SetTextBox ); // sre.RecognizeAsync(), // CheckBox olay işleyicisindedir)

    Pirinç. 9. Windows Forms'a konuşma tanıma desteği ekleyin

    Sistemi kullanarak; System.Data'yı kullanarak; System.Drawing'i kullanarak; System.Windows.Forms'u kullanarak; Microsoft.Speech.Recognition'ı kullanma; System.Globalization'ı kullanarak; ad alanı WinFormSpeech ( public kısmi sınıf Form1: Form ( static CultureInfo ci = new CultureInfo("en-us"); static SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci); public Form1() (InitializeComponent(); sre.SetInputToDefaultAudioDevice(); sre .SpeechRecognized += sre_SpeechRecognized; Grammar g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammar g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloGoodbye); sre.LoadGrammarAsync(g_SetTextBox); // sre.RecognizeAsync() находится // в обработчике события CheckBox ) static Dil Bilgisi GetHelloGoodbyeGrammar() ( Seçimler ch_HelloGoodbye = yeni Seçimler(); ch_HelloGoodbye.Add("merhaba"); ch_HelloGoodbye.Add("güle güle"); GrammarBuilder gb_result = new GrammarBuilder(ch_HelloGoodbye); Gramer g_result = new Gramer(gb_result); return g_result; ) static Gramer GetTextBox1TextGrammar() ( Seçimler ch_Colors = new Choices(); ch_Colors.Add(new string ( "kırmızı", "beyaz", "mavi" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("metin kutusu 1'i ayarla"); gb_result.Append(ch_Colors); Dilbilgisi g_result = new Dilbilgisi(gb_result); g_result'u döndür; ) özel void checkBox1_CheckedChanged(nesne göndereni, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // devre dışı sre.RecognizeAsyncCancel(); ) void sre_SpeechRecognized(nesne gönderen, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; this.Invoke(new MethodInvoker(() =>( listBox1.Items.Add("Söylediğinizi duydum: " + txt); )); // WinForm özellikleri if (txt.IndexOf("text") >= 0 && txt.IndexOf("box") >= 0 && txt.IndexOf("1")>= 0) ( string words = txt.Split( " "); this.Invoke(new MethodInvoker(() => ( textBox1.Text = kelimeler; ))); // WinForm özellikleri ) ) // Form ) // ns

    Bir konsol programında olduğu gibi doğrudan iki Grammar nesnesi oluşturabilirdim, ancak bunun yerine kodu biraz daha net hale getirmek için işi yapan iki yardımcı yöntem (GetHelloGoodbyeGrammar ve GetTextBox1TextGrammar) tanımladım.

    static Grammar GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(new string ("kırmızı", "beyaz", "mavi" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("metni ayarla) kutu 1"); gb_result.Append(ch_Colors); Dilbilgisi g_result = new Dilbilgisi(gb_result); return g_result; )

    Bu yardımcı yöntem "metin kutusu 1'i kırmızıya ayarla" ifadesini tanıyacaktır. Ancak kullanıcının bu ifadeyi tam olarak telaffuz etmesi zorunlu değildir. Örneğin, "Lütfen metin kutusu 1'deki metni kırmızıya ayarlayın" diyebilir ve konuşma tanıma motoru yine de bu ifadeyi "metin kutusu 1'i kırmızıya ayarla" olarak tanıyacaktır; ancak bu, Dilbilgisi ile tam eşleşmeden daha düşük bir güven değerine sahiptir. şablon. Başka bir deyişle Dilbilgisi nesneleri oluştururken bir ifadenin tüm çeşitlemelerini hesaba katmanız gerekmez. Bu, konuşma tanımanın kullanımını radikal biçimde basitleştirir.

    CheckBox'ın olay işleyicisi şu şekilde tanımlanır:

    özel void checkBox1_CheckedChanged(nesne göndereni, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // devre dışı sre.RecognizeAsyncCancel(); )

    Konuşma tanıma motoru nesnesi, sre (konuşma tanıma motoru), Windows Forms uygulamasının ömrü boyunca her zaman mevcuttur. Bu nesne, kullanıcı sırasıyla CheckBox'ta geçiş yaptığında RecognizeAsync ve RecognizeAsyncCancel yöntemlerine yapılan çağrılarla etkinleştirilir ve devre dışı bırakılır.

    SpeechRecognized olay işleyicisi tanımı şununla başlar:

    void sre_SpeechRecognized(nesne gönderen, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; ...

    Az çok sürekli olarak kullanılan Result.Text ve Result.Confidence özelliklerinin yanı sıra, Result nesnesinin keşfetmek isteyebileceğiniz başka yararlı ancak daha karmaşık özellikleri de vardır; örneğin, Homofonlar ve Değiştirilen Kelime Birimleri. Buna ek olarak, konuşma tanıma motoru SpeechHypothessed gibi çeşitli yararlı etkinlikler sağlar.

    this.Invoke((Action)(() => listBox1.Items.Add("Şunu söylediğinizi duydum: " + txt)));

    Teorik olarak, MethodInvoker temsilcisinin kullanılması bu durumda bir Eylemden biraz daha verimlidir çünkü MethodInvoker Windows.Forms ad alanının bir parçasıdır ve bu nedenle Windows Forms uygulamalarına özeldir. Eylem temsilcisi daha çok yönlüdür. Bu örnek, bir Windows Forms uygulamasını konuşma tanıma motoru aracılığıyla tamamen değiştirebileceğinizi gösterir; bu, inanılmaz derecede güçlü ve kullanışlı bir özelliktir.

    Çözüm

    .NET uygulamalarında konuşma sentezini ve tanımayı keşfetmek istiyorsanız, bu makalede sunulan bilgiler hemen başlamanıza yardımcı olacaktır. İlk öğrenme eğrisi ve bileşen kurulumundaki zorlukları aştığınızda, teknolojinin kendisinde ustalaşmak çocuk oyuncağıdır. Konuşma sentezi ve tanımadaki asıl zorluk, bunun gerçekten ne zaman yararlı olduğunu anlamaktır.

    Konsol programlarıyla, kullanıcının soru sorduğu ve programın yanıt verdiği ilginç ileri geri konuşmalar oluşturabilirsiniz; sonuçta Cortana benzeri bir ortam elde edilir. Biraz dikkatli olmalısınız çünkü konuşma bilgisayarınızın hoparlörlerinden geldiğinde mikrofon tarafından algılanacak ve yeniden tanınabilecektir. Kendimi bir soru sorduğumda, uygulamanın bunu tanıyıp yanıt verdiği, ancak sözlü yanıtın bir sonraki tanıma olayını tetiklediği ve sonunda komik, sonsuz bir konuşma döngüsüyle karşılaştığım bazı oldukça komik durumlarda buldum.

    Bir konsol programında konuşmanın başka bir olası kullanımı da "Not Defterini Başlat" ve "Word'ü Başlat" gibi komutları tanımaktır. Başka bir deyişle, böyle bir konsol programı, bilgisayarınızda, aksi takdirde klavye ve farenin çok fazla manipülasyonunu gerektirecek eylemleri gerçekleştirmek için kullanılabilir.

    James McCaffrey(Dr.James McCaffrey) Redmond, Washington'da Microsoft Research için çalışıyor. Internet Explorer ve Bing de dahil olmak üzere birçok Microsoft ürününün oluşturulmasında yer aldı. Kendisiyle iletişim kurulabilir [e-posta korumalı].

    Bu makaleyi inceledikleri için Microsoft Araştırma uzmanları Rob Gruen, Mark Marron ve Curtis von Veh'e teşekkür ederiz.