使用朗讀程式時的音訊描述
語音合成自機器人語音和生硬的發音以來,已有長足的進步。 「朗讀程式」在 Windows 上提供內建的螢幕助讀程式,對於視障使用者是絕佳的助力。 但我們必須設定應用程式,才能好好地利用。
在本單元中,您將了解:
- 如何開啟「朗讀程式」,並在沒有任何特殊旁白屬性的應用程式上測試。
- 如何為應用程式新增特殊屬性以改善旁白的流暢度。
- 如何清除我們字串和訊息中的一些凌亂現象,使其聽起來正確無誤。
- 該旁白中的缺口可由自訂的語音合成器執行個體來填補。
朗讀程式
確定工程計算機應用程式已啟動並正在執行。 我們將必須變更 XAML 和程式碼後置,以確保為使用「朗讀程式」的使用者提供最佳體驗。
開啟並測試朗讀程式
- 在 Windows 搜尋列中輸入「朗讀程式設定」,然後選取 [輕鬆存取朗讀程式設定]。 這會顯示以下畫面。
開啟 [使用朗讀程式] 開關,然後將此視窗最小化。 在應用程式之間切換及開發軟體時,旁白可能較為煩人,因此您可以讓此視窗保持開啟。 如此一來,您將能夠在對程式碼進行變更時將其關閉,然後再重新啟用它來進行測試。
醒目提示計算機的 [顯示常數] 按鈕,並注意「朗讀程式」如何處理描述:顯示常數 (暫停) 按鈕。 我們想要協助「朗讀程式」讓其描述儘可能有幫助,這意謂著要處理其內建功能。 這些功能的其中一項是宣告 UI 元素的類型 (顯然地,在此案例中為「按鈕」)。
現在,選取 [Sqrt] 按鈕並注意發音。 "Sqrt" 是數學中書寫平方根的常見速記形式,但「朗讀程式」並未設定此項目。 同樣地,也不會認得 Sin、Asin、Acos 等,特別是當特製化詞彙也可以用一般英文單字的形式來發音時。 我們將必須改善「朗讀程式」讓這些發音正確。
選取各種其他按鈕 (運算、數字),並注意旁白的處理情況。 有些部分設定完善,有些部分則需要改進。
返回 [顯示常數] 按鈕並選取,然後選取各種常數本身並記下旁白。 選取數個常數並評估發音的實用性。 在我們有些懶惰而輸入速記 (例如 "Gms"、"Ozs"、"Cms" 等) 的情況中,發音並不實用。 如果您的使用者無法理解速記詞彙,速記詞彙就不實用。
最後,輸入下列計算:SqrtAtan0.5。 在不選取 = 的情況下,選取此計算的文字顯示,並注意「朗讀程式」處理的方式。 現在,按下 =,然後再次選取文字顯示。 幸好,「朗讀程式」很擅長處理長數字。
開啟「朗讀程式」的設定視窗,並暫時先關閉旁白。
就我們使用計算機來進行的「朗讀程式」測試而言,顯然有幾個問題要處理:數學函式的發音、數學運算的發音,以及常數清單的清晰度。
讓文字字串變得自然
在本節中,我們會改善「朗讀程式」,使其在使用計算機的任何功能時能夠聽起來自然。 確定 Visual Studio 已搭配工程計算機專案一起開啟。
- 當 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="Π"
<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"
/>
接著,讓我們處理常數清單的凌亂現象。 開啟
MainPage.xaml.cs
檔案,然後找出 LoadConstants 方法。以下列內容取代字串清單,請注意所有速記詞彙是如何被普通寫法所取代的。
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"
};
現在,執行應用程式並開啟旁白。 更徹底地說,您將必須醒目提示每個數學函式、運算及常數,「朗讀程式」才會加以閱讀。 這些項目現在是否都聽起來自然且可理解? 如果不是,請對字串進行更正,或是新增或調整 AutomationProperites.Name 屬性。
嘗試輸入含有括弧和數個數學函式 (是否具有任何數學意義並不重要) 的計算,然後醒目提示文字顯示。 我們將必須進行一些編碼來修正此問題。
新增程式碼以協助朗讀程式
幸虧有我們的變更,「朗讀程式」現在對 UI 元素發揮極佳的作用。 不過,語音訊息會在幾個案例中提供幫助,但觸發事件不是 UI 元素。 此外,我們想要改善計算的發音。 在這裡,我們將新增語音合成器來處理錯誤訊息,以及一些簡短的程式碼變更來處理計算。
- 開啟 MainPage.xaml.cs 檔案,然後更新 using 陳述式以包含下列內容。
using System.Threading.Tasks;
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Automation;
- 將下列內容新增至全域變數清單。
// Declare variables needed for speech output.
SpeechSynthesizer speech;
MediaElement mediaElement;
- 在 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();
}
- 理想的做法是新增切換開關或其他 UI 元素,以便讓使用者能夠決定是否想要旁白說明。 在
MainPage.xaml
檔案中,於 listConstants 項目 (靠近最後的 UI 元素項目) 上方,新增下列內容。
<ToggleSwitch x:Name="ToggleNarration"
Margin="551,407,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Header="Narration help"
IsOn="True" />
注意
請務必在 XAML 檔案中依正確順序排列這些元素。 如果順序不正確,您就會獲得顯現效果,例如此項目出現在常數清單中。
- 回到
MainPage.xaml.cs
中,新增 SayAsync 方法以說出任何指定的文字行。 請注意我們剛才新增之 speech 和 mediaElement 變數的使用,以及這是一項非同步工作。
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();
}
}
- 我們現在必須新增對 SayAsync 方法的呼叫。 從 CalculateAsync 方法的 catch 區塊開始著手。
catch
{
TextError.Visibility = Visibility.Visible;
CopyCalculation(backupCalculation, calculation);
await SayAsync("Oops, there is an error in your calculation.");
}
- 在仍位於 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}");
- 現在,找出 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;
執行應用程式來測試您的程式碼。 確定「朗讀程式」和 [朗讀程式說明] 切換按鈕已開啟。 輸入無意義的計算 (例如 Sqrt (,這會顯示成「平方根左括弧」)。 選取 = 時,您是否收到自然發音錯誤訊息? 請注意相同的語音是如何用於您的 SayAsync 方法和「朗讀程式」,這可讓音訊體驗保持流暢。
完成計算,並注意顯示器中已將文字拼出。 如果您接著醒目提示顯示器,「朗讀程式」就會清楚讀出該計算。 有些選取作業可能仍然有點具挑戰性,但這個已經夠好,足以提供更便於使用的體驗。
將新增語音合成選項新增這應用程式,確實可以填補旁白中的任何缺口。 這是應用程式高度專屬的,因此應優先考慮讓 UI 元素變得方便「朗讀程式」使用。 您所需的可能只是最少量的額外旁白,如這裡的案例所示。
單元摘要
在本單元中,我們已了解語音合成現在非常棒,至少在與其過去相比的情況下是如此。 我們已了解 Windows 隨附相當多的免費旁白,只要開啟「朗讀程式」即可使用。 不過,我們也了解到當使用「朗讀程式」時,我們訊息字串中的凌亂現象立即就變得很明顯。 對於一個便於使用的應用程式來說,我們必須確定我們的訊息字串乾淨且完整。
我們還了解到「朗讀程式」並不完美,在某些情況下需要協助。 例如,"sin" 這類數學單字將無法正確發音,因為此速記形式本身就是一個單字。 但您很容易就可以使用能修正此問題的 XAML 設定,且在實作上並不困難。