ソースを参照

语音播报修改

master
pry 1年前
コミット
4c00ed8748
24個のファイルの変更539行の追加120行の削除
  1. +48
    -0
      BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj
  2. +86
    -0
      BPASmartClient.CustomResource/Pages/Model/VoiceAPI.cs
  3. バイナリ
     
  4. バイナリ
     
  5. バイナリ
     
  6. バイナリ
     
  7. バイナリ
     
  8. バイナリ
     
  9. バイナリ
     
  10. バイナリ
     
  11. バイナリ
     
  12. バイナリ
     
  13. バイナリ
     
  14. バイナリ
     
  15. +1
    -0
      BPASmartClient.Device/BPASmartClient.Device.csproj
  16. +72
    -0
      BPASmartClient.Device/Speech.cs
  17. +75
    -71
      BPASmartClient.MorkS/Control_Morks.cs
  18. +81
    -42
      BPASmartClient.MorkS/VoiceAPI.cs
  19. +3
    -0
      BPASmartClient.MorkSUpgradedVer/Control_MorkSUpgradedVer.cs
  20. +5
    -0
      BPASmartClient/App.xaml.cs
  21. +1
    -0
      WpfApp1/MainWindow.xaml
  22. +14
    -7
      WpfApp1/MainWindow.xaml.cs
  23. +149
    -0
      WpfApp1/Speech.cs
  24. +4
    -0
      WpfApp1/WpfApp1.csproj

+ 48
- 0
BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj ファイルの表示

@@ -266,8 +266,20 @@
<None Remove="Image\顶部线条.png" />
<None Remove="Image\顶部背景.png" />
<None Remove="Image\黑菠萝科技.png" />
<None Remove="Vioce\0.wav" />
<None Remove="Vioce\1.wav" />
<None Remove="Vioce\2.wav" />
<None Remove="Vioce\3.wav" />
<None Remove="Vioce\4.wav" />
<None Remove="Vioce\5.wav" />
<None Remove="Vioce\6.wav" />
<None Remove="Vioce\7.wav" />
<None Remove="Vioce\8.wav" />
<None Remove="Vioce\9.wav" />
<None Remove="Vioce\取餐通知.wav" />
<None Remove="Vioce\号用户取餐.wav" />
<None Remove="Vioce\电子提示音.wav" />
<None Remove="Vioce\请.wav" />
</ItemGroup>

<ItemGroup>
@@ -550,6 +562,42 @@
<Resource Include="Image\顶部线条.png" />
<Resource Include="Image\顶部背景.png" />
<Resource Include="Image\黑菠萝科技.png" />
<EmbeddedResource Include="Vioce\0.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\1.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\2.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\3.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\4.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\5.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\6.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\7.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\8.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\9.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\号用户取餐.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Vioce\请.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>


+ 86
- 0
BPASmartClient.CustomResource/Pages/Model/VoiceAPI.cs ファイルの表示

@@ -0,0 +1,86 @@
using BPASmartClient.Message;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BPASmartClient.CustomResource
{
public class VoiceAPI
{
public VoiceAPI()
{

}

static VoiceAPI()
{
BPA.Helper.ThreadManage.GetInstance().StartLong(new Action(() =>
{
while (msg.Count > 0)
{
if (msg.TryDequeue(out string str))
{
WaitMeaLSpeak(str);
}
}

Thread.Sleep(1000);

}), "语音播报", true);
}

[DllImport("winmm.dll")]
public static extern bool PlaySound(string pszSound, int hmod, int fdwSound);

private static ConcurrentQueue<string> msg { get; set; } = new ConcurrentQueue<string>();


public static void Speak(string s) => msg.Enqueue(s);


// 系统播放wav格式的文件
private static void m_SystemPlayWav(string strPlayFile)
{
try
{
if (strPlayFile.Trim() == "")
{ return; }//为空不放

string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
strPath = strPath + strPlayFile;

int SND_FILENAME = 0x00020000;
int SND_ASYNC = 0x0001;
PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.Message);
}
}

private static void WaitMeaLSpeak(string meal, int count = 1, int IntervalTime = 1000)
{
m_SystemPlayWav(@"Vioce\电子提示音.wav");
Thread.Sleep(1000);
for (int m = 0; m < count; m++)
{
m_SystemPlayWav(@"Vioce\请.wav");
Thread.Sleep(500);
for (int i = 0; i < meal.Length; i++)
{
string name = meal.Substring(i, 1);
m_SystemPlayWav($"Vioce\\{name}.wav");
Thread.Sleep(500);
}
m_SystemPlayWav(@"Vioce\号用户取餐.wav");
Thread.Sleep(1500 + IntervalTime);
}
}
}
}

バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


バイナリ
ファイルの表示


+ 1
- 0
BPASmartClient.Device/BPASmartClient.Device.csproj ファイルの表示

@@ -8,6 +8,7 @@

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.86" />
<PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.27.0" />
</ItemGroup>

<ItemGroup>


+ 72
- 0
BPASmartClient.Device/Speech.cs ファイルの表示

@@ -0,0 +1,72 @@
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;

namespace BPASmartClient.Device
{
public class Speech
{
public static uint SND_ASYNC = 0x0001;
public static uint SND_FILENAME = 0x0002;

[DllImport("winmm.dll", CharSet = CharSet.Auto)]
public static extern int mciSendString(string m_strCmd, string m_strReceive, int m_v1, int m_v2);

[DllImport("Kernel32", CharSet = CharSet.Auto)]
public static extern Int32 GetShortPathName(string path, StringBuilder shortPath, Int32 shortPathLength);

private volatile static Speech _Instance;
public static Speech GetInstance => _Instance ?? (_Instance = new Speech());
private Speech() { }

/// <summary>
/// 播放语音
/// </summary>
/// <param name="SpeakText"></param>
public void Speak(string SpeakText)
{
string path = $"{AppDomain.CurrentDomain.BaseDirectory}Sound";//设置音频文件保存路径
Directory.CreateDirectory(path);
string SpeakPath = $"{path}\\{SpeakText}.wav";
SpeakPath = SpeakPath.Replace(' ', '_');
if (!File.Exists(SpeakPath))
{
var res = SynthesizeAudioAsync(SpeakText, SpeakPath);
}
StringBuilder shortPath = new StringBuilder(200);
int result = GetShortPathName(SpeakPath, shortPath, shortPath.Capacity);
string shortName = shortPath.ToString();
mciSendString(@"close all", null, 0, 0);
mciSendString(@"open " + shortName + " alias song", null, 0, 0);
mciSendString(@"play song", null, 0, 0);
//return "22";
}

/// <summary>
/// 文字转音频
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private string SynthesizeAudioAsync(string text, string path)
{
var config = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2");
config.SpeechSynthesisLanguage = "zh-CN"; //config.SpeechSynthesisVoiceName = "";
using var audioConfig = AudioConfig.FromWavFileOutput(path);
using var synthesizer = new SpeechSynthesizer(config, audioConfig);
synthesizer.SpeakTextAsync(text).Wait();
//await Task.Delay(TimeSpan.FromSeconds(2));
return "1";
}


}




}

+ 75
- 71
BPASmartClient.MorkS/Control_Morks.cs ファイルの表示

@@ -23,6 +23,7 @@ using BPA.Models;
using System.Speech.Synthesis;
using System.Windows.Forms;
using System.Media;
using BPASmartClient.CustomResource;

namespace BPASmartClient.MorkS
{
@@ -317,65 +318,65 @@ namespace BPASmartClient.MorkS
{
EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
{
if (@event == null) return;
if (@event is DoOrderEvent order)
{
mORKS.doOrderEvents.Add(order);
if (order.MorkOrder.GoodBatchings == null) return;
if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId)) return;
OrderCount++;
if (DateTime.Now.Subtract(Json<OrderStatistics>.Data.StatisticsTime).Days != 0)
Json<OrderStatistics>.Data.Count = 0;
Json<OrderStatistics>.Data.StatisticsTime = DateTime.Now;
Json<OrderStatistics>.Data.Count++;
Json<OrderStatistics>.Save();
OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
if (order.MorkOrder.GoodBatchings.Count <= 1)
{
DeviceProcessLogShow($"数据解析失败,商品物料信息为空,请检查后台配置!");
return;
}
DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}");
mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId);
foreach (var item in order.MorkOrder.GoodBatchings)
{
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
if (ushort.TryParse(res.BatchingLoc, out ushort loc))
{
if (loc >= 1 && loc <= 5)
{
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { GoodName = order.MorkOrder.GoodsName, Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId });
}
else if (loc >= 10 && loc <= 11)
{
int index = 0;
if (recipeBoms != null)
{
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId);
index++;
}
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo()
{
BatchingId = res.BatchingId,
GoodName = order.MorkOrder.GoodsName,
Loc = ushort.Parse(res.BatchingLoc),
SuborderId = order.MorkOrder.SuborderId,
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0
});
}
}
}
else
{
DeviceProcessLogShow($"数据解析失败,未找到商品信息,请检查后台配置!");
}
}
}
});
if (@event == null) return;
if (@event is DoOrderEvent order)
{
mORKS.doOrderEvents.Add(order);
if (order.MorkOrder.GoodBatchings == null) return;
if (mORKS.HistorySuborderId.Contains(order.MorkOrder.SuborderId)) return;
OrderCount++;
if (DateTime.Now.Subtract(Json<OrderStatistics>.Data.StatisticsTime).Days != 0)
Json<OrderStatistics>.Data.Count = 0;
Json<OrderStatistics>.Data.StatisticsTime = DateTime.Now;
Json<OrderStatistics>.Data.Count++;
Json<OrderStatistics>.Save();
OrderChange(order.MorkOrder.SuborderId, ORDER_STATUS.WAIT);
if (order.MorkOrder.GoodBatchings.Count <= 1)
{
DeviceProcessLogShow($"数据解析失败,商品物料信息为空,请检查后台配置!");
return;
}
DeviceProcessLogShow($"接收到{OrderCount}次订单,订单ID:{order.MorkOrder.SuborderId}");
mORKS.HistorySuborderId.Add(order.MorkOrder.SuborderId);
foreach (var item in order.MorkOrder.GoodBatchings)
{
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
if (ushort.TryParse(res.BatchingLoc, out ushort loc))
{
if (loc >= 1 && loc <= 5)
{
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { GoodName = order.MorkOrder.GoodsName, Loc = ushort.Parse(res.BatchingLoc), SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId });
}
else if (loc >= 10 && loc <= 11)
{
int index = 0;
if (recipeBoms != null)
{
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId);
index++;
}
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo()
{
BatchingId = res.BatchingId,
GoodName = order.MorkOrder.GoodsName,
Loc = ushort.Parse(res.BatchingLoc),
SuborderId = order.MorkOrder.SuborderId,
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0
});
}
}
}
else
{
DeviceProcessLogShow($"数据解析失败,未找到商品信息,请检查后台配置!");
}
}
}
});
}

public override void MainTask()
@@ -663,7 +664,6 @@ namespace BPASmartClient.MorkS
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】制作完成");
mORKS.CookCompleteFlatBit = true;
mORKS.OutNoodleing = false;
WaitMeaLSpeak(mORKS.OutMealName);
}

//加汤
@@ -678,6 +678,8 @@ namespace BPASmartClient.MorkS
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE);
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成");
ResetCookComplete();
DeviceProcessLogShow($"出餐订单名称【{mORKS.OutMealName}】");
VoiceAPI.Speak(mORKS.OutMealName);
mORKS.CookCompleteFlatBit = false;
mORKS.OutMealId = string.Empty;
mORKS.OutMealName = string.Empty;
@@ -706,17 +708,19 @@ namespace BPASmartClient.MorkS


}
/// <summary>
/// 语音提醒取餐
/// </summary>
/// <param name="meal"></param>
private void WaitMeaLSpeak(string meal)
{
VoiceAPI.m_SystemPlayWav(@"Vioce\电子提示音.wav");
Thread.Sleep(1000);
if (meal != null) mORKS.speech.Speak(meal);
VoiceAPI.m_SystemPlayWav(@"Vioce\取餐通知.wav");
}
///// <summary>
///// 语音提醒取餐
///// </summary>
///// <param name="meal"></param>
//private void WaitMeaLSpeak(string meal)
//{
// VoiceAPI.m_SystemPlayWav(@"Vioce\电子提示音.wav");
// Thread.Sleep(1000);
// if (meal != null) mORKS.speech.Speak(meal);
// VoiceAPI.m_SystemPlayWav(@"Vioce\取餐通知.wav");
//}



#region PLC 控制函数



+ 81
- 42
BPASmartClient.MorkS/VoiceAPI.cs ファイルの表示

@@ -1,42 +1,81 @@
using BPASmartClient.Message;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkS
{
public class VoiceAPI
{
public VoiceAPI()
{
}
[DllImport("winmm.dll")]
public static extern bool PlaySound(string pszSound, int hmod, int fdwSound);


// 系统播放wav格式的文件
public static void m_SystemPlayWav(string strPlayFile)
{
try
{
if (strPlayFile.Trim() == "")
{ return; }//为空不放

string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
strPath = strPath + strPlayFile;

int SND_FILENAME = 0x00020000;
int SND_ASYNC = 0x0001;
PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.Message);
}
}
}
}
//using BPASmartClient.Message;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Linq;
//using System.Runtime.InteropServices;
//using System.Text;
//using System.Threading;
//using System.Threading.Tasks;

//namespace BPASmartClient.MorkS
//{
// public class VoiceAPI
// {
// public VoiceAPI()
// {
// BPA.Helper.ThreadManage.GetInstance().StartLong(new Action(() =>
// {
// while (msg.Count > 0)
// {
// if (msg.TryDequeue(out string str))
// {
// WaitMeaLSpeak(str);
// }
// }

// Thread.Sleep(1000);

// }), "语音播报", true);
// }

// [DllImport("winmm.dll")]
// public static extern bool PlaySound(string pszSound, int hmod, int fdwSound);

// private static ConcurrentQueue<string> msg { get; set; } = new ConcurrentQueue<string>();


// public static void Speak(string s) => msg.Enqueue(s);


// // 系统播放wav格式的文件
// private static void m_SystemPlayWav(string strPlayFile)
// {
// try
// {
// if (strPlayFile.Trim() == "")
// { return; }//为空不放

// string strPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
// strPath = strPath + strPlayFile;

// int SND_FILENAME = 0x00020000;
// int SND_ASYNC = 0x0001;
// PlaySound(strPath, 0, SND_ASYNC | SND_FILENAME);//播放音乐
// }
// catch (Exception ex)
// {
// MessageLog.GetInstance.ShowEx(ex.Message);
// }
// }

// private void WaitMeaLSpeak(string meal, int count = 1, int IntervalTime = 1000)
// {
// m_SystemPlayWav(@"Vioce\电子提示音.wav");
// Thread.Sleep(1000);
// for (int m = 0; m < count; m++)
// {
// m_SystemPlayWav(@"Vioce\请.wav");
// Thread.Sleep(500);
// for (int i = 0; i < meal.Length; i++)
// {
// string name = meal.Substring(i, 1);
// m_SystemPlayWav($"Vioce\\{name}.wav");
// Thread.Sleep(500);
// }
// m_SystemPlayWav(@"Vioce\号用户取餐.wav");
// Thread.Sleep(1500 + IntervalTime);
// }
// }
// }
//}

+ 3
- 0
BPASmartClient.MorkSUpgradedVer/Control_MorkSUpgradedVer.cs ファイルの表示

@@ -22,6 +22,7 @@ using BPASmartClient.Model.小炒机;
using BPA.Models;
using System.Windows.Forms;
using System.Media;
using BPASmartClient.CustomResource;
//using BPA.Helper;

namespace BPASmartClient.MorkSUpgradedVer
@@ -651,6 +652,8 @@ namespace BPASmartClient.MorkSUpgradedVer
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE);
DeviceProcessLogShow($"订单【{mORKS.OutMealId}】取餐完成");
WriteData("M10.1", false);
DeviceProcessLogShow($"出餐订单名称【{mORKS.OutMealName}】");
VoiceAPI.Speak(mORKS.OutMealName);
mORKS.CookCompleteFlatBit = false;
mORKS.OutMealId = string.Empty;
mORKS.OutMealName = string.Empty;


+ 5
- 0
BPASmartClient/App.xaml.cs ファイルの表示

@@ -1,5 +1,7 @@
using BPA.Message;
using BPA.Message.Enum;
using BPASmartClient.CustomResource;
using BPASmartClient.CustomResource.Pages.Model;
using BPASmartClient.Helper;
using BPASmartClient.Message;
using BPASmartClient.Model;
@@ -10,6 +12,8 @@ using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Speech.Synthesis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
@@ -33,6 +37,7 @@ namespace BPASmartClient
NoCompleteOrderInit();
}


/// <summary>
/// 分屏显示
/// </summary>


+ 1
- 0
WpfApp1/MainWindow.xaml ファイルの表示

@@ -25,5 +25,6 @@
Height="30"
Margin="300,24,400,381"
Content="使能" Click="Button_Click_2" />
<TextBox Name="text" Height="30" Margin="36,80,400,325"/>
</Grid>
</Window>

+ 14
- 7
WpfApp1/MainWindow.xaml.cs ファイルの表示

@@ -88,24 +88,31 @@ namespace WpfApp1

}

JaKaHelper jaKaHelper = new JaKaHelper();

private void Button_Click(object sender, RoutedEventArgs e)
{
jaKaHelper.Conn("192.168.0.12");
MessageBox.Show($"连接成功,{jaKaHelper.rshd}");

Speech.GetInstance.aa("请0001号客户到1号窗口取餐");
//Task.Run(() =>
//{
// Speech.GetInstance.Speak($"请0001号客户到1号窗口取餐");
//});
//Speech.GetInstance.SpeechSpeak(new SpeechInfo()
//{
// Text = text.Text,
// time = 10000
//});
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
jaKaHelper.Power_On();
MessageBox.Show($"上电成功,{jaKaHelper.rshd}");

}

private void Button_Click_2(object sender, RoutedEventArgs e)
{
jaKaHelper.Enable_robot();
MessageBox.Show($"使能成功,{jaKaHelper.rshd}");

}
}
}

+ 149
- 0
WpfApp1/Speech.cs ファイルの表示

@@ -0,0 +1,149 @@
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Threading;
using System.Windows.Documents;

namespace WpfApp1
{
public class Speech
{
public static uint SND_ASYNC = 0x0001;
public static uint SND_FILENAME = 0x0002;

[DllImport("winmm.dll", CharSet = CharSet.Auto)]
public static extern int mciSendString(string m_strCmd, string m_strReceive, int m_v1, int m_v2);

[DllImport("Kernel32", CharSet = CharSet.Auto)]
public static extern Int32 GetShortPathName(string path, StringBuilder shortPath, Int32 shortPathLength);

private volatile static Speech _Instance;
public static Speech GetInstance => _Instance ?? (_Instance = new Speech());
private Speech()
{
//Task.Factory.StartNew(() =>
//{
// while (true)
// {
// while (speechInfos.Count > 0)
// {
// if (speechInfos.TryDequeue(out SpeechInfo si))
// {
// for (int i = 0; i < si.Count; i++)
// {
// Speak(si.Text);
// Thread.Sleep(si.time);
// }
// }
// }
// Thread.Sleep(1000);
// }
//});
}
private ConcurrentQueue<SpeechInfo> speechInfos = new ConcurrentQueue<SpeechInfo>();

public void SpeechSpeak(SpeechInfo si)
{
speechInfos.Enqueue(si);
}

private void OutputSpeechSynthesisResult(SpeechSynthesisResult speechSynthesisResult, string text)
{
switch (speechSynthesisResult.Reason)
{
case ResultReason.SynthesizingAudioCompleted:
Console.WriteLine($"Speech synthesized for text: [{text}]");
break;
case ResultReason.Canceled:
var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult);
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
}
break;
default:
break;
}
}

public async void aa(string text)
{
var speechConfig = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2");

// The language of the voice that speaks.
speechConfig.SpeechSynthesisVoiceName = "zh-CN";

using (var speechSynthesizer = new SpeechSynthesizer(speechConfig))
{
// Get text from the console and synthesize to the default speaker.
Console.WriteLine("Enter some text that you want to speak >");
//string text = Console.ReadLine();

var speechSynthesisResult = await speechSynthesizer.SpeakTextAsync(text);
OutputSpeechSynthesisResult(speechSynthesisResult, text);
}

Console.WriteLine("Press any key to exit...");
}

/// <summary>
/// 播放语音
/// </summary>
/// <param name="SpeakText"></param>
public void Speak(string SpeakText)
{
string path = $"{AppDomain.CurrentDomain.BaseDirectory}Sound";//设置音频文件保存路径
Directory.CreateDirectory(path);
string SpeakPath = $"{path}\\{SpeakText}.wav";
SpeakPath = SpeakPath.Replace(' ', '_');
if (!File.Exists(SpeakPath))
{
var res = SynthesizeAudioAsync(SpeakText, SpeakPath);
}
StringBuilder shortPath = new StringBuilder(200);
int result = GetShortPathName(SpeakPath, shortPath, shortPath.Capacity);
string shortName = shortPath.ToString();
mciSendString(@"close all", null, 0, 0);
mciSendString(@"open " + shortName + " alias song", null, 0, 0);
mciSendString(@"play song", null, 0, 0);
//return "22";
}

/// <summary>
/// 文字转音频
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private string SynthesizeAudioAsync(string text, string path)
{
var config = SpeechConfig.FromSubscription("b88f6907c8f64075a6169dc4d7dff65a", "chinanorth2");
config.SpeechSynthesisLanguage = "zh-CN"; //config.SpeechSynthesisVoiceName = "";
using var audioConfig = AudioConfig.FromWavFileOutput(path);
using var synthesizer = new SpeechSynthesizer(config, audioConfig);
synthesizer.SpeakTextAsync(text).Wait();
//await Task.Delay(TimeSpan.FromSeconds(2));
return "1";
}


}


public class SpeechInfo
{
public string Text { get; set; }
public int Count { get; set; } = 1;
public int time { get; set; } = 2000;
}

}

+ 4
- 0
WpfApp1/WpfApp1.csproj ファイルの表示

@@ -7,6 +7,10 @@
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CognitiveServices.Speech" Version="1.19.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.JakaRobot\BPASmartClient.JakaRobot.csproj" />
<ProjectReference Include="..\BPASmartClient.S7Net\BPASmartClient.S7Net.csproj" />


読み込み中…
キャンセル
保存