使用朗讀程式時的音訊描述

已完成

語音合成自機器人語音和生硬的發音以來,已有長足的進步。 「朗讀程式」在 Windows 上提供內建的螢幕助讀程式,對於視障使用者是絕佳的助力。 但我們必須設定應用程式,才能好好地利用它。

在本單元中,您將了解:

  • 如何開啟「朗讀程式」,並在沒有任何特殊旁白屬性的應用程式上測試它。
  • 如何為應用程式新增特殊屬性以改善旁白的流暢度。
  • 如何清除我們字串和訊息中的一些凌亂現象,讓它們聽起來正確無誤。
  • 該旁白中的缺口可由自訂的語音合成器執行個體來填補。

朗讀程式

確定工程計算機應用程式已啟動並正在執行。 我們將必須變更 XAML 和程式碼後置,以確保它為使用「朗讀程式」的使用者提供最佳體驗。

開啟並測試朗讀程式

  1. 在 Windows 搜尋列中輸入「朗讀程式設定」,然後選取 [輕鬆存取朗讀程式設定]。 這會顯示以下畫面。

開啟朗讀程式

  1. 開啟 [使用朗讀程式] 開關,然後將此視窗最小化。 在應用程式之間切換及開發軟體時,旁白可能較為煩人,因此您可以讓此視窗保持開啟。 如此一來,您將能夠在對程式碼進行變更時將其關閉,然後再重新啟用它來進行測試。

  2. 醒目提示計算機的 [顯示常數] 按鈕,並注意「朗讀程式」如何處理描述:顯示常數 (暫停) 按鈕。 我們想要協助「朗讀程式」讓其描述儘可能有幫助,這意謂著要處理其內建功能。 這些功能其中之一是宣告 UI 元素的類型 (顯然地,在此案例中為「按鈕」)。

  3. 現在,選取 [Sqrt] 按鈕並注意發音。 "Sqrt" 是數學中書寫平方根的常見速記形式,但「朗讀程式」並不知道這一點。 同樣地,它也不會認得 SinAsinAcos 等等,特別是當特製化詞彙也可以用一般英文單字的形式來發音時。 我們將必須協助「朗讀程式」讓這些發音正確。

  4. 選取各種其他按鈕 (運算、數字),並注意旁白的處理情況。 有些地方它做得很好,有些地方則需要改進。

  5. 返回 [顯示常數] 按鈕,選取它,然後選取各種常數本身並注意旁白。 選取數個常數並評估發音的實用性。 在我們有些懶惰而輸入速記 (例如 "Gms"、"Ozs"、"Cms" 等) 的情況中,發音並不實用。 如果您的使用者無法理解速記詞彙,速記詞彙就不實用。

  6. 最後,輸入下列計算:Sqrt Atan 0.5。 在不選取 = 的情況下,選取此計算的文字顯示,並注意「朗讀程式」如何處理它。 現在,按 =,然後再次選取文字顯示。 幸好,「朗讀程式」很擅長處理長數字。

  7. 開啟「朗讀程式」的設定視窗,並暫時先關閉旁白。

就我們使用計算機來進行的「朗讀程式」測試而言,顯然有幾個問題要處理:數學函式的發音、數學運算的發音,以及常數清單的清晰度。

讓文字字串變得自然

在本節中,我們會協助「朗讀程式」,使其在使用計算機的任何功能時能夠聽起來自然。 確定 Visual Studio 已搭配工程計算機專案一起開啟。

  1. 當 UI 元素被醒目提示並解說時,「朗讀程式」會先測試是否有 AutomationProperites.Name 屬性。 如果找到,就會使用該單字或片語。 如果找不到,則會改用 Content 屬性。 因此,針對所有未妥善發音的 UI 元素,我們必須新增具有可清楚發音之名稱的 AutomationProperites.Name 屬性。 在 MainPage.xaml 檔案中,將下列名稱屬性新增至其個別的 XAML 項目。 慢慢來,因為這是一份長清單,您將必須逐一新增這些項目。 從以下清單中剪下並貼上,或使用 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. 接著,讓我們處理常數清單的凌亂現象。 開啟 MainPage.xaml.cs 檔案,然後找出 LoadConstants 方法。

  2. 以下列內容取代字串清單,請注意所有速記詞彙是如何被普通寫法所取代的。

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. 現在,執行應用程式並開啟旁白。 更徹底地說,您將必須醒目提示每個數學函式、運算及常數,「朗讀程式」才會朗讀它們。 它們現在是否都聽起來自然且可理解? 如果不是,請對字串進行更正,或是新增或調整 AutomationProperites.Name 屬性。

  2. 嘗試輸入含有括弧和數個數學函式 (是否具有任何數學意義並不重要) 的計算,然後醒目提示文字顯示。 我們將必須進行一些編碼來修正此問題。

新增程式碼以協助朗讀程式

幸虧有我們的變更,「朗讀程式」現在對 UI 元素發揮極佳的作用。 不過,有幾個情況是語音訊息會有幫助,但觸發事件不是 UI 元素。 此外,我們想要改善計算的發音。 在這裡,我們將新增語音合成器來處理錯誤訊息,以及一些簡短的程式碼變更來處理計算。

  1. 開啟 MainPage.xaml.cs 檔案,然後更新 using 陳述式以包含下列內容。
using System.Threading.Tasks;
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Automation;
  1. 將下列內容新增至全域變數清單。
        // Declare variables needed for speech output.
        SpeechSynthesizer speech;
        MediaElement mediaElement;
  1. MainPage 方法中將這些變數初始化,使其現在看起來像這樣。
        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. 理想的做法是新增切換開關或其他 UI 元素,以便讓使用者能夠決定是否想要旁白說明。 在 MainPage.xaml 檔案中,於緊接著 listConstants 項目 (靠近最後的 UI 元素項目) 上方,新增下列內容。
        <ToggleSwitch x:Name="ToggleNarration"
            Margin="551,407,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Header="Narration help"
            IsOn="True" />

注意

請務必在 XAML 檔案中依正確順序排列這些元素。 如果順序不正確,您就會獲得顯現效果,例如此項目出現在常數清單中。

  1. 回到 MainPage.xaml.cs 中,新增 SayAsync 方法以說出任何指定的文字行。 請注意我們剛才新增之 speechmediaElement 變數的使用,以及這是一項非同步工作。
        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. 我們現在需要新增對 SayAsync 方法的呼叫。 從 CalculateAsync 方法的 catch 區塊開始著手。
            catch
            {
                TextError.Visibility = Visibility.Visible;
                CopyCalculation(backupCalculation, calculation);
                await SayAsync("Oops, there is an error in your calculation.");
            }
  1. 在仍於 CalculateAsync 方法中的情況下,於這裡顯示的行之後,新增下列對 SayAsync 的呼叫。
                    // 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. 現在,找出 Button_Click 方法,並將 switch 區塊中的 default: 項目變更如下。 這會讓計算變成可發音。
                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. 執行應用程式來測試您的程式碼。 確定「朗讀程式」和 [朗讀程式說明] 切換按鈕已開啟。 輸入一個無意義的計算 (例如 Sqrt (,這會顯示成「平方根左括弧」)。 選取 = 時,您是否收到自然發音錯誤訊息? 請注意相同的語音是如何用於您的 SayAsync 方法和「朗讀程式」,這可讓音訊體驗保持流暢。

  2. 完成計算,並注意顯示器中已將文字拼出。 如果您接著醒目提示顯示器,「朗讀程式」就會清楚讀出該計算。 有些選取作業可能仍然有點具挑戰性,但這個已經夠好,足以提供更便於使用的體驗。

為應用程式新增語音合成選項確實可以填補旁白中的任何缺口。 這是非常應用程式特定的,因此應優先考慮讓 UI 元素變得方便「朗讀程式」使用。 您所需的可能只是最少量的額外旁白,如這裡的案例所示。

單元摘要

在本單元中,我們已了解語音合成現在非常棒,至少在與其過去相比的情況下是如此。 我們已了解 Windows 隨附相當多的免費旁白,只要開啟「朗讀程式」即可使用。 不過,我們也了解到當使用「朗讀程式」時,我們訊息字串中的凌亂現象立即就變得很明顯。 對於一個便於使用的應用程式來說,我們必須確定我們的訊息字串乾淨且完整。

我們還了解到「朗讀程式」並不完美,在某些情況下需要協助。 例如,"sin" 這類數學單字將無法正確發音,因為此速記形式本身就是一個單字。 但您很容易就可以使用能修正此問題的 XAML 設定,且在實作上並不困難。