C++ SDK

更新时间:
复制 MD 格式

This topic describes how to use the C++ software development kit (SDK) for Alibaba Cloud Intelligent Speech Interaction. It provides installation instructions and code examples.

Prerequisites

Download and install

Download the SDK

You can obtain the SDK in one of the following two ways.

  • Method 1: Obtain the latest source code from GitHub. For detailed compilation and running instructions, see the following sections or the readme.md file in the source code.

    git clone --depth 1 https://github.com/aliyun/alibabacloud-nls-cpp-sdk
  • Method 2: Download the required SDK package directly from the table below. The SDK source code package contains the original SDK code, which you must compile to generate the library files required for integration. The other SDK packages are platform-specific, contain the relevant library and header files, and do not require compilation.

    Latest SDK package

    Platform

    MD5

    alibabacloud-nls-cpp-sdk3.3.0b-master_cbcac53.zip

    SDK source code

    7257c0998654e611cf2e8ca9867670ef

    NlsCppSdk_Linux-x86_64_3.3.0b_cbcac53.tar.gz

    Linux x86_64

    9a93df607f26f1558bc1043a425af6d1

    Note

    The Linux-x86_64 version is compiled with gcc 8.4.0 and _GLIBCXX_USE_CXX11_ABI=0. You can recompile it using the source code package and following the instructions in the readme.md file.

    Where:

    • alibabacloud-nls-cpp-sdk<version>-master_<github commit id>.zip is the SDK source code package.

    • NlsCppSdk_<Platform>_<VersionNumber>_<github commit id>.tar.gz is the SDK package required for development on the corresponding platform. For more information, see the readme.md file inside the package.

SDK package file description

  • scripts/build_linux.sh: A sample compilation script for the Linux platform in the SDK source code.

  • CMakeLists.txt: The CMakeList file for a sample code-based project on Linux or Android platforms in the SDK source code.

  • demo folder: Contains sample integration code. The following table shows examples for the Linux platform.

    File name

    Description

    speechRecognizerDemo.cpp

    Short sentence recognition demo.

    speechSynthesizerDemo.cpp

    Speech synthesis demo.

    speechTranscriberDemo.cpp

    Real-time speech recognition demo.

    flowingSynthesizerDemo.cpp

    Streaming text-to-speech synthesis demo.

    fileTransferDemo.cpp

    Audio file recognition demo.

  • resource folder: This folder in the SDK source code contains sample audio for the Voice Service, which you can use for functional testing. For more information, see the table below.

    File name

    Description

    • test0.wav

    • test1.wav

    • test2.wav

    • test3.wav

    Test audio files (16 kHz audio sampling rate, 16-bit audio bit depth).

  • include: This folder in the SDK source code contains the SDK header files, as shown in the table below.

    File name

    Description

    nlsClient.h

    SDK instance.

    nlsEvent.h

    Callback event description.

    nlsGlobal.h

    Global SDK header file.

    nlsToken.h

    SDK Access Token instance.

    iNlsRequest.h

    Base header file for NLS requests.

    speechRecognizerRequest.h

    Short sentence recognition.

    speechSynthesizerRequest.h

    Speech synthesis and long text-to-speech synthesis.

    speechTranscriberRequest.h

    Real-time audio stream recognition.

    flowingSynthesizerRequest.h

    Streaming text-to-speech synthesis.

    FileTrans.h

    Audio file recognition.

  • lib: SDK library files.

  • readme.md: SDK description.

  • release.log: Describes version updates.

  • version: Version number.

Compile and run (Linux platform)

  1. The minimum required tool versions are as follows:

    • CMake 3.0

    • Glibc 2.5

    • Gcc 4.8.5

  2. Run the following commands in a Linux terminal.

    1. Go to the root directory of the SDK source code.

    2. Generate the SDK library files and executable programs: srDemo for short sentence recognition, stDemo for real-time speech recognition, syDemo for speech synthesis, daDemo for speech dialogue, and fsDemo for streaming text-to-speech synthesis.

      ./scripts/build_linux.sh
    3. View the usage of the demo.

      cd build/demo 
      ./fsDemo 

Key interfaces

Base interfaces

  • NlsClient: The client for voice processing. You can use this client to perform speech processing tasks, such as short sentence recognition, real-time speech recognition, and speech synthesis. This client is thread-safe. Create only one global instance.

    Interface name

    Enabled version

    Feature description

    getInstance

    2.x

    Gets (creates) an NlsClient instance.

    setLogConfig

    2.x

    Sets the log file and storage path.

    setDirectHost

    3.x

    Skips DNS domain name resolution and directly sets the server IPv4 address. If called, it must be called before startWorkThread.

    setAddrInFamily

    3.1.12

    Sets the type of the socket address structure. The default is AF_INET, which only returns IPv4-related address information. This must be called before startWorkThread.

    setUseSysGetAddrInfo

    3.1.13

    If the libevent DNS does not meet requirements and cannot complete DNS resolution, call this interface to switch to the system's interface. This must be called before startWorkThread.

    calculateUtf8Chars

    3.1.14

    Counts the number of characters in the text content. You must pass in text content encoded in UTF-8. One Chinese character, one English letter, or one punctuation mark is counted as one character.

    setSyncCallTimeout

    3.1.17

    Sets the timeout period (in ms) for the synchronous call mode. The default value is 0, which means the synchronous mode is disabled.

    When you use the synchronous call mode:

    • start() is blocked until a result is received from the server.

    • stop() is blocked until the close() callback is triggered.

    setPreconnectedPool

    3.3.0

    Sets a pre-connection pool for each domain name URL.

    • Function:

      Creates a persistent connection pool for a domain name URL. Connections are automatically reused after requests are complete.

      • Reduces the connection time before each request is initiated.

      • Significantly reduces the first-packet latency.

    • This conflicts with the long-lived connection mode and will disable any configured long-lived connection mode.

    • Disabled scenario: Tingwu scenarios.

    • Call constraint: You must call this interface before you call startWorkThread.

    startWorkThread

    3.x

    Starts the number of worker threads. The default is 1, which starts one thread. If set to -1, it starts a number of threads equal to the number of CPU cores. In high-concurrency situations, -1 is recommended. This can be understood as the initialization of the NlsClient instance and must be called.

    getVersion

    3.x

    Gets the SDK version number.

    releaseInstance

    2.x

    Destroys the NlsClient object instance.

    createFlowingSynthesizerRequest

    3.2

    Creates a streaming text-to-speech synthesis object. It is thread-safe and supports high-concurrency requests.

    releaseFlowingSynthesizerRequest

    3.2

    Destroys the streaming text-to-speech synthesis object. This needs to be called after the closed event of the current request.

  • NlsToken: Creates a Token object that is used to request and obtain a Token ID. Before you request a new token, you must obtain a valid timestamp. If a token expires, you must request a new one. Requesting a token multiple times within its validity period causes a Token ID error and renders the token unusable.

    Interface name

    Feature description

    setAccessKeyId

    Sets the AccessKey ID of your Alibaba Cloud account.

    setKeySecret

    Sets the AccessKey secret of your Alibaba Cloud account.

    setDomain

    Sets the domain name. This is optional.

    setServerVersion

    Sets the API version. This is optional.

    setServerResourcePath

    Sets the service path. This is optional.

    setRegionId

    The service ID is an optional setting.

    setAction

    Sets the feature. This is optional.

    applyNlsToken

    Applies for and obtains a Token ID.

    getToken

    Gets the Token ID.

    getExpireTime

    Gets the token's expiration timestamp (in seconds).

    getErrorMsg

    Gets the error message.

  • NlsEvent: The event object. You can use this object to retrieve the request status code, the result returned from the cloud, failure information, and other data.

    Interface name

    Feature description

    getStatusCode

    Gets the status code. A normal status is 0 or 20000000. A failure corresponds to a specific error code.

    getErrorMessage

    In the TaskFailed callback, gets the error message for a failure that occurred during the NlsRequest operation.

    getTaskId

    Gets the TaskId of the task.

    getBinaryData

    Gets the binary data returned from the cloud.

    getAllResponse

    Gets the full result returned from the cloud.

Streaming Text-to-Speech API

The interface descriptions are based on the contents of the flowingSynthesizerRequest.h file.

Interface name

Enabled version

Feature description

setOnSynthesisStarted

3.2

Sets the callback function for when streaming text-to-speech synthesis starts.

setOnSynthesisCompleted

3.2

Sets the callback function for when speech synthesis is completed.

setOnChannelClosed

2.x

Sets the callback function for when the channel is closed.

setOnTaskFailed

2.x

Sets the callback function for errors.

setOnSentenceBegin

3.2

The callback function for when the server detects the beginning of a sentence.

setOnSentenceEnd

3.2

The callback function for when the server detects the end of a sentence and returns the full timestamp for that sentence.

setOnBinaryDataReceived

2.x

Sets the callback function for receiving binary audio data from speech synthesis.

setOnSentenceSynthesis

3.2

The callback function that incrementally returns the speech synthesis result, including the latest audio and timestamps, full intra-sentence data, and incremental inter-sentence data.

setOnMessage

3.1.16

Sets the callback function for the server-side response message. All callbacks are output from this callback for you to parse. This is optional. After setting, you must call setEnableOnMessage to enable it.

setAppKey

2.x

Sets the AppKey.

setToken

2.x

Security token authentication. All requests must be authenticated using the SetToken method before they can be used.

setUrl

2.x

Sets the service URL address. This is optional.

sendText

3.2

In a single streaming TTS session, a single synthesis cannot exceed 5,000 characters, and the total cannot exceed 100,000 characters. One Chinese character, one English letter, one punctuation mark, or one space between sentences is counted as one character.

setVoice

2.x

Sets the voice.

setVolume

2.x

Sets the volume.

setFormat

2.x

Sets the audio data encoding format. The default is PCM. Supported formats are PCM, WAV, and MP3.

setSampleRate

2.x

Sets the audio sampling rate.

setSpeechRate

2.x

Sets the speech rate.

setPitchRate

2.x

Sets the pitch rate.

setEnableSubtitle

2.x

Enables the caption feature.

setPayloadParam

2.x

Sets parameters. The input parameter is a JSON formatted string.

setTimeout

2.x

Sets the connection timeout period. The default is 5000 ms.

setContextParam

2.x

Sets custom user parameters. The input parameter is a JSON formatted string.

AppendHttpHeaderParam

2.x

Sets custom HTTP header parameters for the WebSocket phase.

setSendTimeout

3.1.14

Sets the sending timeout period. The default is 5000 ms.

setEnableOnMessage

3.1.16

Enables the callback for server return messages.

getTaskId

3.1.17

Gets the task_id of the current request.

start

2.x

Starts the FlowingSynthesizerRequest.

stop

3.2

Ends the synthesis task. You must wait for the synthesis to complete.

cancel

2.x

Directly closes the speech synthesis process without confirming the closure with the server.

Code examples

Note
  • The example saves the synthesized audio to a file. For audio playback with high real-time requirements, use streaming playback. Streaming playback plays the audio data as it is received. This reduces latency because you do not need to wait for the synthesis to complete before you process the audio stream.

  • For a complete example, see the flowingSynthesizerRequest.cpp file in the demo directory of the SDK package.

  • Before you call the interface, you must configure the environment variables to read the access credentials. The environment variables for the AccessKey ID, AccessKey secret, and AppKey of Intelligent Speech Interaction are NLS_AK_ENV, NLS_SK_ENV, and NLS_APPKEY_ENV, respectively.

Code example

#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include "nlsClient.h"
#include "nlsEvent.h"
#include "nlsToken.h"
#include "flowingSynthesizerRequest.h"

#define SAMPLE_RATE_16K 16000
#define DEFAULT_STRING_LEN 512
#define AUDIO_TEXT_LENGTH 2048

/**
 * Globally maintain a service authentication token and its corresponding expiration timestamp.
 * Before calling the service, first check if the token has expired.
 * If it has expired, regenerate a token using the AccessKey ID and AccessKey
 * Secret, and update this global token and its expiration timestamp.
 *
 * Note: Do not regenerate a new token every time you call the service. Only regenerate it when the token is about to expire. All concurrent services can share one token.
 */
// Custom thread parameters
struct ParamStruct {
  char text[AUDIO_TEXT_LENGTH];
  char token[DEFAULT_STRING_LEN];
  char appkey[DEFAULT_STRING_LEN];
  char url[DEFAULT_STRING_LEN];

  pthread_mutex_t mtx;
};

// Custom event callback parameters
struct ParamCallBack {
 public:
  explicit ParamCallBack(ParamStruct* param) {
    tParam = param;
    pthread_mutex_init(&mtxWord, NULL);
    pthread_cond_init(&cvWord, NULL);
  };
  ~ParamCallBack() {
    tParam = NULL;
    pthread_mutex_destroy(&mtxWord);
    pthread_cond_destroy(&cvWord);
  };

  pthread_mutex_t mtxWord;
  pthread_cond_t cvWord;

  ParamStruct* tParam;
};

std::string g_appkey = "";
std::string g_akId = "";
std::string g_akSecret = "";
std::string g_token = "";
std::string g_url = "";
std::string g_voice = "xiaoyun";
int g_threads = 1;
bool g_save_audio = true;
std::string g_text = "";
std::string g_format = "wav";
long g_expireTime = -1;
static int sample_rate = SAMPLE_RATE_16K;
static bool enableSubtitle = false;

std::vector<std::string> splitString(
    const std::string& str, const std::vector<std::string>& delimiters) {
  std::vector<std::string> result;
  size_t startPos = 0;

  // Find each separator in the string
  while (startPos < str.length()) {
    size_t minPos = std::string::npos;
    size_t delimiterLength = 0;

    for (std::vector<std::string>::const_iterator it = delimiters.begin();
         it != delimiters.end(); ++it) {
      std::size_t position = str.find(*it, startPos);
      // Find the nearest separator
      if (position != std::string::npos &&
          (minPos == std::string::npos || position < minPos)) {
        minPos = position;
        delimiterLength = it->size();
      }
    }

    // If a separator is found, extract the preceding string
    if (minPos != std::string::npos) {
      result.push_back(str.substr(startPos, minPos - startPos));
      startPos = minPos + delimiterLength;
    } else {
      // No more separators, the rest is one part
      result.push_back(str.substr(startPos));
      break;
    }
  }

  return result;
}

/**
 * Regenerate a token using the AccessKey ID and AccessKey Secret, and get its expiration timestamp.
 */
int generateToken(std::string akId, std::string akSecret, std::string* token,
                  long* expireTime) {
  AlibabaNlsCommon::NlsToken nlsTokenRequest;
  nlsTokenRequest.setAccessKeyId(akId);
  nlsTokenRequest.setKeySecret(akSecret);

  int retCode = nlsTokenRequest.applyNlsToken();
  /*Get the failure cause*/
  if (retCode < 0) {
    std::cout << "Failed error code: " << retCode
              << "  error msg: " << nlsTokenRequest.getErrorMsg() << std::endl;
    return retCode;
  }

  *token = nlsTokenRequest.getToken();
  *expireTime = nlsTokenRequest.getExpireTime();

  return 0;
}

void OnSynthesisStarted(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout << "OnSynthesisStarted:"
            << "  status code: " << cbEvent->getStatusCode()
            << "  task id: " << cbEvent->getTaskId()
            << "  all response:" << cbEvent->getAllResponse() << std::endl;
}

/**
 * @brief When the SDK receives a synthesis completion message from the cloud, the SDK's internal thread reports a Completed event.
 * @note After the Completed event is reported, the SDK will close the recognition connection channel internally.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 */
void OnSynthesisCompleted(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout
      << "OnSynthesisCompleted: "
      << ", status code: "
      << cbEvent
             ->getStatusCode()  // Gets the status code of the message. Success is 0 or 20000000. Failure corresponds to a specific error code.
      << ", task id: "
      << cbEvent->getTaskId()  // The task ID of the current task. It is recommended to output this for troubleshooting.
      << std::endl;
  std::cout << "OnSynthesisCompleted: All response:"
            << cbEvent->getAllResponse()
            << std::endl;  // Gets all information returned by the server.
}

/**
 * @brief If an exception occurs during the synthesis process, the SDK's internal thread reports a TaskFailed event.
 * @note After the TaskFailed event is reported, the SDK will close the recognition connection channel internally.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 */
void OnSynthesisTaskFailed(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  FILE* failed_stream = fopen("synthesisTaskFailed.log", "a+");
  if (failed_stream) {
    char outbuf[1024] = {0};
    snprintf(outbuf, sizeof(outbuf),
             "OnSynthesisTaskFailed status code:%d task id:%s error mesg:%s\n",
             cbEvent->getStatusCode(), cbEvent->getTaskId(),
             cbEvent->getErrorMessage());
    std::cout << outbuf << std::endl;
    fwrite(outbuf, strlen(outbuf), 1, failed_stream);
    fclose(failed_stream);
  }
}

/**
 * @brief When recognition ends or an exception occurs, the connection channel is closed.
 * The SDK's internal thread reports a ChannelClosed event.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 */
void OnSynthesisChannelClosed(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  ParamCallBack* tmpParam = static_cast<ParamCallBack*>(cbParam);
  if (tmpParam) {
    std::cout << "OnSynthesisChannelClosed: "
              << ", All response: " << cbEvent->getAllResponse()
              << std::endl;  // Gets all information returned by the server.
  }
}

/**
 * @brief After the text is reported to the server, binary audio data is received from the server.
 * The SDK's internal thread reports this to the user through a BinaryDataRecved event.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 * @notice Do not perform blocking operations here. Only transfer and store the audio data. If too many operations are performed in this callback,
 *         it will block subsequent data callbacks and the completed event callback.
 */
void OnBinaryDataRecved(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::vector<unsigned char> data =
      cbEvent->getBinaryData();  // getBinaryData() gets the binary audio data of the text synthesis.
  std::cout
      << "  OnBinaryDataRecved: status code: "
      << cbEvent
             ->getStatusCode()  // Gets the status code of the message. Success is 0 or 20000000. Failure corresponds to a specific error code.
      << ", taskId: "
      << cbEvent->getTaskId()  // The task ID of the current task. It is recommended to output this for troubleshooting.
      << ", data size: " << data.size()  // The size of the data.
      << std::endl;

  if (g_save_audio && data.size() > 0) {
    // Append the binary audio data to the file.
    std::string dir = "./tts_audio";
    if (access(dir.c_str(), 0) == -1) {
      mkdir(dir.c_str(), S_IRWXU);
    }
    char file_name[256] = {0};
    snprintf(file_name, 256, "%s/%s.%s", dir.c_str(), cbEvent->getTaskId(),
             g_format.c_str());
    FILE* tts_stream = fopen(file_name, "a+");
    if (tts_stream) {
      fwrite((char*)&data[0], data.size(), 1, tts_stream);
      fclose(tts_stream);
    }
  }
}

void OnSentenceBegin(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout
      << "OnSentenceBegin "
      << "Response: "
      << cbEvent
             ->getAllResponse()  // Gets the status code of the message. Success is 0 or 20000000. Failure corresponds to a specific error code.
      << std::endl;
}

void OnSentenceEnd(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout
      << "OnSentenceEnd "
      << "Response: "
      << cbEvent
             ->getAllResponse()  // Gets the status code of the message. Success is 0 or 20000000. Failure corresponds to a specific error code.
      << std::endl;
}

/**
 * @brief Returns log information corresponding to the TTS text, and incrementally returns corresponding caption information.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 */
void OnSentenceSynthesis(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout
      << "OnSentenceSynthesis "
      << "Response: "
      << cbEvent
             ->getAllResponse()  // Gets the status code of the message. Success is 0 or 20000000. Failure corresponds to a specific error code.
      << std::endl;
}

/**
 * @brief All information returned by the server is fed back through this callback.
 * @param cbEvent Callback event structure. For more information, see nlsEvent.h.
 * @param cbParam Custom callback parameter, default is NULL. You can customize parameters as needed.
 * @return
 */
void onMessage(AlibabaNls::NlsEvent* cbEvent, void* cbParam) {
  std::cout << "onMessage: All response:" << cbEvent->getAllResponse()
            << std::endl;
}

/**
 * @brief Worker thread in short-connection mode.
 *        It loops as follows:
 *        createFlowingSynthesizerRequest   <----|
 *                   |                              |
 *           request->start()                       |
 *                   |                              |
 *           request->sendText()                    |
 *                   |                              |
 *           request->stop()                        |
 *                   |                              |
 *           Receive OnSynthesisChannelClosed callback |
 *                   |                              |
 *      releaseFlowingSynthesizerRequest(request) --|
 */
void* pthreadFunc(void* arg) {
  int testCount = 0;  // Run count, used to exit after exceeding the set loop count.
  bool timedwait_flag = false;

  // Get token, configuration files, and other parameters from the custom thread parameters.
  ParamStruct* tst = static_cast<ParamStruct*>(arg);
  if (tst == NULL) {
    std::cout << "arg is not valid." << std::endl;
    return NULL;
  }

  pthread_mutex_init(&(tst->mtx), NULL);

  // Initialize custom callback parameters.
  ParamCallBack cbParam(tst);

  /*
   * 1. Create a FlowingSynthesizerRequest object for streaming text-to-speech synthesis.
   *
   * For more information about streaming text-to-speech synthesis, see:
   * https://help.aliyun.com/document_detail/423223.html
   */

  AlibabaNls::FlowingSynthesizerRequest* request =
      AlibabaNls::NlsClient::getInstance()->createFlowingSynthesizerRequest();
  if (request == NULL) {
    std::cout << "createFlowingSynthesizerRequest failed." << std::endl;
    return NULL;
  }

  /*
   * 2. Set the callback for receiving results.
   */
  // Set the callback function for when audio synthesis can start.
  request->setOnSynthesisStarted(OnSynthesisStarted, &cbParam);
  // Set the callback function for when audio synthesis is completed.
  request->setOnSynthesisCompleted(OnSynthesisCompleted, &cbParam);
  // Set the callback function for when the audio synthesis channel is closed.
  request->setOnChannelClosed(OnSynthesisChannelClosed, &cbParam);
  // Set the callback function for exception failures.
  request->setOnTaskFailed(OnSynthesisTaskFailed, &cbParam);
  // Set the callback function for receiving text-to-audio data.
  request->setOnBinaryDataReceived(OnBinaryDataRecved, &cbParam);
  // Set caption information.
  request->setOnSentenceSynthesis(OnSentenceSynthesis, &cbParam);
  // A sentence begins.
  request->setOnSentenceBegin(OnSentenceBegin, &cbParam);
  // A sentence ends.
  request->setOnSentenceEnd(OnSentenceEnd, &cbParam);
  // Set the callback function for all server return messages.
  // request->setOnMessage(onMessage, &cbParam);
  // Enable the callback function for all server return messages. Other callbacks (except OnBinaryDataRecved) will become invalid.
  // request->setEnableOnMessage(true);

  /*
   * 3. Set the relevant parameters for the request.
   */
  // The voice, such as "xiaoyun", "ruoxi", and "xiaogang". This is an optional parameter. The default value is xiaoyun.
  request->setVoice(g_voice.c_str());
  // The volume. The range is 0 to 100. This is an optional parameter. The default value is 50.
  request->setVolume(50);
  // The audio encoding format. This is an optional parameter. The default value is wav. Supported formats are pcm, wav, and mp3.
  request->setFormat("wav");
  // The audio sampling rate, such as 8000 and 16000. This is an optional parameter. The default value is 16000.
  request->setSampleRate(sample_rate);
  // The speech rate. The range is -500 to 500. This is an optional parameter. The default value is 0.
  request->setSpeechRate(0);
  // The pitch rate. The range is -500 to 500. This is an optional parameter. The default value is 0.
  request->setPitchRate(0);
  // Enable captions.
  request->setEnableSubtitle(enableSubtitle);

  // Set the AppKey. This is a required parameter. For more information, see the official website to apply for one.
  if (strlen(tst->appkey) > 0) {
    request->setAppKey(tst->appkey);
  }
  // Set the account verification token. This is a required parameter.
  if (strlen(tst->token) > 0) {
    request->setToken(tst->token);
  }

  if (strlen(tst->url) > 0) {
    request->setUrl(tst->url);
  }

  // Set the connection timeout to 500 ms.
  // request->setTimeout(500);
  // Get the encoding format of the returned text.
  // const char* output_format = request->getOutputFormat();
  // std::cout << "text format: " << output_format << std::endl;

  /*
   * 4.
   * start() is an asynchronous operation. If it succeeds, the system starts to return BinaryRecv events. If it fails, it returns a TaskFailed event.
   */
  std::cout << "start -> pid " << pthread_self() << std::endl;
  struct timespec outtime;
  struct timeval now;
  int ret = request->start();
  testCount++;
  if (ret < 0) {
    std::cout << "start failed. pid:" << pthread_self() << std::endl;
    const char* request_info = request->dumpAllInfo();
    if (request_info) {
      std::cout << "  all info: " << request_info << std::endl;
    }
    AlibabaNls::NlsClient::getInstance()->releaseFlowingSynthesizerRequest(
        request);  // start() failed, release the request object.
    return NULL;
  } else {
    std::cout << "start success. pid " << pthread_self() << std::endl;
    /*
     * Wait for the started event to be returned, which indicates that start() is successful. Then, send the audio data.
     * The voice server may not be able to process the current request in time and does not return any callbacks within 10 seconds.
     * After 10 seconds, it returns a TaskFailed callback. Therefore, you must set a timeout mechanism.
     */
    std::cout << "wait started callback." << std::endl;
    gettimeofday(&now, NULL);
    outtime.tv_sec = now.tv_sec + 10;
    outtime.tv_nsec = now.tv_usec * 1000;
    pthread_mutex_lock(&(cbParam.mtxWord));
    if (ETIMEDOUT == pthread_cond_timedwait(&(cbParam.cvWord),
                                            &(cbParam.mtxWord), &outtime)) {
      std::cout << "start timeout" << std::endl;
      timedwait_flag = true;
      pthread_mutex_unlock(&(cbParam.mtxWord));
      // start() call timed out. cancel() cancels the current request.
      request->cancel();
      return NULL;
    }
    pthread_mutex_unlock(&(cbParam.mtxWord));
  }

  /*
   * 5. Simulate the streaming return of text results from a large model and perform speech synthesis one by one.
   */
  std::string text_str(tst->text);
  if (!text_str.empty()) {
    const char* delims[] = {".", "!", ";", "?", "\n"};
    std::vector<std::string> delimiters(
        delims, delims + sizeof(delims) / sizeof(delims[0]));
    std::vector<std::string> sentences = splitString(text_str, delimiters);
    for (std::vector<std::string>::const_iterator it = sentences.begin();
         it != sentences.end(); ++it) {
      std::cout << "sendText: " << *it << std::endl;
      ret = request->sendText(it->c_str());
      if (ret < 0) {
        break;
      }
      usleep(500 * 1000);
    }  // for
    if (ret < 0) {
      std::cout << "sendText failed. pid:" << pthread_self() << std::endl;
      const char* request_info = request->dumpAllInfo();
      if (request_info) {
        std::cout << "  all info: " << request_info << std::endl;
      }
      AlibabaNls::NlsClient::getInstance()->releaseFlowingSynthesizerRequest(
          request);  // start() failed, release the request object.
      return NULL;
    }
  }

  /*
   * 6. start() succeeded. Start waiting to receive all synthesized data.
   *    stop() is a meaningless interface. The entire process runs regardless of whether it is called.
   *    cancel() stops the task immediately and no callback is returned. If it fails, a TaskFailed event is returned.
   */
  //    ret = request->cancel();
  ret = request->stop();

  /*
   * Start waiting to receive all synthesized data.
   */
  if (ret == 0) {
    /*
     * Wait for the started event to be returned, which indicates that start() is successful. Then, send the audio data.
     * The voice server may not be able to process the current request in time and does not return any callbacks within 10 seconds.
     * After 10 seconds, it returns a TaskFailed callback. Therefore, you must set a timeout mechanism.
     */
    // Release after the closed event is returned. Otherwise, a crash may occur.
    std::cout << "wait closed callback." << std::endl;
    /*
     * The voice server may not be able to process the current request in time and does not return any callbacks within 10 seconds.
     * After 10 seconds, it returns a TaskFailed callback with the error message:
     * "Gateway:IDLE_TIMEOUT:Websocket session is idle for too long time,
     * the last directive is 'XXXX'!" Therefore, you must set a timeout mechanism.
     */
    gettimeofday(&now, NULL);
    outtime.tv_sec = now.tv_sec + 30;
    outtime.tv_nsec = now.tv_usec * 1000;
    // Release after the closed event is returned. Otherwise, a crash may occur.
    pthread_mutex_lock(&(cbParam.mtxWord));
    if (ETIMEDOUT == pthread_cond_timedwait(&(cbParam.cvWord),
                                            &(cbParam.mtxWord), &outtime)) {
      std::cout << "stop timeout" << std::endl;
      pthread_mutex_unlock(&(cbParam.mtxWord));
      return NULL;
    }
    pthread_mutex_unlock(&(cbParam.mtxWord));
  } else {
    std::cout << "ret is " << ret << ", pid " << pthread_self() << std::endl;
  }
  gettimeofday(&now, NULL);
  std::cout << "current request task_id:" << request->getTaskId() << std::endl;
  std::cout << "stop finished. pid " << pthread_self() << " tv: " << now.tv_sec
            << std::endl;

  /*
   * 7. Release the current request after all tasks are complete.
   *    Release the request after the closed event is returned to confirm that all tasks are complete. Otherwise, the internal state machine may be damaged
   * and the running request will be forcibly uninstalled.
   */
  const char* request_info = request->dumpAllInfo();
  if (request_info) {
    std::cout << "  all info: " << request_info << std::endl;
  }
  AlibabaNls::NlsClient::getInstance()->releaseFlowingSynthesizerRequest(
      request);
  std::cout << "release Synthesizer success. pid " << pthread_self()
            << std::endl;

  pthread_mutex_destroy(&(tst->mtx));

  return NULL;
}

/**
 * Synthesize multiple text data.
 * Multi-threading in the SDK means one thread for one text data, not multiple threads for one text data.
 * The sample code starts four threads to synthesize four files at the same time.
 * Free users cannot have more than two concurrent connections.
 */
#define AUDIO_TEXT_NUMS 4
#define AUDIO_FILE_NAME_LENGTH 32
int flowingSynthesizerMultFile(const char* appkey, int threads) {
  /**
   * Get the current system timestamp to check whether the token has expired.
   */
  std::time_t curTime = std::time(0);
  if (g_token.empty()) {
    if (g_expireTime - curTime < 10) {
      std::cout << "the token will be expired, please generate new token by "
                   "AccessKey-ID and AccessKey-Secret."
                << std::endl;
      int ret = generateToken(g_akId, g_akSecret, &g_token, &g_expireTime);
      if (ret < 0) {
        std::cout << "generate token failed" << std::endl;
        return -1;
      } else {
        if (g_token.empty() || g_expireTime < 0) {
          std::cout << "generate empty token" << std::endl;
          return -2;
        }
        std::cout << "token: " << g_token << std::endl;
      }
    }
  }

  /* Do not exceed AUDIO_TEXT_LENGTH */
  const char texts[AUDIO_TEXT_LENGTH] = {
      "Chirp, chirp, and again, chirp, chirp, Mulan weaves at the door. The sound of the shuttle is not heard, only the girl's sighs. They ask the girl what she is thinking, they ask the girl what she is remembering."
      "The girl is not thinking of anything, the girl is not remembering anything. Last night I saw the draft papers, the Khan is calling up a great army. The army list is in twelve scrolls, and on every scroll is my father's name."
      "Father has no grown-up son, Mulan has no elder brother. I want to buy a saddle and horse, and serve in the army in my father's place. In the East Market she buys a fine horse, in the West Market a saddle and cloth,"
      "in the South Market a bridle, in the North Market a long whip. At dawn she bids farewell to her parents, at dusk she camps by the Yellow River. She doesn't hear her parents' call, only the splashing water of the Yellow River. At dawn she leaves the Yellow River, at dusk she reaches the Black Mountain. She doesn't hear her parents' call, only the neighing of the nomad horses on Mount Yan."
      " She travels thousands of miles to the war, crossing mountains as if flying. The northern air carries the watchman's clapper, the cold light shines on her iron armor. Generals die in a hundred battles, and the bravest soldiers return after ten years"
      ". "
      "On her return she sees the Son of Heaven, the Son of Heaven sits in the Splendid Hall. He records her merits in twelve ranks, and bestows rewards of a hundred thousand and more. The Khan asks what she desires, Mulan has no use for a minister's post"
      ", I want to ride a swift horse for a thousand miles, to take me back to my old home. "
      "When her parents hear their daughter is coming, they go out to the city wall to welcome her; When her elder sister hears her sister is coming, she puts on her red makeup at the door; When her younger brother hears his sister is coming, he sharpens his knife, whirring, for the pig and sheep"
      ". I open my east chamber door, and sit on my west chamber bed. I take off my wartime robe, and put on my old-time clothes. By the window I arrange my cloud-like hair, before the mirror I put on the yellow flower. I go out to see my comrades, my comrades are all amazed and bewildered: 'We traveled together for twelve years, and didn't know Mulan was a girl.' "
      "The male rabbit's feet hop and skip, the female rabbit's eyes are blurred and dim; But when the two rabbits run side by side, how can you tell which is the male and which is the female?"};

  ParamStruct pa[threads];

  for (int i = 0; i < threads; i++) {
    memset(pa[i].token, 0, DEFAULT_STRING_LEN);
    memcpy(pa[i].token, g_token.c_str(), g_token.length());

    memset(pa[i].appkey, 0, DEFAULT_STRING_LEN);
    memcpy(pa[i].appkey, appkey, strlen(appkey));

    memset(pa[i].text, 0, AUDIO_TEXT_LENGTH);
    if (g_text.empty()) {
      memcpy(pa[i].text, texts, strlen(texts));
    } else {
      memcpy(pa[i].text, g_text.data(), strlen(g_text.data()));
    }

    memset(pa[i].url, 0, DEFAULT_STRING_LEN);
    if (!g_url.empty()) {
      memcpy(pa[i].url, g_url.c_str(), g_url.length());
    }
  }

  std::vector<pthread_t> pthreadId(threads);
  // Start four worker threads to recognize four audio files at the same time.
  for (int j = 0; j < threads; j++) {
    pthread_create(&pthreadId[j], NULL, &pthreadFunc, (void*)&(pa[j]));
  }

  std::cout << "start pthread_join..." << std::endl;

  for (int j = 0; j < threads; j++) {
    pthread_join(pthreadId[j], NULL);
  }

  std::cout << "flowingSynthesizerMultFile exit..." << std::endl;
  return 0;
}

int main(int argc, char* argv[]) {
  std::string g_appkey = getenv("NLS_APPKEY_ENV");
  g_akId = getenv("NLS_AK_ENV");
  g_akSecret = getenv("NLS_SK_ENV");

  std::cout << " appKey: " << g_appkey << std::endl;
  std::cout << " akId: " << g_akId << std::endl;
  std::cout << " akSecret: " << g_akSecret << std::endl;
  std::cout << " voice: " << g_voice << std::endl;
  std::cout << "\n" << std::endl;

  int ret = AlibabaNls::NlsClient::getInstance()->setLogConfig(
      "log-flowingSynthesizer", AlibabaNls::LogDebug, 400, 50, NULL);
  if (ret < 0) {
    std::cout << "set log failed." << std::endl;
    return -1;
  }

  // Set the socket address type required by the running environment. The default value is AF_INET.
  // This must be called before startWorkThread().
  // AlibabaNls::NlsClient::getInstance()->setAddrInFamily("AF_INET");

  // Set the direct connection IP for private cloud deployments.
  // This must be called before startWorkThread().
  // AlibabaNls::NlsClient::getInstance()->setDirectHost("xxx.xxx.xxx.xxx");

  std::cout << "startWorkThread begin... " << std::endl;

  // Start the worker thread. This function must be called before creating and starting a request.
  // If the input parameter is negative, the number of available cores in the current system is started.
  // For high concurrency, 4 is recommended. For a single request, 1 is recommended.
  // If the CPU usage is high in a high-concurrency scenario, you can set it to -1 to enable all CPU cores.
  AlibabaNls::NlsClient::getInstance()->startWorkThread(1);

  std::cout << "startWorkThread finish" << std::endl;

  // Synthesize multiple texts.
  ret = flowingSynthesizerMultFile(g_appkey.c_str(), g_threads);
  if (ret) {
    std::cout << "flowingSynthesizerMultFile failed." << std::endl;
    AlibabaNls::NlsClient::releaseInstance();
    return -2;
  }

  // After all tasks are complete, release nlsClient before the process exits.
  // Note that releaseInstance() is not thread-safe.
  std::cout << "releaseInstance -> " << std::endl;
  AlibabaNls::NlsClient::releaseInstance();
  std::cout << "releaseInstance done." << std::endl;

  return 0;
}

Status codes

C++ SDK status codes

Status code

Status message

Reason

Solution

0

Success

Success

None

-10

DefaultError

Default error.

Not in use.

-11

JsonParseFailed

Incorrect JSON format.

Check whether the input JSON string is in the correct JSON format.

-12

JsonObjectError

Incorrect JSON object.

Try again.

-13

MallocFailed

Malloc failed.

Check if there is sufficient memory.

-14

ReallocFailed

Realloc failed.

Check if there is sufficient memory.

-15

InvalidInputParam

An invalid parameter was passed in.

Not in use.

-50

InvalidLogLevel

Invalid log level.

Check the configured log level.

-51

InvalidLogFileSize

Invalid log file size.

Check the configured log file size parameter.

-52

InvalidLogFileNum

The number of invalid log files.

Check the configured number of log files parameter.

-100

EncoderExistent

The NLS encoder already exists.

Try again.

-101

EncoderInexistent

The NLS encoder does not exist.

We recommend that you re-initialize.

-102

OpusEncoderCreateFailed

Failed to create the Opus encoder.

We recommend reinitializing.

-103

OggOpusEncoderCreateFailed

Failed to create the OggOpus encoder.

We recommend re-initializing.

-104

InvalidEncoderType

Invalid encoder type.

OPUS may have been disabled at compile-time but is being used, or check the ENCODER_TYPE.

-150

EventClientEmpty

The main worker thread has a null pointer and has been released.

Re-initialize by calling startWorkThread().

-151

SelectThreadFailed

Failed to select a worker thread. It has not been initialized.

Re-initialize by calling startWorkThread().

-160

StartCommandFailed

Failed to send the start command.

Try again.

-161

InvokeStartFailed

The request state machine is incorrect, which causes the start operation to fail.

Check whether the current request has not been created or has been completed.

-162

InvokeSendAudioFailed

The request state machine is incorrect, which causes the sendAudio operation to fail.

Check whether the current request has started (i.e., the started event callback has been received) or has been completed.

-163

InvalidOpusFrameSize

Invalid Opus frame size. The default is 640 bytes.

In OPU encoding mode, sendAudio only accepts 640 bytes of data per frame.

-164

InvokeStopFailed

The request state machine is incorrect, which causes the stop operation to fail.

Check whether the current request has not yet started (meaning the `started` event callback has not been received) or has been completed.

-165

InvokeCancelFailed

The request state machine is incorrect, which causes the stop operation to fail.

Verify that the current request is either not yet started (the 'started' event callback has not been received) or is already complete.

-166

InvokeStControlFailed

The request state machine is incorrect, which causes the stControl operation to fail.

Check whether the 'started' event callback for the current request has not been received, or the request is already complete.

-200

NlsEventEmpty

The NLS event is empty.

For internal SDK use. The NlsEvent frame was lost.

-201

NewNlsEventFailed

Failed to create NlsEvent.

For internal SDK use. Failed to create the NlsEvent frame.

-202

NlsEventMsgEmpty

The message in the NLS event is empty.

The message string was found to be empty during parsing by parseJsonMsg().

-203

InvalidNlsEventMsgType

Invalid message type in the NLS event.

For internal SDK use. The event type of the NlsEvent frame is invalid.

-204

InvalidNlsEventMsgStatusCode

Invalid message status code in the NLS event.

For internal SDK use. The event message status of the NlsEvent frame is invalid.

-205

InvalidNlsEventMsgHeader

Invalid message header in the NLS event.

For internal SDK use. The event message header of the NlsEvent frame is invalid.

-250

CancelledExitStatus

Cancel has been called.

Not in use.

-251

InvalidWorkStatus

Invalid working status.

For internal SDK use. The internal status of the current request is invalid.

-252

InvalidNodeQueue

The NodeQueue in WorkThread is invalid.

For internal SDK use. The current request to be run is invalid. Release the current request and try again.

-300

InvalidRequestParams

The request parameters are invalid.

The data passed to SendAudio is empty.

-301

RequestEmpty

The request is a null pointer.

For internal SDK use. The current request has been released. Release the current request and try again.

-302

InvalidRequest

Invalid request.

For internal SDK use. The current request has been released. Release the current request and try again.

-303

SetParamsEmpty

The parameters passed in for setting are empty.

Check if the passed-in parameters are empty.

-350

GetHttpHeaderFailed

Failed to get the HTTP header.

For internal SDK use. Locate the issue based on the feedback in the logs.

-351

HttpGotBadStatus

HTTP error status.

For internal SDK use. Locate the issue based on the feedback in the logs.

-352

WsResponsePackageFailed

Failed to parse the WebSocket response package.

For internal SDK use. Locate the issue based on the feedback in the logs.

-353

WsResponsePackageEmpty

The parsed WebSocket response package is empty.

For internal SDK use. Locate the issue based on the feedback in the logs.

-354

WsRequestPackageEmpty

The WebSocket request package is empty.

For internal SDK use. Locate the issue based on the feedback in the logs.

-355

UnknownWsFrameHeadType

Unknown WebSocket frame header type.

For internal SDK use. Locate the issue based on the feedback in the logs.

-356

InvalidWsFrameHeaderSize

Invalid WebSocket frame header size.

For internal SDK use. Locate the issue based on the feedback in the logs.

-357

InvalidWsFrameHeaderBody

Invalid WebSocket frame header body.

For internal SDK use. Locate the issue based on the feedback in the logs.

-358

InvalidWsFrameBody

Invalid WebSocket frame body.

For internal SDK use. Locate the issue based on the feedback in the logs.

-359

WsFrameBodyEmpty

The frame data is empty. This is often due to receiving dirty data.

For internal SDK use. Locate the issue based on the feedback in the logs.

-400

NodeEmpty

The node is a null pointer.

Release the current request and try again.

-401

InvaildNodeStatus

The node is in an invalid state.

For internal SDK use. Release the current request and try again.

-402

GetAddrinfoFailed

Detection is based on parsing the DNS address.

For internal SDK use. Check whether DNS is available in the current environment.

-403

ConnectFailed

Network connection failed.

Check whether the current network is available.

-404

InvalidDnsSource

The current device has no DNS.

For internal SDK use. Check whether DNS is available in the current environment.

-405

ParseUrlFailed

Invalid URL.

Check whether the configured URL is valid.

-406

SslHandshakeFailed

SSL handshake failed.

For internal SDK use. Check whether the current network is available and try again.

-407

SslCtxEmpty

SSL_CTX is empty.

For internal SDK use. Check whether the current network is available and try again.

-408

SslNewFailed

SSL_new failed.

For internal SDK use. Check whether the current network is available and try again.

-409

SslSetFailed

Failed to set SSL parameters.

For internal SDK use. Check whether the current network is available and try again.

-410

SslConnectFailed

SSL_connect failed.

For internal SDK use. Check whether the current network is available and try again.

-411

SslWriteFailed

Failed to send data over SSL.

For internal SDK use. Check whether the current network is available and try again.

-412

SslReadSysError

A SYSCALL error was received when receiving data over SSL.

For internal SDK use. Check whether the current network is available and try again.

-413

SslReadFailed

Failed to receive data over SSL.

For internal SDK use. Check whether the current network is available and try again.

-414

SocketFailed

Failed to create a socket.

For internal SDK use. Check whether the current network is available and try again.

-415

SetSocketoptFailed

Failed to set socket parameters.

For internal SDK use. Check whether the current network is available and try again.

-416

SocketConnectFailed

Failed to establish a socket connection.

For internal SDK use. Check whether the current network is available and try again.

-417

SocketWriteFailed

Failed to send data over the socket.

For internal SDK use. Check whether the current network is available and try again.

-418

SocketReadFailed

Failed to receive data from the socket.

For internal SDK use. Check whether the current network is available and try again.

-430

NlsReceiveFailed

Failed to receive NLS frame data.

For internal SDK use. Check whether the current network is available and try again.

-431

NlsReceiveEmpty

The received NLS frame data is empty.

For internal SDK use. Check whether the current network is available and try again.

-432

ReadFailed

Failed to receive data.

For internal SDK use. Check whether the current network is available and try again.

-433

NlsSendFailed

Failed to send NLS data.

For internal SDK use. Check whether the current network is available and try again.

-434

NewOutputBufferFailed

Failed to create a buffer.

For internal SDK use. Check if there is sufficient memory.

-435

NlsEncodingFailed

Audio encoding failed.

For internal SDK use. Release the current request and try again.

-436

EventEmpty

The event is empty.

For internal SDK use. Release the current request and try again.

-437

EvbufferTooMuch

Too much data in the evbuffer.

For internal SDK use. The send data buffer is full (max cache for 16K audio is 320000, for 8K audio is 160000). Check if audio data is being sent too frequently or if too much data is being sent at once.

-438

EvutilSocketFalied

Failed to set evutil parameters.

For internal SDK use. Release the current request and try again.

-439

InvalidExitStatus

Invalid exit status.

Check if the current request has been canceled.

-450

InvalidAkId

Invalid AccessKey ID for the Alibaba Cloud account.

Check if the AccessKey ID for the Alibaba Cloud account is empty.

-451

InvalidAkSecret

Invalid AccessKey secret for the Alibaba Cloud account.

Check if the AccessKey secret for the Alibaba Cloud account is empty.

-452

InvalidAppKey

Invalid project AppKey.

Check if the Alibaba Cloud project AppKey is empty.

-453

InvalidDomain

Invalid domain.

Check if the input domain is empty.

-454

InvalidAction

Invalid action.

Check if the input action is empty.

-455

InvalidServerVersion

Invalid ServerVersion.

Check if the input ServerVersion is empty.

-456

InvalidServerResource

Invalid ServerResource.

Check if the input ServerResource is empty.

-457

InvalidRegionId

Invalid RegionId.

Check if the input Region ID is empty.

-500

InvalidFileLink

Invalid audio file link.

The audio file transcription link is empty.

-501

ErrorStatusCode

Error status code.

Audio file transcription returned an error. For more information, see the error code.

-502

IconvOpenFailed

The request to transform the description failed.

UTF-8 to GBK conversion failed.

-503

IconvFailed

Encoding conversion failed.

UTF-8 to GBK conversion failed.

-504

ClientRequestFaild

The account client request failed.

The audio file transcription request failed.

-999

NlsMaxErrorCode

None

None

Other status codes

Status code

Status message

Reason

Solution

10000001

NewSslCtxFailed

SSL: couldn't create a context!

We recommend re-initializing.

10000002

DefaultErrorCode

return of SSL_read: error:00000000:lib(0):func(0):reason(0)

Try again.

return of SSL_read: error:140E0197:SSL routines:SSL_shutdown:shutdown while in init

10000003

SysErrorCode

System error.

Handle the error based on the feedback from the system.

10000004

EmptyUrl

URL: The url is empty.

The passed-in URL is empty. Enter a correct URL.

10000005

InvalidWsUrl

Could not parse WebSocket url:

The passed-in URL format is incorrect. Enter a correct URL.

10000007

JsonStringParseFailed

JSON: Json parse failed.

Abnormal JSON format. Check the logs for the specific error point.

10000008

UnknownWsHeadType

WEBSOCKET: unkown head type.

Network connection failed. Check if the local DNS resolution and URL are valid.

10000009

HttpConnectFailed

HTTP: connect failed.

Failed to connect to the cloud. Check the network and try again.

10000010

MemNotEnough

Out of memory.

Check if there is sufficient memory.

10000015

SysConnectFailed

connect failed.

Network connection failed. Check if the local DNS resolution and URL are valid.

10000100

HttpGotBadStatusWith403

Got bad status host=xxxxx line=HTTP/1.1 403 Forbidden

The connection was rejected. Check the account, especially whether the token has expired.

10000101

EvSendTimeout

Send timeout. socket error:

libevent timed out when sending an event. Check whether there are time-consuming tasks in the callback, or whether high concurrency prevents events from being processed promptly.

10000102

EvRecvTimeout

Recv timeout. socket error:

libevent timed out when receiving an event. Check whether there are time-consuming tasks in the callback, or whether high concurrency prevents events from being processed promptly.

10000103

EvUnknownEvent

Unknown event:

Unknown libevent event. Try again.

10000104

OpNowInProgress

Operation now in progress

The connection is in progress. Try again.

10000105

BrokenPipe

Broken pipe

The pipe cannot handle the request. Try again.

10000110

TokenHasExpired

Gateway:ACCESS_DENIED:The token 'xxx' has expired!

Update the token.

10000111

TokenIsInvalid

Meta:ACCESS_DENIED:The token 'xxx' is invalid!

Check the validity of the token.

10000112

NoPrivilegeToVoice

Gateway:ACCESS_DENIED:No privilege to this voice! (voice: zhinan, privilege: 0)

You do not have permission to use this voice.

10000113

MissAuthHeader

Gateway:ACCESS_DENIED:Missing authorization header!

Check if the account has permission, or if the concurrency is within the limit.

10000120

Utf8ConvertError

utf8ToGbk failed

UTF-8 transcoding failed. This is often a system issue. Try again.

20000000

SuccessStatusCode

Success

Server-side response status codes

For more information about service status codes, see Service status codes.