linux 下 QT 讯飞语音合成

1. 下载讯飞基于Linux的语音文档Linux_tts_online

demo链接https://download.csdn.net/download/weixin_39841821/10568834

里面的目录如下:
bin: 一些用来测试的文件
doc:技术文档
include:将使用的头文件
lib:qt编译需要加入的库文件
samples:使用demo
2. 新建widgt窗体项目,这里我的项目名是TTLSpeech_Demo,右击项目名,选择add Library->Browse加入lib中libmsc.so 库文件,选择Framework(静态库)确定

3. pro加入multimedia 用于播放合成后的语音QSound类

==TTLSpeech_Demo.pro如下==

#-------------------------------------------------
#
# Project created by QtCreator 2018-07-26T09:24:48
#
#-------------------------------------------------

QT       += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = TTLSpeech_Demo
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp \
    myttlfunction.cpp

HEADERS  += widget.h \
    ttl_h/msp_cmn.h \
    ttl_h/msp_errors.h \
    ttl_h/msp_types.h \
    ttl_h/qise.h \
    ttl_h/qisr.h \
    ttl_h/qtts.h \
    myttlfunction.h

FORMS    += widget.ui

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../ttlsdk/libs/x86/release/ -lmsc
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../ttlsdk/libs/x86/debug/ -lmsc
else:mac: LIBS += -F$$PWD/../../ttlsdk/libs/x86/ -framework msc
else:unix: LIBS += -L$$PWD/../../ttlsdk/libs/x86/ -lmsc

INCLUDEPATH += $$PWD/../../ttlsdk/libs/x86
DEPENDPATH += $$PWD/../../ttlsdk/libs/x86

RESOURCES += \
    testfile.qrc

4.把Linux_tts_online->include复制到项目目录下,然后右击项目头文件Header->add Existing File,将所有.h文件加入

5. 右击项目选择add New->c++->c++ class->object,新建一个object类,我这个类的名字为myttfunction,然后会生成myttlfunction.h和myttlfunction.cpp

myttlfunction.h

#ifndef MYTTLFUNCTION_H
#define MYTTLFUNCTION_H
#include "ttl_h/qtts.h"
#include "ttl_h/msp_cmn.h"
#include "ttl_h/msp_errors.h"

#include <QObject>

class myttlFunction : public QObject
{
    Q_OBJECT
public:
    explicit myttlFunction(QObject *parent = 0);
    int text_to_speech(const char* src_text, const char* des_path, const char* params);
    QString TextToVoice_Speak(const char * src_text,const char * des_path,const char* session_begin_params);

    /* wav音频头部格式 */
    typedef struct _wave_pcm_hdr
    {
        char            riff[4];                // = "RIFF"
        int     size_8;                 // = FileSize - 8
        char            wave[4];                // = "WAVE"
        char            fmt[4];                 // = "fmt "
        int     fmt_size;       // = 下一个结构体的大小 : 16

        short int       format_tag;             // = PCM : 1
        short int       channels;               // = 通道数 : 1
        int     samples_per_sec;        // = 采样率 : 8000 | 6000 | 11025 | 16000
        int     avg_bytes_per_sec;      // = 每秒字节数 : samples_per_sec * bits_per_sample / 8
        short int       block_align;            // = 每采样点字节数 : wBitsPerSample / 8
        short int       bits_per_sample;        // = 量化比特数: 8 | 16

        char            data[4];                // = "data";
        int     data_size;              // = 纯数据长度 : FileSize - 44
    } wave_pcm_hdr;

signals:

public slots:
};

#endif // MYTTLFUNCTION_H

myttlfunction.cpp

#include "myttlfunction.h"
#include <QtDebug>
#include <QThread>
#include "include/qtts.h"
#include "include/msp_cmn.h"
#include "include/msp_errors.h"
myttlFunction::myttlFunction(QObject *parent) : QObject(parent)
{

}

/* 默认wav音频头部数据 */
myttlFunction::wave_pcm_hdr default_wav_hdr =
{
    { 'R', 'I', 'F', 'F' },
    0,
    {'W', 'A', 'V', 'E'},
    {'f', 'm', 't', ' '},
    16,
    1,
    1,
    16000,
    32000,
    2,
    16,
    {'d', 'a', 't', 'a'},
    0
};


int myttlFunction::text_to_speech(const char *src_text, const char *des_path, const char *params)
{
    int          ret          = -1;
    FILE*        fp           = NULL;
    const char*  sessionID    = NULL;
    unsigned int audio_len    = 0;
    wave_pcm_hdr wav_hdr      = default_wav_hdr;
    int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;

    if (NULL == src_text || NULL == des_path)
    {
        qDebug("params is error!\n");
        return ret;
    }
    fp = fopen(des_path, "wb");
    if (NULL == fp)
    {
        printf("open %s error.\n", des_path);
        return ret;
    }
    /* 开始合成 */
    sessionID = QTTSSessionBegin(params, &ret);
    if (MSP_SUCCESS != ret)
    {
       qDebug("QTTSSessionBegin failed, error code: %d.\n", ret);
        fclose(fp);
        return ret;
    }
    ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);
    if (MSP_SUCCESS != ret)
    {
        qDebug("QTTSTextPut failed, error code: %d.\n",ret);
        QTTSSessionEnd(sessionID, "TextPutError");
        fclose(fp);
        return ret;
    }
    qDebug("正在合成 ...\n");
    fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000
    while (1)
    {
        /* 获取合成音频 */
        const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
        if (MSP_SUCCESS != ret)
            break;
        if (NULL != data)
        {
            fwrite(data, audio_len, 1, fp);
            wav_hdr.data_size += audio_len; //计算data_size大小
        }
        if (MSP_TTS_FLAG_DATA_END == synth_status)
            break;
        printf(">");
        QThread::usleep(150*1000); //防止频繁占用CPU

    }
    printf("\n");
    if (MSP_SUCCESS != ret)
    {
        printf("QTTSAudioGet failed, error code: %d.\n",ret);
        QTTSSessionEnd(sessionID, "AudioGetError");
        fclose(fp);
        return ret;
    }
    /* 修正wav文件头数据的大小 */
    wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8);

    /* 将修正过的数据写回文件头部,音频文件为wav格式 */
    fseek(fp, 4, 0);
    fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值
    fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置
    fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值
    fclose(fp);
    fp = NULL;
    /* 合成完毕 */
    ret = QTTSSessionEnd(sessionID, "Normal");
    if (MSP_SUCCESS != ret)
    {
        printf("QTTSSessionEnd failed, error code: %d.\n",ret);
    }

    return ret;
}

QString myttlFunction::TextToVoice_Speak(const char *src_text, const char *des_path,const char *session_begin_params)
{
    qDebug()<<"dd";
    QString errorWarn;
    int         ret                  = MSP_SUCCESS;
    const char* login_params         = "appid = 5b586f68, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动

    ret = MSPLogin("[email protected]", "hong1996", login_params);//第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取
    if (MSP_SUCCESS != ret)
    {
        errorWarn="MSPLogin failed, error code: " +QString::number(ret);
        return errorWarn;
    }
    qDebug("开始合成 ...\n");

    ret = text_to_speech(src_text, des_path, session_begin_params);
    if (MSP_SUCCESS != ret)
    {
       errorWarn="text_to_speech failed, error code: " +QString::number(ret);
       return errorWarn;

    }
    qDebug("合成完毕\n");
    errorWarn="finish";
    return errorWarn;
}

==widge.h==

#ifndef WIDGET_H
#define WIDGET_H
#include "myttlfunction.h"
#include <QWidget>
#include <QSound>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();


private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
    myttlFunction *ttlAsk;
    QSound *sound;

};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <QtDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    sound = new QSound("/home/csgec/Videos/10.wav");
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    QString result;
    const char* session_begin_params = "voice_name = yanping, text_encoding = utf8, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";
    ttlAsk = new myttlFunction;
    result=ttlAsk->TextToVoice_Speak("第一个参数是用户名","/home/csgec/Videos/10.wav",session_begin_params);
    qDebug()<<result<<"my";
}

void Widget::on_pushButton_2_clicked()
{

    sound->play();
    sound->setLoops(2);
    qDebug() << "loops:" << sound->loops() ;
}

==main.cpp==

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

6. widget 里托两个button,用来生成音频文件和播放音频文件

==widget.ui==

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>260</y>
     <width>99</width>
     <height>27</height>
    </rect>
   </property>
   <property name="text">
    <string>transform</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_2">
   <property name="geometry">
    <rect>
     <x>220</x>
     <y>260</y>
     <width>99</width>
     <height>27</height>
    </rect>
   </property>
   <property name="text">
    <string>PushButton</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

猜你喜欢

转载自blog.csdn.net/weixin_39841821/article/details/81254336