Opisy audio w Narratorze

Ukończone

Funkcja syntezy mowy przeszła długą drogę rozwoju od czasu mechanicznie brzmiących głosów i sztywnej wymowy. Narrator udostępnia w systemie Windows wbudowany czytnik ekranu, który może być doskonałym wsparciem dla użytkowników niedowidzących. Musimy jednak skonfigurować naszą aplikację, aby mogła z niego bezproblemowo korzystać.

W tej lekcji dowiesz się:

  • Jak włączyć Narratora i przetestować go w aplikacji bez jakichkolwiek specjalnych atrybutów narracji.
  • Jak dodać specjalne atrybuty do aplikacji w celu poprawienia płynności narracji.
  • Jak usunąć pewne niedokładności z naszych ciągów i komunikatów, aby brzmiały prawidłowo.
  • Przerwy w narracji można wypełnić niestandardowym wystąpieniem syntezatora mowy.

Narrator

Upewnij się, że aplikacja kalkulatora naukowego została uruchomiona. Będziemy musieli zmienić kod XAML oraz kod bazowy, aby upewnić się, że zapewnia on najlepsze środowisko dla użytkowników korzystających z Narratora.

Włączanie i testowanie Narratora

  1. Wpisz „ustawienia Narratora” na pasku wyszukiwania systemu Windows, a następnie wybierz opcję Ustawienia Narratora w Ułatwieniach dostępu. Spowoduje to wyświetlenie następującego ekranu.

Turning on the narrator.

  1. Włącz przełącznik Użyj Narratora, a następnie zminimalizuj to okno. Narracja może sprawiać problemy podczas przełączania się między aplikacjami i tworzenia oprogramowania, dlatego warto pozostawić to okno otwarte. Dzięki temu będzie można wyłączyć Narratora podczas wprowadzania zmian w kodzie, a następnie ponownie go włączyć na potrzeby testowania.

  2. Wyróżnij przycisk Pokaż stałe kalkulatora i zwróć uwagę, jak Narrator obsługuje opis: Pokaż stałe (wstrzymywanie). Chcemy usprawnić Narratora, aby podawane przez niego opisy były jak najbardziej przydatne, co będzie oznaczało pracę z jego wbudowanymi funkcjami. Jedną z tych funkcji jest ogłaszanie typu elementu interfejsu użytkownika (wyraźnie „button” — przycisk — w tym przypadku).

  3. Teraz wybierz przycisk Sqrt i zwróć uwagę na wymowę. „Sqrt” to typowa skrócona forma angielskich słów oznaczających w matematyce pierwiastek kwadratowy, ale Narrator nie wie tego. Podobnie nie rozpozna on form Sin, Asin, Acos itd., szczególnie gdy specjalistyczne terminy mogą być również wymawiane jak zwykłe słowa angielskie. Będziemy musieli pomóc Narratorowi w poprawnej interpretacji wymowy tych słów.

  4. Zwróć uwagę na jakość narracji w przypadku innych przycisków (operacje, cyfry). W niektórych obszarach narracja wypada całkiem dobrze, a w innych należy ją poprawić.

  5. Wróć do przycisku Show constants (Pokaż stałe), wybierz go, a następnie wybieraj różne stałe, zwracając uwagę na narrację. Wybierz kilka stałych i oceń przydatność ich wymowy. W tych miejscach, gdzie byliśmy nieco leniwi i wstawiliśmy skróty, takie jak „Gms”, „Ozs”, „Cms” itd., wymowa nie jest przydatna. Terminy skrócone są bezużyteczne, jeśli użytkownicy ich nie rozumieją.

  6. Na koniec wprowadź następujące obliczenie: SqrtAtan0.5. Bez wybierania przycisku = zaznacz wyświetlany tekst obliczenia i zwróć uwagę, jak Narrator go obsługuje. Teraz naciśnij przycisk = i ponownie zaznacz wyświetlany tekst. Na szczęście dla nas Narrator całkiem dobrze sobie radzi z długimi liczbami.

  7. Otwórz okno ustawień Narratora i wyłącz na razie narrację.

Po przeprowadzeniu testu Narratora z kalkulatorem okazało się, że musimy rozwiązać kilka problemów, takich jak wymowa funkcji i operacji matematycznych oraz przejrzystość listy stałych.

Zwiększanie naturalności ciągów tekstowych

W tej sekcji sprawimy, że dźwięk Narratora będzie brzmiał naturalnie podczas korzystania z dowolnej funkcji kalkulatora. Upewnij się, że program Visual Studio jest otwarty z projektem kalkulatora naukowego.

  1. Gdy element interfejsu użytkownika zostanie wyróżniony i ma zostać opisany dźwiękowo, Narrator najpierw sprawdza właściwość AutomationProperites.Name. Jeśli taka właściwość zostanie znaleziona, zostanie użyte określone słowo lub fraza. Jeśli właściwość nie zostanie znaleziona, zamiast niej zostanie użyta właściwość Content. Dlatego dla wszystkich elementów interfejsu użytkownika, które nie są dobrze wymawiane, musimy dodać właściwość AutomationProperites.Name z wyraźnie wypowiedzianą nazwą. W pliku MainPage.xaml dodaj następujące właściwości nazwy do odpowiednich wpisów xaml. Ta czynność zajmie sporo czasu, ponieważ jest to długa lista, do której wpisy są wprowadzane pojedynczo. Wytnij i wklej elementy z poniższej listy lub użyj funkcji szybkiego wprowadzania atrybutów w programie Visual Studio.
 <Button x:Name="ButtonNMemoryPlus" AutomationProperties.Name="Memory plus" Content="M+"
 <Button x:Name="ButtonNMemoryMinus" AutomationProperties.Name="Memory minus" Content="M-"
 <Button x:Name="ButtonNMemoryMultiply" AutomationProperties.Name="Memory times" Content="M*"
 <Button x:Name="ButtonNMemoryDivide" AutomationProperties.Name="Memory divided by" Content="M/"
 <Button x:Name="ButtonLeft" AutomationProperties.Name="Open" Content="("
 <Button x:Name="ButtonSqrt" AutomationProperties.Name="Square root" Content="Sqrt"
 <Button x:Name="ButtonPow" AutomationProperties.Name="to the Power of" Content="^"
 <Button x:Name="ButtonPi" AutomationProperties.Name="Pi" Content="&#928;"
 <Button x:Name="ButtonRight" AutomationProperties.Name="Close" Content=")"
 <Button x:Name="ButtonArcsine" AutomationProperties.Name="Arc sine" Content="Asin"
 <Button x:Name="ButtonArccosine" AutomationProperties.Name="Arc cosine" Content="Acos"
 <Button x:Name="ButtonArctangent" AutomationProperties.Name="Arc tangent" Content="Atan"
 <Button x:Name="ButtonSin" AutomationProperties.Name="Sine" Content="Sin"
 <Button x:Name="ButtonCos" AutomationProperties.Name="Cosine" Content="Cos"
 <Button x:Name="ButtonTan" AutomationProperties.Name="Tangent" Content="Tan"
 <Button x:Name="ButtonNegative" AutomationProperties.Name="Negative" Content="-N"
 <Button x:Name="ButtonPlus" AutomationProperties.Name="plus" Content="+"
 <Button x:Name="ButtonMinus" AutomationProperties.Name="minus" Content="-"
 <Button x:Name="ButtonMultiply" AutomationProperties.Name="times" Content="*"
 <Button x:Name="ButtonDivide" AutomationProperties.Name="divided by" Content="/"
 <Button x:Name="ButtonEquals" AutomationProperties.Name="equals" Content="="
 <TextBox x:Name="TextDisplay" AutomationProperties.Name="Calculation"
 <Button x:Name="ButtonClr" AutomationProperties.Name="Clear" Content="Clr"
 <Button x:Name="ButtonDel" AutomationProperties.Name="Delete" Content="Del"
   />
  1. Teraz zajmiemy się niedokładnościami na liście stałych. Otwórz plik MainPage.xaml.cs i znajdź metodę LoadConstants.

  2. Zamień ciągi z listy na następujące ciągi i zwróć uwagę, że wszystkie skrócone wyrażenia zostały zastąpione ich długimi formami.

string[] initialConstants = {
                "Acceleration due to gravity = 9.80665",
                "Bars to pounds per square inch = 14.5037738",
                "Centimeters to inches = 0.393700787",
                "Degrees to radians = 0.0174532925",
                "Feet to meters = 0.3048",
                "Grams to ounces = 0.035273",
                "Inches to centimeters = 2.540",
                "Inches to millimeters = 25.4",
                "Kilograms to pounds = 2.20462262",
                "Kilometers to miles = 0.621371192",               
                "Liters to pints = 2.11337642",
                "Meters to feet= 3.2808",
                "Miles to kilometers = 1.609344",
                "Millimeters to inches = 0.0393700787",
                "Ounces to grams = 28.3495",
                "Pints to liters = 0.473176473",   
                "Pounds per square inch to bars = 0.0689475729",
                "Pounds to kilograms = 0.45359237",                            
                "Radians to degrees = 57.2957795",
                "Speed of light in meters per second = 299792458",
                "Speed of light in miles per second = 186282.397"
            };
  1. Uruchom aplikację i włącz narrację. Wyróżnij poszczególne funkcje i operacje matematyczne oraz stałe i pozwól Narratorowi, aby odczytał ich nazwy. Ta czynność musi być wykonana starannie. Czy wszystkie nazwy brzmią teraz naturalnie i są zrozumiałe? Jeśli nie, wprowadź poprawki do ciągów lub dodaj bądź dostosuj właściwość AutomationProperites.Name.

  2. Spróbuj wprowadzić obliczenie zawierające nawiasy i kilka funkcji matematycznych (nie muszą być one poprawne matematycznie), a następnie zaznacz wyświetlany tekst. Aby rozwiązać ten problem, musimy nieco zmodyfikować kod.

Dodawanie kodu ułatwiającego działanie Narratora

Dzięki wprowadzonym przez nas zmianom Narrator doskonale radzi sobie teraz z elementami interfejsu użytkownika. Istnieje jednak kilka przypadków, w których komunikat mówiony byłby pomocny, ale wyzwalające zdarzenie nie jest elementem interfejsu użytkownika. Chcielibyśmy również poprawić wymowę obliczeń. Dodamy tutaj syntezator mowy, który będzie obsługiwał komunikaty o błędach, oraz kilka drobnych zmian kodu do obsługi obliczeń.

  1. Otwórz plik MainPage.xaml.cs i zaktualizuj instrukcje using, aby uwzględnić następujące elementy.
using System.Threading.Tasks;
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Automation;
  1. Dodaj następujące elementy do listy zmiennych globalnych.
        // Declare variables needed for speech output.
        SpeechSynthesizer speech;
        MediaElement mediaElement;
  1. Zainicjuj te zmienne w metodzie MainPage. Powinna ona wyglądać następująco.
        public MainPage()
        {
            this.InitializeComponent();

            // Hide the error field.
            textError.Visibility = Visibility.Collapsed;

            LoadConstants();

            calculation = new ArrayList();
            backupCalculation = new ArrayList();

            mode = Emode.Calculate;

            // The objects for controlling and playing audio.
            speech = new SpeechSynthesizer();
            mediaElement = new MediaElement();
        }
  1. Dobrym sposobem jest dodanie przełącznika lub innego elementu interfejsu użytkownika umożliwiającego włączanie i wyłączanie pomocy narracyjnej. W pliku MainPage.xaml tuż nad wpisem listConstants (blisko wpisów dotyczących ostatniego elementu interfejsu użytkownika) dodaj następujący kod.
        <ToggleSwitch x:Name="ToggleNarration"
            Margin="551,407,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Header="Narration help"
            IsOn="True" />

Uwaga

Ważne jest, aby te elementy były ułożone w pliku XAML w odpowiedniej kolejności. Jeśli tak nie będzie, uzyskasz efekt prześwitywania polegający na tym, że na przykład ten wpis pojawi się na liście stałych.

  1. Z powrotem w pliku MainPage.xaml.cs dodaj metodę SayAsync umożliwiającą wypowiadanie dowolnego podanego wiersza tekstu. Zwróć uwagę na użycie zmiennych speech i mediaElement, które zostały właśnie dodane, i że jest to zadanie asynchroniczne.
        private async Task SayAsync(string text)
        {
            // Narrate the given text if narration help is on.
            if (ToggleNarration.IsOn == true)
            {
                // Generate the audio stream from plain text.
                SpeechSynthesisStream stream = await speech.SynthesizeTextToStreamAsync(text);

                // Send the stream to the media object, then play it.
                mediaElement.SetSource(stream, stream.ContentType);
                mediaElement.Play();
            }
        }
  1. Teraz musimy dodać wywołania metody SayAsync. Zacznij od bloku catch metody CalculateAsync.
            catch
            {
                TextError.Visibility = Visibility.Visible;
                CopyCalculation(backupCalculation, calculation);
                await SayAsync("Oops, there is an error in your calculation.");
            }
  1. Również w metodzie CalculateAsync dodaj następujące wywołanie funkcji SayAsync po wierszach przedstawionych tutaj.
                    // Add the entry to the next calculation, just in case the user wants to add to it.
                    OneEntry resultEntry = new OneEntry(Etoken.Number, result, txt);
                    calculation.Add((object)resultEntry);

                    await SayAsync($"The result is: {txt}");
  1. Teraz znajdź metodę Button_Click i zmień wpis default: w bloku przełącznika na następujący. Dzięki temu obliczenie da się wypowiedzieć.
                default:

                    // User has clicked a math or digit button.
                    string tag = b.Tag.ToString();
                    string txt = "";

                    // If in narrative mode, then use a full English string for the display text, if a full string has been specified.
                    if (ToggleNarration.IsOn == true)
                    {
                        txt = b.GetValue(AutomationProperties.NameProperty).ToString();
                    }

                    // Use the content of the button as the equation text.
                    if (txt.Length == 0)
                    {
                        txt = b.Content.ToString();
                    }

                    MathEntry(txt, tag);
                    break;
  1. Przetestuj swój kod, uruchamiając aplikację. Upewnij się, że przełączniki Narratora i pomocy narracyjnej są w pozycji włączonej. Wprowadź jakieś bezsensowne obliczenie, na przykład Sqrt (, które zostanie wyświetlone jako Square root Open (pierwiastek kwadratowy otwórz). Czy po wybraniu przycisku = komunikat o błędzie jest wypowiadany w naturalny sposób? Zauważ, że ten sam głos jest używany przez metodę SayAsync i Narratora, dzięki czemu dźwięk jest odtwarzany bezproblemowo.

  2. Uzupełnij obliczenia i zwróć uwagę, że tekst jest wyświetlany na ekranie. Jeśli następnie zaznaczysz wyświetlany tekst, obliczenie zostanie wyraźnie odczytane przez Narratora. Niektóre operacje wyboru mogą nadal stanowić pewne wyzwanie, ale jak do tej pory udało nam się utworzyć o wiele bardziej dostępne środowisko.

Dzięki dodaniu opcji syntezy mowy do aplikacji można wypełnić wszystkie luki w narracji, co może okazać się pomocne dla użytkowników. Ta opcja jest wysoce specyficzna dla aplikacji, więc priorytetem powinno być najpierw uczynienie elementów interfejsu użytkownika przyjaznych dla Narratora. Minimalna ilość dodatkowej narracji może być wystarczająca, co sprawdziło się w tym przypadku.

Podsumowanie lekcji

W tej lekcji dowiedzieliśmy się, że synteza mowy jest obecnie zadziwiająco skuteczna, przynajmniej w porównaniu z tym, czym była wcześniej. Uświadomiliśmy sobie, że całkiem sprawny system narracji jest dostępny bezpłatnie w systemie Windows. Wystarczy tylko włączyć Narratora. Dowiedzieliśmy się również jednak, że jeśli korzystamy z Narratora, uwidaczniają się wszelkie niedokładności w naszych ciągach komunikatów. W przypadku dostępnej aplikacji musimy się upewnić, że nasze ciągi komunikatów są jednoznaczne i szczegółowe.

Wiemy już teraz, że Narrator nie jest idealny i potrzebuje pomocy w pewnych okolicznościach. Na przykład słowo matematyczne „sin” (sinus) nie będzie poprawnie wymawiane, ponieważ jego skrócona forma jest identyczna jak inne angielskie słowo. Jednak ustawienia języka XAML umożliwiające rozwiązanie tego problemu są łatwo dostępne i nietrudne do zaimplementowania.