• C#语音播报(通过CoreAudioAPI完成对扬声器的控制)


    1,效果:

    • 作用:
    1. 可对当前内容(例如此例中的重量信息)进行语音合成播报 。
    2. 可设置系统扬声器音量与状态(是否静音),同时根据扬声器状态同步更新当前控件状态与值,实现强制PC扬声器按照指定的音量进行播报,杜绝人为静音的可能。

    2,引入相关程序集,命名空间。

    • 程序集

            微软语音合成程序集:System.Speech

            第三方程序集:CoreAudioAPI(为方便使用,进行了部分修改包装)

    • 命名空间:
    1. using System.Speech.Synthesis;
    2. using CoreAudioAPIs;

    3,代码:

    1. <Grid>
    2. <Grid.ColumnDefinitions>
    3. <ColumnDefinition Width="112*"/>
    4. <ColumnDefinition Width="320*"/>
    5. <ColumnDefinition Width="85*"/>
    6. Grid.ColumnDefinitions>
    7. <Grid.RowDefinitions>
    8. <RowDefinition Height="59*"/>
    9. <RowDefinition Height="51*"/>
    10. <RowDefinition Height="77*"/>
    11. <RowDefinition Height="43*"/>
    12. <RowDefinition Height="32*"/>
    13. <RowDefinition Height="58*"/>
    14. Grid.RowDefinitions>
    15. <TextBlock Text="重量:" FontSize="32" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,8">TextBlock>
    16. <TextBox Grid.Column="1" VerticalContentAlignment="Center" x:Name="txtWeight" FontSize="30">TextBox>
    17. <ComboBox x:Name="combo01" Grid.Column="2" VerticalContentAlignment="Center" FontSize="32">
    18. <ComboBoxItem FontSize="32" IsSelected="True">KGComboBoxItem>
    19. <ComboBoxItem FontSize="32">TComboBoxItem>
    20. <ComboBoxItem FontSize="32">GComboBoxItem>
    21. ComboBox>
    22. <Button x:Name="btnPlay" Content="播报" FontSize="25" Grid.Row="1" Grid.Column="1" Margin="20,3" Click="btnPlay_Click">Button>
    23. <Grid Grid.Row="2" Grid.Column="1">
    24. <Grid.RowDefinitions>
    25. <RowDefinition >RowDefinition>
    26. <RowDefinition >RowDefinition>
    27. Grid.RowDefinitions>
    28. <TextBlock x:Name="txtStatus" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Status}" Foreground="{Binding StatusForeground}" FontSize="16">TextBlock>
    29. <TextBlock FontSize="24" Grid.Row="1" Text="PC扬声器设置" HorizontalAlignment="Center" VerticalAlignment="Bottom">TextBlock>
    30. Grid>
    31. <TextBlock Text="播放音量:" Grid.Row="3" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,11,0,10">TextBlock>
    32. <Slider Grid.Row="3" Grid.Column="1" ValueChanged="slider01_ValueChanged" Minimum="0" VerticalAlignment="Center" Maximum="100" x:Name="slider01" SmallChange="1" LargeChange="5" TickPlacement="BottomRight" IsSnapToTickEnabled="True" Margin="0,11,0,10">Slider>
    33. <TextBlock Grid.Row="3" Grid.Column="2" FontSize="16" VerticalAlignment="Center" Margin="10,0" DockPanel.Dock="Left" Text="{Binding ElementName=slider01 ,Path=Value}">TextBlock>
    34. <CheckBox Grid.Row="4" x:Name="muteCheck01" Click="muteCheck01_Checked" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="16">静音CheckBox>
    35. Grid>
    1. public partial class MainWindow : Window, System.ComponentModel.INotifyPropertyChanged
    2. {
    3. VolumeControl volumeControl = new VolumeControl();
    4. public event PropertyChangedEventHandler PropertyChanged;
    5. SpeechSynthesizer speeker = new SpeechSynthesizer();
    6. public MainWindow()
    7. {
    8. InitializeComponent();
    9. volumeControl.VolumeStateChange += VolumeControl_VolumeStateChange;
    10. slider01.Value = Volume;
    11. muteCheck01.IsChecked = Mute;
    12. this.DataContext = this;
    13. Status = "准备就绪!";
    14. StatusForeground = new SolidColorBrush(Colors.Green);
    15. }
    16. public bool Mute
    17. {
    18. get
    19. {
    20. return volumeControl.IsMuted;
    21. }
    22. set
    23. {
    24. volumeControl.IsMuted = value;
    25. OnPropertyChanged(nameof(Mute));
    26. }
    27. }
    28. public int Volume
    29. {
    30. get
    31. {
    32. return volumeControl.Volume;
    33. }
    34. set
    35. {
    36. volumeControl.Volume = value;
    37. OnPropertyChanged(nameof(Volume));
    38. }
    39. }
    40. string status;
    41. public string Status
    42. {
    43. get
    44. {
    45. return status;
    46. }
    47. set
    48. {
    49. status = value;
    50. OnPropertyChanged(nameof(Status));
    51. }
    52. }
    53. Brush statusForeground = new SolidColorBrush(Colors.Black);
    54. public Brush StatusForeground
    55. {
    56. set
    57. {
    58. statusForeground = value;
    59. OnPropertyChanged(nameof(statusForeground));
    60. }
    61. get
    62. {
    63. return statusForeground;
    64. }
    65. }
    66. private void VolumeControl_VolumeStateChange(bool mute, int volumeValue)
    67. {
    68. Dispatcher.Invoke(() =>
    69. {
    70. //移除注册,否则更新控件时将出现循环,这也是不用绑定的原因
    71. slider01.ValueChanged -= slider01_ValueChanged;
    72. muteCheck01.Checked -= muteCheck01_Checked;
    73. this.muteCheck01.IsChecked = mute;
    74. slider01.Value = volumeValue;
    75. //重新注册
    76. slider01.ValueChanged += slider01_ValueChanged;
    77. muteCheck01.Checked += muteCheck01_Checked;
    78. });
    79. }
    80. private void slider01_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    81. {
    82. Volume = (int)slider01.Value;
    83. }
    84. private void muteCheck01_Checked(object sender, RoutedEventArgs e)
    85. {
    86. Mute = muteCheck01.IsChecked.HasValue ? muteCheck01.IsChecked.Value : false;
    87. }
    88. private void btnPlay_Click(object sender, RoutedEventArgs e)
    89. {
    90. PromptBuilder builder = new PromptBuilder();
    91. builder.AppendText("当前重量:", PromptVolume.Loud);
    92. builder.AppendBreak(PromptBreak.Medium);
    93. PromptStyle style = new PromptStyle();
    94. style.Emphasis = PromptEmphasis.Strong;
    95. style.Rate = PromptRate.Medium;
    96. style.Volume = PromptVolume.ExtraLoud;
    97. builder.StartStyle(style);
    98. builder.AppendTextWithHint(txtWeight.Text.Trim(), SayAs.NumberCardinal);
    99. builder.EndStyle();
    100. string str = "";
    101. switch (combo01.Text)
    102. {
    103. case "KG":
    104. str = "千克";
    105. break;
    106. case "G":
    107. str = "克";
    108. break;
    109. default:
    110. str = "吨";
    111. break;
    112. }
    113. builder.AppendBreak(PromptBreak.Small);
    114. builder.AppendText(str, PromptEmphasis.Strong);
    115. SpeechBroadcasting(builder);
    116. }
    117. async void SpeechBroadcasting(PromptBuilder builder)
    118. {
    119. Status = "播报中.....";
    120. StatusForeground = new SolidColorBrush(Colors.Orange);
    121. await Task.Run(() =>
    122. {
    123. //耗时长
    124. speeker.Speak(builder);
    125. }).ContinueWith(t =>
    126. {
    127. Dispatcher.Invoke(() =>
    128. {
    129. Status = "播报完成!";
    130. StatusForeground = new SolidColorBrush(Colors.BlueViolet);
    131. });
    132. System.Threading.Thread.Sleep(1000);
    133. });
    134. Status = "准备就绪!";
    135. StatusForeground = new SolidColorBrush(Colors.Green);
    136. }
    137. void OnPropertyChanged(string propertyName)
    138. {
    139. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    140. }
    141. }

    4,Demo链接:

    https://download.csdn.net/download/lingxiao16888/89298014

  • 相关阅读:
    R语言实现:统计学及计量专业中的多种平均值计算方式
    webpack + vite 前端构建工具
    反向迭代器------封装的力量
    取Dataset子集(pytorch)
    【爬虫】8.1. 深度使用tesseract-OCR技术识别图形验证码
    C. Fibonacci Words-April Fools Day Contest 2021
    SpringBoot 3.2.5 引入Swagger(OpenApi)
    【Java基础】Java基础知识
    GBase8s数据库INTO table 子句
    3D视觉学习路线 + 路线规划
  • 原文地址:https://blog.csdn.net/lingxiao16888/article/details/138747581