QT实现语音识别功能

人工智能85

QT实现语音识别功能的相关步骤如下(附程序代码):

1.阿里云注册账号,登录智能语音交互平台:创建新项目,此时或获得AppKey,进入智能语音交互总览一页,右上方会看见一个Access Token,然后点击头像进入accessKey管理页面,你会看到accessKeyID和accessKey secret.记住这四个参数,后面会用的到的

QT实现语音识别功能

2.找到帮助文档中一句话识别下的下载C++SDK的文件,下载下来

QT实现语音识别功能

3.往下翻找到编译环境的搭建步骤:

QT实现语音识别功能

环境配置好之后就可以开始进行编程了

4.附上详细的代码(具体步骤自己看程序理解)

详细代码附上,压缩文件格式的,亲测可行:

5.


QT       += core gui multimedia

INCLUDEPATH += /home/wangzhen/IOTEK/Qt/NlsSdkCpp3.X/include

LIBS += -L/home/wangzhen/IOTEK/Qt/NlsSdkCpp3.X/lib -lalibabacloud-idst-common -lalibabacloud-idst-speech

6.myrecord.h

#ifndef MYRECORD_H
#define MYRECORD_H

#include <qwidget>
#include<qaudioinput>//&#x5B9E;&#x73B0;&#x5F55;&#x97F3;&#x529F;&#x80FD;
#include<qaudioformat>//&#x8BBE;&#x7F6E;&#x5F55;&#x97F3;&#x683C;&#x5F0F;
#include<qaudiodeviceinfo>//&#x8BBE;&#x7F6E;&#x5F55;&#x97F3;&#x8BBE;&#x5907;&#x4FE1;&#x606F;
#include<qfile>
namespace Ui {
class MyRecord;
}

struct WAVHEARD
{
    //RIFF&#x5934;
    char RiffName[4];
    unsigned int nRiffLength;
    //&#x6570;&#x636E;&#x7C7B;&#x578B;&#x6807;&#x8BC6;&#x7B26;
    char WavName[4];
    //&#x683C;&#x5F0F;&#x5757;&#x4E2D;&#x7684;&#x5757;&#x5934;
    char FmtName[4];
    unsigned int nFmtLength;

    //&#x683C;&#x5F0F;&#x5177;&#x4F53;&#x6570;&#x636E;
    unsigned short nAudioFormat;
    unsigned short nChannleNumber;
    unsigned int nSampleRate;
    unsigned int nBytesPerSecond;
    unsigned short nBytesPerSample;
    unsigned short nBitsPerSample;

    //&#x97F3;&#x9891;&#x6570;&#x636E;&#x4FE1;&#x606F;
    char DataName[4];
    unsigned int nDataLength;

};

class MyRecord : public QWidget
{
    Q_OBJECT

public:
    explicit MyRecord(QWidget *parent = nullptr);
    ~MyRecord();
    void initAudio();
    void rawTowav();
    void loadConfig();
public slots:
    void recvMsg(QString msg);
private slots:
    void on_start_pb_clicked();

    void on_stop_pb_clicked();

private:
    Ui::MyRecord *ui;

    QAudioInput *m_pAudioInput;
    QFile m_rawFile;
    QFile m_wavFile;

    QString m_strAppkey;
    QString m_strAKID;
    QString m_strAKSecret;
    QString m_strToken;
};

#endif // MYRECORD_H
</qfile></qaudiodeviceinfo></qaudioformat></qaudioinput></qwidget>

7.result.h

#ifndef RESULT_H
#define RESULT_H

#include <qwidget>

class Result : public QWidget
{
    Q_OBJECT
public:
    explicit Result(QWidget *parent = nullptr);
    void send(std::string msg);
    static Result& getInstance();
signals:
    void sendMsg(QString msg);
public slots:
};

#endif // RESULT_H
</qwidget>

8.speechRecognizerDemo.h

#ifndef SPEECH_H
#define SPEECH_H
/*
 * Copyright 2015 Alibaba Group Holding Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the Licenise for the specific language governing permissions and
 * limitations under the License.

 */
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <ctime>
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sys time.h>
#include "nlsClient.h"
#include "nlsEvent.h"
#include "speechRecognizerRequest.h"
#include "nlsCommonSdk/Token.h"

#define FRAME_SIZE 3200
#define SAMPLE_RATE 16000

using namespace AlibabaNlsCommon;
using AlibabaNls::NlsClient;
using AlibabaNls::NlsEvent;
using AlibabaNls::LogDebug;
using AlibabaNls::LogInfo;
using AlibabaNls::LogError;
using AlibabaNls::SpeechRecognizerRequest;

// &#x81EA;&#x5B9A;&#x4E49;&#x7EBF;&#x7A0B;&#x53C2;&#x6570;
struct ParamStruct {
    std::string fileName;
    std::string appkey;
    std::string token;
};

// &#x81EA;&#x5B9A;&#x4E49;&#x4E8B;&#x4EF6;&#x56DE;&#x8C03;&#x53C2;&#x6570;
struct ParamCallBack {
    int userId;
    char userInfo[8];
};

//&#x5168;&#x5C40;&#x7EF4;&#x62A4;&#x4E00;&#x4E2A;&#x670D;&#x52A1;&#x9274;&#x6743;token&#x548C;&#x5176;&#x5BF9;&#x5E94;&#x7684;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;&#xFF0C;
//&#x6BCF;&#x6B21;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x4E4B;&#x524D;&#xFF0C;&#x9996;&#x5148;&#x5224;&#x65AD;token&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x8FC7;&#x671F;&#xFF0C;
//&#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x8FC7;&#x671F;&#xFF0C;&#x5219;&#x6839;&#x636E;AccessKey ID&#x548C;AccessKey Secret&#x91CD;&#x65B0;&#x751F;&#x6210;&#x4E00;&#x4E2A;token&#xFF0C;&#x5E76;&#x66F4;&#x65B0;&#x8FD9;&#x4E2A;&#x5168;&#x5C40;&#x7684;token&#x548C;&#x5176;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;&#x3002;
//&#x6CE8;&#x610F;&#xFF1A;&#x4E0D;&#x8981;&#x6BCF;&#x6B21;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x4E4B;&#x524D;&#x90FD;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x65B0;token&#xFF0C;&#x53EA;&#x9700;&#x5728;token&#x5373;&#x5C06;&#x8FC7;&#x671F;&#x65F6;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x5373;&#x53EF;&#x3002;&#x6240;&#x6709;&#x7684;&#x670D;&#x52A1;&#x5E76;&#x53D1;&#x53EF;&#x5171;&#x7528;&#x4E00;&#x4E2A;token&#x3002;

#if 0
// &#x6839;&#x636E;AccessKey ID&#x548C;AccessKey Secret&#x91CD;&#x65B0;&#x751F;&#x6210;&#x4E00;&#x4E2A;token&#xFF0C;&#x5E76;&#x83B7;&#x53D6;&#x5176;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;
// token&#x4F7F;&#x7528;&#x89C4;&#x5219;&#xFF1A;&#x5728;&#x6709;&#x6548;&#x671F;&#x5230;&#x671F;&#x524D;&#x53EF;&#x4EE5;&#x4E00;&#x76F4;&#x4F7F;&#x7528;&#xFF0C;&#x4E14;&#x53EF;&#x4EE5;&#x591A;&#x4E2A;&#x8FDB;&#x7A0B;/&#x591A;&#x4E2A;&#x7EBF;&#x7A0B;/&#x591A;&#x4E2A;&#x5E94;&#x7528;&#x4F7F;&#x7528;&#x5747;&#x53EF;&#xFF0C;&#x5EFA;&#x8BAE;&#x5728;&#x6709;&#x6548;&#x671F;&#x5FEB;&#x5230;&#x671F;&#x65F6;&#x63D0;&#x8D77;&#x7533;&#x8BF7;&#x65B0;&#x7684;token
int generateToken(std::string akId, std::string akSecret, std::string* token, long* expireTime) {
    NlsToken nlsTokenRequest;
    nlsTokenRequest.setAccessKeyId(akId);
    nlsTokenRequest.setKeySecret(akSecret);

    if (-1 == nlsTokenRequest.applyNlsToken()) {
        // &#x83B7;&#x53D6;&#x5931;&#x8D25;&#x539F;&#x56E0;
        printf("generateToken Failed: %s\n", nlsTokenRequest.getErrorMsg());
        return -1;
    }

    *token = nlsTokenRequest.getToken();
    *expireTime = nlsTokenRequest.getExpireTime();
    return 0;
}
#endif
//@brief &#x83B7;&#x53D6;sendAudio&#x53D1;&#x9001;&#x5EF6;&#x65F6;&#x65F6;&#x95F4;
//@param dataSize &#x5F85;&#x53D1;&#x9001;&#x6570;&#x636E;&#x5927;&#x5C0F;
//@param sampleRate &#x91C7;&#x6837;&#x7387; 16k/8K
//@param compressRate &#x6570;&#x636E;&#x538B;&#x7F29;&#x7387;&#xFF0C;&#x4F8B;&#x5982;&#x538B;&#x7F29;&#x6BD4;&#x4E3A;10:1&#x7684;16k opus&#x7F16;&#x7801;&#xFF0C;&#x6B64;&#x65F6;&#x4E3A;10&#xFF1B;&#x975E;&#x538B;&#x7F29;&#x6570;&#x636E;&#x5219;&#x4E3A;1
//@return &#x8FD4;&#x56DE;sendAudio&#x4E4B;&#x540E;&#x9700;&#x8981;sleep&#x7684;&#x65F6;&#x95F4;
//@note &#x5BF9;&#x4E8E;8k pcm &#x7F16;&#x7801;&#x6570;&#x636E;, 16&#x4F4D;&#x91C7;&#x6837;&#xFF0C;&#x5EFA;&#x8BAE;&#x6BCF;&#x53D1;&#x9001;1600&#x5B57;&#x8282; sleep 100 ms.

// &#x5BF9;&#x4E8E;16k pcm &#x7F16;&#x7801;&#x6570;&#x636E;, 16&#x4F4D;&#x91C7;&#x6837;&#xFF0C;&#x5EFA;&#x8BAE;&#x6BCF;&#x53D1;&#x9001;3200&#x5B57;&#x8282; sleep 100 ms.

// &#x5BF9;&#x4E8E;&#x5176;&#x5B83;&#x7F16;&#x7801;&#x683C;&#x5F0F;&#x7684;&#x6570;&#x636E;, &#x7528;&#x6237;&#x6839;&#x636E;&#x538B;&#x7F29;&#x6BD4;, &#x81EA;&#x884C;&#x4F30;&#x7B97;, &#x6BD4;&#x5982;&#x538B;&#x7F29;&#x6BD4;&#x4E3A;10:1&#x7684; 16k opus,
// &#x9700;&#x8981;&#x6BCF;&#x53D1;&#x9001;3200/10=320 sleep 100ms.

unsigned int getSendAudioSleepTime(int dataSize, int sampleRate, int compressRate);

//@brief &#x8C03;&#x7528;start(), &#x6210;&#x529F;&#x4E0E;&#x4E91;&#x7AEF;&#x5EFA;&#x7ACB;&#x8FDE;&#x63A5;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;started&#x4E8B;&#x4EF6;
//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionStarted(NlsEvent* cbEvent, void* cbParam);

//@brief &#x8BBE;&#x7F6E;&#x5141;&#x8BB8;&#x8FD4;&#x56DE;&#x4E2D;&#x95F4;&#x7ED3;&#x679C;&#x53C2;&#x6570;, sdk&#x5728;&#x63A5;&#x6536;&#x5230;&#x4E91;&#x7AEF;&#x8FD4;&#x56DE;&#x5230;&#x4E2D;&#x95F4;&#x7ED3;&#x679C;&#x65F6;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;ResultChanged&#x4E8B;&#x4EF6;
//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionResultChanged(NlsEvent* cbEvent, void* cbParam);

//@brief sdk&#x5728;&#x63A5;&#x6536;&#x5230;&#x4E91;&#x7AEF;&#x8FD4;&#x56DE;&#x8BC6;&#x522B;&#x7ED3;&#x675F;&#x6D88;&#x606F;&#x65F6;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;Completed&#x4E8B;&#x4EF6;
//@note &#x4E0A;&#x62A5;Completed&#x4E8B;&#x4EF6;&#x4E4B;&#x540E;, SDK&#x5185;&#x90E8;&#x4F1A;&#x5173;&#x95ED;&#x8BC6;&#x522B;&#x8FDE;&#x63A5;&#x901A;&#x9053;. &#x6B64;&#x65F6;&#x8C03;&#x7528;sendAudio&#x4F1A;&#x8FD4;&#x56DE;-1, &#x8BF7;&#x505C;&#x6B62;&#x53D1;&#x9001;.

//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionCompleted(NlsEvent* cbEvent, void* cbParam);

void OnRecognitionTaskFailed(NlsEvent* cbEvent, void* cbParam);

void* pthreadFunction(void* arg);
//&#x7EBF;&#x7A0B;&#x5FAA;&#x73AF;&#x8BC6;&#x522B;
//&#x9700;&#x8981;&#x8C03;&#x6574;count&#x503C;&#x548C;&#x6BCF;&#x6B21;&#x8981;&#x8BC6;&#x522B;&#x7684;&#x6587;&#x4EF6;&#xFF0C;Demo&#x4E2D;&#x9ED8;&#x8BA4;&#x6BCF;&#x6B21;&#x8BC6;&#x522B;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;
void* multiRecognize(void* arg);

// &#x8BC6;&#x522B;&#x5355;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;
int speechRecognizerFile();

//&#x8BC6;&#x522B;&#x591A;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;;
 //sdk&#x591A;&#x7EBF;&#x7A0B;&#x6307;&#x4E00;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;&#x6E90;&#x5BF9;&#x5E94;&#x4E00;&#x4E2A;&#x7EBF;&#x7A0B;, &#x975E;&#x4E00;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;&#x5BF9;&#x5E94;&#x591A;&#x4E2A;&#x7EBF;&#x7A0B;.

 //&#x793A;&#x4F8B;&#x4EE3;&#x7801;&#x4E3A;&#x540C;&#x65F6;&#x5F00;&#x542F;2&#x4E2A;&#x7EBF;&#x7A0B;&#x8BC6;&#x522B;2&#x4E2A;&#x6587;&#x4EF6;;
 //&#x514D;&#x8D39;&#x7528;&#x6237;&#x5E76;&#x53D1;&#x8FDE;&#x63A5;&#x4E0D;&#x80FD;&#x8D85;&#x8FC7;2&#x4E2A;;
#define AUDIO_FILE_NUMS 2
#define AUDIO_FILE_NAME_LENGTH 32
int speechRecognizerMultFile(const char* appkey);

#endif
</sys></fstream></vector></iostream></string></ctime></stdlib.h></pthread.h></unistd.h></string.h>

9.main.cpp

#include "myrecord.h"
#include <qapplication>

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

    return a.exec();
}
</qapplication>

10.myrecord.cpp

#include "myrecord.h"
#include "ui_myrecord.h"
#include"speechRecognizerDemo.h"
#include<qdebug>
#include"result.h"
extern std::string g_appkey;
extern std::string g_akId;
extern std::string g_akSecret;
extern std::string g_token;
MyRecord::MyRecord(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyRecord)
{
    ui->setupUi(this);
    initAudio();
    loadConfig();

    connect(&(Result::getInstance()),SIGNAL(sendMsg(QString)),
            this,SLOT(recvMsg(QString)));
    // &#x6839;&#x636E;&#x9700;&#x8981;&#x8BBE;&#x7F6E;SDK&#x8F93;&#x51FA;&#x65E5;&#x5FD7;, &#x53EF;&#x9009;. &#x6B64;&#x5904;&#x8868;&#x793A;SDK&#x65E5;&#x5FD7;&#x8F93;&#x51FA;&#x81F3;log-recognizer.txt&#xFF0C; LogDebug&#x8868;&#x793A;&#x8F93;&#x51FA;&#x6240;&#x6709;&#x7EA7;&#x522B;&#x65E5;&#x5FD7;&#xFF0C;&#x652F;&#x6301;LogInfo&#x3001;LogWarning&#x3001;LogError&#xFF0C; 400&#x8868;&#x793A;&#x5355;&#x4E2A;&#x6587;&#x4EF6;400MB
    int ret = NlsClient::getInstance()->setLogConfig("log-recognizer", LogDebug, 400);
    if (-1 == ret) {
        printf("set log failed.\n");
    }

    //&#x542F;&#x52A8;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;
    NlsClient::getInstance()->startWorkThread(4);

}

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

void MyRecord::initAudio()
{
    QAudioFormat format;
    format.setSampleRate(16000);//&#x8BBE;&#x7F6E;&#x91C7;&#x6837;&#x9891;&#x7387;&#x4E3A;16KHZ
    format.setChannelCount(1);//&#x8BBE;&#x7F6E;&#x4E3A;&#x5355;&#x58F0;&#x9053;
    format.setSampleSize(16);//&#x91C7;&#x6837;&#x5B57;&#x8282;&#x5927;&#x5C0F;
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);//&#x8BBE;&#x7F6E;&#x91C7;&#x7528;&#x5B58;&#x653E;&#x97F3;&#x9891;&#x6570;&#x636E;&#x662F;&#x5927;&#x7AEF;&#x5B57;&#x8282;&#x5E8F;&#x8FD8;&#x662F;&#x5C0F;&#x7AEF;&#x5B57;&#x8282;&#x5E8F;
    format.setSampleType(QAudioFormat::SignedInt);

    QAudioDeviceInfo defInfo = QAudioDeviceInfo::defaultInputDevice();
    if(!defInfo.isFormatSupported(format)){
        format = defInfo.nearestFormat(format);
     }
     m_pAudioInput = new QAudioInput(format,this);

}

void MyRecord::rawTowav()
{
    m_rawFile.open(QIODevice::ReadOnly);
    m_wavFile.setFileName("test.wav");
    m_wavFile.open(QIODevice::WriteOnly|QIODevice::Truncate);

    static WAVHEARD wavHeard;
    qstrcpy(wavHeard.RiffName,"RIFF");
    qstrcpy(wavHeard.WavName,"WAVE");
    qstrcpy(wavHeard.FmtName,"fmt");
    qstrcpy(wavHeard.DataName,"data");

    wavHeard.nFmtLength =16;
    wavHeard.nAudioFormat =1;
    wavHeard.nBitsPerSample = 16;
    wavHeard.nChannleNumber =1;
    wavHeard.nBytesPerSample = 2;
    wavHeard.nSampleRate = 16;
    wavHeard.nBytesPerSecond = 32000;
    wavHeard.nRiffLength = m_rawFile.size()-8+sizeof(WAVHEARD);
    wavHeard.nDataLength = m_rawFile.size();

    m_wavFile.write(reinterpret_cast<char*>(&wavHeard),sizeof(WAVHEARD));
    m_wavFile.write(m_rawFile.readAll());

    m_rawFile.close();
    m_wavFile.close();

}

void MyRecord::loadConfig()
{
    QFile file(":/speech.config");
    file.open(QIODevice::ReadOnly);
    QByteArray data = file.readLine();
    m_strAppkey = data.data();
    m_strAppkey.remove("\n");

    data = file.readLine();
    m_strAKID = data.data();
    m_strAKID.remove("\n");

    data = file.readLine();
    m_strAKSecret = data.data();
    m_strAKSecret.remove("\n");

    data = file.readLine();
    m_strToken = data.data();
    m_strToken.remove("\n");

    file.close();
    g_appkey = m_strAppkey.toStdString();
    g_akId = m_strAKID.toStdString();
    g_akSecret = m_strAKSecret.toStdString();
    g_token = m_strToken.toStdString();
}

void MyRecord::recvMsg(QString msg)
{
    ui->showResult->append(msg);
}

void MyRecord::on_start_pb_clicked()
{
    m_rawFile.setFileName("test.raw");
    m_rawFile.open(QIODevice::WriteOnly|QIODevice::Truncate);
    m_pAudioInput->start(&m_rawFile);
}

void MyRecord::on_stop_pb_clicked()
{
    m_pAudioInput->stop();
    m_rawFile.close();

    rawTowav();
    speechRecognizerFile();
}
</char*></qdebug>

11.result.cpp

#include "result.h"

Result::Result(QWidget *parent) : QWidget(parent)
{

}

void Result::send(std::string msg)
{
    emit sendMsg(msg.c_str());
}

Result &Result::getInstance()
{
    static Result instance;
    return instance;
}

12.speechRecognizerDemo.cpp

#include"speechRecognizerDemo.h"
#include"result.h"
//&#x5168;&#x5C40;&#x7EF4;&#x62A4;&#x4E00;&#x4E2A;&#x670D;&#x52A1;&#x9274;&#x6743;token&#x548C;&#x5176;&#x5BF9;&#x5E94;&#x7684;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;&#xFF0C;
//&#x6BCF;&#x6B21;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x4E4B;&#x524D;&#xFF0C;&#x9996;&#x5148;&#x5224;&#x65AD;token&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x8FC7;&#x671F;&#xFF0C;
//&#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x8FC7;&#x671F;&#xFF0C;&#x5219;&#x6839;&#x636E;AccessKey ID&#x548C;AccessKey Secret&#x91CD;&#x65B0;&#x751F;&#x6210;&#x4E00;&#x4E2A;token&#xFF0C;&#x5E76;&#x66F4;&#x65B0;&#x8FD9;&#x4E2A;&#x5168;&#x5C40;&#x7684;token&#x548C;&#x5176;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;&#x3002;
//&#x6CE8;&#x610F;&#xFF1A;&#x4E0D;&#x8981;&#x6BCF;&#x6B21;&#x8C03;&#x7528;&#x670D;&#x52A1;&#x4E4B;&#x524D;&#x90FD;&#x91CD;
std::string g_appkey="";
std::string g_akId = "";
std::string g_akSecret = "";
std::string g_token = "";
std::string g_result = "";
long g_expireTime = -1;

struct timeval tv;
struct timeval tv1;
#if 0
// &#x6839;&#x636E;AccessKey ID&#x548C;AccessKey Secret&#x91CD;&#x65B0;&#x751F;&#x6210;&#x4E00;&#x4E2A;token&#xFF0C;&#x5E76;&#x83B7;&#x53D6;&#x5176;&#x6709;&#x6548;&#x671F;&#x65F6;&#x95F4;&#x6233;
// token&#x4F7F;&#x7528;&#x89C4;&#x5219;&#xFF1A;&#x5728;&#x6709;&#x6548;&#x671F;&#x5230;&#x671F;&#x524D;&#x53EF;&#x4EE5;&#x4E00;&#x76F4;&#x4F7F;&#x7528;&#xFF0C;&#x4E14;&#x53EF;&#x4EE5;&#x591A;&#x4E2A;&#x8FDB;&#x7A0B;/&#x591A;&#x4E2A;&#x7EBF;&#x7A0B;/&#x591A;&#x4E2A;&#x5E94;&#x7528;&#x4F7F;&#x7528;&#x5747;&#x53EF;&#xFF0C;&#x5EFA;&#x8BAE;&#x5728;&#x6709;&#x6548;&#x671F;&#x5FEB;&#x5230;&#x671F;&#x65F6;&#x63D0;&#x8D77;&#x7533;&#x8BF7;&#x65B0;&#x7684;token
int generateToken(std::string akId, std::string akSecret, std::string* token, long* expireTime) {
    NlsToken nlsTokenRequest;
    nlsTokenRequest.setAcc
}essKeyId(akId);
    nlsTokenRequest.setKeySecret(akSecret);

    if (-1 == nlsTokenRequest.applyNlsToken()) {
        // &#x83B7;&#x53D6;&#x5931;&#x8D25;&#x539F;&#x56E0;
        printf("generateToken Failed: %s\n", nlsTokenRequest.getErrorMsg());
        return -1;
    }

    *token = nlsTokenRequest.getToken();
    *expireTime = nlsTokenRequest.getExpireTime();
    return 0;
}
#endif
//@brief &#x83B7;&#x53D6;sendAudio&#x53D1;&#x9001;&#x5EF6;&#x65F6;&#x65F6;&#x95F4;
//@param dataSize &#x5F85;&#x53D1;&#x9001;&#x6570;&#x636E;&#x5927;&#x5C0F;
//@param sampleRate &#x91C7;&#x6837;&#x7387; 16k/8K
//@param compressRate &#x6570;&#x636E;&#x538B;&#x7F29;&#x7387;&#xFF0C;&#x4F8B;&#x5982;&#x538B;&#x7F29;&#x6BD4;&#x4E3A;10:1&#x7684;16k opus&#x7F16;&#x7801;&#xFF0C;&#x6B64;&#x65F6;&#x4E3A;10&#xFF1B;&#x975E;&#x538B;&#x7F29;&#x6570;&#x636E;&#x5219;&#x4E3A;1
//@return &#x8FD4;&#x56DE;sendAudio&#x4E4B;&#x540E;&#x9700;&#x8981;sleep&#x7684;&#x65F6;&#x95F4;
//@note &#x5BF9;&#x4E8E;8k pcm &#x7F16;&#x7801;&#x6570;&#x636E;, 16&#x4F4D;&#x91C7;&#x6837;&#xFF0C;&#x5EFA;&#x8BAE;&#x6BCF;&#x53D1;&#x9001;1600&#x5B57;&#x8282; sleep 100 ms.

// &#x5BF9;&#x4E8E;16k pcm &#x7F16;&#x7801;&#x6570;&#x636E;, 16&#x4F4D;&#x91C7;&#x6837;&#xFF0C;&#x5EFA;&#x8BAE;&#x6BCF;&#x53D1;&#x9001;3200&#x5B57;&#x8282; sleep 100 ms.

// &#x5BF9;&#x4E8E;&#x5176;&#x5B83;&#x7F16;&#x7801;&#x683C;&#x5F0F;&#x7684;&#x6570;&#x636E;, &#x7528;&#x6237;&#x6839;&#x636E;&#x538B;&#x7F29;&#x6BD4;, &#x81EA;&#x884C;&#x4F30;&#x7B97;, &#x6BD4;&#x5982;&#x538B;&#x7F29;&#x6BD4;&#x4E3A;10:1&#x7684; 16k opus,
// &#x9700;&#x8981;&#x6BCF;&#x53D1;&#x9001;3200/10=320 sleep 100ms.

unsigned int getSendAudioSleepTime(int dataSize, int sampleRate, int compressRate) {
    // &#x4EC5;&#x652F;&#x6301;16&#x4F4D;&#x91C7;&#x6837;
    const int sampleBytes = 16;
    // &#x4EC5;&#x652F;&#x6301;&#x5355;&#x901A;&#x9053;
    const int soundChannel = 1;

    // &#x5F53;&#x524D;&#x91C7;&#x6837;&#x7387;&#xFF0C;&#x91C7;&#x6837;&#x4F4D;&#x6570;&#x4E0B;&#x6BCF;&#x79D2;&#x91C7;&#x6837;&#x6570;&#x636E;&#x7684;&#x5927;&#x5C0F;
    int bytes = (sampleRate * sampleBytes * soundChannel) / 8;
    // &#x5F53;&#x524D;&#x91C7;&#x6837;&#x7387;&#xFF0C;&#x91C7;&#x6837;&#x4F4D;&#x6570;&#x4E0B;&#x6BCF;&#x6BEB;&#x79D2;&#x91C7;&#x6837;&#x6570;&#x636E;&#x7684;&#x5927;&#x5C0F;
    int bytesMs = bytes / 1000;
    // &#x5F85;&#x53D1;&#x9001;&#x6570;&#x636E;&#x5927;&#x5C0F;&#x9664;&#x4EE5;&#x6BCF;&#x6BEB;&#x79D2;&#x91C7;&#x6837;&#x6570;&#x636E;&#x5927;&#x5C0F;&#xFF0C;&#x4EE5;&#x83B7;&#x53D6;sleep&#x65F6;&#x95F4;
    int sleepMs = (dataSize * compressRate) / bytesMs;
    return sleepMs;
}
//@brief &#x8C03;&#x7528;start(), &#x6210;&#x529F;&#x4E0E;&#x4E91;&#x7AEF;&#x5EFA;&#x7ACB;&#x8FDE;&#x63A5;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;started&#x4E8B;&#x4EF6;
//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionStarted(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // &#x6F14;&#x793A;&#x5982;&#x4F55;&#x6253;&#x5370;/&#x4F7F;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#x793A;&#x4F8B;
    printf("OnRecognitionStarted: %d, %s\n", tmpParam->userId, tmpParam->userInfo);
    // &#x83B7;&#x53D6;&#x6D88;&#x606F;&#x7684;&#x72B6;&#x6001;&#x7801;&#xFF0C;&#x6210;&#x529F;&#x4E3A;0&#x6216;&#x8005;20000000&#xFF0C;&#x5931;&#x8D25;&#x65F6;&#x5BF9;&#x5E94;&#x5931;&#x8D25;&#x7684;&#x9519;&#x8BEF;&#x7801;
    // &#x5F53;&#x524D;&#x4EFB;&#x52A1;&#x7684;task id&#xFF0C;&#x65B9;&#x4FBF;&#x5B9A;&#x4F4D;&#x95EE;&#x9898;&#xFF0C;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#xFF0C;&#x7279;&#x522B;&#x63D0;&#x9192;&#x8BE5;taskid&#x975E;&#x5E38;&#x91CD;&#x8981;&#xFF0C;&#x662F;&#x548C;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;&#x7684;&#x552F;&#x4E00;&#x6807;&#x8BC6;&#xFF0C;&#x56E0;&#x6B64;&#x5EFA;&#x8BAE;&#x5728;&#x5B9E;&#x9645;&#x4F7F;&#x7528;&#x65F6;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#x8BE5;taskid
    printf("OnRecognitionStarted: status code=%d, task id=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId());
    // &#x83B7;&#x53D6;&#x670D;&#x52A1;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x5168;&#x90E8;&#x4FE1;&#x606F;
    //printf("OnRecognitionStarted: all response=%s\n", cbEvent->getAllResponse());
}

//@brief &#x8BBE;&#x7F6E;&#x5141;&#x8BB8;&#x8FD4;&#x56DE;&#x4E2D;&#x95F4;&#x7ED3;&#x679C;&#x53C2;&#x6570;, sdk&#x5728;&#x63A5;&#x6536;&#x5230;&#x4E91;&#x7AEF;&#x8FD4;&#x56DE;&#x5230;&#x4E2D;&#x95F4;&#x7ED3;&#x679C;&#x65F6;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;ResultChanged&#x4E8B;&#x4EF6;
//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionResultChanged(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // &#x6F14;&#x793A;&#x5982;&#x4F55;&#x6253;&#x5370;/&#x4F7F;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#x793A;&#x4F8B;
    printf("OnRecognitionResultChanged: %d, %s\n", tmpParam->userId, tmpParam->userInfo);
    // &#x5F53;&#x524D;&#x4EFB;&#x52A1;&#x7684;task id&#xFF0C;&#x65B9;&#x4FBF;&#x5B9A;&#x4F4D;&#x95EE;&#x9898;&#xFF0C;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#xFF0C;&#x7279;&#x522B;&#x63D0;&#x9192;&#x8BE5;taskid&#x975E;&#x5E38;&#x91CD;&#x8981;&#xFF0C;&#x662F;&#x548C;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;&#x7684;&#x552F;&#x4E00;&#x6807;&#x8BC6;&#xFF0C;&#x56E0;&#x6B64;&#x5EFA;&#x8BAE;&#x5728;&#x5B9E;&#x9645;&#x4F7F;&#x7528;&#x65F6;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#x8BE5;taskid
    printf("OnRecognitionResultChanged: status code=%d, task id=%s, result=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId(), cbEvent->getResult());
    // &#x83B7;&#x53D6;&#x670D;&#x52A1;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x5168;&#x90E8;&#x4FE1;&#x606F;
    //printf("OnRecognitionResultChanged: response=%s\n", cbEvent->getAllResponse());
}

//@brief sdk&#x5728;&#x63A5;&#x6536;&#x5230;&#x4E91;&#x7AEF;&#x8FD4;&#x56DE;&#x8BC6;&#x522B;&#x7ED3;&#x675F;&#x6D88;&#x606F;&#x65F6;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;Completed&#x4E8B;&#x4EF6;
//@note &#x4E0A;&#x62A5;Completed&#x4E8B;&#x4EF6;&#x4E4B;&#x540E;, SDK&#x5185;&#x90E8;&#x4F1A;&#x5173;&#x95ED;&#x8BC6;&#x522B;&#x8FDE;&#x63A5;&#x901A;&#x9053;. &#x6B64;&#x65F6;&#x8C03;&#x7528;sendAudio&#x4F1A;&#x8FD4;&#x56DE;-1, &#x8BF7;&#x505C;&#x6B62;&#x53D1;&#x9001;.

//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionCompleted(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // &#x6F14;&#x793A;&#x5982;&#x4F55;&#x6253;&#x5370;/&#x4F7F;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#x793A;&#x4F8B;
    printf("OnRecognitionCompleted: %d, %s\n", tmpParam->userId, tmpParam->userInfo);

    // &#x5F53;&#x524D;&#x4EFB;&#x52A1;&#x7684;task id&#xFF0C;&#x65B9;&#x4FBF;&#x5B9A;&#x4F4D;&#x95EE;&#x9898;&#xFF0C;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#xFF0C;&#x7279;&#x522B;&#x63D0;&#x9192;&#x8BE5;taskid&#x975E;&#x5E38;&#x91CD;&#x8981;&#xFF0C;&#x662F;&#x548C;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;&#x7684;&#x552F;&#x4E00;&#x6807;&#x8BC6;&#xFF0C;&#x56E0;&#x6B64;&#x5EFA;&#x8BAE;&#x5728;&#x5B9E;&#x9645;&#x4F7F;&#x7528;&#x65F6;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#x8BE5;taskid
    printf("OnRecognitionCompleted: status code=%d, task id=%s, result=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId(), cbEvent->getResult());
    g_result = cbEvent->getResult();
    Result::getInstance().send(g_result);
    // &#x83B7;&#x53D6;&#x670D;&#x52A1;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x5168;&#x90E8;&#x4FE1;&#x606F;
    //printf("OnRecognitionCompleted: response=%s\n", cbEvent->getAllResponse());
}

//@brief &#x8BC6;&#x522B;&#x8FC7;&#x7A0B;&#x53D1;&#x751F;&#x5F02;&#x5E38;&#x65F6;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;TaskFailed&#x4E8B;&#x4EF6;
//@note &#x4E0A;&#x62A5;TaskFailed&#x4E8B;&#x4EF6;&#x4E4B;&#x540E;, SDK&#x5185;&#x90E8;&#x4F1A;&#x5173;&#x95ED;&#x8BC6;&#x522B;&#x8FDE;&#x63A5;&#x901A;&#x9053;. &#x6B64;&#x65F6;&#x8C03;&#x7528;sendAudio&#x4F1A;&#x8FD4;&#x56DE;-1, &#x8BF7;&#x505C;&#x6B62;&#x53D1;&#x9001;.

//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
//@return
void OnRecognitionTaskFailed(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // &#x6F14;&#x793A;&#x5982;&#x4F55;&#x6253;&#x5370;/&#x4F7F;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#x793A;&#x4F8B;
    printf("OnRecognitionTaskFailed: %d, %s\n", tmpParam->userId, tmpParam->userInfo);

    // &#x5F53;&#x524D;&#x4EFB;&#x52A1;&#x7684;task id&#xFF0C;&#x65B9;&#x4FBF;&#x5B9A;&#x4F4D;&#x95EE;&#x9898;&#xFF0C;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#xFF0C;&#x7279;&#x522B;&#x63D0;&#x9192;&#x8BE5;taskid&#x975E;&#x5E38;&#x91CD;&#x8981;&#xFF0C;&#x662F;&#x548C;&#x670D;&#x52A1;&#x7AEF;&#x4EA4;&#x4E92;&#x7684;&#x552F;&#x4E00;&#x6807;&#x8BC6;&#xFF0C;&#x56E0;&#x6B64;&#x5EFA;&#x8BAE;&#x5728;&#x5B9E;&#x9645;&#x4F7F;&#x7528;&#x65F6;&#x5EFA;&#x8BAE;&#x8F93;&#x51FA;&#x8BE5;taskid
    printf("OnRecognitionTaskFailed: status code=%d, task id=%s, error message=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId(), cbEvent->getErrorMessage());
    // &#x83B7;&#x53D6;&#x670D;&#x52A1;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x5168;&#x90E8;&#x4FE1;&#x606F;
    //printf("OnRecognitionTaskFailed: response=%s\n", cbEvent->getAllResponse());
}

//@brief &#x8BC6;&#x522B;&#x7ED3;&#x675F;&#x6216;&#x53D1;&#x751F;&#x5F02;&#x5E38;&#x65F6;&#xFF0C;&#x4F1A;&#x5173;&#x95ED;&#x8FDE;&#x63A5;&#x901A;&#x9053;, sdk&#x5185;&#x90E8;&#x7EBF;&#x7A0B;&#x4E0A;&#x62A5;ChannelCloseed&#x4E8B;&#x4EF6;
//@param cbEvent &#x56DE;&#x8C03;&#x4E8B;&#x4EF6;&#x7ED3;&#x6784;, &#x8BE6;&#x89C1;nlsEvent.h
//@param cbParam &#x56DE;&#x8C03;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;NULL, &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x6C42;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;
void OnRecognitionChannelClosed(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // &#x6F14;&#x793A;&#x5982;&#x4F55;&#x6253;&#x5370;/&#x4F7F;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x53C2;&#x6570;&#x793A;&#x4F8B;
    printf("OnRecognitionChannelClosed: %d, %s\n", tmpParam->userId, tmpParam->userInfo);
    // &#x83B7;&#x53D6;&#x670D;&#x52A1;&#x7AEF; qDebug()<< m_strAppkey << m_strAKID;&#x8FD4;&#x56DE;&#x7684;&#x5168;&#x90E8;&#x4FE1;&#x606F;
    printf("OnRecognitionChannelClosed: response=%s\n", cbEvent->getAllResponse());
    delete tmpParam; //&#x8BC6;&#x522B;&#x6D41;&#x7A0B;&#x7ED3;&#x675F;,&#x91CA;&#x653E;&#x56DE;&#x8C03;&#x53C2;&#x6570;
}

void* pthreadFunction(void* arg) {
    int sleepMs = 0;
    ParamCallBack *cbParam = nullptr;

    //&#x521D;&#x59CB;&#x5316;&#x81EA;&#x5B9A;&#x4E49;&#x56DE;&#x8C03;&#x53C2;&#x6570;, &#x4EE5;&#x4E0B;&#x4E24;&#x53D8;&#x91CF;&#x4EC5;&#x4F5C;&#x4E3A;&#x793A;&#x4F8B;&#x8868;&#x793A;&#x53C2;&#x6570;&#x4F20;&#x9012;, &#x5728;demo&#x4E2D;&#x4E0D;&#x8D77;&#x4EFB;&#x4F55;&#x4F5C;&#x7528;
    //&#x56DE;&#x8C03;&#x53C2;&#x6570;&#x5728;&#x5806;&#x4E2D;&#x5206;&#x914D;&#x4E4B;&#x540E;, SDK&#x5728;&#x9500;&#x6BC1;requesr&#x5BF9;&#x8C61;&#x65F6;&#x4F1A;&#x4E00;&#x5E76;&#x9500;&#x6BC1;, &#x5916;&#x754C;&#x65E0;&#x9700;&#x5728;&#x91CA;&#x653E;
    cbParam = new ParamCallBack;
    cbParam->userId = rand() % 100;
    strcpy(cbParam->userInfo, "User.");

    // 0: &#x4ECE;&#x81EA;&#x5B9A;&#x4E49;&#x7EBF;&#x7A0B;&#x53C2;&#x6570;&#x4E2D;&#x83B7;&#x53D6;token, &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x7B49;&#x53C2;&#x6570;.

    ParamStruct *tst = (ParamStruct *) arg;
    if (tst == nullptr) {
        printf("arg is not valid\n");
        return nullptr;
    }

    // &#x6253;&#x5F00;&#x97F3;&#x9891;&#x6587;&#x4EF6;, &#x83B7;&#x53D6;&#x6570;&#x636E;
    std::ifstream fs;
    fs.open(tst->fileName.c_str(), std::ios::binary | std::ios::in);
    if (!fs) {
        printf("%s isn't exist..\n", tst->fileName.c_str());
        return nullptr;
    }

    //1: &#x521B;&#x5EFA;&#x4E00;&#x53E5;&#x8BDD;&#x8BC6;&#x522B;SpeechRecognizerRequest&#x5BF9;&#x8C61;
    SpeechRecognizerRequest *request = NlsClient::getInstance()->createRecognizerRequest();
    if (request == nullptr) {
        printf("createRecognizerRequest failed\n");
        return nullptr;
    }

    request->setOnRecognitionStarted(OnRecognitionStarted, cbParam);        // &#x8BBE;&#x7F6E;start()&#x6210;&#x529F;&#x56DE;&#x8C03;&#x51FD;&#x6570;
    request->setOnTaskFailed(OnRecognitionTaskFailed, cbParam);             // &#x8BBE;&#x7F6E;&#x5F02;&#x5E38;&#x8BC6;&#x522B;&#x56DE;&#x8C03;&#x51FD;&#x6570;
    request->setOnChannelClosed(OnRecognitionChannelClosed, cbParam);       // &#x8BBE;&#x7F6E;&#x8BC6;&#x522B;&#x901A;&#x9053;&#x5173;&#x95ED;&#x56DE;&#x8C03;&#x51FD;&#x6570;
    request->setOnRecognitionResultChanged(OnRecognitionResultChanged, cbParam); // &#x8BBE;&#x7F6E;&#x4E2D;&#x95F4;&#x7ED3;&#x679C;&#x56DE;&#x8C03;&#x51FD;&#x6570;
    request->setOnRecognitionCompleted(OnRecognitionCompleted, cbParam);    // &#x8BBE;&#x7F6E;&#x8BC6;&#x522B;&#x7ED3;&#x675F;&#x56DE;&#x8C03;&#x51FD;&#x6570;

    request->setAppKey(tst->appkey.c_str());        // &#x8BBE;&#x7F6E;AppKey, &#x5FC5;&#x586B;&#x53C2;&#x6570;, &#x8BF7;&#x53C2;&#x7167;&#x5B98;&#x7F51;&#x7533;&#x8BF7;
    request->setFormat("pcm");                      // &#x8BBE;&#x7F6E;&#x97F3;&#x9891;&#x6570;&#x636E;&#x7F16;&#x7801;&#x683C;&#x5F0F;, &#x53EF;&#x9009;&#x53C2;&#x6570;, &#x76EE;&#x524D;&#x652F;&#x6301;pcm, opus. &#x9ED8;&#x8BA4;&#x662F;pcm
    request->setSampleRate(SAMPLE_RATE);            // &#x8BBE;&#x7F6E;&#x97F3;&#x9891;&#x6570;&#x636E;&#x91C7;&#x6837;&#x7387;, &#x53EF;&#x9009;&#x53C2;&#x6570;, &#x76EE;&#x524D;&#x652F;&#x6301;16000, 8000. &#x9ED8;&#x8BA4;&#x662F;16000
    request->setIntermediateResult(true);           // &#x8BBE;&#x7F6E;&#x662F;&#x5426;&#x8FD4;&#x56DE;&#x4E2D;&#x95F4;&#x8BC6;&#x522B;&#x7ED3;&#x679C;, &#x53EF;&#x9009;&#x53C2;&#x6570;. &#x9ED8;&#x8BA4;false
    request->setPunctuationPrediction(true);        // &#x8BBE;&#x7F6E;&#x662F;&#x5426;&#x5728;&#x540E;&#x5904;&#x7406;&#x4E2D;&#x6DFB;&#x52A0;&#x6807;&#x70B9;, &#x53EF;&#x9009;&#x53C2;&#x6570;. &#x9ED8;&#x8BA4;false
    request->setInverseTextNormalization(true);     // &#x8BBE;&#x7F6E;&#x662F;&#x5426;&#x5728;&#x540E;&#x5904;&#x7406;&#x4E2D;&#x6267;&#x884C;ITN, &#x53EF;&#x9009;&#x53C2;&#x6570;. &#x9ED8;&#x8BA4;false
    //request->setEnableVoiceDetection(true);       //&#x662F;&#x5426;&#x542F;&#x52A8;&#x8BED;&#x97F3;&#x68C0;&#x6D4B;, &#x53EF;&#x9009;, &#x9ED8;&#x8BA4;&#x662F;False
    //&#x5141;&#x8BB8;&#x7684;&#x6700;&#x5927;&#x5F00;&#x59CB;&#x9759;&#x97F3;, &#x53EF;&#x9009;, &#x5355;&#x4F4D;&#x662F;&#x6BEB;&#x79D2;, &#x8D85;&#x51FA;&#x540E;&#x670D;&#x52A1;&#x7AEF;&#x5C06;&#x4F1A;&#x53D1;&#x9001;RecognitionCompleted&#x4E8B;&#x4EF6;, &#x7ED3;&#x675F;&#x672C;&#x6B21;&#x8BC6;&#x522B;. &#x6CE8;&#x610F;: &#x9700;&#x8981;&#x5148;&#x8BBE;&#x7F6E;enable_voice_detection&#x4E3A;true
    //request->setMaxStartSilence(5000);
    //&#x5141;&#x8BB8;&#x7684;&#x6700;&#x5927;&#x7ED3;&#x675F;&#x9759;&#x97F3;, &#x53EF;&#x9009;, &#x5355;&#x4F4D;&#x662F;&#x6BEB;&#x79D2;, &#x8D85;&#x51FA;&#x540E;&#x670D;&#x52A1;&#x7AEF;&#x5C06;&#x4F1A;&#x53D1;&#x9001;RecognitionCompleted&#x4E8B;&#x4EF6;, &#x7ED3;&#x675F;&#x672C;&#x6B21;&#x8BC6;&#x522B;. &#x6CE8;&#x610F;: &#x9700;&#x8981;&#x5148;&#x8BBE;&#x7F6E;enable_voice_detection&#x4E3A;true
    //request->setMaxEndSilence(800);
    //request->setCustomizationId("TestId_123"); //&#x5B9A;&#x5236;&#x8BED;&#x8A00;&#x6A21;&#x578B;id, &#x53EF;&#x9009;.

    //request->setVocabularyId("TestId_456"); //&#x5B9A;&#x5236;&#x6CDB;&#x70ED;&#x8BCD;id, &#x53EF;&#x9009;.

    // &#x7528;&#x4E8E;&#x4F20;&#x9012;&#x67D0;&#x4E9B;&#x5B9A;&#x5236;&#x5316;&#x3001;&#x9AD8;&#x7EA7;&#x53C2;&#x6570;&#x8BBE;&#x7F6E;&#xFF0C;&#x53C2;&#x6570;&#x683C;&#x5F0F;&#x4E3A;json&#x683C;&#x5F0F;&#xFF1A; {"key": "value"}
    //request->setPayloadParam("{\"vad_model\": \"farfield\"}");

    request->setToken(tst->token.c_str()); // &#x8BBE;&#x7F6E;&#x8D26;&#x53F7;&#x6821;&#x9A8C;token, &#x5FC5;&#x586B;&#x53C2;&#x6570;

    // 2: start()&#x4E3A;&#x5F02;&#x6B65;&#x64CD;&#x4F5C;&#x3002;&#x6210;&#x529F;&#x8FD4;&#x56DE;started&#x4E8B;&#x4EF6;&#x3002;&#x5931;&#x8D25;&#x8FD4;&#x56DE;TaskFailed&#x4E8B;&#x4EF6;&#x3002;
    if (request->start() < 0) {
        printf("start() failed. may be can not connect server. please check network or firewalld\n");
        NlsClient::getInstance()->releaseRecognizerRequest(request); // start()&#x5931;&#x8D25;&#xFF0C;&#x91CA;&#x653E;request&#x5BF9;&#x8C61;
        return nullptr;
    }

    while (!fs.eof()) {
        uint8_t data[FRAME_SIZE] = {0};
        fs.read((char *) data, sizeof(uint8_t) * FRAME_SIZE);
        size_t nlen = fs.gcount();
        if (nlen <= 0) { continue; } 3: 发送音频数据. sendaudio为异步操作, 返回-1表示发送失败, 需要停止发送. int ret="request-">sendAudio(data, nlen);
        if (ret < 0) {
            // &#x53D1;&#x9001;&#x5931;&#x8D25;, &#x9000;&#x51FA;&#x5FAA;&#x73AF;&#x6570;&#x636E;&#x53D1;&#x9001;
            printf("send data fail.\n");
            break;
        }

        // &#x8BED;&#x97F3;&#x6570;&#x636E;&#x53D1;&#x9001;&#x63A7;&#x5236;&#xFF1A;
        // &#x8BED;&#x97F3;&#x6570;&#x636E;&#x662F;&#x5B9E;&#x65F6;&#x7684;, &#x4E0D;&#x7528;sleep&#x63A7;&#x5236;&#x901F;&#x7387;, &#x76F4;&#x63A5;&#x53D1;&#x9001;&#x5373;&#x53EF;.

        // &#x8BED;&#x97F3;&#x6570;&#x636E;&#x6765;&#x81EA;&#x6587;&#x4EF6;&#xFF08;&#x4E5F;&#x5373;&#x672C;&#x793A;&#x4F8B;&#x4EE3;&#x7801;&#x6A21;&#x62DF;&#x7684;&#x8BED;&#x97F3;&#x6D41;&#x53D1;&#x9001;&#x673A;&#x5236;&#xFF09;, &#x53D1;&#x9001;&#x65F6;&#x9700;&#x8981;&#x63A7;&#x5236;&#x901F;&#x7387;, &#x4F7F;&#x5355;&#x4F4D;&#x65F6;&#x95F4;&#x5185;&#x53D1;&#x9001;&#x7684;&#x6570;&#x636E;&#x5927;&#x5C0F;&#x63A5;&#x8FD1;&#x5355;&#x4F4D;&#x65F6;&#x95F4;&#x539F;&#x59CB;&#x8BED;&#x97F3;&#x6570;&#x636E;&#x5B58;&#x50A8;&#x7684;&#x5927;&#x5C0F;.

        sleepMs = getSendAudioSleepTime(nlen, SAMPLE_RATE, 1); // &#x6839;&#x636E; &#x53D1;&#x9001;&#x6570;&#x636E;&#x5927;&#x5C0F;&#xFF0C;&#x91C7;&#x6837;&#x7387;&#xFF0C;&#x6570;&#x636E;&#x538B;&#x7F29;&#x6BD4; &#x6765;&#x83B7;&#x53D6;sleep&#x65F6;&#x95F4;
        // 4: &#x8BED;&#x97F3;&#x6570;&#x636E;&#x53D1;&#x9001;&#x5EF6;&#x65F6;&#x63A7;&#x5236;
        usleep(sleepMs * 1000);
    }
    printf("sendAudio done.\n");

    //5: &#x5173;&#x95ED;&#x97F3;&#x9891;&#x6587;&#x4EF6;
    fs.close();

    //6: &#x901A;&#x77E5;&#x4E91;&#x7AEF;&#x6570;&#x636E;&#x53D1;&#x9001;&#x7ED3;&#x675F;.

    //stop()&#x4E3A;&#x5F02;&#x6B65;&#x64CD;&#x4F5C;.&#x5931;&#x8D25;&#x8FD4;&#x56DE;TaskFailed&#x4E8B;&#x4EF6;&#x3002;
    request->stop();

    //7: &#x901A;&#x77E5;SDK&#x91CA;&#x653E;request.

    NlsClient::getInstance()->releaseRecognizerRequest(request);
    return nullptr;
}

//&#x7EBF;&#x7A0B;&#x5FAA;&#x73AF;&#x8BC6;&#x522B;
//&#x9700;&#x8981;&#x8C03;&#x6574;count&#x503C;&#x548C;&#x6BCF;&#x6B21;&#x8981;&#x8BC6;&#x522B;&#x7684;&#x6587;&#x4EF6;&#xFF0C;Demo&#x4E2D;&#x9ED8;&#x8BA4;&#x6BCF;&#x6B21;&#x8BC6;&#x522B;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;
void* multiRecognize(void* arg) {
    int count = 2;
    while (count > 0) {
        pthreadFunction(arg);
        count--;
    }
    return nullptr;
}

// &#x8BC6;&#x522B;&#x5355;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;
int speechRecognizerFile() {
     //&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x65F6;&#x95F4;&#x6233;&#xFF0C;&#x5224;&#x65AD;token&#x662F;&#x5426;&#x8FC7;&#x671F;
//    std::time_t curTime = std::time(0);
//    if (g_expireTime - curTime < 10) {
//      printf("the token will be expired, please generate new token by AccessKey-ID and AccessKey-Secret.\n");
//        if (-1 == generateToken(g_akId, g_akSecret, &g_token, &g_expireTime)) {
//            return -1;
//        }
//    }

    ParamStruct pa;
    pa.token = g_token;
    pa.appkey =g_appkey;
    pa.fileName = "test.wav";

    pthread_t pthreadId;
    // &#x542F;&#x52A8;&#x4E00;&#x4E2A;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;, &#x7528;&#x4E8E;&#x5355;&#x6B21;&#x8BC6;&#x522B;
    pthread_create(&pthreadId, nullptr, &pthreadFunction, (void *)&pa);
    // &#x542F;&#x52A8;&#x4E00;&#x4E2A;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;, &#x7528;&#x4E8E;&#x5FAA;&#x73AF;&#x8BC6;&#x522B;
    // pthread_create(&pthreadId, NULL, &multiRecognize, (void *)&pa);
    pthread_join(pthreadId, nullptr);
    return 0;
}

 //&#x8BC6;&#x522B;&#x591A;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;;
 //sdk&#x591A;&#x7EBF;&#x7A0B;&#x6307;&#x4E00;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;&#x6E90;&#x5BF9;&#x5E94;&#x4E00;&#x4E2A;&#x7EBF;&#x7A0B;, &#x975E;&#x4E00;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;&#x5BF9;&#x5E94;&#x591A;&#x4E2A;&#x7EBF;&#x7A0B;.

 //&#x793A;&#x4F8B;&#x4EE3;&#x7801;&#x4E3A;&#x540C;&#x65F6;&#x5F00;&#x542F;2&#x4E2A;&#x7EBF;&#x7A0B;&#x8BC6;&#x522B;2&#x4E2A;&#x6587;&#x4EF6;;
 //&#x514D;&#x8D39;&#x7528;&#x6237;&#x5E76;&#x53D1;&#x8FDE;&#x63A5;&#x4E0D;&#x80FD;&#x8D85;&#x8FC7;2&#x4E2A;;
#define AUDIO_FILE_NUMS 2
#define AUDIO_FILE_NAME_LENGTH 32
int speechRecognizerMultFile(const char* appkey) {
    //&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7CFB;&#x7EDF;&#x65F6;&#x95F4;&#x6233;&#xFF0C;&#x5224;&#x65AD;token&#x662F;&#x5426;&#x8FC7;&#x671F;
//    std::time_t curTime = std::time(0);
//    if (g_expireTime - curTime < 10) {
//      printf("the token will be expired, please generate new token by AccessKey-ID and AccessKey-Secret.\n");
//        if (-1 == generateToken(g_akId, g_akSecret, &g_token, &g_expireTime)) {
//           return -1;
//        }
//    }

    char audioFileNames[AUDIO_FILE_NUMS][AUDIO_FILE_NAME_LENGTH] = {"test0.wav", "test1.wav"};
    ParamStruct pa[AUDIO_FILE_NUMS];

    for (int i = 0; i < AUDIO_FILE_NUMS; i ++) {
        pa[i].token = g_token;
        pa[i].appkey = appkey;
        pa[i].fileName = audioFileNames[i];
    }

    std::vector<pthread_t> pthreadId(AUDIO_FILE_NUMS);
    // &#x542F;&#x52A8;AUDIO_FILE_NUMS&#x4E2A;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;, &#x540C;&#x65F6;&#x8BC6;&#x522B;AUDIO_FILE_NUMS&#x4E2A;&#x97F3;&#x9891;&#x6587;&#x4EF6;
    for (int j = 0; j < AUDIO_FILE_NUMS; j++) {
        pthread_create(&pthreadId[j], nullptr, &pthreadFunction, (void *)&(pa[j]));
    }
    for (int j = 0; j < AUDIO_FILE_NUMS; j++) {
        pthread_join(pthreadId[j], nullptr);
    }
    return 0;
}
#if 0
int main(int arc, char* argv[]) {
    if (arc < 4) {
        printf("params is not valid. Usage: ./demo <your appkey> <your accesskey id> <your accesskey secret>\n");
        return -1;
    }

    std::string appkey = argv[1];
    g_akId = argv[2];
    g_akSecret = argv[3];

    // &#x6839;&#x636E;&#x9700;&#x8981;&#x8BBE;&#x7F6E;SDK&#x8F93;&#x51FA;&#x65E5;&#x5FD7;, &#x53EF;&#x9009;. &#x6B64;&#x5904;&#x8868;&#x793A;SDK&#x65E5;&#x5FD7;&#x8F93;&#x51FA;&#x81F3;log-recognizer.txt&#xFF0C; LogDebug&#x8868;&#x793A;&#x8F93;&#x51FA;&#x6240;&#x6709;&#x7EA7;&#x522B;&#x65E5;&#x5FD7;&#xFF0C;&#x652F;&#x6301;LogInfo&#x3001;LogWarning&#x3001;LogError&#xFF0C; 400&#x8868;&#x793A;&#x5355;&#x4E2A;&#x6587;&#x4EF6;400MB
    int ret = NlsClient::getInstance()->setLogConfig("log-recognizer", LogDebug, 400);
    if (-1 == ret) {
        printf("set log failed.\n");
        return -1;
    }

    //&#x542F;&#x52A8;&#x5DE5;&#x4F5C;&#x7EBF;&#x7A0B;
    NlsClient::getInstance()->startWorkThread(4);

    // &#x8BC6;&#x522B;&#x5355;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;
    speechRecognizerFile(appkey.c_str());

    // &#x5E76;&#x53D1;&#x8BC6;&#x522B;&#x591A;&#x4E2A;&#x97F3;&#x9891;&#x6570;&#x636E;
    //speechRecognizerMultFile(appkey.c_str());

    // &#x6240;&#x6709;&#x5DE5;&#x4F5C;&#x5B8C;&#x6210;&#xFF0C;&#x8FDB;&#x7A0B;&#x9000;&#x51FA;&#x524D;&#xFF0C;&#x91CA;&#x653E;nlsClient. &#x8BF7;&#x6CE8;&#x610F;, releaseInstance()&#x975E;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;.

    NlsClient::releaseInstance();
    return 0;
}
#endif
</your></your></your></pthread_t></=>

13.config

diThhK1nbgO8NcG0
LTAI5tAhmUo4aKLdVuu1oKTK
tAjf2qsmsrAoq5fTqkwFYJzbh7uNqS
f1c642a7436349849823997d469e6841

Original: https://blog.csdn.net/weixin_41392061/article/details/117431550
Author: weixin_41392061
Title: QT实现语音识别功能



相关阅读1

Title: 常用的图像增强方法

大规模数据集是成功应用深度神经网络的前提。例如,我们可以对图像进行不同方式的裁剪,使感兴趣的物体出现在不同位置,从而减轻模型对物体出现位置的依赖性。我们也可以调整亮度、色彩等因素来降低模型对色彩的敏感度。可以说,在当年AlexNet的成功中,图像增强技术功不可没

1.常用的图像增强方法

图像增强(image augmentation)指通过剪切、旋转/反射/翻转变换、缩放变换、平移变换、尺度变换、对比度变换、噪声扰动、颜色变换等一种或多种组合数据增强变换的方式来增加数据集的大小。图像增强的意义是通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模,而且随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。

常见的图像增强方式可以分为两类:几何变换类和颜色变换类

  • 几何变换类,主要是对图像进行几何变换操作,包括翻转,旋转,裁剪,变形,缩放等。

  • 颜色变换类,指通过模糊、颜色变换、擦除、填充等方式对图像进行处理

实现图像增强可以通过tf.image来完成,也可以通过tf.keras.imageGenerator来完成。

2.tf.image进行图像增强

导入所需的工具包并读取要处理的图像:

&#x5BFC;&#x5165;&#x5DE5;&#x5177;&#x5305;
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
&#x8BFB;&#x53D6;&#x56FE;&#x50CF;&#x5E76;&#x663E;&#x793A;
cat = plt.imread('./cat.jpg')
plt.imshow(cat)

左右翻转图像是最早也是最广泛使用的一种图像增广方法。可以通过 tf.image.random_flip_left_right来实现图像左右翻转。

&#x5DE6;&#x53F3;&#x7FFB;&#x8F6C;&#x5E76;&#x663E;&#x793A;
cat1 = tf.image.random_flip_left_right(cat)
plt.imshow(cat1&#xFF09;

创建 tf.image.random_flip_up_down实例来实现图像的上下翻转,上下翻转使用的较少。

&#x4E0A;&#x4E0B;&#x7FFB;&#x8F6C;
cat2 = tf.image.random_flip_up_down(cat)
plt.imshow(cat2)
&#x968F;&#x673A;&#x88C1;&#x526A;
cat3 = tf.image.random_crop(cat,(200,200,3))
plt.imshow(cat3)

另一类增广方法是颜色变换。我们可以从4个方面改变图像的颜色:亮度、对比度、饱和度和色调。接下来将图像的亮度随机变化为原图亮度的50%50%(即1−0.51−0.5)∼150%∼150%(即1+0.51+0.5)。

cat4=tf.image.random_brightness(cat,0.5)
plt.imshow(cat4)

类似地,我们也可以随机变化图像的色调

cat5 = tf.image.random_hue(cat,0.5)
plt.imshow(cat5)

3 使用ImageDataGenerator()进行图像增强

ImageDataGenerator()是keras.preprocessing.image模块中的图片生成器,可以在batch中对数据进行增强,扩充数据集大小,增强模型的泛化能力。比如旋转,变形等,如下所示:

keras.preprocessing.image.ImageDataGenerator(
               rotation_range=0, #&#x6574;&#x6570;&#x3002;&#x968F;&#x673A;&#x65CB;&#x8F6C;&#x7684;&#x5EA6;&#x6570;&#x8303;&#x56F4;&#x3002;
               width_shift_range=0.0, #&#x6D6E;&#x70B9;&#x6570;&#x3001;&#x5BBD;&#x5EA6;&#x5E73;&#x79FB;
               height_shift_range=0.0, #&#x6D6E;&#x70B9;&#x6570;&#x3001;&#x9AD8;&#x5EA6;&#x5E73;&#x79FB;
               brightness_range=None, # &#x4EAE;&#x5EA6;&#x8C03;&#x6574;
               shear_range=0.0, # &#x88C1;&#x526A;
               zoom_range=0.0, #&#x6D6E;&#x70B9;&#x6570; &#x6216; [lower, upper]&#x3002;&#x968F;&#x673A;&#x7F29;&#x653E;&#x8303;&#x56F4;
               horizontal_flip=False, # &#x5DE6;&#x53F3;&#x7FFB;&#x8F6C;
               vertical_flip=False, # &#x5782;&#x76F4;&#x7FFB;&#x8F6C;
               rescale=None # &#x5C3A;&#x5EA6;&#x8C03;&#x6574;
            )

来看下水平翻转的结果:

&#x83B7;&#x53D6;&#x6570;&#x636E;&#x96C6;
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
&#x5C06;&#x6570;&#x636E;&#x8F6C;&#x6362;&#x4E3A;4&#x7EF4;&#x7684;&#x5F62;&#x5F0F;
x_train = X_train.reshape(X_train.shape[0],28,28,1)
x_test = X_test.reshape(X_test.shape[0],28,28,1)
&#x8BBE;&#x7F6E;&#x56FE;&#x50CF;&#x589E;&#x5F3A;&#x65B9;&#x5F0F;&#xFF1A;&#x6C34;&#x5E73;&#x7FFB;&#x8F6C;
datagen = ImageDataGenerator(horizontal_flip=True)
&#x67E5;&#x770B;&#x589E;&#x5F3A;&#x540E;&#x7684;&#x7ED3;&#x679C;
for X_batch,y_batch in datagen.flow(x_train,y_train,batch_size=9):
    plt.figure(figsize=(8,8)) # &#x8BBE;&#x5B9A;&#x6BCF;&#x4E2A;&#x56FE;&#x50CF;&#x663E;&#x793A;&#x7684;&#x5927;&#x5C0F;
    # &#x4EA7;&#x751F;&#x4E00;&#x4E2A;3*3&#x7F51;&#x683C;&#x7684;&#x56FE;&#x50CF;
    for i in range(0,9):
        plt.subplot(330+1+i)
        plt.title(y_batch[i])
        plt.axis('off')
        plt.imshow(X_batch[i].reshape(28,28),cmap='gray')
    plt.show()
    break

Original: https://blog.csdn.net/weixin_46556352/article/details/124167804
Author: AI耽误的大厨
Title: 常用的图像增强方法

相关阅读2

Title: 【平头哥RVB2601开发板试用体验】基于 HTTPClient 的云语音识别 2

作者 | 哈猪猪

在文章1中我们计划用 HTTPClient 组件帮助我们与服务器通信,上传录音文件并接收识别结果,最终实现云语音识别。经过测试后没有问题,因此接下来我们需要理解该组件提供的功能,并实现文件对服务器的上传。

首先,根据 HTTPClient 组件的示例程序 http_examples.c,我们得知了一个完整的 HTTP 请求需要调用的接口流程,大致如下。以 POST 请求为例,并直接设置 url 而非 host&path:

http_client_config_t config = {
    .url = "http://httpbin.org/get",
    .event_handler = _http_event_handler,
};
http_client_handle_t client = http_client_init(&config);
&#x200B;
const char *post_data = "field1=value1&field2=value2";
http_client_set_method(client, HTTP_METHOD_POST);
http_client_set_post_field(client, post_data, strlen(post_data));
err = http_client_perform(client);
if (err == HTTP_CLI_OK) {
    LOGI(TAG, "HTTP POST Status = %d, content_length = %d \r\n",
            http_client_get_status_code(client),
            http_client_get_content_length(client));
} else {
    LOGE(TAG, "HTTP POST request failed: 0x%x @#@@@@@@", (err));
    e_count ++;
}

整个流程主要涉及到以下几个函数:

http_client_init() 主要是基于 config 对 client 结构的各种变量赋初值,包括在请求中会用的到的各种缓存空间,以及 header 中的基本信息。其中 config 未设置的会赋缺省值。也可以用库提供的各种 set_xxx 函数来对变量赋值。

http_client_set_post_field():对于有请求体的 POST,我们需要调用这个函数将发送数据的指针以及长度赋予 client:

web_err_t http_client_set_post_field(http_client_handle_t client, const char *data, int len)
{
    web_err_t err = WEB_OK;
    client->post_data = (char *)data;   // &#x5F85;&#x53D1;&#x9001;&#x6570;&#x636E;&#x6307;&#x9488;
    client->post_len = len;             // &#x5F85;&#x53D1;&#x9001;&#x6570;&#x636E;&#x957F;&#x5EA6;
    LOGD(TAG, "set post file length = %d", len);
    // &#x5982;&#x679C;&#x6B64;&#x524D;&#x6CA1;&#x6709;&#x8BBE;&#x7F6E; Content-Type&#xFF0C;&#x5219;&#x8BBE;&#x7F6E;&#x4E3A; application/x-www-form-urlencoded
    if (client->post_data)
    {
        char *value = NULL;
        if ((err = http_client_get_header(client, "Content-Type", &value)) != WEB_OK)
        {
            return err;
        }
        if (value == NULL)
        {
            err = http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");
        }
    }
    else
    {
        client->post_len = 0;
        err = http_client_set_header(client, "Content-Type", NULL);
    }
    return err;
}

阅读源码可见,库默认支持"Content-Type"为"application/x-www-form-urlencoded"的 POST 请求,而我们要上传音频文件是"multipart/form-data"类型的。然而浏览了整个 HTTPClient 组件发现它就支持这一种类型......POST 的具体实现也只支持这一种。我们接着往下看就知道了......

http_client_perform():无论是什么 HTTP 请求,在设置完 client 之后最后都是经由这一个函数来具体实现。该函数将根据当前所处的 HTTP 请求流程,调用对应的函数,而这些函数最终会调用 transport 组件即在传输层上读写,最终实现整个 HTTP 请求。http_client_perform() 依次主要调用了以下几个函数:

http_client_prepare();
http_client_connect();
http_client_request_send();
http_client_send_post_data();
http_client_fetch_headers();
http_check_response();
http_client_get_data();
http_client_close();

实现的功能与其函数名一致,也是我们熟知的 HTTP 请求流程。其中我们最关心的当然是http_client_send_post_data():

static web_err_t http_client_send_post_data(http_client_handle_t client)
{
    // &#x6B64;&#x65F6;&#x8BF7;&#x6C42;&#x5934;&#x5E94;&#x53D1;&#x9001;&#x5B8C;&#x6BD5;
    if (client->state != HTTP_STATE_REQ_COMPLETE_HEADER)
    {
        LOGE(TAG, "Invalid state");
        return WEB_ERR_INVALID_STATE;
    }
    // &#x6CA1;&#x6709;&#x8981;&#x53D1;&#x9001;&#x7684; post_data &#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#xFF08;&#x5305;&#x62EC;&#x5176;&#x5B83;&#x8BF7;&#x6C42;&#xFF09;
    if (!(client->post_data && client->post_len))
    {
        goto success;
    }
&#x200B;
    // &#x53D1;&#x9001; post_data
    int wret = http_client_write(client, client->post_data + client->data_written_index, client->data_write_left);
    if (wret < 0)
    {
        return wret;
    }
    // &#x5728; request send &#x91CC;&#x9762; data_write_left &#x6700;&#x540E;&#x88AB;&#x8D4B;&#x503C;&#x4E3A; post_len
    client->data_write_left -= wret;
    // &#x5728; request send &#x91CC;&#x9762; data_written_index &#x6700;&#x540E;&#x88AB;&#x8D4B;&#x503C;&#x4E3A; 0
    client->data_written_index += wret;
&#x200B;
    // &#x53D1;&#x9001;&#x5B8C;&#x6BD5;
    if (client->data_write_left <= 0) { goto success; } else return err_http_write_data; ​ success: 更新状态 client->state = HTTP_STATE_REQ_COMPLETE_DATA;
    return WEB_OK;
}</=>

可见,整个 POST 实现只会发送一次 post_data,它指向我们最初在 http_client_set_post_field() 中填入的待发送数据。然而,我们知道要发送"multipart/form-data"类型的数据,需要按照格式用 boundary 对请求体进行封装,并在请求头中提前告知 boundary。当然,HTTPClient 组件是没有实现这些的......因此如果我们要利用 HTTPClient 发送音频数据,就必须手动实现"multipart/form-data"类型请求体的封装与发送。

当我终于大致理解了 HTTPClient 组件后,我在浏览 YOC 源码时发现了一个就叫"http"的组件,它并没有出现在 YOC 文档里然而它已经实现了"multipart/form-data"类型的 POST......囿于我技术水平有限,源码缺少注释,感觉学习成本过高,遂放弃。

事实上针对本项目要实现的云语音识别,YOC 还有很多更适合的组件:麦克风服务,云音交互(AUI Cloud)......甚至后者本身就是为语音识别等应用构建的。然而由于源码没有注释,只有接口介绍文档,以及其它板子上的相关例程,感觉"移植"组件对自己难度过大,最终都没有使用,选择了基于 HTTPClient 手动实现音频数据的发送。

欢迎关注公众号: 芯片开放社区(ID:OCC_THEAD),查看更多应用实战文章。

Original: https://blog.csdn.net/OCC_THEAD/article/details/123706836
Author: 平头哥芯片开放社区
Title: 【平头哥RVB2601开发板试用体验】基于 HTTPClient 的云语音识别 2

相关阅读3

Title: cuda10.1+cudnn10.1+tensorflow2.2.0+pytorch1.7.1下载安装及配置

一、cuda及cudnn下载

1、查看自己电脑是否支持GPU

方法:鼠标移动到此电脑,点击鼠标右键,依次选择属性、设备管理器、显示适配器有以下图标(NVIDIA)即可安装GPU,我的是MX130的。

QT实现语音识别功能

2、选择和自己电脑相匹配的cuda版本

2.1 查看自己电脑cuda版本:点击电脑左下角的搜索图标(放大镜)输入NVIDIA,选择如下应用

QT实现语音识别功能

点击帮助、系统信息、组件找到NVCUDA64.DLL查看cuda版本,显示的是最高可安装的cuda版本,并非仅支持,我的是11.2.162版本

QT实现语音识别功能

3、下载cuda

cuda官网:CUDA Toolkit Archive | NVIDIA Developer

游览器打开相比较于迅雷更慢,下载速度也很慢,建议直接复制网址进入迅雷搜索下载,进入后选择与自己电脑相匹配的版本,选择10.1

下载速度慢的另一个方法是通过像迅雷一样的第三方软件 Internet Download Manager下载(哔哩哔哩看到的,未亲测)

QT实现语音识别功能

点击进入后,选择自己的系统,我的是WIN10系统(local完整版2.8G,network程序很小59.2MB),建议选择完整版,点击download下载完成即可

QT实现语音识别功能

4、下载CUDNN 安装包

CUDNN官网:https://developer.nvidia.com/rdp/cudnn-download

方法和下载cuda一样,建议复制链接到迅雷下载

显示需要会员才能下载,点击立即加入,用邮箱注册一个账号,填写一个调查问卷即可下载

QT实现语音识别功能

注册登陆后,勾选下列图标,进入CUDNN版本选择页

QT实现语音识别功能

下图所显示的下面的链接表示10.2以前的版本,我的是11.2的,选择上面的版本,如下图QT实现语音识别功能

点开链接后选择和自己电脑系统匹配的CUDNN,点击进入,即跳转到下载界面,接着选择自己的下载路径即可

QT实现语音识别功能

二、cuda安装

1、移动鼠标到cuda安装包上,选择以管理员身份运行,如下图

QT实现语音识别功能

2、选择安装路径,选择不存在的,能够自己创建(建议选择默认路径,因为后面的安装需要相同的路径)

QT实现语音识别功能

点击OK进入下一步

QT实现语音识别功能

进入cuda安装环境后不要进行任何操作

返回电脑桌面,滑动鼠标右击此电脑—管理—服务和应用程序—服务

找到Windows Installer点击启动此服

QT实现语音识别功能

选择自定义安装,下一步

QT实现语音识别功能

下一步全部选择,电脑有更高的驱动的话,下面三个均可以不选

QT实现语音识别功能

下一步选择安装位置(建议默认)

QT实现语音识别功能

下一步如果有Visual Studio则勾选以下图标,没有则先安装Visual StudioQT实现语音识别功能最后,点击next进行安装,接下来就等着安装就可以了

我也是摸索了好几天,下了好几个版本,最终成功了cuda10.1

里面有cuda10.1+cudann,cuda10.0+cudann,cuda11.2+cudnn,有需要的自行下载

提取码:2458

cuda10.1+cudnn+torch1.7.1+torchvision0.8.2+torchaudio0.7.2 QT实现语音识别功能https://pan.baidu.com/s/1nAc24qkIUPz8lta0_XOedA ;

tensorflow,torch详细配置见

torch.cuda.is_available()返回false——解决办法_Nefu_lyh的博客-CSDN博客

Original: https://blog.csdn.net/qq_53057371/article/details/121358408
Author: qq_53057371
Title: cuda10.1+cudnn10.1+tensorflow2.2.0+pytorch1.7.1下载安装及配置