Taligenkänning med .NET-skrivbordsapplikationer. Ultrasnabb taligenkänning utan servrar med ett riktigt exempel offline taligenkänning i Android 6.0

) med hjälp av ett riktigt Hello World-exempel på hushållsapparater.
Varför hushållsapparater? Ja, för tack vare ett sådant exempel kan du uppskatta det hastighet och noggrannhet som kan uppnås genom att använda helt lokalt taligenkänning utan servrar som Google ASR eller Yandex SpeechKit.
Jag bifogar också till artikeln all källkod för programmet och själva monteringen för Android.

Varför plötsligt?

Efter att nyligen ha stött på detta frågade jag författaren varför han ville använda serverbaserad taligenkänning för sitt program (enligt min mening var detta onödigt och ledde till vissa problem). För det ändamålet skulle jag kunna beskriva mer detaljerat användningen av alternativa metoder för projekt där det inte finns något behov av att känna igen någonting, och ordboken består av en ändlig uppsättning ord. Och även med ett exempel på praktisk tillämpning...

Varför behöver vi något annat än Yandex och Google?

För just den "praktiska tillämpningen" valde jag ämnet röststyrning för smarta hem.
Varför just detta exempel? Eftersom det visar flera fördelar med helt lokal taligenkänning framför igenkänning med hjälp av molnlösningar. Nämligen:
  • Fart– vi är inte beroende av servrar och är därför inte beroende av deras tillgänglighet, bandbredd osv. faktorer
  • Noggrannhet- vår motor fungerar bara med den ordbok som intresserar vår applikation, vilket ökar kvaliteten på igenkänningen
  • Pris- vi behöver inte betala för varje begäran till servern
  • Röstaktivering- som en extra bonus till de första poängen - vi kan ständigt "lyssna på sändningen" utan att slösa med vår trafik och utan att ladda servrarna

Notera

Låt mig omedelbart göra en reservation för att dessa fördelar kan betraktas som fördelar endast för en viss klass av projekt, Var är vi vi vet säkert i förväg, vilken ordbok och vilken grammatik användaren kommer att arbeta med. Det vill säga när vi inte behöver känna igen godtycklig text (till exempel ett SMS-meddelande eller en sökfråga). Annars är molnigenkänning oumbärlig.

Så Android kan känna igen tal utan internet!
Ja, ja... Bara på JellyBean. Och bara från en halv meter, inte mer. Och detta erkännande är samma diktat, bara med en mycket mindre modell. Så vi kan inte hantera eller konfigurera det heller. Och vad hon kommer tillbaka till oss nästa gång är okänt. Fast helt rätt för SMS!

Vad gör vi?

Vi kommer att implementera en röstfjärrkontroll för hushållsapparater, som kommer att fungera exakt och snabbt, från några meter och till och med på billiga, taskiga, mycket billiga Android-smarttelefoner, surfplattor och klockor.
Logiken kommer att vara enkel men väldigt praktisk. Vi aktiverar mikrofonen och säger ett eller flera enhetsnamn. Applikationen känner igen dem och slår på och av dem beroende på det aktuella tillståndet. Eller så får han en förmögenhet av dem och uttalar det med en trevlig kvinnlig röst. Till exempel den aktuella temperaturen i rummet.

Praktiska tillämpningar finns i överflöd

På morgonen, utan att öppna ögonen, slog du handflatan mot smartphoneskärmen på nattduksbordet och befallde "God morgon!" - manuset startar, kaffebryggaren sätts på och surrar, trevlig musik spelas, gardinerna öppnas.
Låt oss hänga en billig (2 tusen, inte mer) smartphone på väggen i varje rum. Vi går hem efter jobbet och befaller in i tomrummet ”Smart Home! Ljus, TV! – Jag tror inte att det finns något behov av att säga vad som händer härnäst.

Transkriptioner



Grammatik beskriver vad vad användaren kan säga. För Pocketsphinx att veta, Hur han kommer att uttala det, det är nödvändigt för varje ord från grammatiken att skriva hur det låter i motsvarande språkmodell. Det är transkription varje ord. Det kallas lexikon.

Transkriptioner beskrivs med en speciell syntax. Till exempel:
smart uu m n ay j hus d oo m

I princip inget komplicerat. En dubbel vokal i transkription indikerar stress. En dubbelkonsonant är en mjuk konsonant följt av en vokal. Alla möjliga kombinationer för alla ljud av det ryska språket.

Det är tydligt att vi inte i förväg kan beskriva alla transkriptioner i vår applikation, eftersom vi inte i förväg vet vilka namn användaren kommer att ge sina enheter. Därför kommer vi att generera sådana transkriptioner "i farten" enligt vissa regler för rysk fonetik. För att göra detta kan du implementera följande PhonMapper-klass, som kan ta emot en sträng som indata och generera rätt transkription för den.

Röstaktivering

Detta är förmågan hos taligenkänningsmotorn att "lyssna på sändningen" hela tiden för att reagera på en förutbestämd fras (eller fraser). Samtidigt kommer alla andra ljud och tal att förkastas. Detta är inte samma sak som att beskriva grammatik och bara slå på mikrofonen. Jag kommer inte att presentera teorin för denna uppgift och mekaniken för hur den fungerar. Låt mig bara säga att nyligen implementerade programmerarna som arbetar med Pocketsphinx en sådan funktion, och nu är den tillgänglig direkt i API:et.

En sak är definitivt värd att nämna. För en aktiveringsfras behöver du inte bara ange transkriptionen, utan också välja den lämpliga känslighetströskelvärde. Ett värde som är för litet kommer att leda till många falska positiva resultat (det är när du inte sa aktiveringsfrasen, men systemet känner igen den). Och för hög - till immunitet. Därför är denna inställning av särskild betydelse. Ungefärligt värdeintervall - från 1e-1 till 1e-40 beroende på aktiveringsfrasen.

Aktivering av närhetssensor

Denna uppgift är specifik för vårt projekt och är inte direkt relaterad till erkännande. Koden kan ses direkt i huvudaktiviteten.
Hon genomför SensorEventListener och vid närmandeögonblicket (sensorvärdet är mindre än maxvärdet) slår den på timern och kontrollerar efter en viss fördröjning om sensorn fortfarande är blockerad. Detta görs för att eliminera falska positiva resultat.
När sensorn inte blockeras igen stoppar vi igenkänningen och får resultatet (se beskrivning nedan).

Låt oss börja känna igen

Pocketsphinx tillhandahåller ett bekvämt API för att konfigurera och köra igenkänningsprocessen. Det här är klasserna SpechRecognizer Och Speech Recognizer Setup.
Så här ser konfigurationen och lanseringen av igenkänning ut:

PhonMapper phonMapper = new PhonMapper(getAssets().open("dict/ru/hotwords")); Grammatik grammatik = ny grammatik(namn, phonMapper); grammar.addWords(kommandoord); DataFiles dataFiles = new DataFiles(getPackageName(), "ru"); File hmmDir = new File(dataFiles.getHmm()); File dict = new File(dataFiles.getDict()); File jsgf = new File(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, hotword); mRecognizer.addGrammarSearch(COMMAND_SEARCH, jsgf);

Här kopierar vi först alla nödvändiga filer till disk (Pocketpshinx kräver en akustisk modell, grammatik och ordbok med transkriptioner för att finnas på disk). Sedan konfigureras själva igenkänningsmotorn. Sökvägarna till modell- och ordboksfilerna anges, liksom några parametrar (känslighetströskel för aktiveringsfrasen). Därefter konfigureras sökvägen till filen med grammatiken, såväl som aktiveringsfrasen.

Som du kan se av den här koden är en motor konfigurerad för både grammatik och igenkänning av aktiveringsfraser. Varför görs detta? Så att vi snabbt kan växla mellan det vi just nu behöver känna igen. Så här ser det ut att starta processen för identifiering av aktiveringsfraser:

MRecognizer.startListening(KWS_SEARCH);
Och så här känner man igen tal enligt en given grammatik:

MRecognizer.startListening(COMMAND_SEARCH, 3000);
Det andra argumentet (valfritt) är antalet millisekunder efter vilket igenkänningen automatiskt avslutas om ingen säger något.
Som du kan se kan du bara använda en motor för att lösa båda problemen.

Hur man får ett erkännanderesultat

För att få igenkänningsresultatet måste du också ange en händelseavlyssnare som implementerar gränssnittet RecognitionListener.
Den har flera metoder som anropas av pocketsfinx när en av händelserna inträffar:
  • onBeginningOfSpeech- motorn hörde något ljud, kanske var det tal (eller kanske inte)
  • onEndOfSpeech- ljudet slutar
  • onPartialResult- Det finns mellanliggande erkännanderesultat. För en aktiveringsfras betyder det att den fungerade. Argument Hypotes
  • onResult- det slutliga resultatet av erkännandet. Denna metod kommer att anropas efter att metoden har anropats slutaTaligenkännare. Argument Hypotes innehåller igenkänningsdata (sträng och poäng)

Genom att implementera onPartialResult- och onResult-metoderna på ett eller annat sätt kan du ändra igenkänningslogiken och få det slutliga resultatet. Så här går det till när det gäller vår ansökan:

@Override public void onEndOfSpeech() ( Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) ( mRecognizer.stop(); ) ) @Åsidosätt offentlig void onPartialResult(Hypothesis) ( if (hypotes == null) return; String text = hypothesis.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) ( startRecognition(); ) else ( Log.d(TAG, text); ) ) @Override public void onResult(Hypothesis hypothesis) ( mMicView.setBackgroundResource(R.drawable.background_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); Strängtext = hypotes != null ? hypothesis.getHypstr() : Log.d: , "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); ) )

När vi tar emot onEndOfSpeech-händelsen, och om vi samtidigt känner igen kommandot som ska köras, måste vi stoppa igenkänningen, varefter onResult kommer att anropas omedelbart.
OnResult måste kontrollera vad som just identifierades. Om detta är ett kommando måste du starta det för exekvering och växla motorn för att känna igen aktiveringsfrasen.
I onPartialResult är vi bara intresserade av att känna igen aktiveringsfrasen. Om vi ​​upptäcker det startar vi omedelbart kommandoigenkänningsprocessen. Så här ser det ut:

Privat synkroniserad void startRecognition() ( if (mRecognizer == null || COMMAND_SEARCH.equals(mRecognizer.getSearchName())) return; mRecognizer.cancel(); new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOneTone) 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,); "Listend(TAG) kommandon"); post(4000, mStopRecognitionCallback); ) )); )
Här spelar vi först en liten signal för att meddela användaren att vi har hört honom och är redo för hans kommando. Under denna tid bör mikrofonen vara avstängd. Därför börjar vi igenkänningen efter en kort timeout (något längre än signalens varaktighet, för att inte höra dess eko). Det startar också en tråd som med kraft kommer att stoppa igenkänningen om användaren pratar för länge. I det här fallet är det 3 sekunder.

Hur man omvandlar igenkänd sträng till kommandon

Tja, allt här är specifikt för en viss applikation. När det gäller det nakna exemplet drar vi helt enkelt ut enhetsnamnen från raden, söker efter den önskade enheten och ändrar antingen dess tillstånd med hjälp av en HTTP-förfrågan till kontrollenheten för smarta hem, eller rapporterar dess nuvarande tillstånd (som i fallet med en termostat). Denna logik kan ses i klassen Controller.

Hur man syntetiserar tal

Talsyntes är den omvända operationen av igenkänning. Här är det tvärtom - du måste förvandla en textrad till tal så att användaren kan höra den.
När det gäller termostaten måste vi få vår Android-enhet att tala den aktuella temperaturen. Använder API Text till tal detta är ganska lätt att göra (tack vare Google för den underbara kvinnliga TTS för det ryska språket):

Privat void speak(Strängtext) (synkroniserad (mSpeechQueue) (​mRecognizer.stop(); mSpeechQueue.add(text); HashMap params = ny 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(text, TextToSpeech.QUEUE_ADD, params); ) )

Jag ska nog säga något banalt, men före syntesprocessen är det nödvändigt att inaktivera igenkänning. På vissa enheter (till exempel alla Samsung-enheter) är det i allmänhet omöjligt att lyssna på mikrofonen och syntetisera något samtidigt.
Slutet på talsyntesen (det vill säga slutet av processen att läsa upp text med en synthesizer) kan spåras i lyssnaren:

Private final TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() ( @Override public void onUtteranceCompleted(String utteranceId) (synkroniserad (mSpeechQueue) (​mSpeechQueue(​mSpeech()(mSpeechQueue) (mSpeech(Quee)(mSpeechRequeue)(mSpeechRequeue). börja Lyssna( KWS_SÖK) ; ) ) ) );

I den kontrollerar vi helt enkelt om det finns något annat i synteskön, och aktiverar aktiveringsfrasigenkänning om det inte finns något annat.

Och det är allt?

Ja! Som du kan se är det inte svårt att snabbt och effektivt känna igen tal direkt på enheten, tack vare närvaron av sådana underbara projekt som Pocketsphinx. Det ger ett mycket bekvämt API som kan användas för att lösa problem relaterade till att känna igen röstkommandon.

I det här exemplet har vi kopplat erkännande till en helt specifik uppgift - röststyrning av smarta hemenheter. På grund av lokal igenkänning uppnådde vi mycket hög hastighet och minimerade fel.
Det är tydligt att samma kod kan användas för andra röstrelaterade uppgifter. Det behöver inte vara ett smart hem.

  • röst kontroll
  • röstmotor
  • Lägg till taggar

    Inget program kan helt ersätta det manuella arbetet med att transkribera inspelat tal. Det finns dock lösningar som avsevärt kan påskynda och underlätta översättningen av tal till text, det vill säga förenkla transkriptionen.

    Transkription är inspelning av en ljud- eller videofil i textform. Det finns betalda betalda uppgifter på Internet, när artisten får betalt en viss summa pengar för att transkribera texten.

    Tal till text översättning är användbar

    • studenter att översätta inspelade ljud- eller videoföreläsningar till text,
    • bloggare som driver webbplatser och bloggar,
    • författare, journalister för att skriva böcker och texter,
    • informationsaffärsmän som behöver en text efter deras webinar, tal, etc.,
    • personer som har svårt att skriva - de kan diktera ett brev och skicka det till familj eller vänner,
    • andra alternativ.

    Vi kommer att beskriva de mest effektiva verktygen som finns tillgängliga på datorer, mobilapplikationer och onlinetjänster.

    1 Webbplats speechpad.ru

    Detta är en onlinetjänst som låter dig översätta tal till text med webbläsaren Google Chrome. Tjänsten fungerar med mikrofon och färdiga filer. Kvaliteten blir förstås mycket högre om du använder en extern mikrofon och dikterar själv. Tjänsten gör dock ett bra jobb även med YouTube-videor.

    Klicka på "Aktivera inspelning", svara på frågan om "Använda en mikrofon" - för att göra detta, klicka på "Tillåt".

    De långa instruktionerna om att använda tjänsten kan komprimeras genom att klicka på knapp 1 i Fig. 3. Du kan bli av med reklam genom att göra en enkel registrering.

    Ris. 3. Speechpad-tjänst

    Det färdiga resultatet är lätt att redigera. För att göra detta måste du antingen korrigera det markerade ordet manuellt eller diktera det igen. Resultaten av arbetet sparas på ditt personliga konto, de kan även laddas ner till din dator.

    Lista över videolektioner om att arbeta med speechpad:

    Du kan transkribera videor från Youtube eller från din dator, men du behöver en mixer, mer information:

    Video "ljudtranskription"

    Tjänsten fungerar på sju språk. Det finns ett litet minus. Det ligger i det faktum att om du behöver transkribera en färdig ljudfil, hörs dess ljud genom högtalarna, vilket skapar ytterligare störningar i form av ett eko.

    2 Service dictation.io

    En underbar onlinetjänst som låter dig översätta tal till text gratis och enkelt.

    Ris. 4. Service dictation.io

    1 i fig. 4 – Ryska språket kan väljas i slutet av sidan. I webbläsaren Google Chrome är språket valt, men av någon anledning i Mozilla finns inget sådant alternativ.

    Det är anmärkningsvärt att möjligheten att automatiskt spara det färdiga resultatet har implementerats. Detta kommer att förhindra oavsiktlig radering som ett resultat av att en flik eller webbläsare stängs. Den här tjänsten känner inte igen färdiga filer. Fungerar med mikrofon. Du måste namnge skiljetecken när du dikterar.

    Texten känns igen helt korrekt, det finns inga stavfel. Du kan själv infoga skiljetecken från tangentbordet. Det färdiga resultatet kan sparas på din dator.

    3 RealSpeaker

    Detta program låter dig enkelt översätta mänskligt tal till text. Den är designad för att fungera på olika system: Windows, Android, Linux, Mac. Med dess hjälp kan du konvertera tal som hörs till en mikrofon (det kan till exempel byggas in i en bärbar dator), samt spelas in till ljudfiler.

    Kan förstå 13 världsspråk. Det finns en betaversion av programmet som fungerar som en onlinetjänst:

    Du måste följa länken ovan, välja det ryska språket, ladda upp din ljud- eller videofil till onlinetjänsten och betala för transkriptionen. Efter transkription kan du kopiera den resulterande texten. Ju större filen för transkription, desto mer tid tar det att bearbeta den, mer detaljer:

    Under 2017 fanns det ett gratis transkriptionsalternativ med RealSpeaker, men 2018 finns det inget sådant alternativ. Det är mycket förvirrande att den transkriberade filen är tillgänglig för alla användare för nedladdning, kanske kommer detta att förbättras.

    Utvecklarens kontakter (VKontakte, Facebook, Youtube, Twitter, e-post, telefon) av programmet finns på sidan på hans webbplats (mer exakt, i sidfoten på webbplatsen):

    4 Speechlogger

    Ett alternativ till den tidigare applikationen för mobila enheter som körs på Android. Finns gratis i app store:

    Texten redigeras automatiskt och skiljetecken läggs till. Mycket praktiskt för att diktera anteckningar till dig själv eller göra listor. Som ett resultat kommer texten att vara av mycket anständig kvalitet.

    5 Drakdiktering

    Detta är en applikation som distribueras gratis för mobila enheter från Apple.

    Programmet kan fungera med 15 språk. Det låter dig redigera resultatet och välja önskade ord från listan. Du måste uttala alla ljud tydligt, inte göra onödiga pauser och undvika intonation. Ibland finns det fel i ändelserna på ord.

    Applikationen Dragon Dictation används av ägare, till exempel för att diktera en inköpslista i en butik medan de rör sig i lägenheten. När jag kommer dit kan jag titta på texten i lappen och jag behöver inte lyssna.

    Oavsett vilket program du använder i din träning, var beredd att dubbelkolla resultaten och göra vissa justeringar. Detta är det enda sättet att få en felfri text utan fel.

    Också användbara tjänster:

    Få de senaste artiklarna om datorkunskap direkt till din inkorg.
    Redan mer 3 000 prenumeranter

    .

    Produkter och teknologier:

    Visual Studio, C#, .NET Speech Libraries

    Artikeln diskuterar:

    • lägga till stöd för taligenkänning till konsolapplikationen;
    • bearbetning av igenkänt tal;
    • installation av taligenkänningsbibliotek;
    • jämförelse av Microsoft.Speech och System.Speech;
    • Lägga till stöd för taligenkänning i en Windows Forms-applikation.

    Med tillkomsten av Windows Phone Cortana, en talaktiverad personlig assistent (liksom en motsvarighet för fruktföretag som inte kan talas förgäves), har talaktiverade appar blivit allt mer framträdande inom mjukvaruutveckling. I den här artikeln visar jag hur du kommer igång med taligenkänning och syntes i Windows-konsolapplikationer, Windows Forms-applikationer och Windows Presentation Foundation (WPF).

    Observera att du även kan lägga till talfunktioner till Windows Phone-appar, ASP.NET-webbappar, Windows Store-appar, Windows RT och Xbox Kinect, men teknikerna skiljer sig från de som diskuteras i den här artikeln.

    Ett bra sätt att få en uppfattning om exakt vad den här artikeln kommer att diskutera är att titta på skärmdumparna av två olika demoprogram på ris. 1 Och 2 . Efter att ha startat konsolapplikationen på ris. 1 säger omedelbart frasen "Jag är vaken." Naturligtvis kommer du inte att kunna höra demoapplikationen när du läser den här artikeln, så den visar texten till vad datorn säger. Sedan säger användaren kommandot "Tal på". Demoapplikationen svarar med igenkänd text och lyssnar sedan internt och svarar på förfrågningar om att lägga till två nummer.

    Ris. 1. Taligenkänning och syntes i en konsolapplikation


    Ris. 2. Taligenkänning i ett Windows Forms-program

    Användaren bad appen att lägga till en och två, sedan två och tre. Applikationen kände igen de talade kommandona och gav svar med rösten. Jag kommer att beskriva mer användbara sätt att använda taligenkänning senare.

    Användaren sa sedan "Tal av", ett röstkommando som inaktiverar att lyssna på tilläggskommandon, men inte helt inaktiverar taligenkänning. Efter detta verbala kommando ignorerades nästa kommando för att lägga till ett och två. Slutligen slog användaren på kommandot lyssna igen och uttalade det meningslösa kommandot "Klatu barada nikto", som applikationen kände igen som ett kommando för att helt inaktivera taligenkänning och avsluta sig själv.

    ris. 2 visar ett Windows Forms-program med dummy-tal aktiverat. Denna applikation känner igen talade kommandon, men svarar inte på dem med röstutmatning. När du först startade appen var kryssrutan Tal på inte markerad, vilket indikerar att taligenkänning inte var aktiv. Användaren markerade den här kryssrutan och sa sedan "Hej". Applikationen svarade genom att visa den igenkända texten i ListBox-kontrollen längst ner i fönstret.

    Användaren sa sedan, "Sätt textruta 1 till röd." Applikationen kände igen talet och svarade: "Sätt textruta 1 röd", vilket är nästan (men inte riktigt) exakt vad användaren sa. Fast på ris. 2 Du kan inte se det, texten i TextBox-kontrollen längst upp i fönstret är verkligen röd.

    Sedan sa användaren: "Sätt textruta 1 till vit." Appen kände igen detta som "ställ textruta 1 vit" och gjorde just det. Användaren avslutade med att säga "hej då" och programmet visade den texten, men gjorde ingenting med Windows Forms, även om det till exempel kunde ha avmarkerat kryssrutan Tal på.

    Att använda synthesizerobjektet är ganska enkelt.

    I följande avsnitt kommer jag att leda dig genom processen att skapa båda demoprogrammen, inklusive installation av nödvändiga .NET-talbibliotek. Den här artikeln förutsätter att du har åtminstone medelstora programmeringskunskaper, men att du inte vet något om taligenkänning och syntes.

    Lägga till stöd för taligenkänning i en konsolapplikation

    För att skapa demon som visas i ris. 1, Jag lanserade Visual Studio och skapade en ny C#-konsolapplikation som heter ConsoleSpeech. Jag har använt talverktyg framgångsrikt med Visual Studio 2010 och 2012, men alla relativt nya versioner borde vara bra. Efter att ha laddat in mallkoden i editorn döpte jag om Program.cs-filen i Solution Explorer-fönstret till det mer beskrivande ConsoleSpeechProgram.cs, och Visual Studio döpte om Program-klassen åt mig.

    Därefter lade jag till en länk till filen Microsoft.Speech.dll, som finns i C:\ProgramFiles (x86)\Microsoft SDKs\Speech\v11.0\Assembly. Denna DLL saknades på min dator och jag var tvungen att ladda ner den. Att installera de filer som behövs för att lägga till taligenkänning och syntes till en applikation är inte så trivialt. Jag kommer att förklara installationsprocessen i detalj i nästa avsnitt, men låt oss nu anta att Microsoft.Speech.dll finns på ditt system.

    Genom att lägga till en referens till tal-DLL:n tog jag bort alla användningssatser från toppen av koden förutom den som pekade på systemnamnrymden på toppnivå. Sedan lade jag till med hjälp av uttalanden för namnområdena Microsoft.Speech.Recognition, Microsoft.Speech.Synthesis och System.Globalization. De två första namnområdena mappas till tal-DLL:n. Observera att det även finns namnutrymmen som System.Speech.Recognition och System.Speech.Synthesis, vilket kan vara förvirrande. Jag ska snart förklara skillnaden mellan dem. Globaliseringsnamnrymden var tillgänglig som standard och krävde ingen ny referens för att läggas till projektet.

    All källkod för demokonsolapplikationen tillhandahålls på ris. 3, och finns även i källkodspaketet som medföljer den här artikeln. Jag har tagit bort all standardfelhantering för att undvika att skymma huvudidéerna så mycket som möjligt.

    Ris. 3. Demokonsolapplikationens källkod

    använder System; använder Microsoft.Speech.Recognition; använder Microsoft.Speech.Synthesis; använder System.Globalization; namnrymden ConsoleSpeech ( klass ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( try ( sdioTovicDefaultA(W) ("\n(Talar: Jag är vaken)"); ss.Speak("Jag är vaken"); CultureInfo ci = new CultureInfo("en-us"); sre = new SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice( ; sre.Speechrecognized += sre_Speechrecognized; choices ch_startstopcommands = Nya val (); ch_startstopcommands.add ("Tal på"); ch_startstopcommands.add ("S Peech Off "); ch_startStopcommands.add (" Klatuarda Baratbu Nikilder "); = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammar g_StartStop = new Grammar(gb_StartStop); Choices ch_Numbers = new Choices(); ch_Numbers.Add("1"); ch_Numbers.Add_("Numbers.ch); Add("3"); ch_Numbers.Add("4"); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Vad är"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammatik g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY); sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple); while (done == false) ( ; ) Console.WriteLine("\nHit< enter >för att stänga skal\n"); Console.ReadLine(); ) catch (Undantag ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Huvudstatiskt tomrum sre_SpeechRecognized(objektavsändare, SpeechRecognizedEventArgs e ) ( string txt = e.Result.Text; float confidence = e.Result.Confidence; Console.WriteLine("\nKänt: " + txt); if (confidence< 0.60) return; if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("Tal är nu PÅ"); speechOn = true; ) if (txt.IndexOf("tal av") >= 0) ( Console.WriteLine("Tal är nu AV"); speechOn = false; ) if (talPå == false) return; if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) (((SpeechRecognitionEngine)sender). RecognizeAsyncCancel(); done = true; Console.WriteLine("(På tal: Farväl)"); ss.Speak("Farväl"); ) if (txt.IndexOf("What") >= 0 && txt.IndexOf("plus") >= 0) ( strängord = txt.Split(" "); int num1 = int.Parse(ord); int num2 = int.Parse(ord); int summa = num1 + num2; Console.WriteLine("(Pratar: " + ord + " plus " + ord + " är lika med " + summa + ")"); ss.SpeakAsync(ord + " plus " + ord + " lika med " + summa); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Efter användningssatserna börjar demokoden så här:

    namespace ConsoleSpeech ( klass ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( ...

    SpeechSynthesizer-objektet, på klassnivå, gör det möjligt för en applikation att syntetisera tal. SpeechRecognitionEngine-objektet tillåter ett program att lyssna på och känna igen talade ord eller fraser. Den booleska variabeln done bestämmer när hela applikationen avslutas. Den booleska variabeln speechOn styr om programmet lyssnar på andra kommandon än kommandot för att avsluta programmet.

    Tanken här är att konsolapplikationen inte accepterar tangentbordsinmatning, så den lyssnar alltid efter kommandon. Men om speechOn är falskt är det bara kommandot för att avsluta programmet som känns igen och exekveras; andra kommandon känns igen men ignoreras.

    Huvudmetoden börjar så här:

    try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine("\n(Talar: Jag är vaken)"); ss.Speak("Jag är vaken");

    En instans av SpeechSynthesizer-objektet skapades när det deklarerades. Att använda synthesizerobjektet är ganska enkelt. Metoden SetOutputToDefaultAudioDevice skickar utdata till högtalare som är anslutna till din dator (du kan också skicka utdata till en fil). Speak-metoden tar en sträng och talar sedan upp den. Så enkelt är det.

    Taligenkänning är mycket mer komplex än talsyntes. Huvudmetoden fortsätter genom att skapa ett resolverobjekt:

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

    För det första anger CultureInfo-objektet vilket språk som ska kännas igen, i det här fallet amerikansk engelska. CultureInfo-objektet finns i Globalization-namnområdet, som vi refererade till med en användningssats. Sedan, efter att ha anropat SpeechRecognitionEngine-konstruktören, tilldelas röstinmatningen till standardljudenheten - oftast mikrofonen. Observera att de flesta bärbara datorer har en inbyggd mikrofon, men stationära datorer kräver en extern mikrofon (ofta kombinerat med hörlurar nuförtiden).

    Nyckelmetoden för igenkänningsobjektet är händelsehanteraren SpeechRecognized. När du använder Visual Studio, om du skriver "sre.SpeechRecognized +=" och väntar en bråkdel av en sekund, kommer IntelliSense automatiskt att avsluta ditt uttryck med händelsehanterarens namn - sre_SpeechRecognized. Jag föreslår att du trycker på Tab-tangenten för att acceptera förslaget och använder det här namnet som standard.

    Choices ch_Numbers = new Choices(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers.Add("3"); ch_Numbers.Add("4"); // ur teknisk synvinkel, // detta är Add(ny sträng ("4")); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Vad är"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammatik g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY);

    De tre huvudobjekten här är valuppsättningen, mallen GrammarBuilder och grammatikkontrollen. När jag skapar en grammatik för igenkänning börjar jag med att lista några specifika exempel på vad jag behöver känna igen. Låt oss säga, "Vad är ett plus två?" och "Vad är tre plus fyra?"

    Sedan definierar jag motsvarande generiska mall, till exempel "Vad är plus ?. Mallen är en GrammarBuilder, och de specifika värdena som skickas till mallen är en uppsättning val. Grammatikobjektet kapslar in mallen och val.

    I demoprogrammet begränsar jag tilläggen till 1 till 4 och lägger till dem som strängar i valuppsättningen. Effektivare tillvägagångssätt:

    strängnummer = ny sträng ("1", "2", "3", "4" ); Val ch_Numbers = nya val(tal);

    Jag presenterar ett mindre effektivt sätt att skapa en valuppsättning av två anledningar. För det första var att lägga till en rad i taget det enda sättet jag sett i andra taligenkänningsexempel. För det andra kanske du tror att det inte borde fungera att lägga till en rad i taget; Visual Studio IntelliSense visar i realtid att en av Add-överbelastningarna accepterar en parameter av typen params-strängfraser. Om du inte märkte nyckelordet params kan du ha antagit att Add-metoden bara accepterar arrayer av strängar och inte en enda sträng. Men så är det inte: han accepterar båda. Jag rekommenderar att du passerar en array.

    Att skapa en uppsättning val från sekventiella nummer är något av ett specialfall och möjliggör ett programmatiskt tillvägagångssätt som:

    strängnummer = ny sträng; för (int i = 0; i< 100; ++i) numbers[i] = i.ToString(); Choices ch_Numbers = new Choices(numbers);

    Efter att ha skapat val för att fylla GrammarBuilder-platserna skapar demoprogrammet en GrammarBuilder och sedan en styrande Grammar:

    GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Vad är"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("plus"); gb_WhatIsXplusY.Append(ch_Numbers); Grammatik g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY);

    Demoprogrammet använder en liknande mall för att skapa grammatiken för start- och stoppkommandon:

    Choices ch_StartStopCommands = new Choices(); ch_StartStopCommands.Add("tal på"); ch_StartStopCommands.Add("tal av"); ch_StartStopCommands.Add("klatu barada nikto"); GrammarBuilder gb_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammatik g_StartStop = new Grammar(gb_StartStop);

    Grammatik kan definieras mycket flexibelt. Här placeras kommandona "tal på", "tal av" och "klatu barada nikto" i en grammatik, eftersom de är logiskt relaterade. Dessa tre kommandon kan definieras i tre olika grammatiker, eller kommandona "tal på" och "tal av" kan placeras i en grammatik och kommandot "klatu barada nikto" i en andra.

    När du har skapat alla grammatikobjekt lägger du in dem i taligenkännaren och taligenkänning aktiveras:

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

    Argumentet RecognizeMode.Multiple behövs när du har mer än en grammatik, vilket kommer att vara fallet i alla utom de enklaste programmen. Huvudmetoden slutförs enligt följande:

    While (done == false) ( ; ) Console.WriteLine("\nHit< enter >för att stänga skal\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main

    En tom while-loop som ser konstigt ut låter dig hålla skalet på en konsolapplikation igång. Slingan kommer att slutföras när den booleska klassnivåvariabeln done ställs in på sann av taligenkänningshändelsehanteraren.

    Igenkänd talbearbetning

    Koden för hantering av taligenkänningshändelser börjar så här:

    statiskt tomrum sre_SpeechRecognized(objektavsändare, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float confidence = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (confidence)< 0.60) return; ...

    Den igenkända texten lagras i egenskapen Result.Text för SpeechRecognizedEventArgs-objektet. Alternativt kan du använda uppsättningen Result.Words. Egenskapen Result.Confidence lagrar ett värde mellan 0,0 och 1,0 som är en grov uppskattning av hur väl den talade texten matchar någon av grammatikerna som är kopplade till igenkännaren. Demoprogrammet instruerar händelsehanteraren att ignorera text med låg tilltro till den igenkända texten.

    Konfidensvärden varierar mycket beroende på komplexiteten i din grammatik, mikrofonkvalitet och andra faktorer. Till exempel, om demoprogrammet bara behöver känna igen siffrorna 1 till 4, är konfidensvärdena på min dator vanligtvis runt 0,75. Men om grammatiken måste känna igen siffror från 1 till 100, sjunker konfidensvärdena till cirka 0,25. I ett nötskal bör du generellt experimentera med konfidensvärden för att uppnå bra taligenkänningsresultat.

    if (txt.IndexOf("tal på") >= 0) ( Console.WriteLine("Tal är nu PÅ"); speechOn = sant; ) if (txt.IndexOf("tal av") >= 0) ( Console .WriteLine("Tal är nu AV"); speechOn = false; ) if (speechOn == false) return;

    Även om det kanske inte är helt uppenbart till en början, borde denna logik vara vettig om du tänker efter. Det hemliga utgångskommandot bearbetas sedan:

    if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) (((SpeechRecognitionEngine)sender).RecognizeAsyncCancel(); done = true; Console.WriteLine("(På tal: Farväl)"); ss.Speak("Farväl"); )

    Observera att taligenkänningsmotorn faktiskt kan känna igen nonsensord. Om ett Grammar-objekt innehåller ord som inte finns i objektets inbyggda ordbok, försöker Grammar identifiera dessa ord med hjälp av semantisk heuristik om möjligt, och är vanligtvis ganska framgångsrikt. Det var därför jag använde "klatu" istället för den korrekta "klaatu" (från en gammal sci-fi-film).

    Observera också att du inte behöver bearbeta all text som känns igen av grammatik ("klatu barada nikto") - du behöver bara ha tillräckligt med information för att unikt identifiera den grammatiska frasen ("klatu" och "barada").

    If (txt.IndexOf("Vad") >= 0 && txt.IndexOf("plus") >= 0) ( strängord = txt.Split(" "); int num1 = int.Parse(ord); int num2 = int.Parse(ord); int summa = num1 + num2; Console.WriteLine("(Pratar: " + ord + " plus " + ord + " är lika med " + summa + ")"); ss.SpeakAsync(ord + " plus " + ord + " är lika med " + summa); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Observera att texten i Results.Text är skiftlägeskänslig ("Vad" och "vad"). Efter att ha känt igen en fras kan den tolkas till specifika ord. I det här fallet är den igenkända texten av formen "Vad är x plus y", så "Vad" placeras i ord, och de två tillagda siffrorna (som strängar) lagras i ord och ord.

    Installerar bibliotek

    Förklaringen av demoprogrammet förutsätter att alla nödvändiga talbibliotek är installerade på din dator. För att skapa och köra demoprogram måste du installera fyra paket: SDK (ger möjlighet att skapa demos i Visual Studio), runtime (kör demos efter att de har skapats) och de igenkända och syntetiserade (uttalade) språken.

    För att installera SDK, sök på Internet efter "Speech Platform 11 SDK." Detta tar dig till rätt sida i Microsoft Download Center ( ris. 4). Genom att klicka på knappen Ladda ner ser du alternativen som visas i ris. 5. SDK kommer i 32- och 64-bitarsversioner. Jag rekommenderar starkt att du använder 32-bitarsversionen oavsett bitstorleken på ditt system. 64-bitarsversionen fungerar inte med vissa applikationer.


    Ris. 4. Huvudsidan för SDK-installation i Microsoft Download Center


    Ris. 5. Installera Speech SDK

    Du behöver inte mer än en enda .msi-fil under x86 (för 32-bitars system). Genom att välja den här filen och klicka på Nästa kan du köra installationsprogrammet direkt härifrån. Talbibliotek ger inte mycket feedback om när installationen är klar, så leta inte efter några framgångsmeddelanden.


    Ris. 6. Installation av runtime-miljön

    Det är extremt viktigt att välja samma plattformsversion (11 i demon) och bitdjup (32 eller 64) som SDK. Återigen, jag rekommenderar starkt 32-bitarsversionen, även om du kör på ett 64-bitarssystem.

    Du kan sedan ställa in igenkänningsspråket. Nedladdningssidan finns på ris. 7. Demoprogrammet använder filen MSSpeech_SR_en-us_TELE.msi (Engelska-U.S.). SR står för taligenkänning, och TELE står för telefoni; det betyder att det igenkända språket är utformat för att fungera med ljudinmatning av låg kvalitet, till exempel från en telefon eller skrivbordsmikrofon.


    Ris. 7. Ställa in ett känt språk

    Slutligen kan du ställa in språk och röst för talsyntes. Nedladdningssidan finns på ris. 8. Demoprogrammet använder filen MSSpeech_TTS_en-us_Helen.msi. TTS (text-till-tal) är i huvudsak synonymt med talsyntes. Observera de två tillgängliga rösterna engelska, U.S. Det finns andra engelska röster, men inte U.S. Att skapa syntetiska språkfiler är en mycket svår uppgift. Du kan dock köpa och installera andra röster från en mängd olika företag.


    Ris. 8. Ställa in röst- och syntesspråk

    Intressant nog, även om taligenkänningsspråk och röst-/talsyntesspråk faktiskt är helt olika saker, är båda paketen alternativ på samma nedladdningssida. Download Center UI låter dig kontrollera både igenkänningsspråket och syntesspråket, men att försöka installera dem samtidigt var katastrofalt för mig, så jag rekommenderar att du installerar dem separat.

    Jämför Microsoft.Speech med System.Speech

    Om du är ny på taligenkänning och syntes för Windows-applikationer kan du lätt bli förvirrad av dokumentationen eftersom det finns flera talplattformar. Mer specifikt, förutom Microsoft.Speech.dll-biblioteket som används av demoprogrammen i den här artikeln, finns det ett bibliotek som heter System.Speech.dll som är en del av Windows-operativsystemet. De två biblioteken är lika i den meningen att deras API:er är nästan, men inte helt, identiska. Om du därför letar efter talbearbetningsexempel på Internet och ser kodsnuttar snarare än kompletta program är det inte alls självklart om exemplet är System.Speech eller Microsoft.Speech.

    Om du är ny på talbearbetning, använd Microsoft.Speech-biblioteket snarare än System.Speech för att lägga till talstöd till din .NET-applikation.

    Även om båda biblioteken delar en gemensam kärnkodbas och liknande API:er, är de definitivt olika. Några viktiga skillnader sammanfattas i tabell 1.

    Tabell 1. Huvudsakliga skillnader mellan Microsoft.Speech och System.Speech

    System.Speech DLL är en del av operativsystemet, så det är installerat på alla Windows-system. Microsoft.Speech DLL (och dess tillhörande körtid och språk) måste laddas ner och installeras på systemet. Igenkänning med System.Speech kräver vanligtvis utbildning för en specifik användare, när användaren läser en del text, och systemet lär sig att förstå uttalsegenskapen för denna användare. Igenkänning med Microsoft.Speech fungerar omedelbart för alla användare. System.Speech kan känna igen nästan alla ord (detta kallas fri diktering). Microsoft.Speech känner bara igen ord och fraser som finns i det grammatikobjekt som definieras i programmet.

    Lägga till stöd för taligenkänning i en Windows Forms-applikation

    Processen för att lägga till taligenkänning och syntesstöd till en Windows Forms- eller WPF-applikation liknar den för en konsolapplikation. För att skapa demoprogrammet som visas i ris. 2, jag startade Visual Studio, skapade en ny C# Windows Forms-applikation och döpte om den till WinFormSpeech.

    Efter att ha laddat in mallkoden i editorn lade jag till en länk till filen Microsoft.Speech.dll i Solution Explorer-fönstret - precis som jag gjorde i konsolprogrammet. Överst i källkoden tog jag bort onödiga användningssatser, och lämnade endast referenser till namnrymden System, Data, Drawing och Forms. Sedan lade jag till två med satser för namnområdena Microsoft.Speech.Recognition och System.Globalization.

    Den Windows Forms-baserade demon använder inte talsyntes, så jag länkar inte till Microsoft.Speech.Synthesis-biblioteket. Att lägga till talsyntes i en Windows Forms-applikation är samma som i en konsolapplikation.

    I Visual Studio i designläge drog jag en TextBox, CheckBox och ListBox-kontroller till formuläret. Dubbelklickade på CheckBox och Visual Studio skapade automatiskt en skelett CheckChanged-händelsehanteraremetod.

    Kom ihåg att demokonsolprogrammet omedelbart började lyssna efter talade kommandon och fortsatte att göra det tills det avslutades. Det här tillvägagångssättet skulle kunna användas i en Windows Forms-applikation, men istället bestämde jag mig för att tillåta användaren att aktivera och inaktivera taligenkänning med hjälp av en CheckBox-kontroll (dvs. en kryssruta).

    Källkoden i demoprogrammets Form1.cs-fil, där partialklassen är definierad, visas på ris. 9. Ett taligenkänningsmotorobjekt deklareras och skapas som en formulärmedlem. I formulärets konstruktor kopplar jag upp händelsehanteraren SpeechRecognized och skapar och laddar sedan två Grammars-objekt:

    public Form1() ( InitializeComponent(); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized; Grammatik g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammatik g_SetTextBox =GetTexmmts.A; HelloGoodby e);sre.LoadGrammarAsync(g_SetTextBox) ; // sre.RecognizeAsync() är // i CheckBox-händelsehanteraren)

    Ris. 9. Lägg till stöd för taligenkänning i Windows Forms

    använder System; använder System.Data; använder System.Drawing; använder System.Windows.Forms; använder Microsoft.Speech.Recognition; använder System.Globalization; namnutrymme WinFormSpeech ( offentlig delklass Form1: Form ( static CultureInfo ci = new CultureInfo("en-us"); static SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci); public Form1() ( InitializeComponent(); sre.SetInputToDefault(); sre.SetInputToDefault(); .SpeechRecognized += sre_SpeechRecognized; Grammatik g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammar g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloA.LoadGrasgSrec/sync(g_HelloA.LoadGrasgSrec/sync); Identifiera Async() är // i CheckBox-händelsehanteraren ) static Grammar GetHelloGoodbyeGrammar() ( Choices ch_HelloGoodbye = new Choices(); ch_HelloGoodbye.Add("hello"); ch_HelloGoodbye.Add("goodbye"); GrammarBuilder gb_result = new GrammarBuilder(ch_HelloGoodgres) GrammarBuilder(ch_HelloGoodgres) ; return g_result; ) static Grammar GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(ny sträng ( "röd", "vit", "blå" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("set text box 1"); gb_result.Append(ch_Colors); Grammatik g_result = new Grammar(gb_result); returnera g_result; ) privat void checkBox1_CheckedChanged(objektavsändare, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); annars if (checkBox1.Checked == false) // disabled sre.RecognizeA(); void sre_SpeechRecognized(objektavsändare, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; this.Invoke(new MethodInvoker(() =>( listBox1.Items.Add("Jag hörde dig säga: " + txt); ))); // WinForm specificerar if (txt.IndexOf("text") >= 0 && txt.IndexOf("box") >= 0 && txt.IndexOf("1")>= 0) ( strängord = txt.Split( " "); this.Invoke(new MethodInvoker(() => ( textBox1.Text = ord; ))); // WinForm specifics ) ) ) // Form ) // ns

    Jag kunde ha skapat två Grammar-objekt direkt, som i ett konsolprogram, men istället, för att göra koden lite tydligare, definierade jag två hjälpmetoder (GetHelloGoodbyeGrammar och GetTextBox1TextGrammar) som gör jobbet.

    statisk grammatik GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(ny sträng ( "röd", "vit", "blå" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("set text ruta 1"); gb_result.Append(ch_Colors); Grammatik g_result = new Grammar(gb_result); return g_result; )

    Denna hjälpmetod kommer att känna igen frasen "ställ textruta 1 röd". Användaren behöver dock inte uttala denna fras exakt. Till exempel kunde han säga "Sätt texten i textruta 1 till röd" och taligenkänningsmotorn skulle fortfarande känna igen frasen som "ställ textruta 1 röd" - om än med ett lägre konfidensvärde än en exakt matchning med grammatiken mall. Med andra ord, när du skapar grammatikobjekt behöver du inte ta hänsyn till alla varianter av en fras. Detta förenklar radikalt användningen av taligenkänning.

    Händelsehanteraren för CheckBox definieras så här:

    privat void checkBox1_CheckedChanged(objektavsändare, EventArgs e) (if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); annars if (checkBox1.Checked == false) // disabled sre.CRecognizeAsync);

    Objektet för taligenkänningsmotorn, sre (taligenkänningsmotor), finns alltid under hela livet av en Windows Forms-applikation. Detta objekt aktiveras och inaktiveras av anrop till metoderna RecognizeAsync och RecognizeAsyncCancel när användaren växlar kryssrutan respektive.

    Definitionen av händelsehanteraren SpeechRecognized börjar med:

    void sre_SpeechRecognized(objektavsändare, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; ...

    Förutom de mer eller mindre ständigt använda egenskaperna Result.Text och Result.Confidence, har Result-objektet flera andra användbara men mer komplexa egenskaper som du kanske vill utforska; till exempel Homofoner och Ersättningsordenheter. Dessutom ger taligenkänningsmotorn flera användbara händelser som SpeechHypothesized.

    this.Invoke((Action)(() => listBox1.Items.Add("Jag hörde dig säga: " + txt)));

    I teorin är det något effektivare att använda MethodInvoker-delegaten än en Action i den här situationen eftersom MethodInvoker är en del av Windows.Forms-namnområdet och därför specifikt för Windows Forms-applikationer. Actiondelegaten är mer mångsidig. Det här exemplet visar att du helt kan manipulera en Windows Forms-applikation genom taligenkänningsmotorn - det här är en otroligt kraftfull och användbar funktion.

    Slutsats

    Informationen som presenteras i den här artikeln bör få dig igång direkt om du vill utforska talsyntes och igenkänning i .NET-applikationer. Att bemästra själva tekniken är en bris när du väl kommer förbi gupparna med den inledande inlärningskurvan och komponentinstallationen. Den verkliga utmaningen i talsyntes och igenkänning är att förstå när det faktiskt är användbart.

    Med konsolprogram kan du skapa intressanta konversationer fram och tillbaka där användaren ställer en fråga och programmet svarar, vilket i huvudsak resulterar i en Cortana-liknande miljö. Du måste vara försiktig eftersom när tal kommer från din dators högtalare kommer det att fångas upp av mikrofonen och kan kännas igen igen. Jag har hamnat i några ganska roliga situationer där jag ställde en fråga, appen kände igen den och svarade, men det talade svaret utlöste nästa igenkänningshändelse, och jag slutade med en rolig, oändlig talslinga.

    En annan möjlig användning av tal i ett konsolprogram är att känna igen kommandon som "Launch Notepad" och "Launch Word". Med andra ord kan ett sådant konsolprogram användas på din dator för att utföra åtgärder som annars skulle kräva mycket manipulation av tangentbordet och musen.

    James McCaffrey(Dr James McCaffrey) arbetar för Microsoft Research i Redmond, Washington. Han deltog i skapandet av flera Microsoft-produkter, inklusive Internet Explorer och Bing. Han kan kontaktas på [e-postskyddad].

    Tack till Microsoft Research-experterna Rob Gruen, Mark Marron och Curtis von Veh för att ha granskat den här artikeln.