阿里云语音合成

By admin at 2020-04-06 • 1人收藏 • 1473人看过

感谢aardio培训群: 撒旦微笑 分享代码

https://github.com/nlysh007/aliyun-tts-aardio/releases


更新:

此代码已发布到aardio扩展库, 可以去扩展库管理器里安装后双击打开使用示例!


image.png

import fonts.fontAwesome;
import win.ui;
/*DSG{{*/
var winform = win.form(text="阿里云TTS";right=353;bottom=507)
winform.add(
bk={cls="bk";text="语调";left=19;top=76;right=46;bottom=94;align="left";z=16};
bk2={cls="bk";text="语速";left=19;top=118;right=46;bottom=136;align="left";z=17};
bk3={cls="bk";text="音量";left=19;top=160;right=46;bottom=178;align="left";z=18};
custom={cls="custom";text="自定义控件";left=349;top=501;right=350;bottom=502;z=15};
pitch_rate={cls="plus";left=57;top=76;right=309;bottom=94;bgcolor=-7223;border={radius=-1};color=16754775;foreRight=18;forecolor=-18315;paddingBottom=7;paddingTop=7;z=7};
play={cls="plus";text="立即合成";left=18;top=433;right=339;bottom=490;color=16777215;font=LOGFONT(h=-16;name='FontAwesome');forecolor=16754775;iconStyle={align="left";font=LOGFONT(h=-21;name='FontAwesome');padding={left=150}};iconText=" ";notify=1;z=14};
plus4={cls="plus";left=305;top=76;right=344;bottom=94;z=10};
plus5={cls="plus";left=305;top=118;right=344;bottom=136;z=11};
plus6={cls="plus";left=305;top=160;right=344;bottom=178;z=12};
speech_rate={cls="plus";left=57;top=118;right=309;bottom=136;bgcolor=-7223;border={radius=-1};color=16754775;foreRight=18;forecolor=-18315;paddingBottom=7;paddingTop=7;z=8};
txt={cls="plus";left=15;top=196;right=336;bottom=409;align="left";border={color=-3546113;width=2};editable=true;forecolor=16777215;iconColor=12632256;iconStyle={align="right";font=LOGFONT(name='FontAwesome');padding={right=10;bottom=10};valign="bottom"};iconText="0/300";multiline=1;textPadding={left=10;top=10;right=10;bottom=10};wrap=1;z=13};
voice={cls="plus";left=183;top=17;right=336;bottom=48;bgcolor=15132390;border={color=-3546113;width=2};editable=true;font=LOGFONT(h=-13);forecolor=16777215;iconStyle={align="right";font=LOGFONT(name='FontAwesome');padding={right=8}};iconText='\uF078';notify=1;paddingRight=28;textPadding={left=2;top=6;right=1;bottom=2};z=4};
voiceItem={cls="plus";text="temp";left=183;top=48;right=336;bottom=81;border={left=1;right=1;bottom=1;color=-3546113};font=LOGFONT(name='FontAwesome';charset=0);tabstop=1;z=5};
voiceItem2={cls="plus";text="temp";left=183;top=81;right=336;bottom=114;border={left=1;right=1;bottom=1;color=-3546113};font=LOGFONT(name='FontAwesome');tabstop=1;z=6};
voiceType={cls="plus";left=17;top=17;right=170;bottom=48;bgcolor=15132390;border={color=-3546113;width=2};editable=true;font=LOGFONT(h=-13);forecolor=16777215;iconStyle={align="right";font=LOGFONT(name='FontAwesome');padding={right=8}};iconText='\uF078';notify=1;paddingRight=28;textPadding={left=2;top=6;right=1;bottom=2};z=1};
voiceTypeMenuItem={cls="plus";text="temp";left=17;top=48;right=170;bottom=81;border={left=1;right=1;bottom=1;color=-3546113};font=LOGFONT(name='FontAwesome';charset=0);tabstop=1;z=2};
voiceTypeMenuItem2={cls="plus";text="temp";left=17;top=81;right=170;bottom=114;border={left=1;right=1;bottom=1;color=-3546113};font=LOGFONT(name='FontAwesome');tabstop=1;z=3};
volume={cls="plus";left=57;top=160;right=309;bottom=178;bgcolor=-7223;border={radius=-1};color=16754775;foreRight=18;forecolor=-18315;paddingBottom=7;paddingTop=7;z=9}
)
/*}}*/

_IMPORTURL.aliyun = "https://github.com/nlysh007/aliyun-tts-aardio/releases/latest/download/aliyun.tar.lzma"
import aliyun;
import aliyun.tts;
//aliyun.tts 配置

//测试用配置,如过期请修改
var appkey = "cpl1IGovfV6I05wb"; 
//当accessKeySecret为空时,accessKeyId 即token;
var accessKeyId = "16308e3ce0ea48e2be113fad6ec87727";//有效期1天
var accessKeySecret = "";

//voice 信息表
var tab = {
                {"小云";"Xiaoyun";"标准女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"小刚";"Xiaogang";"标准男声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"小梦";"Xiaomeng";"标准女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"小威";"Xiaowei";"标准男声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"若兮";"Ruoxi";"温柔女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"思琪";"Siqi";"温柔女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"思佳";"Sijia";"标准女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"思诚";"Sicheng";"标准男声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾琪";"Aiqi";"温柔女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾佳";"Aijia";"标准女声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾诚";"Aicheng";"标准男声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾达";"Aida";"标准男声";"通用场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"宁儿";"Ninger";"标准女声";"通用场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"瑞琳";"Ruilin";"标准女声";"通用场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"阿美";"Amei";"甜美女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"小雪";"Xiaoxue";"温柔女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K"}};
                {"思悦";"Siyue";"温柔女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾雅";"Aiya";"严厉女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾夏";"Aixia";"亲和女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾美";"Aimei";"甜美女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾雨";"Aiyu";"自然女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾悦";"Aiyue";"温柔女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾婧";"Aijing";"严厉女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"小美";"Xiaomei";"甜美女声";"客服场景";"支持中文及中英文混合场景";{"8K";"16K";"24K"}};
                {"艾娜";"Aina";"浙普女声";"客服场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"伊娜";"Yina";"浙普女声";"客服场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"思婧";"Sijing";"严厉女声";"客服场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"思彤";"Sitong";"儿童音";"童声场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"小北";"Xiaobei";"萝莉女声";"童声场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"艾彤";"Aitong";"儿童音";"童声场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"艾薇";"Aiwei";"萝莉女声";"童声场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"艾宝";"Aibao";"萝莉女声";"童声场景";"仅支持纯中文场景";{"8K";"16K";"24K"}};
                {"Halen";"Halen";"英音女声";"英文场景";"仅支持英文场景";{"8K";"16K"}};
                {"Harry";"Harry";"英音男声";"英文场景";"仅支持英文场景";{"8K";"16K"}};
                {"Eric";"Eric";"英音男声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"Emily";"Emily";"英音女声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"Luna";"Luna";"英音女声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"Luca";"Luca";"英音男声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"Wendy";"Wendy";"英音女声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"William";"William";"英音男声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"Olivia";"Olivia";"英音女声";"英文场景";"仅支持英文场景";{"8K";"16K";"24K"}};
                {"姗姗";"Shanshan";"粤语女声";"方言场景";"支持标准粤文(简体)及粤英文混合场景";{"8K";"16K";"24K"}}
           }	
//获取文本长度
var getTxtLen = function(txt){
    var len = 0; 
    for m in string.gmatch( txt,":|.") {    
        if(string.find(m,':')){
            len +=2;
        }else {
            len +=1;
        } 
    }
    return len; 	
}; 
// 获取 voice 类型表
var getVoiceTypes = function(param){
    var voiceTypes = {}
    for(k,v in param){      
        if(!table.find(voiceTypes,v[3])){
            table.push(voiceTypes,v[3])
        }
    
    }
    return voiceTypes; 
}; 

var trackSkin = {	
    background={
        default=0xFFC9E3FF
    };
    foreground={
        default=0xFF75B8FF
    };
    color={
        default=0xFF57A8FF;
        hover=0xFF2E93FF
    }
}
winform.pitch_rate.setTrackbarRange(-500,500);

winform.pitch_rate.progressPos = 0;
winform.plus4.text = winform.pitch_rate.progressPos;
//trackbar
winform.pitch_rate.onPosChanged = function( pos,thumbTrack ){
    if(thumbTrack){
        winform.plus4.text = pos;
    }
}
winform.pitch_rate.skin(trackSkin)

winform.speech_rate.setTrackbarRange(-500,500);
winform.speech_rate.progressPos = 0;
winform.speech_rate.skin(trackSkin)
winform.plus5.text = winform.speech_rate.progressPos;
//trackbar
winform.speech_rate.onPosChanged = function( pos,thumbTrack ){
    if(thumbTrack){
        winform.plus5.text = pos;
    }
}

winform.txt.editBox.onChange = function(){  
    var num = getTxtLen(winform.txt.text)||0;
    if(num>300){
        winform.txt.iconColor = 0xFFFF0000;
    } else {
        winform.txt.iconColor = 0xFFC0C0C0;
    }
    winform.txt.iconText = num++"/300";

    
}

winform.volume.setTrackbarRange(1,100);
winform.volume.progressPos = 50;
winform.volume.skin(trackSkin)

winform.plus6.text = winform.volume.progressPos;
//trackbar
winform.volume.onPosChanged = function( pos,thumbTrack ){
    if(thumbTrack){
        winform.plus6.text = pos;
    }
}


import win.ui.tabs;
var skin = 	{ 
            foreground={
                default = 0xFFFFFFFF;
                hover= 0xFFE6E6E6;
            };
            checked = { 
                foreground={
                    default = 0xFFE6E6E6;
                }; 
            }
        }

var voiceTypeMenu = win.ui.tabs(winform.voiceTypeMenuItem,winform.voiceTypeMenuItem2)
voiceTypeMenu.skin( skin)
var voiceMenu = win.ui.tabs(winform.voiceItem,winform.voiceItem2)
voiceMenu.skin( skin)
// 切换到弹出列表模式,并使用参数指定的控件处理键盘事件
voiceTypeMenu.initPopup(winform.voiceType.editBox)
voiceMenu.initPopup(winform.voice.editBox)

var voiceTypes = getVoiceTypes(tab);
var getInfoByType = function(tab,voiceType){

    var info = table.filter(tab,function(v,index){
                    if(v[3] = voiceType){
                        return v; 
                    }
                })	
    return info; 
}
voiceTypeMenu.clear()
voiceMenu.clear()
voiceTypeMenu.setItemTexts(voiceTypes)

winform.voiceType.editState = false;
winform.voiceType.editBox.onChange = function(){
    var voiceType = voiceTypeMenu.selText ||voiceTypes[1];
    var voice = getInfoByType(tab,voiceType)
    if(voice){
        for(k,v in voice){
            voice[k] = v[1]
        }
        voiceMenu.setItemTexts(voice) 
        winform.voice.text=voice[1];	
    }
}
winform.voiceType.text=voiceTypes[1];
// 用户点选菜单项触发此事件,strip参数是点选的控件
voiceTypeMenu.onOk = function(strip){
    winform.voiceType.setFocus(voiceTypeMenu.selText)
}
voiceMenu.onOk = function(strip){
    winform.voice.setFocus(voiceMenu.selText)
}

// 禁止共享编辑框外观状态(focus状态除外)
winform.voiceType.editState = false;
winform.voice.editState = false;
winform.voiceType.skin({
    background = { hover = 0x5E00CCFF }
    checked = { 
        iconText = '\uF077';
    }  
})

winform.voice.skin({
    background = { hover = 0x5E00CCFF }
    checked = { 
        iconText = '\uF077';
    }  
})
// 显示弹出菜单,弹出菜单会自动修改winform.voiceType的checked属性为菜单打开状态
winform.voiceType.oncommand = function(id,event){ 
    if(winform.voiceType.checked ){
        voiceTypeMenu.selText = winform.voiceType.text
        voiceTypeMenu.popup(true,winform.voiceType)
    }  
}
winform.voice.oncommand = function(id,event){  
    if(winform.voice.checked ){
        voiceMenu.selText = winform.voice.text
        voiceMenu.popup(true,winform.voice)
    }  
}

var wmp = winform.custom.createEmbed( "WMPlayer.OCX" )._object;
winform.play.oncommand = function(id,event){
    if(winform.txt.text==""){
        win.msgbox("文本不能为空")
        return ; 
    }
    if(appkey == "" or accessKeyId == ""){
        win.msgbox("请至少配置 accessKeyId,token")
        return ; 
    }
    winform.play.iconColor =0xFFFFFFFF;
    //获取对应voice的配置信息
      var voice = table.filter(tab,function(v,index){
            if(v[1]===winform.voice.text){
                return v; 
            }
        })
    
    
    //获取tts地址

     client := aliyun.tts.client(appkey,accessKeyId,accessKeySecret)
    var param =   {
            text = winform.txt.text;
            voice = voice[1][[2]];
            pitch_rate = winform.pitch_rate.progressPos;
            speech_rate = winform.speech_rate.progressPos;
            volume	= winform.volume.progressPos;
            format = "wav";
      }; 
    var url = client.getTTS(param)
    
    wmp.url = url;
    
    winform.play.disabled = true;
        winform.setInterval( 
        1000,function(){
            select(wmp.playState) {
                case 1 {
                    winform.play.disabledText = null;
                    winform.play.disabled = false;
                    winform.play.text = "立即合成"
                    return false; 
                }
                case 3,9 {
                    if(wmp.playState==3){
                        winform.play.disabledText =  {'\uF026';'\uF027';'\uF028';'\uF026'};
                        winform.play.text = null
                    }			
    
                }
                else {
                    winform.play.disabledText = null;
                    winform.play.disabled = false;
                    winform.play.text = "立即合成"
                    return false; 
                }
            }
    
        } 
    )	

}


winform.show() 
win.loopMessage();

如果不能自动下载aliyun扩展库的话, 

aliyun.zip


1 个回复 | 最后更新于 2021-11-02
2020-04-08   #1

这个非常不错,最近做linux也遇到了,需要将文本转为语言后通过hdmi输出音频到喇叭播放,还没找到比较好的C语言代码转换方案。

登录后方可回帖

登 录
信息栏
公告:
个人博客
专注分享
谢谢合作!

本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
打赏本站
Loading...