JavascriptProva

giovedì 31 marzo 2016

La mia vecchia libreria jacSpeech: la classe per il riconoscimento vocale.

Ed ecco un bel codice che ho creato un paio di anni fa in VB.NET e che devo ristudiare...

Imports System.Threading
Public Class jacRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("it-IT"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
    Public lista As New ArrayList
    Public matrice() As String

    Sub New()
        motore.SetInputToDefaultAudioDevice()
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class



Public Class jacSpeaker
    Public sintetizzatore As New SpeechSynthesizer
    Sub New()
        sintetizzatore.SetOutputToDefaultAudioDevice()
        sintetizzatore.SelectVoice("Microsoft Server Speech Text to Speech Voice (it-IT, Lucia)")
        sintetizzatore.Volume = 100
    End Sub
    Sub parla(ByVal parola As String)
        sintetizzatore.Speak(parola)
    End Sub
End Class


Public Class jacEngRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("en-US"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)

    Public lista As New ArrayList
    Public matrice() As String


    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("en-US")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub

End Class


Public Class jacRecorder
    Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" (ByVal messaggio As String, ByVal retmessage As String, ByVal valore As Integer, ByVal handle As Integer) As Integer

    Public path As String
    Sub record(ByVal tempo As Integer)
        mciSendString("open new type waveaudio alias suono", 0, 0, 0)
        mciSendString("record suono", 0, 0, 0)
        Dim sw As New Stopwatch
        sw.Start()
        Thread.Sleep(tempo)
        sw.Stop()
        mciSendString("save suono " + path, 0, 0, 0)
        mciSendString("close suono", "", 0, 0)
    End Sub
    Sub play()
        mciSendString("open " + path + " alias suono", 0, 0, 0)
        mciSendString("play suono wait", 0, 0, 0)
        mciSendString("close suono", 0, 0, 0)

    End Sub
End Class

Bene. Ci sono due classi. Comincio a studiarmi la prima...
Public Class jacRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("it-IT"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
    Public lista As New ArrayList
    Public matrice() As String

    Sub New()
        motore.SetInputToDefaultAudioDevice()
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class
Dunque... innanzitutto vengono dichiarate delle variabili:
  • SpeechRecognitionEngine
  • GrammarBuilder
  • Grammar
E poi altre variabili di tipo Event eccetera... che vedrò dopo...

Intanto, nel costruttore di JacRecognizer si eseguono alcune istruzioni:
Viene chiamato il metodo
motore.SetInputToDefaultAudioDevice()
che probabilmente setta l'input per il riconoscitore al microfono del dispositivo.

Quindi viene fatto "qualcosa" a carico del GrammarBuilder (che io con una scelta infelice ho chiamato "costruttore" generando facile confusione con il costruttore della classe).
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
Per prima cosa viene istanziato l'oggetto della classe GrammarBuilder
costruttore = New GrammarBuilder


Viene attribuita la lingua a questo oggetto GrammarBuilder chiamato "costruttore":
costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")


Vengono create delle "scelte" (oggetti Choices) e "appese" al costruttore di tipo GrammarBuilder:
Dim scelte As New Choices("u")
        costruttore.Append(scelte)
Il significato di quella "u" mi sfugge completamente.

Ah, ecco! In pratica, costruiamo l'oggetto costruttore (GrammarBuilder) e gli attribuiamo due cose:
  • la proprietà Culture, ossia la lingua;
  • Le scelte, ossia le parole che comprenderà la "grammatica".
La grammatica verrà costruita semplicemente ponendo il costruttore come parametro nel suo costruttore (che brutta denominazione che ho scelto! Confusiva al massimo!)
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
e poi:
grammatica = New Grammar(costruttore)

...quindi il motore si "carica" la grammatica:
motore.LoadGrammar(grammatica)
Resta da studiare l'ultimo metodo del motore, RecognizeAsync...

Ecco: sarebbe mettere il motore in condizioni di eseguire il riconoscimento.
motore.RecognizeAsync(RecognizeMode.Multiple)
Il "Multiple" starebbe per "multiple operazioni di riconoscimento.


Nel mio jacRecognizer ho overloadato il costruttore, però, avendone anche un altro con un parametro:
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
Ecco: il parametro fornito a questo costruttore è una stringa contenente il nome di un file.
Questo file viene aperto e le righe vengono lette e caricate in una ArrayList (quella che viene dichiarata e istanziata inizialmente nella dichiarazione della classe); quindi dalla ArrayList vengono poste in una matrice.
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)
(in celeste, le operazioni di lettura del file il cui indirizzo è stato passato come parametro, in rosso la copiatura dell'ArrayList nella matrice)

Quindi questa matrice viene usata per creare delle scelte (Choices) e "appesa" al costruttore, col quale verrà costruita la grammatica, che sarà quindi caricata dal motore, come prima, quindi il motore si mette in ascolto:
        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub

Restano le subroutines di elevazione degli eventi:
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class
Questi eventi erano stati dichiarati inizialmente:
    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
E' importante, nelle subroutines che evocano gli eventi, la parte Handles:
       Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub

Bene.
Adesso apro il programma che usa questo oggetto jacRecognizer...

E ho trovato la via spianata per la costruzione di tutto quello che voglio! Verso l'infinito e oltre!!!

Nessun commento:

Posta un commento