欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

金额数字语音播报

程序员文章站 2022-04-29 15:40:00
最近在做一个语音播报功能,开始是用Speech做的。感觉效果还不错,直接可以文字转语音,然后播报出来。但是后面再测试机器上,发现播放的是英语,搜索过后发现需要语音支持。还有可能有些系统整个语音功能都可能被阉割了,所以只能另外想办法了。 另起思路:其实只有数字变化的,其他语音文字一般是固定的。那么我们 ......

最近在做一个语音播报功能,开始是用speech做的。感觉效果还不错,直接可以文字转语音,然后播报出来。但是后面再测试机器上,发现播放的是英语,搜索过后发现需要语音支持。还有可能有些系统整个语音功能都可能被阉割了,所以只能另外想办法了。

另起思路:其实只有数字变化的,其他语音文字一般是固定的。那么我们可以把0-9单独录制为10个wav文件,然后把金额数字拆分为char,播放对应的文件不就ok了吗!说干就干:

金额数字语音播报

 先把需要的文件录制出来,具体实现代码如下:

task.run(() =>
            {
                decimal payamt = 123.56m;
                string paystring = payamt.tostring("f2");
                //播放固定的前缀语音“龙支付收款”
                using (soundplayer simplesound = new soundplayer($"{application.startuppath}\\auido\\ccb.wav"))
                {
                    simplesound.play();
                    //这里需要等待,具体时间为语音文件的长度
                    system.threading.thread.sleep(1450);
                    foreach (var item in paystring.toarray())
                    {
                        //播放具体数字
                        simplesound.soundlocation = $"{application.startuppath}\\auido\\{item}.wav";
                        simplesound.play();
                        system.threading.thread.sleep(400);
                    }
                    //播放元
                    simplesound.soundlocation = $"{application.startuppath}\\auido\\yuan.wav";
                    simplesound.play();
                }
            });

看起来功能已经实现了,只是听起来感觉有点迟钝的样纸,但是先这样吧。提交给测试了,后面测试过来说这个声音怎么没有单位啊,能不能加上单位呢。嗯!!!可以。

于是开始实现数字播报加单位,先去找了段数字转大字文字的功能代码参考了下,其实逻辑差不多,然后稍微改造下就ok了,思路还是一样的,先录制语音文件,需要增加单位语音文件:十百千万

金额数字语音播报

 然后把需要转换的数字tostring("f2"),这里不要转n2,不然会有逗号分隔的,我这里设计只支持到小于一亿元的播报。

直接上代码

public void payauido(decimal paymoney)
        { 
            if (paymoney >= 100000000 || paymoney == 0)
            {
                return;
            }
            task.run(() =>
            {
                list<string> payauidourls = new list<string>();
                string paystring = paymoney.tostring("f2");
                //如果小于11位,则补零
                if (paystring.length < 11)
                {
                    paystring = paystring.padleft(11, '0');
                }
                string paywan = paystring.substring(0, 4);//取得'万'单元
                string payyuan = paystring.substring(4, 4);//取得'元'单元
                string paynum = paystring.substring(9, 2);//取得小数部分

                //处理万
                list<string> payauidourlswan = convert(paywan);
                if (payauidourlswan.count > 0)
                { 
                    payauidourlswan.add($"{application.startuppath}\\auido\\wan.wav");
                }

                //处理元
                list<string> payauidourlsyuan = convert(payyuan);

                //元第一个字符是否为‘零’
                if (payauidourlswan.count > 0 && payauidourlsyuan.count > 0 && paystring[4] == '0')
                {
                    payauidourlswan.add($"{application.startuppath}\\auido\\0.wav");
                }
                payauidourls.addrange(payauidourlswan);
                payauidourls.addrange(payauidourlsyuan);

                //处理小数位
                if (paynum != "00")
                {
                    //如果只有小数,则添加‘零’
                    if (payauidourls.count == 0)
                    {
                        payauidourls.add($"{application.startuppath}\\auido\\0.wav");
                    }
                    payauidourls.add($"{application.startuppath}\\auido\\..wav");
                    payauidourls.add($"{application.startuppath}\\auido\\{paynum[0]}.wav");
                    //如果最后一位为‘零’,则不需要播报
                    if (paynum[1] != '0')
                    {
                        payauidourls.add($"{application.startuppath}\\auido\\{paynum[1]}.wav");
                    }
                }

                //添加元
                payauidourls.add($"{application.startuppath}\\auido\\yuan.wav");
                //播放“龙支付收款”
                using (soundplayer simplesound = new soundplayer($"{application.startuppath}\\auido\\ccb.wav"))
                { 
                    simplesound.play();
                    system.threading.thread.sleep(1450); 
                    foreach (string payauidourl in payauidourls)
                    {
                        //播放每个数字
                        simplesound.soundlocation = payauidourl; 
                        simplesound.play();
                        system.threading.thread.sleep(400); 
                    }
                }
            });
        }

        /// <summary>
        /// 每四位数转换一次
        /// </summary>
        /// <param name="payvalue">当前转换的金额</param>
        /// <returns></returns>
        public list<string> convert(string payvalue)
        {
            list<string> payauidos = new list<string>();
            //如果为四个零,则不需要播报
            if (payvalue == "0000")
            {
                return payauidos;
            }

            char tmp0 = payvalue[0];
            char tmp1 = payvalue[1];
            char tmp2 = payvalue[2];
            char tmp3 = payvalue[3];
            //千位
            if (tmp0 != '0')
            {
                payauidos.add($"{application.startuppath}\\auido\\{tmp0}.wav");
                payauidos.add($"{application.startuppath}\\auido\\qian.wav");
            }
            else
            {
                payauidos.add($"{application.startuppath}\\auido\\0.wav");
            }
            //百位
            if (tmp1 != '0')
            {
                payauidos.add($"{application.startuppath}\\auido\\{tmp1}.wav");
                payauidos.add($"{application.startuppath}\\auido\\bai.wav");
            }
            else
            {
                //只添加一个零
                if (tmp0 != '0')
                {
                    payauidos.add($"{application.startuppath}\\auido\\0.wav");
                }
            }
            //十位
            if (tmp2 != '0')
            {
                payauidos.add($"{application.startuppath}\\auido\\{tmp2}.wav");
                payauidos.add($"{application.startuppath}\\auido\\shi.wav");
            }
            else
            {
                //只添加一个零
                if (tmp1 != '0')
                {
                    payauidos.add($"{application.startuppath}\\auido\\0.wav");
                }
            }
            //个位
            if (tmp3 != '0')
            {
                payauidos.add($"{application.startuppath}\\auido\\{tmp3}.wav");
            }
            //如果第一个音频为零,则去掉
            if (payauidos[0].contains("0.wav"))
            {
                payauidos.removeat(0);
            }
            //如果最后一个音频为零,则去掉
            if (payauidos[payauidos.count - 1].contains("0.wav"))
            {
                payauidos.removeat(payauidos.count - 1);
            }
            return payauidos; 
        }

输入数字,既可转换为语音播报,其实思路很简单,就是把每个数字及单位对应的语音文件连续播放出来即可。demo下载