Talegjenkjenning ved hjelp av .NET desktop-applikasjoner. Ultrarask talegjenkjenning uten servere ved å bruke et ekte eksempel frakoblet talegjenkjenning i Android 6.0

) ved å bruke et ekte Hello World-eksempel på styring av husholdningsapparater.
Hvorfor husholdningsapparater? Ja, for takket være et slikt eksempel kan du sette pris på det hastighet og nøyaktighet som kan oppnås ved å bruke helt lokalt talegjenkjenning uten servere som Google ASR eller Yandex SpeechKit.
Jeg legger også ved artikkelen all kildekoden til programmet og selve sammenstillingen for Android.

Hvorfor plutselig?

Etter å ha kommet over dette nylig, spurte jeg forfatteren hvorfor han ønsket å bruke serverbasert talegjenkjenning for programmet sitt (etter min mening var dette unødvendig og førte til noen problemer). For det formål, kunne jeg beskrive mer detaljert bruken av alternative metoder for prosjekter der det ikke er behov for å gjenkjenne noe, og ordboken består av et begrenset sett med ord. Og selv med et eksempel på praktisk anvendelse...

Hvorfor trenger vi noe annet enn Yandex og Google?

For den veldig "praktiske anvendelsen" valgte jeg emnet stemmestyring for smarthus.
Hvorfor akkurat dette eksemplet? Fordi det viser flere fordeler med helt lokal talegjenkjenning fremfor gjenkjenning ved bruk av skyløsninger. Nemlig:
  • Hastighet- vi er ikke avhengige av servere og er derfor ikke avhengige av tilgjengelighet, båndbredde osv. faktorer
  • Nøyaktighet- motoren vår fungerer bare med ordboken som interesserer applikasjonen vår, og øker dermed kvaliteten på gjenkjennelsen
  • Pris- vi trenger ikke betale for hver forespørsel til serveren
  • Stemmeaktivering- som en ekstra bonus til de første poengene - kan vi hele tiden "lytte til sendingen" uten å kaste bort trafikken vår og uten å laste serverne

Merk

La meg ta en reservasjon med en gang om at disse fordelene kan betraktes som fordeler bare for en viss klasse prosjekter, Hvor er vi vi vet sikkert på forhånd, hvilken ordbok og hvilken grammatikk brukeren vil operere med. Det vil si når vi ikke trenger å gjenkjenne vilkårlig tekst (for eksempel en SMS-melding eller et søk). Ellers er skygjenkjenning uunnværlig.

Så Android kan gjenkjenne tale uten Internett!
Ja, ja... Bare på JellyBean. Og bare fra en halv meter, ikke mer. Og denne erkjennelsen er den samme diktatet, bare ved å bruke en mye mindre modell. Så vi kan heller ikke administrere eller konfigurere det. Og hva hun kommer tilbake til oss neste gang er ukjent. Selv om akkurat passe for SMS!

Hva skal vi gjøre?

Vi vil implementere en stemmefjernkontroll for husholdningsapparater, som vil fungere nøyaktig og raskt, fra noen få meter og til og med på billige, kjipe, veldig rimelige Android-smarttelefoner, nettbrett og klokker.
Logikken vil være enkel, men veldig praktisk. Vi aktiverer mikrofonen og sier ett eller flere enhetsnavn. Applikasjonen gjenkjenner dem og slår dem av og på avhengig av gjeldende tilstand. Eller han mottar en formue fra dem og uttaler det med en behagelig kvinnestemme. For eksempel gjeldende temperatur i rommet.

Praktiske bruksområder florerer

Om morgenen, uten å åpne øynene, slo du håndflaten på smarttelefonskjermen på nattbordet og kommanderte "God morgen!" – manuset starter, kaffetrakteren slår seg på og nynner, hyggelig musikk spiller, gardinene åpnes.
La oss henge en billig (2 tusen, ikke mer) smarttelefon på veggen i hvert rom. Vi går hjem etter jobb og kommanderer inn i tomrommet «Smart Home! Lys, TV! – Jeg tror ikke det er nødvendig å si hva som skjer videre.

Transkripsjoner



Grammatikk beskriver hva hva brukeren kan si. For Pocketsphinx å vite, Hvordan han vil uttale det, det er nødvendig for hvert ord fra grammatikken å skrive hvordan det høres ut i den tilsvarende språkmodellen. Det er transkripsjon hvert ord. Det kalles ordbok.

Transkripsjoner er beskrevet ved hjelp av en spesiell syntaks. For eksempel:
smart uu m n ay j hus d oo m

I prinsippet ingenting komplisert. En dobbel vokal i transkripsjon indikerer stress. En dobbel konsonant er en myk konsonant etterfulgt av en vokal. Alle mulige kombinasjoner for alle lyder av det russiske språket.

Det er klart at vi ikke på forhånd kan beskrive alle transkripsjonene i applikasjonen vår, fordi vi ikke på forhånd vet navnene som brukeren vil gi til enhetene sine. Derfor vil vi generere slike transkripsjoner "i farten" i henhold til noen regler for russisk fonetikk. For å gjøre dette kan du implementere følgende PhonMapper-klasse, som kan motta en streng som input og generere riktig transkripsjon for den.

Stemmeaktivering

Dette er evnen til talegjenkjenningsmotoren til å "lytte til sendingen" hele tiden for å reagere på en forhåndsbestemt frase (eller fraser). Samtidig vil alle andre lyder og tale bli forkastet. Dette er ikke det samme som å beskrive grammatikk og bare slå på mikrofonen. Jeg vil ikke her presentere teorien om denne oppgaven og mekanikken for hvordan den fungerer. La meg bare si at programmererne som jobber med Pocketsphinx nylig implementerte en slik funksjon, og nå er den tilgjengelig rett ut av boksen i API.

En ting er absolutt verdt å nevne. For en aktiveringsfrase må du ikke bare spesifisere transkripsjonen, men også velge den riktige sensitivitetsterskelverdi. En verdi som er for liten vil føre til mange falske positiver (dette er når du ikke sa aktiveringsfrasen, men systemet gjenkjenner den). Og for høy - til immunitet. Derfor er denne innstillingen av spesiell betydning. Omtrentlig verdiområde - fra 1e-1 til 1e-40 avhengig av aktiveringsfrasen.

Aktivering av nærhetssensor

Denne oppgaven er spesifikk for prosjektet vårt og er ikke direkte relatert til anerkjennelse. Koden kan sees direkte i hovedaktiviteten.
Hun gjennomfører SensorEventListener og i tilnærmingsøyeblikket (sensorverdien er mindre enn maksimum) slår den på timeren, og sjekker etter en viss forsinkelse om sensoren fortsatt er blokkert. Dette gjøres for å eliminere falske positiver.
Når sensoren ikke er blokkert igjen, stopper vi gjenkjenningen og får resultatet (se beskrivelse nedenfor).

La oss begynne å gjenkjenne

Pocketsphinx gir en praktisk API for å konfigurere og kjøre gjenkjenningsprosessen. Dette er klassene Spech Recognizer Og Speech Recognizer Setup.
Slik ser konfigurasjonen og lanseringen av gjenkjenning ut:

PhonMapper phonMapper = new PhonMapper(getAssets().open("dict/ru/hotwords")); Grammatikk grammatikk = ny grammatikk(navn, phonMapper); grammatikk.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, kommandoord); mRecognizer.addGrammarSearch(COMMAND_SEARCH, jsgf);

Her kopierer vi først alle nødvendige filer til disk (Pocketpshinx krever en akustisk modell, grammatikk og ordbok med transkripsjoner for å være på disk). Deretter er selve gjenkjenningsmotoren konfigurert. Stiene til modell- og ordbokfilene er angitt, samt noen parametere (sensitivitetsterskel for aktiveringsfrasen). Deretter konfigureres banen til filen med grammatikken, samt aktiveringsfrasen.

Som du kan se fra denne koden, er én motor konfigurert for både grammatikk og aktiveringsfrasegjenkjenning. Hvorfor gjøres dette? Slik at vi raskt kan bytte mellom det vi for øyeblikket trenger å gjenkjenne. Slik ser det ut å starte gjenkjenningsprosessen for aktiveringsfrase:

MRecognizer.startListening(KWS_SEARCH);
Og dette er hvordan tale gjenkjennes i henhold til en gitt grammatikk:

MRecognizer.startListening(COMMAND_SEARCH, 3000);
Det andre argumentet (valgfritt) er antall millisekunder hvoretter gjenkjenningen automatisk avsluttes hvis ingen sier noe.
Som du kan se, kan du bare bruke én motor for å løse begge problemene.

Hvordan få anerkjennelsesresultatet

For å få gjenkjenningsresultatet må du også spesifisere en hendelseslytter som implementerer grensesnittet RecognitionListener.
Den har flere metoder som kalles av pocketsfinx når en av hendelsene inntreffer:
  • onBeginningOfSpeech- motoren hørte en lyd, kanskje det var tale (eller kanskje ikke)
  • onEndOfSpeech- Lyden slutter
  • påPartialResult- det er mellomliggende gjenkjenningsresultater. For en aktiveringsfrase betyr dette at den fungerte. Argument Hypotese
  • påResultat- det endelige resultatet av anerkjennelse. Denne metoden vil bli kalt etter at metoden er kalt StoppeSpeech Recognizer. Argument Hypotese inneholder gjenkjenningsdata (streng og poengsum)

Ved å implementere onPartialResult- og onResult-metodene på en eller annen måte, kan du endre gjenkjennelseslogikken og få det endelige resultatet. Slik gjøres det for søknaden vår:

@Override public void onEndOfSpeech() ( Log.d(TAG, "onEndOfSpeech"); if (mRecognizer.getSearchName().equals(COMMAND_SEARCH)) ( mRecognizer.stop(); ) ) @Override public void onPartialResult(Hypothesis) ( if (hypotese == null) returnerer; Strengtekst = hypothesis.getHypstr(); if (KWS_SEARCH.equals(mRecognizer.getSearchName())) ( startRecognition(); ) else ( Log.d(TAG, tekst); ) ) @Override public void onResult(Hypothesis hypothesis) ( mMicView.setBackgroundResource(R.drawable.background_big_mic); mHandler.removeCallbacks(mStopRecognitionCallback); Stringtekst = hypotese != null ? hypothesis.getHypstr() .d: , "onResult " + text); if (COMMAND_SEARCH.equals(mRecognizer.getSearchName())) ( if (tekst != null) ( Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); prosess(tekst ); ) mRecognizer.startListening(KWS_SEARCH); ) )

Når vi mottar onEndOfSpeech-hendelsen, og hvis vi samtidig gjenkjenner kommandoen som skal utføres, må vi stoppe gjenkjenningen, hvoretter onResult vil bli kalt umiddelbart.
I onResult må du sjekke hva som nettopp ble gjenkjent. Hvis dette er en kommando, må du starte den for utførelse og bytte motoren for å gjenkjenne aktiveringsfrasen.
I onPartialResult er vi bare interessert i å gjenkjenne aktiveringsfrasen. Hvis vi oppdager det, starter vi umiddelbart kommandogjenkjenningsprosessen. Slik ser det ut:

Privat synkronisert void startRecognition() ( if (mRecognizer == null || COMMAND_SEARCH.equals(mRecognizer.getSearchName())) returner; mRecognizer.cancel(); new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOneTone).start 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,); "Listen(TAG) kommandoer"); post(4000, mStopRecognitionCallback); ) )); )
Her spiller vi først et lite signal for å varsle brukeren om at vi har hørt ham og er klare for kommandoen hans. I løpet av denne tiden bør mikrofonen være slått av. Derfor starter vi gjenkjenning etter en kort timeout (litt lenger enn varigheten av signalet, for ikke å høre ekkoet). Den starter også en tråd som med kraft vil stoppe gjenkjenningen hvis brukeren snakker for lenge. I dette tilfellet er det 3 sekunder.

Hvordan gjøre gjenkjent streng til kommandoer

Vel, alt her er spesifikt for en bestemt applikasjon. Når det gjelder det nakne eksempelet, trekker vi ganske enkelt ut enhetsnavnene fra linjen, søker etter ønsket enhet og endrer enten tilstanden ved hjelp av en HTTP-forespørsel til smarthjemkontrolleren, eller rapporterer dens nåværende tilstand (som i tilfellet med en termostat). Denne logikken kan sees i Controller-klassen.

Hvordan syntetisere tale

Talesyntese er den omvendte operasjonen av gjenkjenning. Her er det omvendt - du må gjøre en tekstlinje om til tale slik at brukeren kan høre den.
Når det gjelder termostaten, må vi få Android-enheten vår til å si gjeldende temperatur. Ved hjelp av API Tekst til tale dette er ganske enkelt å gjøre (takk til Google for den fantastiske kvinnelige TTS for det russiske språket):

Privat void snakk(strengtekst) (synkronisert (mSpeechQueue) (​mRecognizer.stop(); mSpeechQueue.add(text); HashMap params = nytt 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(tekst, TextToSpeech.QUEUE_ADD, params); ) )

Jeg skal nok si noe banalt, men før synteseprosessen er det nødvendig å deaktivere gjenkjenning. På noen enheter (for eksempel alle Samsung-enheter) er det generelt umulig å lytte til mikrofonen og syntetisere noe samtidig.
Slutten av talesyntese (det vil si slutten av prosessen med å lese tekst med en synthesizer) kan spores i lytteren:

Private final TextToSpeech.OnUtteranceCompletedListener mUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() ( @Override public void onUtteranceCompleted(String utteranceId) (synkronisert (mSpeechQueue) (​mSpeech.OnUtteranceCompletedListener); startListening( KWS_SEARCH) ; ) ) ) );

I den sjekker vi ganske enkelt om det er noe annet i syntesekøen, og aktiverer aktiveringsfrasegjenkjenning hvis det ikke er noe annet.

Og det er alt?

Ja! Som du kan se, er det ikke vanskelig å gjenkjenne tale direkte på enheten raskt og effektivt, takket være tilstedeværelsen av slike fantastiske prosjekter som Pocketsphinx. Det gir en veldig praktisk API som kan brukes til å løse problemer knyttet til å gjenkjenne talekommandoer.

I dette eksemplet har vi knyttet anerkjennelse til en helt spesifikk oppgave - stemmestyring av smarthusenheter. På grunn av lokal gjenkjennelse oppnådde vi svært høy hastighet og minimaliserte feil.
Det er tydelig at den samme koden kan brukes til andre stemmerelaterte oppgaver. Det trenger ikke være et smart hjem.

  • stemmekontroll
  • stemmemotor
  • Legg til merkelapper

    Ingen programmer kan fullstendig erstatte det manuelle arbeidet med å transkribere innspilt tale. Det finnes imidlertid løsninger som betydelig kan fremskynde og lette oversettelsen av tale til tekst, det vil si forenkle transkripsjon.

    Transkripsjon er opptak av en lyd- eller videofil i tekstform. Det er betalte betalte oppgaver på Internett, når utøveren får betalt en viss sum penger for å transkribere teksten.

    Oversettelse av tale til tekst er nyttig

    • studenter å oversette innspilte lyd- eller videoforelesninger til tekst,
    • bloggere som driver nettsteder og blogger,
    • forfattere, journalister for å skrive bøker og tekster,
    • informasjonsforretningsmenn som trenger en tekst etter webinaret, talen, etc.,
    • folk som har problemer med å skrive - de kan diktere et brev og sende det til familie eller venner,
    • andre muligheter.

    Vi vil beskrive de mest effektive verktøyene som er tilgjengelig på PC-er, mobilapplikasjoner og nettjenester.

    1 Nettsted speechpad.ru

    Dette er en nettbasert tjeneste som lar deg oversette tale til tekst ved hjelp av Google Chrome-nettleseren. Tjenesten fungerer med mikrofon og ferdige filer. Kvaliteten blir selvsagt mye høyere hvis du bruker ekstern mikrofon og dikterer deg selv. Tjenesten gjør imidlertid en god jobb selv med YouTube-videoer.

    Klikk på "Aktiver opptak", svar på spørsmålet om "Bruk av en mikrofon" - for å gjøre dette, klikk på "Tillat".

    De lange instruksjonene om bruk av tjenesten kan skjules ved å klikke på knapp 1 i fig. 3. Du kan bli kvitt reklame ved å fullføre en enkel registrering.

    Ris. 3. Speechpad-tjeneste

    Det ferdige resultatet er enkelt å redigere. For å gjøre dette må du enten korrigere det uthevede ordet manuelt eller diktere det på nytt. Resultatene av arbeidet lagres på din personlige konto, de kan også lastes ned til datamaskinen din.

    Liste over videoleksjoner om arbeid med talepute:

    Du kan transkribere videoer fra Youtube eller fra datamaskinen din, men du trenger en mikser, flere detaljer:

    Video "lydtranskripsjon"

    Tjenesten opererer på syv språk. Det er et lite minus. Det ligger i det faktum at hvis du trenger å transkribere en ferdig lydfil, høres lyden gjennom høyttalerne, noe som skaper ytterligere interferens i form av et ekko.

    2 Service dictation.io

    En fantastisk nettjeneste som lar deg oversette tale til tekst gratis og enkelt.

    Ris. 4. Service dictation.io

    1 i fig. 4 – Russisk språk kan velges på slutten av siden. I Google Chrome-nettleseren er språket valgt, men av en eller annen grunn i Mozilla er det ikke noe slikt alternativ.

    Det er bemerkelsesverdig at muligheten til å automatisk lagre det ferdige resultatet er implementert. Dette vil forhindre utilsiktet sletting som følge av lukking av en fane eller nettleser. Denne tjenesten gjenkjenner ikke ferdige filer. Fungerer med mikrofon. Du må navngi skilletegn når du dikterer.

    Teksten gjenkjennes ganske korrekt, det er ingen stavefeil. Du kan selv sette inn skilletegn fra tastaturet. Det ferdige resultatet kan lagres på datamaskinen din.

    3 RealSpeaker

    Dette programmet lar deg enkelt oversette menneskelig tale til tekst. Den er designet for å fungere på forskjellige systemer: Windows, Android, Linux, Mac. Med dens hjelp kan du konvertere tale hørt til en mikrofon (for eksempel kan den bygges inn i en bærbar datamaskin), samt tas opp til lydfiler.

    Kan forstå 13 verdensspråk. Det er en betaversjon av programmet som fungerer som en nettbasert tjeneste:

    Du må følge lenken ovenfor, velge russisk språk, laste opp lyd- eller videofilen din til nettjenesten og betale for transkripsjonen. Etter transkripsjon kan du kopiere den resulterende teksten. Jo større filen for transkripsjon, jo mer tid vil det ta å behandle den, flere detaljer:

    I 2017 var det et gratis transkripsjonsalternativ ved bruk av RealSpeaker, men i 2018 er det ikke noe slikt alternativ. Det er veldig forvirrende at den transkriberte filen er tilgjengelig for alle brukere for nedlasting; kanskje dette vil bli forbedret.

    Kontakter til utvikleren (VKontakte, Facebook, Youtube, Twitter, e-post, telefon) av programmet finner du på siden til nettstedet hans (mer presist, i bunnteksten på nettstedet):

    4 Talelogger

    Et alternativ til den forrige applikasjonen for mobile enheter som kjører på Android. Tilgjengelig gratis i App Store:

    Teksten redigeres automatisk og skilletegn legges til. Veldig praktisk for å diktere notater til deg selv eller lage lister. Som et resultat vil teksten være av veldig grei kvalitet.

    5 Dragediktasjon

    Dette er en applikasjon som distribueres gratis for mobile enheter fra Apple.

    Programmet kan fungere med 15 språk. Den lar deg redigere resultatet og velge de ønskede ordene fra listen. Du må uttale alle lyder tydelig, ikke ta unødvendige pauser og unngå intonasjon. Noen ganger er det feil i avslutningene på ord.

    Dragon Dictation-applikasjonen brukes av eiere, for eksempel til å diktere en handleliste i en butikk mens de beveger seg rundt i leiligheten. Når jeg kommer dit, kan jeg se på teksten i notatet, og jeg trenger ikke å lytte.

    Uansett hvilket program du bruker i praksisen din, vær forberedt på å dobbeltsjekke resultatene og foreta visse justeringer. Dette er den eneste måten å få en feilfri tekst uten feil.

    Også nyttige tjenester:

    Motta de nyeste artiklene om datakunnskap direkte i innboksen din.
    Allerede flere 3000 abonnenter

    .

    Produkter og teknologier:

    Visual Studio, C#, .NET talebiblioteker

    Artikkelen diskuterer:

    • legge til talegjenkjenningsstøtte til konsollapplikasjonen;
    • behandling av anerkjent tale;
    • installasjon av talegjenkjenningsbiblioteker;
    • sammenligning av Microsoft.Speech og System.Speech;
    • Legge til talegjenkjenningsstøtte til en Windows Forms-applikasjon.

    Med bruken av Windows Phone Cortana, en taleaktivert personlig assistent (så vel som en motpart i fruktselskapet som ikke kan snakkes forgjeves), har taleaktiverte apper blitt stadig mer fremtredende i programvareutvikling. I denne artikkelen skal jeg vise deg hvordan du kommer i gang med talegjenkjenning og syntese i Windows-konsollapplikasjoner, Windows Forms-applikasjoner og Windows Presentation Foundation (WPF).

    Merk at du også kan legge til talefunksjoner til Windows Phone-apper, ASP.NET-nettapper, Windows Store-apper, Windows RT og Xbox Kinect, men teknikkene er forskjellige fra de som er omtalt i denne artikkelen.

    En god måte å få en ide om nøyaktig hva denne artikkelen skal diskutere, er å se på skjermbildene av to forskjellige demoprogrammer på ris. 1 Og 2 . Etter å ha startet konsollapplikasjonen på ris. 1 sier umiddelbart uttrykket "Jeg er våken." Selvfølgelig vil du ikke kunne høre demoapplikasjonen mens du leser denne artikkelen, så den viser teksten til det datamaskinen sier. Deretter sier brukeren kommandoen "Tale på". Demoapplikasjonen svarer med gjenkjent tekst og lytter deretter internt og svarer på forespørsler om å legge til to tall.

    Ris. 1. Talegjenkjenning og syntese i en konsollapplikasjon


    Ris. 2. Talegjenkjenning i en Windows Forms-applikasjon

    Brukeren ba appen legge til en og to, deretter to og tre. Applikasjonen gjenkjente de talte kommandoene og ga svar med stemmen. Jeg vil beskrive flere nyttige måter å bruke talegjenkjenning på senere.

    Brukeren sa deretter «Tale av», en talekommando som deaktiverer lytting til tilleggskommandoer, men som ikke deaktiverer talegjenkjenning fullstendig. Etter denne verbale kommandoen ble den neste kommandoen for å legge til en og to ignorert. Til slutt slo brukeren på kommandolytting igjen og uttalte den meningsløse kommandoen "Klatu barada nikto", som applikasjonen gjenkjente som en kommando for å fullstendig deaktivere talegjenkjenning og avslutte seg selv.

    ris. 2 viser et Windows Forms-program med dummy tale-aktivert. Denne applikasjonen gjenkjenner talte kommandoer, men svarer ikke på dem med stemmeutdata. Da du først startet appen, var det ikke merket av for Tale på, noe som indikerer at talegjenkjenning ikke var aktiv. Brukeren merket av i denne avmerkingsboksen og sa deretter "Hei". Applikasjonen svarte ved å vise den gjenkjente teksten i ListBox-kontrollen nederst i vinduet.

    Brukeren sa deretter: "Sett tekstboks 1 til rød." Applikasjonen gjenkjente talen og svarte: «Sett tekstboks 1 til rød», som er nesten (men ikke helt) nøyaktig hva brukeren sa. Selv om på ris. 2 Du kan ikke se det, teksten i TextBox-kontrollen øverst i vinduet er virkelig rød.

    Så sa brukeren: "Vennligst sett tekstboks 1 til hvit." Appen gjenkjente dette som "sett tekstboks 1 hvit" og gjorde nettopp det. Brukeren avsluttet med å si «farvel», og applikasjonen viste den teksten, men gjorde ingenting med Windows Forms, selv om den for eksempel kunne ha fjernet avmerkingsboksen Tale på.

    Å bruke synthesizer-objektet er ganske enkelt.

    I de følgende delene vil jeg lede deg gjennom prosessen med å lage begge demoprogrammene, inkludert installasjon av de nødvendige .NET-talebibliotekene. Denne artikkelen forutsetter at du minst har middels programmeringskunnskaper, men at du ikke vet noe om talegjenkjenning og syntese.

    Legge til talegjenkjenningsstøtte til en konsollapplikasjon

    For å lage demoen vist i ris. 1, lanserte jeg Visual Studio og laget en ny C#-konsollapplikasjon kalt ConsoleSpeech. Jeg har brukt taleverktøy med hell med Visual Studio 2010 og 2012, men alle relativt nyere versjoner burde være bra. Etter å ha lastet inn malkoden i editoren, ga jeg nytt navn til Program.cs-filen i Solution Explorer-vinduet til den mer beskrivende ConsoleSpeechProgram.cs, og Visual Studio ga nytt navn til Program-klassen for meg.

    Deretter la jeg til en kobling til Microsoft.Speech.dll-filen, som ligger i C:\ProgramFiles (x86)\Microsoft SDKs\Speech\v11.0\Assembly. Denne DLL-filen manglet på datamaskinen min, og jeg måtte laste den ned. Å installere filene som trengs for å legge til talegjenkjenning og syntese i en applikasjon er ikke så trivielt. Jeg vil forklare installasjonsprosessen i detalj i neste avsnitt, men la oss foreløpig anta at Microsoft.Speech.dll er på systemet ditt.

    Ved å legge til en referanse til tale-DLL, fjernet jeg alle brukssetningene fra toppen av koden bortsett fra den som pekte til systemnavneområdet på øverste nivå. Deretter la jeg til ved å bruke setninger for navnerommene Microsoft.Speech.Recognition, Microsoft.Speech.Synthesis og System.Globalization. De to første navnerommene er tilordnet til tale-DLL. Merk at det også finnes navneområder som System.Speech.Recognition og System.Speech.Synthesis, som kan være forvirrende. Jeg skal snart forklare forskjellen mellom dem. Globaliseringsnavneområdet var tilgjengelig som standard og krevde ingen ny referanse for å bli lagt til prosjektet.

    All kildekode for demokonsollapplikasjonen er gitt på ris. 3, og er også tilgjengelig i kildepakken som følger med denne artikkelen. Jeg har fjernet all standard feilhåndtering for å unngå å skjule hovedideene så mye som mulig.

    Ris. 3. Kildekode for demokonsollapplikasjon

    bruker System; bruker Microsoft.Speech.Recognition; bruker Microsoft.Speech.Synthesis; bruker System.Globalization; navneområde ConsoleSpeech ( class ConsoleSpeechProgram ( static SpeechSynthesizer ss = new SpeechSynthesizer(); static SpeechRecognitionEngine sre; static bool done = false; static bool speechOn = true; static void Main(string args) ( try ( ssdioTovicDefaultA) ("\n(Snakker: Jeg er våken)"); ss.Speak("Jeg er våken"); CultureInfo ci = new CultureInfo("en-us"); sre = new SpeechRecognitionEngine(ci); sre.SetInputToDefaultAudioDevice( ; sre.Speechrecognized += sre_Speechrecognized; choices ch_startstopcommands = Nye valg (); ch_startstopcommands.add ("Tale på"); ch_startstopcommands.add ("S Peech Off "); ch_startStopcommands.add ("Klatu Baratbu Nikopilder "); = 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_"2".ch Add("3"); ch_Numbers.Add("4"); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("Hva er"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("pluss"); gb_WhatIsXplusY.Append(ch_Numbers); Grammar g_WhatIsXplusY = ny Grammar(gb_WhatIsXplusY); sre.LoadGrammarAsync(g_StartStop); sre.LoadGrammarAsync(g_WhatIsXplusY); sre.RecognizeAsync(RecognizeMode.Multiple); while (ferdig == usann) ( ; ) Console.WriteLine("\nHit< enter >for å lukke skallet\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Statisk hovedtomrom sre_SpeechRecognized(objektavsender, SpeechRecognizedEventArgs e ) ( string txt = e.Result.Text; float confidence = e.Result.Confidence; Console.WriteLine("\nGjenkjent: " + txt); if (confidence)< 0.60) return; if (txt.IndexOf("speech on") >= 0) ( Console.WriteLine("Tale er nå PÅ"); speechOn = true; ) if (txt.IndexOf("tale av") >= 0) ( Console.WriteLine("Tale er nå AV"); speechOn = usann; ) if (talePå == usann) return; if (txt.IndexOf("klatu") >= 0 && txt.IndexOf("barada") >= 0) (((SpeechRecognitionEngine)sender). RecognizeAsyncCancel(); done = true; Console.WriteLine("(Snakker: Farvel)"); ss.Speak("Farvel"); ) if (txt.IndexOf("What") >= 0 && txt.IndexOf("pluss") >= 0) ( strengord = txt.Split(" "); int num1 = int.Parse(ord); int num2 = int.Parse(ord); int sum = num1 + num2; Console.WriteLine("(Snakker: " + ord + " pluss " + ord + " er lik " + sum + ")"); ss.SpeakAsync(ord + " pluss " + ord + " lik " + sum); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Etter brukssetningene starter demokoden slik:

    navneområde ConsoleSpeech ( klasse 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å klassenivå, gjør det mulig for en applikasjon å syntetisere tale. SpeechRecognitionEngine-objektet lar et program lytte til og gjenkjenne talte ord eller setninger. Den boolske variabelen utført bestemmer når hele applikasjonen avsluttes. SpeechOn boolean-variabelen kontrollerer om applikasjonen lytter til andre kommandoer enn kommandoen for å avslutte programmet.

    Tanken her er at konsollapplikasjonen ikke aksepterer tastaturinndata, så den lytter alltid etter kommandoer. Men hvis speechOn er falsk, gjenkjennes og utføres bare kommandoen for å avslutte programmet; andre kommandoer gjenkjennes, men ignoreres.

    Hovedmetoden starter slik:

    try ( ss.SetOutputToDefaultAudioDevice(); Console.WriteLine("\n(Snakker: Jeg er våken)"); ss.Speak("Jeg er våken");

    En forekomst av SpeechSynthesizer-objektet ble opprettet da det ble deklarert. Å bruke synthesizer-objektet er ganske enkelt. SetOutputToDefaultAudioDevice-metoden sender utdata til høyttalere som er koblet til datamaskinen din (du kan også sende utdata til en fil). Speak-metoden tar en streng og sier den deretter. Så enkelt er det.

    Talegjenkjenning er mye mer kompleks enn talesyntese. Hovedmetoden fortsetter ved å lage et resolverobjekt:

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

    Først spesifiserer CultureInfo-objektet språket som skal gjenkjennes, i dette tilfellet amerikansk engelsk. CultureInfo-objektet er i Globalization-navneområdet, som vi refererte til med en brukersetning. Deretter, etter å ha ringt SpeechRecognitionEngine-konstruktøren, blir stemmeinngangen tilordnet standard lydenhet - oftest mikrofonen. Merk at de fleste bærbare datamaskiner har en innebygd mikrofon, men stasjonære datamaskiner vil kreve en ekstern mikrofon (ofte kombinert med hodetelefoner i disse dager).

    Nøkkelmetoden for gjenkjennerobjektet er SpeechRecognized hendelsesbehandler. Når du bruker Visual Studio, hvis du skriver "sre.SpeechRecognized +=" og venter et brøkdel av et sekund, vil IntelliSense automatisk avslutte uttrykket ditt med hendelsesbehandlernavnet - sre_SpeechRecognized. Jeg foreslår at du trykker på Tab-tasten for å godta forslaget og bruker dette navnet som standard.

    Valg ch_Numbers = nye valg(); ch_Numbers.Add("1"); ch_Numbers.Add("2"); ch_Numbers.Add("3"); ch_Numbers.Add("4"); // fra et teknisk synspunkt, // dette er Add(ny streng ("4")); GrammarBuilder gb_WhatIsXplusY = ny GrammarBuilder(); gb_WhatIsXplusY.Append("Hva er"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("pluss"); gb_WhatIsXplusY.Append(ch_Numbers); Grammatikk g_WhatIsXplusY = ny Grammar(gb_WhatIsXplusY);

    De tre hovedobjektene her er valgsettet, GrammarBuilder-malen og grammatikkkontrollen. Når jeg lager en grammatikk for gjenkjennelse, starter jeg med å liste noen spesifikke eksempler på hva jeg trenger å gjenkjenne. La oss si: "Hva er én pluss to?" og "Hva er tre pluss fire?"

    Deretter definerer jeg den tilsvarende generiske malen, for eksempel "Hva er Plus ?. Malen er en GrammarBuilder, og de spesifikke verdiene som sendes til malen er et sett med valg. Grammatikkobjektet innkapsler malen og valg.

    I demoprogrammet begrenser jeg tilleggene til 1 til 4 og legger dem til som strenger i valgsettet. Mer effektiv tilnærming:

    strengtall = ny streng ("1", "2", "3", "4" ); Valg ch_Numbers = new Choices(numbers);

    Jeg presenterer en mindre effektiv tilnærming til å lage et valg-sett av to grunner. For det første var å legge til en linje om gangen den eneste tilnærmingen jeg har sett i andre talegjenkjenningseksempler. For det andre tror du kanskje at å legge til én rad om gangen ikke burde fungere i det hele tatt; Visual Studio IntelliSense viser i sanntid at en av Add-overbelastningene godtar en parameter av typen params-strengfraser. Hvis du ikke la merke til params-nøkkelordet, kan du ha antatt at Add-metoden bare godtar arrays av strenger og ikke en enkelt streng. Men dette er ikke tilfelle: han godtar begge deler. Jeg anbefaler å passere en array.

    Å lage et sett med valg fra sekvensielle tall er noe av et spesielt tilfelle og gir mulighet for en programmatisk tilnærming som:

    strengtall = ny streng; for (int i = 0; i< 100; ++i) numbers[i] = i.ToString(); Choices ch_Numbers = new Choices(numbers);

    Etter å ha opprettet valg for å fylle GrammarBuilder-sporene, oppretter demoprogrammet en GrammarBuilder og deretter en kontrollerende Grammar:

    GrammarBuilder gb_WhatIsXplusY = ny GrammarBuilder(); gb_WhatIsXplusY.Append("Hva er"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("pluss"); gb_WhatIsXplusY.Append(ch_Numbers); Grammatikk g_WhatIsXplusY = ny Grammar(gb_WhatIsXplusY);

    Demoprogrammet bruker en lignende mal for å lage grammatikken for start- og stoppkommandoer:

    Valg ch_StartStopCommands = nye valg(); ch_StartStopCommands.Add("tale på"); ch_StartStopCommands.Add("tale av"); ch_StartStopCommands.Add("klatu bareda nikto"); GrammarBuilder gb_StartStop = ny GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammatikk g_StartStop = ny Grammatikk(gb_StartStop);

    Grammatikk kan defineres veldig fleksibelt. Her er kommandoene "tale på", "tale av" og "klatu barada nikto" plassert i én grammatikk, siden de er logisk relatert. Disse tre kommandoene kan defineres i tre forskjellige grammatikker, eller kommandoene "tale på" og "tale av" kan plasseres i én grammatikk og kommandoen "klatu barada nikto" på et sekund.

    Når du har opprettet alle grammatikkobjektene, legger du dem inn i talegjenkjenningen og talegjenkjenning aktiveres:

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

    Argumentet RecognizeMode.Multiple er nødvendig når du har mer enn én grammatikk, noe som vil være tilfellet i alle unntatt de enkleste programmene. Hovedmetoden fullføres som følger:

    While (ferdig == usann) ( ; ) Console.WriteLine("\nTrykk< enter >for å lukke skallet\n"); Console.ReadLine(); ) catch (Exception ex) ( Console.WriteLine(ex.Message); Console.ReadLine(); ) ) // Main

    En tom while-løkke som ser merkelig ut, lar deg holde skallet til en konsollapplikasjon i gang. Sløyfen vil bli fullført når den boolske variabelen på klassenivå er satt til sann av hendelsesbehandleren for talegjenkjenning.

    Gjenkjent talebehandling

    Koden for håndtering av talegjenkjenningshendelser starter slik:

    statisk void sre_SpeechRecognized(objektavsender, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float confidence = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (confidence);< 0.60) return; ...

    Den gjenkjente teksten lagres i egenskapen Result.Text til SpeechRecognizedEventArgs-objektet. Alternativt kan du bruke Result.Words-settet. Result.Confidence-egenskapen lagrer en verdi mellom 0,0 og 1,0 som er et grovt estimat på hvor godt den talte teksten samsvarer med noen av grammatikkene knyttet til gjenkjenneren. Demoprogrammet instruerer hendelsesbehandleren om å ignorere tekst med lav tillit til den gjenkjente teksten.

    Konfidensverdier varierer sterkt avhengig av kompleksiteten til grammatikken din, mikrofonkvaliteten og andre faktorer. For eksempel, hvis demoprogrammet bare trenger å gjenkjenne tallene 1 til 4, er konfidensverdiene på datamaskinen min vanligvis rundt 0,75. Men hvis grammatikken må gjenkjenne tall fra 1 til 100, faller konfidensverdiene til omtrent 0,25. I et nøtteskall bør du generelt eksperimentere med tillitsverdier for å oppnå gode talegjenkjenningsresultater.

    if (txt.IndexOf("tale på") >= 0) ( Console.WriteLine("Tale er nå PÅ"); speechOn = true; ) if (txt.IndexOf("tale av") >= 0) ( Konsoll .WriteLine("Tale er nå AV"); speechOn = usann; ) if (talePå == usann) returnerer;

    Selv om det kanskje ikke er helt åpenbart med det første, bør denne logikken gi mening hvis du tenker deg om. Den hemmelige utgangskommandoen behandles deretter:

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

    Merk at talegjenkjenningsmotoren faktisk kan gjenkjenne tullord. Hvis et grammatikkobjekt inneholder ord som ikke er i objektets innebygde ordbok, prøver Grammatikk å identifisere disse ordene ved hjelp av semantisk heuristikk hvis mulig, og er vanligvis ganske vellykket. Derfor brukte jeg "klatu" i stedet for den korrekte "klaatu" (fra en gammel sci-fi-film).

    Vær også oppmerksom på at du ikke er pålagt å behandle all teksten som gjenkjennes av grammatikk ("klatu barada nikto") - du trenger bare å ha nok informasjon til å identifisere den grammatiske frasen unikt ("klatu" og "barada").

    If (txt.IndexOf("What") >= 0 && txt.IndexOf("pluss") >= 0) ( strengord = txt.Split(" "); int num1 = int.Parse(ord); int num2 = int.Parse(ord); int sum = num1 + num2; Console.WriteLine("(Snakker: " + ord + " pluss " + ord + " er lik " + sum + ")"); ss.SpeakAsync(ord + " pluss " + ord + " er lik " + sum); ) ) // sre_SpeechRecognized ) // Program ) // ns

    Merk at teksten i Results.Text skiller mellom store og små bokstaver ("Hva" og "hva"). Etter å ha gjenkjent en setning, kan den analyseres til bestemte ord. I dette tilfellet har den gjenkjente teksten formen "Hva er x pluss y", så "Hva" er plassert i ord, og de to tilføyde tallene (som strenger) lagres i ord og ord.

    Installere biblioteker

    Forklaringen til demoprogrammet forutsetter at alle nødvendige talebiblioteker er installert på datamaskinen din. For å lage og kjøre demoprogrammer, må du installere fire pakker: SDK (gir muligheten til å lage demoer i Visual Studio), kjøretiden (kjører demoene etter at de er opprettet), og de anerkjente og syntetiserte (uttales) språkene.

    For å installere SDK, søk på Internett etter «Speech Platform 11 SDK». Dette tar deg til riktig side i Microsoft Download Center ( ris. 4). Ved å klikke på Last ned-knappen vil du se alternativene vist i ris. 5. SDK-en kommer i 32- og 64-biters versjoner. Jeg anbefaler på det sterkeste å bruke 32-bitsversjonen uavhengig av bitstørrelsen på systemet ditt. 64-bitsversjonen fungerer ikke med enkelte programmer.


    Ris. 4. Hoved SDK-installasjonsside i Microsoft Download Center


    Ris. 5. Installer Speech SDK

    Du trenger ikke noe mer enn en enkelt .msi-fil under x86 (for 32-bits systemer). Ved å velge denne filen og klikke på Neste, kan du kjøre installasjonsprogrammet direkte herfra. Talebiblioteker gir ikke mye tilbakemelding om når installasjonen er fullført, så ikke se etter noen suksessmeldinger.


    Ris. 6. Installasjon av kjøretidsmiljøet

    Det er ekstremt viktig å velge samme plattformversjon (11 i demoen) og bitdybde (32 eller 64) som SDK. Igjen, jeg anbefaler på det sterkeste 32-bitsversjonen, selv om du kjører på et 64-bitssystem.

    Du kan deretter stille inn gjenkjenningsspråket. Nedlastingssiden finnes på ris. 7. Demoprogrammet bruker filen MSSpeech_SR_en-us_TELE.msi (Engelsk-U.S.). SR står for talegjenkjenning, og TELE står for telefoni; dette betyr at det gjenkjente språket er designet for å fungere med lydinngang av lav kvalitet, for eksempel fra en telefon eller skrivebordsmikrofon.


    Ris. 7. Stille inn et gjenkjent språk

    Til slutt kan du stille inn språk og stemme for talesyntese. Nedlastingssiden finnes på ris. 8. Demoprogrammet bruker filen MSSpeech_TTS_en-us_Helen.msi. TTS (tekst-til-tale) er i hovedsak synonymt med talesyntese. Legg merke til de to tilgjengelige stemmene engelsk, U.S. Det er andre engelske stemmer, men ikke U.S. Å lage syntetiske språkfiler er en veldig vanskelig oppgave. Du kan imidlertid kjøpe og installere andre stemmer fra en rekke selskaper.


    Ris. 8. Stille inn stemme- og syntesespråk

    Interessant nok, selv om talegjenkjenningsspråk og tale-/talesyntesespråk faktisk er helt forskjellige ting, er begge pakkene alternativer på samme nedlastingsside. Nedlastingssenterets brukergrensesnitt lar deg sjekke både gjenkjenningsspråket og syntesespråket, men å prøve å installere dem samtidig var katastrofalt for meg, så jeg anbefaler å installere dem separat.

    Sammenligning av Microsoft.Speech med System.Speech

    Hvis du er ny på talegjenkjenning og syntese for Windows-applikasjoner, kan du lett bli forvirret av dokumentasjonen fordi det er flere taleplattformer. Nærmere bestemt, i tillegg til Microsoft.Speech.dll-biblioteket som brukes av demoprogrammene i denne artikkelen, er det et bibliotek kalt System.Speech.dll som er en del av Windows-operativsystemet. De to bibliotekene er like i den forstand at API-ene deres er nesten, men ikke helt, identiske. Derfor, hvis du ser etter talebehandlingseksempler på Internett og ser kodebiter i stedet for komplette programmer, er det slett ikke åpenbart om eksemplet er System.Speech eller Microsoft.Speech.

    Hvis du er ny på talebehandling, bruk Microsoft.Speech-biblioteket i stedet for System.Speech for å legge til talestøtte til .NET-applikasjonen.

    Selv om begge bibliotekene deler en felles kjernekodebase og lignende APIer, er de definitivt forskjellige. Noen viktige forskjeller er oppsummert i bord 1.

    Bord 1. Hovedforskjeller mellom Microsoft.Speech og System.Speech

    System.Speech DLL er en del av operativsystemet, så det er installert på alle Windows-systemer. Microsoft.Speech DLL (og tilhørende kjøretid og språk) må lastes ned og installeres på systemet. Gjenkjenning ved bruk av System.Speech krever vanligvis opplæring for en spesifikk bruker, når brukeren leser noe tekst, og systemet lærer å forstå uttalekarakteristikken til denne brukeren. Gjenkjenning ved hjelp av Microsoft.Speech fungerer umiddelbart for enhver bruker. System.Speech kan gjenkjenne nesten alle ord (dette kalles fri diktering). Microsoft.Speech vil bare gjenkjenne ord og uttrykk som er i grammatikkobjektet som er definert i programmet.

    Legge til talegjenkjenningsstøtte til en Windows Forms-applikasjon

    Prosessen for å legge til talegjenkjenning og syntesestøtte til en Windows Forms- eller WPF-applikasjon ligner på den for en konsollapplikasjon. For å lage demoprogrammet vist i ris. 2, lanserte jeg Visual Studio, opprettet en ny C# Windows Forms-applikasjon og ga den nytt navn til WinFormSpeech.

    Etter å ha lastet inn malkoden i editoren, la jeg til en lenke til Microsoft.Speech.dll-filen i Solution Explorer-vinduet - akkurat som jeg gjorde i konsollprogrammet. Øverst i kildekoden fjernet jeg unødvendig bruk av setninger, og la bare referanser til system-, data-, tegnings- og skjemanavnene. Deretter la jeg til to ved å bruke setninger for navnerommene Microsoft.Speech.Recognition og System.Globalization.

    Den Windows Forms-baserte demoen bruker ikke talesyntese, så jeg kobler ikke til Microsoft.Speech.Synthesis-biblioteket. Å legge til talesyntese i et Windows Forms-program er det samme som i et konsollprogram.

    I Visual Studio i designmodus dro jeg en TextBox, CheckBox og ListBox-kontroller til skjemaet. Dobbeltklikket CheckBox og Visual Studio opprettet automatisk en skjelett CheckChanged hendelsesbehandlermetode.

    Husk at demokonsollprogrammet umiddelbart begynte å lytte etter talte kommandoer og fortsatte å gjøre det til det ble avsluttet. Denne tilnærmingen kan brukes i en Windows Forms-applikasjon, men i stedet bestemte jeg meg for å la brukeren slå talegjenkjenning av og på ved hjelp av en CheckBox-kontroll (dvs. en avmerkingsboks).

    Kildekoden i demoprogrammets Form1.cs-fil, hvor delklassen er definert, vises på ris. 9. Et talegjenkjenningsmotorobjekt er deklarert og opprettet som et skjemamedlem. I skjemaets konstruktør kobler jeg opp SpeechRecognized hendelsesbehandleren og lager og laster deretter to Grammars-objekter:

    public Form1() ( InitializeComponent(); sre.SetInputToDefaultAudioDevice(); sre.SpeechRecognized += sre_SpeechRecognized; Grammatikk g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammatikk g_SetTextBox =GetTexmmtsAmmar(Texmmt.syn); HelloGoodby e);sre.LoadGrammarAsync(g_SetTextBox) ; // sre.RecognizeAsync() er // i hendelsesbehandleren CheckBox)

    Ris. 9. Legg til støtte for talegjenkjenning i Windows Forms

    bruker System; bruker System.Data; ved hjelp av System.Drawing; bruker System.Windows.Forms; bruker Microsoft.Speech.Recognition; bruker System.Globalization; navneområde WinFormSpeech ( offentlig delklasse Form1: Form ( static CultureInfo ci = new CultureInfo("en-us"); static SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci); public Form1() ( InitializeComponent(); sre.SetInputToDefault(AudiosInputToDefault); .SpeechRecognized += sre_SpeechRecognized; Grammatikk g_HelloGoodbye = GetHelloGoodbyeGrammar(); Grammar g_SetTextBox = GetTextBox1TextGrammar(); sre.LoadGrammarAsync(g_HelloA.LoadGrasgSrec/sync(g_HelloA.LoadGrasgSre/sync); Gjenkjenne at Async() er // i hendelsesbehandleren CheckBox ) statisk Grammatikk GetHelloGoodbyeGrammar() ( Choices ch_HelloGoodbye = new Choices(); ch_HelloGoodbye.Add("hello"); ch_HelloGoodbye.Add("goodbye"); GrammarBuilder gb_result = new GrammarBuilder(ch_HelloGoodgult) GrammarBuilder(ch_HelloGoodgrese); ; return g_result; ) static Grammar GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(ny streng ( "rød", "hvit", "blå" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("sett tekstboks 1"); gb_result.Append(ch_Colors); Grammar g_result = new Grammar(gb_result); returner g_result; ) privat void checkBox1_CheckedChanged(objektavsender, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // disabled sre.RecognizeA(); void sre_SpeechRecognized(objektavsender, SpeechRecognizedEventArgs e) ( string txt = e.Result.Text; float conf = e.Result.Confidence; if (conf< 0.65) return; this.Invoke(new MethodInvoker(() =>( listBox1.Items.Add("Jeg hørte deg si: " + txt); ))); // WinForm specifics if (txt.IndexOf("text") >= 0 && txt.IndexOf("box") >= 0 && txt.IndexOf("1")>= 0) ( string words = txt.Split( " "); this.Invoke(new MethodInvoker(() => ( textBox1.Text = ord; ))); // WinForm specifics ) ) ) // Form ) // ns

    Jeg kunne ha laget to Grammar-objekter direkte, som i et konsollprogram, men i stedet, for å gjøre koden litt klarere, definerte jeg to hjelpemetoder (GetHelloGoodbyeGrammar og GetTextBox1TextGrammar) som gjør jobben.

    statisk grammatikk GetTextBox1TextGrammar() ( Choices ch_Colors = new Choices(); ch_Colors.Add(ny streng ( "rød", "hvit", "blå" )); GrammarBuilder gb_result = new GrammarBuilder(); gb_result.Append("sett tekst boks 1"); gb_result.Append(ch_Colors); Grammar g_result = new Grammar(gb_result); return g_result; )

    Denne hjelpemetoden vil gjenkjenne uttrykket "sett tekstboks 1 rød". Brukeren er imidlertid ikke pålagt å uttale denne setningen nøyaktig. For eksempel kan han si "Vennligst sett teksten i tekstboks 1 til rød" og talegjenkjenningsmotoren vil fortsatt gjenkjenne setningen som "sett tekstboks 1 rød" - om enn med en lavere konfidensverdi enn en eksakt samsvar med grammatikken mal. Med andre ord, når du oppretter grammatikkobjekter, er du ikke pålagt å ta hensyn til alle varianter av en frase. Dette forenkler bruken av talegjenkjenning radikalt.

    Hendelsesbehandleren for CheckBox er definert slik:

    private void checkBox1_CheckedChanged(objektsender, EventArgs e) ( if (checkBox1.Checked == true) sre.RecognizeAsync(RecognizeMode.Multiple); else if (checkBox1.Checked == false) // disabled sre.CrecognizeAsync);

    Objektet for talegjenkjenningsmotoren, sre (talegjenkjenningsmotor), eksisterer alltid så lenge et Windows Forms-program varer. Dette objektet aktiveres og deaktiveres ved anrop til metodene RecognizeAsync og RecognizeAsyncCancel når brukeren veksler mellom henholdsvis avmerkingsboksen.

    SpeechRecognized hendelsesbehandlerdefinisjonen begynner med:

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

    Foruten de mer eller mindre konstant brukte egenskapene Result.Text og Result.Confidence, har Result-objektet flere andre nyttige, men mer komplekse egenskaper som du kanskje vil utforske; for eksempel Homofoner og ReplacementWordUnits. I tillegg gir talegjenkjenningsmotoren flere nyttige hendelser som SpeechHypothesized.

    this.Invoke((Action)(() => listBox1.Items.Add("Jeg hørte deg si: " + txt)));

    I teorien er det litt mer effektivt å bruke MethodInvoker-delegaten enn en handling i denne situasjonen fordi MethodInvoker er en del av Windows.Forms-navneområdet og derfor spesifikt for Windows Forms-applikasjoner. Action-delegaten er mer allsidig. Dette eksemplet viser at du fullstendig kan manipulere en Windows Forms-applikasjon gjennom talegjenkjenningsmotoren - dette er en utrolig kraftig og nyttig funksjon.

    Konklusjon

    Informasjonen som presenteres i denne artikkelen bør få deg i gang med en gang hvis du vil utforske talesyntese og gjenkjenning i .NET-applikasjoner. Å mestre selve teknologien er en lek når du kommer forbi ujevnhetene med innledende læringskurve og komponentinstallasjon. Den virkelige utfordringen i talesyntese og gjenkjenning er å forstå når det faktisk er nyttig.

    Med konsollprogrammer kan du lage interessante frem-og-tilbake-samtaler der brukeren stiller et spørsmål og programmet svarer, noe som i hovedsak resulterer i et Cortana-lignende miljø. Du må være forsiktig, for når tale kommer fra datamaskinens høyttalere, vil den bli fanget opp av mikrofonen og kan gjenkjennes igjen. Jeg har havnet i noen ganske morsomme situasjoner der jeg stilte et spørsmål, appen gjenkjente det og svarte, men det talte svaret utløste neste gjenkjenningshendelse, og jeg endte opp med en morsom, endeløs talesløyfe.

    En annen mulig bruk av tale i et konsollprogram er å gjenkjenne kommandoer som "Launch Notepad" og "Launch Word". Et slikt konsollprogram kan med andre ord brukes på datamaskinen din til å utføre handlinger som ellers ville kreve mye manipulering av tastatur og mus.

    James McCaffrey(Dr. James McCaffrey) jobber for Microsoft Research i Redmond, Washington. Han deltok i opprettelsen av flere Microsoft-produkter, inkludert Internet Explorer og Bing. Han kan kontaktes på [e-postbeskyttet].

    Takk til Microsoft Research-ekspertene Rob Gruen, Mark Marron og Curtis von Veh for gjennomgang av denne artikkelen.