diff --git a/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj b/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj index 86047719..da3d3ed2 100644 --- a/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj +++ b/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj @@ -266,8 +266,20 @@ + + + + + + + + + + + + @@ -550,6 +562,42 @@ + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + diff --git a/BPASmartClient.CustomResource/Pages/Model/VoiceAPI.cs b/BPASmartClient.CustomResource/Pages/Model/VoiceAPI.cs new file mode 100644 index 00000000..c6330f28 --- /dev/null +++ b/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 msg { get; set; } = new ConcurrentQueue(); + + + 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); + } + } + } +} diff --git a/BPASmartClient.CustomResource/Vioce/0.wav b/BPASmartClient.CustomResource/Vioce/0.wav new file mode 100644 index 00000000..6f7f4a88 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/0.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/1.wav b/BPASmartClient.CustomResource/Vioce/1.wav new file mode 100644 index 00000000..91fc8059 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/1.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/2.wav b/BPASmartClient.CustomResource/Vioce/2.wav new file mode 100644 index 00000000..b5273f53 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/2.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/3.wav b/BPASmartClient.CustomResource/Vioce/3.wav new file mode 100644 index 00000000..bf830372 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/3.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/4.wav b/BPASmartClient.CustomResource/Vioce/4.wav new file mode 100644 index 00000000..4f13363b Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/4.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/5.wav b/BPASmartClient.CustomResource/Vioce/5.wav new file mode 100644 index 00000000..ee49ad3d Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/5.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/6.wav b/BPASmartClient.CustomResource/Vioce/6.wav new file mode 100644 index 00000000..f13dc262 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/6.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/7.wav b/BPASmartClient.CustomResource/Vioce/7.wav new file mode 100644 index 00000000..6ed2439b Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/7.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/8.wav b/BPASmartClient.CustomResource/Vioce/8.wav new file mode 100644 index 00000000..b3112554 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/8.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/9.wav b/BPASmartClient.CustomResource/Vioce/9.wav new file mode 100644 index 00000000..3bf21ce6 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/9.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/号用户取餐.wav b/BPASmartClient.CustomResource/Vioce/号用户取餐.wav new file mode 100644 index 00000000..1c2c4297 Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/号用户取餐.wav differ diff --git a/BPASmartClient.CustomResource/Vioce/请.wav b/BPASmartClient.CustomResource/Vioce/请.wav new file mode 100644 index 00000000..d87f370d Binary files /dev/null and b/BPASmartClient.CustomResource/Vioce/请.wav differ diff --git a/BPASmartClient.Device/BPASmartClient.Device.csproj b/BPASmartClient.Device/BPASmartClient.Device.csproj index 2cc1541a..f1da1ba7 100644 --- a/BPASmartClient.Device/BPASmartClient.Device.csproj +++ b/BPASmartClient.Device/BPASmartClient.Device.csproj @@ -8,6 +8,7 @@ + diff --git a/BPASmartClient.Device/Speech.cs b/BPASmartClient.Device/Speech.cs new file mode 100644 index 00000000..4f20d9b5 --- /dev/null +++ b/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() { } + + /// + /// 播放语音 + /// + /// + 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"; + } + + /// + /// 文字转音频 + /// + /// + /// + 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"; + } + + + } + + + + +} diff --git a/BPASmartClient.MorkS/Control_Morks.cs b/BPASmartClient.MorkS/Control_Morks.cs index 41e0aa39..8f91aba8 100644 --- a/BPASmartClient.MorkS/Control_Morks.cs +++ b/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(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.Data.StatisticsTime).Days != 0) - Json.Data.Count = 0; - Json.Data.StatisticsTime = DateTime.Now; - Json.Data.Count++; - Json.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.Data.StatisticsTime).Days != 0) + Json.Data.Count = 0; + Json.Data.StatisticsTime = DateTime.Now; + Json.Data.Count++; + Json.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 } - /// - /// 语音提醒取餐 - /// - /// - 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"); - } + ///// + ///// 语音提醒取餐 + ///// + ///// + //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 控制函数 diff --git a/BPASmartClient.MorkS/VoiceAPI.cs b/BPASmartClient.MorkS/VoiceAPI.cs index 99dcc433..9608396e 100644 --- a/BPASmartClient.MorkS/VoiceAPI.cs +++ b/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 msg { get; set; } = new ConcurrentQueue(); + + +// 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); +// } +// } +// } +//} diff --git a/BPASmartClient.MorkSUpgradedVer/Control_MorkSUpgradedVer.cs b/BPASmartClient.MorkSUpgradedVer/Control_MorkSUpgradedVer.cs index fef122c1..06b64a60 100644 --- a/BPASmartClient.MorkSUpgradedVer/Control_MorkSUpgradedVer.cs +++ b/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; diff --git a/BPASmartClient/App.xaml.cs b/BPASmartClient/App.xaml.cs index b5919965..4ef458a1 100644 --- a/BPASmartClient/App.xaml.cs +++ b/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(); } + /// /// 分屏显示 /// diff --git a/WpfApp1/MainWindow.xaml b/WpfApp1/MainWindow.xaml index 9e5f5e2b..2a8012a0 100644 --- a/WpfApp1/MainWindow.xaml +++ b/WpfApp1/MainWindow.xaml @@ -25,5 +25,6 @@ Height="30" Margin="300,24,400,381" Content="使能" Click="Button_Click_2" /> + diff --git a/WpfApp1/MainWindow.xaml.cs b/WpfApp1/MainWindow.xaml.cs index ea98f3da..3e03cd53 100644 --- a/WpfApp1/MainWindow.xaml.cs +++ b/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}"); + } } } diff --git a/WpfApp1/Speech.cs b/WpfApp1/Speech.cs new file mode 100644 index 00000000..d6a91b65 --- /dev/null +++ b/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 speechInfos = new ConcurrentQueue(); + + 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..."); + } + + /// + /// 播放语音 + /// + /// + 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"; + } + + /// + /// 文字转音频 + /// + /// + /// + 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; + } + +} diff --git a/WpfApp1/WpfApp1.csproj b/WpfApp1/WpfApp1.csproj index 4bf6fe58..e622e1af 100644 --- a/WpfApp1/WpfApp1.csproj +++ b/WpfApp1/WpfApp1.csproj @@ -7,6 +7,10 @@ true + + + +