100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Linux下 python调用讯飞离线语音合成(tts)

Linux下 python调用讯飞离线语音合成(tts)

时间:2022-11-23 10:57:13

相关推荐

Linux下 python调用讯飞离线语音合成(tts)

Linux下,使用Python调用讯飞TTS离线SDK,源代码:

/cch96/iflytek_tts具体使用方法参照readme

解决过程

Windows

Windows的SDK有编译好的可以直接被python用ctypes模块调用的动态链接库。可以直接根据科大讯飞的接口文档以及错误码进行开发调试。

bin文件夹下的dll

接口文档:/windows/api/iFlytekMSCReferenceManual/files.html错误码:/document/error-code

Linux

Linux版的SDK没有编译好的so,但是Linux的SDK中有一些函数库的动态链接库。

libs文件夹下的so

于是开始尝试使用这个库来调用接口,实现功能。在此期间出现了一些问题。

问题1:

在导入libmsc.so时出现异常

OSError: libs/x64/libmsc.so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE

该异常是由于讯飞的tts是由c++实现了,需要链接c++的一些基础依赖库。这里是少了lstdc++.so

解决1:

ctypes中有两种加载动态链接库的方式ctype.CDLL()或者ctypes.cdll.load_libary(),

CDLL有一个mode的可选参数,mode=ctypes.RTLD_GLOBAL,可以全局引入动态链接,如果调用的动态库有其它依赖库时,提前加载的功能

把lstdc++.so提前导入即可ctypes.CDLL("lstdc++.so", mode=ctypes.RTLD_GLOBAL)

问题2:

解决了依赖库问题,在调用接口时出现异常

segmentation fault

段错误,访问了不存在或者受限的内存,这个问题涉及到ctypes与c的交互的内部机制,不好解决,于是换了个思路

解决2:

放弃原来的思路,即用ctypes调用动态链接库中的接口,完成语言合成的逻辑。

改用,用c封装语音合成的逻辑,由它去调用动态链接库中的函数,而python只需要简单调用这些c封装好的接口。

其实官方的sdk中的c语言demo是可用的,把它稍加改造就可以满足我们的要求,就不用自己封装了。

最终解决

官方demo改成接口模块,并编译成so

$gcc -c -fPIC -o mylib.o tts_offline_sample.c

$gcc -shared -o libtts.so mylib.o

将libstdc++.so, libmsc.so, libtts.so都加载进来

def __new__(cls, *args, **kwargs):# 加载库ctypes.CDLL("libstdc++.so.6", mode=ctypes.RTLD_GLOBAL)plat = platform.architecture()if plat[0] == '32bit':dll = CDLL(os.path.join(WORK_ROOT, 'libs/x86/libmsc.so'), mode=ctypes.RTLD_GLOBAL)else:dll = CDLL(os.path.join(WORK_ROOT, 'libs/x64/libmsc.so'), mode=ctypes.RTLD_GLOBAL)cls.dll = cdll.LoadLibrary(os.path.join(WORK_ROOT, "libtts.so"))cls.lock = threading.RLock()return super(IflytekTTS, cls).__new__(cls)

python去调用libtts.so中的接口

def text2wav(self, text, filename):"""文字合成语音"""# 底层的c是不支持多线程的,所以这里限制一下with self.lock:ret = self.dll.msp_login(None, None, self.login_params)if (self.MSP_SUCCESS != ret):# 如果登陆验证失败print("MSPLogin failed, error code: %d.\n", ret)return# 登陆成功# print("开始合成 ...\n")ret = self.dll.text_to_speech(text, filename, self.session_begin_params)# print("合成完毕\n")# 退出登录self.dll.msp_logout()

第一次写博客,若有哪里不对请大家斧正

参考

/weizehua/article/details/88305752

/u013783095/article/details/79639754

/hello–the-world/archive//05/31/2528326.html

/help/show-7989

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。