C++ SDK
Use the SDK for C++ to stream audio and receive intermediate results and final sentence-level results. The Linux x86_64 examples use version 3.3.0b.
Quick start
Prepare a Linux build environment, obtain the SDK, configure credentials, and run the complete example. For request parameters and response events, see Real-time speech recognition API reference.
The discontinued API 2.0 has different definitions from API 3.1 used in this example.
Prepare the environment
The minimum Linux build tool versions are CMake 3.0, glibc 2.5, and GCC 4.8.5.
The example uses Linux x86_64, GCC 10.2.1, and glibc 2.32.
Obtain and install the SDK
Source repository
Obtain the source code from the SDK GitHub repository. The default branch may differ from the downloadable package. Follow the readme.md for the version being built.
git clone --depth 1 https://github.com/aliyun/alibabacloud-nls-cpp-sdk
Downloadable packages
Build the source package to generate libraries. Precompiled platform packages contain libraries and header files.
|
SDK package |
Platform |
MD5 |
|
SDK source code |
7257c0998654e611cf2e8ca9867670ef |
|
|
Linux x86_64 |
9a93df607f26f1558bc1043a425af6d1 |
|
|
Linux aarch64 |
76c34a3ab397d7285963a139b9270ff4 |
alibabacloud-nls-cpp-sdk<version>-master_<github commit id>.zip is a source package; NlsCppSdk_<platform>_<version>_<github commit id>.tar.gz is a precompiled platform package. See the included readme.md for instructions.
Build and integrate
Build from source
Run the following command in the source root directory to generate SDK libraries and examples, including srDemo (short sentence recognition), stDemo (real-time speech recognition), syDemo (speech synthesis), and daDemo (voice interaction).
./scripts/build_linux.sh
The generated headers and libraries are in build/install/NlsSdk3.X_LINUX. In the build/demo directory, run ./stDemo to display usage instructions for the packaged example.
Precompiled packages
Extract the SDK package for the CPU architecture, and select a Debug or Release package. Use the same C++ ABI as the application. CXX11 packages use _GLIBCXX_USE_CXX11_ABI=1.
In the Linux x86_64 Release CXX11 package for version 3.3.0b, demo/build_linux_demo.sh still specifies ABI=0. When using this package, set the example build option to ABI=1 to avoid linker errors.
Configure credentials
Before running the example, set the following environment variables for the process. The AppKey and AccessKey must belong to the account used to access the service. Do not hard-code credentials or write them to logs.
|
Environment variable |
Description |
|
NLS_APPKEY_ENV |
The AppKey of the project. |
|
NLS_AK_ENV |
AccessKey ID. |
|
NLS_SK_ENV |
AccessKey secret. |
export NLS_APPKEY_ENV='<appkey>'
export NLS_AK_ENV='<accesskey-id>'
export NLS_SK_ENV='<accesskey-secret>'
When running the example in an IDE, also set these variables in its run configuration. The example obtains a token through NlsToken, caches the token and its expiration time, and refreshes it shortly before expiration. Concurrent requests can share a valid token.
Sample code
The complete example initializes the client, obtains a token, handles asynchronous events, sends audio, and releases resources. Use test0.wav from the SDK package and place it in the working directory. The concurrent example also uses test1.wav.
The sample audio has a sample rate of 16000 Hz, and the project uses the Universal model in the console. For other audio, select a model that supports the audio's use case. For model configuration, see Manage projects.
The example waits for the started event before sending audio, stops sending after a failure event, and propagates failures as a nonzero process exit code. On success, TranscriptionCompleted is followed by the channel-closed event.
#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 <errno.h>
#include <atomic>
#include "nlsClient.h"
#include "nlsEvent.h"
#include "nlsToken.h"
#include "speechTranscriberRequest.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::SpeechTranscriberRequest;
struct ParamStruct {
std::string fileName;
std::string appkey;
std::string token;
int result = -1;
};
struct ParamCallBack {
public:
ParamCallBack() {
pthread_mutex_init(&mtxWord, NULL);
pthread_cond_init(&cvWord, NULL);
};
~ParamCallBack() {
pthread_mutex_destroy(&mtxWord);
pthread_cond_destroy(&cvWord);
};
std::atomic<bool> started{false}, closed{false}, failed{false}, completed{false};
int userId;
char userInfo[8];
pthread_mutex_t mtxWord;
pthread_cond_t cvWord;
};
std::string g_akId = "";
std::string g_akSecret = "";
std::string g_token = "";
long g_expireTime = -1;
int g_sync_timeout = 0;
struct timeval tv;
struct timeval tv1;
int generateToken(std::string akId, std::string akSecret,
std::string* token, long* expireTime) {
NlsToken nlsTokenRequest;
nlsTokenRequest.setAccessKeyId(akId);
nlsTokenRequest.setKeySecret(akSecret);
int ret = nlsTokenRequest.applyNlsToken();
if (ret < 0) {
printf("generateToken Failed, error code:%d msg:%s\n",
ret, nlsTokenRequest.getErrorMsg());
return ret;
}
*token = nlsTokenRequest.getToken();
*expireTime = nlsTokenRequest.getExpireTime();
return 0;
}
unsigned int getSendAudioSleepTime(int dataSize,
int sampleRate,
int compressRate) {
const int sampleBytes = 16;
const int soundChannel = 1;
int bytes = (sampleRate * sampleBytes * soundChannel) / 8;
int bytesMs = bytes / 1000;
int sleepMs = (dataSize * compressRate) / bytesMs;
return sleepMs;
}
void onTranscriptionStarted(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
printf("onTranscriptionStarted: %d\n", tmpParam->userId);
printf("onTranscriptionStarted: status code=%d, task id=%s\n",
cbEvent->getStatusCode(), cbEvent->getTaskId());
pthread_mutex_lock(&(tmpParam->mtxWord));
tmpParam->started = true;
pthread_cond_signal(&(tmpParam->cvWord));
pthread_mutex_unlock(&(tmpParam->mtxWord));
}
void onSentenceBegin(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
printf("onSentenceBegin: %d\n", tmpParam->userId);
printf("onSentenceBegin: status code=%d, task id=%s, index=%d, time=%d\n",
cbEvent->getStatusCode(), cbEvent->getTaskId(),
cbEvent->getSentenceIndex(),
cbEvent->getSentenceTime()
);
}
void onSentenceEnd(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
printf("onSentenceEnd: %d\n", tmpParam->userId);
printf("onSentenceEnd: status code=%d, task id=%s, index=%d, time=%d, begin_time=%d, result=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getSentenceIndex(),
cbEvent->getSentenceTime(),
cbEvent->getSentenceBeginTime(),
cbEvent->getResult()
);
}
void onTranscriptionResultChanged(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
printf("onTranscriptionResultChanged: %d\n", tmpParam->userId);
printf("onTranscriptionResultChanged: status code=%d, task id=%s, index=%d, time=%d, result=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getSentenceIndex(),
cbEvent->getSentenceTime(),
cbEvent->getResult()
);
}
void onTranscriptionCompleted(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
tmpParam->completed = true;
printf("onTranscriptionCompleted: %d\n", tmpParam->userId);
printf("onTranscriptionCompleted: status code=%d, task id=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId());
}
void onTaskFailed(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
pthread_mutex_lock(&tmpParam->mtxWord);
tmpParam->failed = true;
pthread_cond_broadcast(&tmpParam->cvWord);
pthread_mutex_unlock(&tmpParam->mtxWord);
printf("onTaskFailed: %d\n", tmpParam->userId);
printf("onTaskFailed: status code=%d, task id=%s, error message=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getErrorMessage()
);
}
void onChannelClosed(NlsEvent* cbEvent, void* cbParam) {
ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
printf("onChannelClosed: %d, %s\n", tmpParam->userId, tmpParam->userInfo);
printf("onChannelClosed: response=%s\n", cbEvent->getAllResponse());
pthread_mutex_lock(&(tmpParam->mtxWord));
tmpParam->closed = true;
pthread_cond_broadcast(&(tmpParam->cvWord));
pthread_mutex_unlock(&(tmpParam->mtxWord));
}
void* pthreadFunction(void* arg) {
int sleepMs = 0;
int ret = 0;
ParamCallBack *cbParam = NULL;
cbParam = new ParamCallBack();
cbParam->userId = rand() % 100;
strcpy(cbParam->userInfo, "User.");
ParamStruct *tst = (ParamStruct *) arg;
if (tst == NULL) {
printf("arg is not valid\n");
delete cbParam;
return NULL;
}
std::ifstream fs;
fs.open(tst->fileName.c_str(), std::ios::binary | std::ios::in);
if (!fs) {
printf("Cannot open %s\n", tst->fileName.c_str());
delete cbParam;
return NULL;
}
SpeechTranscriberRequest* request =
NlsClient::getInstance()->createTranscriberRequest();
if (request == NULL) {
printf("createTranscriberRequest failed\n");
delete cbParam;
return NULL;
}
request->setOnTranscriptionStarted(onTranscriptionStarted, cbParam);
request->setOnTranscriptionResultChanged(onTranscriptionResultChanged, cbParam);
request->setOnTranscriptionCompleted(onTranscriptionCompleted, cbParam);
request->setOnSentenceBegin(onSentenceBegin, cbParam);
request->setOnSentenceEnd(onSentenceEnd, cbParam);
request->setOnTaskFailed(onTaskFailed, cbParam);
request->setOnChannelClosed(onChannelClosed, cbParam);
request->setAppKey(tst->appkey.c_str());
request->setToken(tst->token.c_str());
request->setUrl("wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1");
request->setFormat("opus");
request->setSampleRate(SAMPLE_RATE);
request->setIntermediateResult(true);
request->setPunctuationPrediction(true);
request->setInverseTextNormalization(true);
struct timespec outtime;
struct timeval now;
ret = request->start();
if (ret < 0) {
printf("start() failed. may be can not connect server. please check network or firewalld\n");
NlsClient::getInstance()->releaseTranscriberRequest(request);
delete cbParam;
return NULL;
} else {
if (g_sync_timeout == 0) {
printf("wait started callback.\n");
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 5;
outtime.tv_nsec = now.tv_usec * 1000;
pthread_mutex_lock(&(cbParam->mtxWord));
while (!cbParam->started && !cbParam->failed && !cbParam->closed) {
if (ETIMEDOUT == pthread_cond_timedwait(&(cbParam->cvWord), &(cbParam->mtxWord), &outtime)) {
printf("start timeout.\n");
pthread_mutex_unlock(&(cbParam->mtxWord));
request->cancel();
NlsClient::getInstance()->releaseTranscriberRequest(request);
delete cbParam;
return NULL;
}
}
pthread_mutex_unlock(&(cbParam->mtxWord));
} else {
}
}
while (cbParam->started && !cbParam->failed && !cbParam->closed && !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;
}
ret = request->sendAudio(data, nlen, ENCODER_OPUS);
if (ret < 0) {
printf("send data fail.\n");
cbParam->failed = true;
break;
}
sleepMs = getSendAudioSleepTime(nlen, SAMPLE_RATE, 1);
usleep(sleepMs * 1000);
}
printf("sendAudio done.\n");
fs.close();
ret = cbParam->failed || cbParam->closed ? -1 : request->stop();
if (ret == 0) {
if (g_sync_timeout == 0) {
printf("wait closed callback.\n");
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 5;
outtime.tv_nsec = now.tv_usec * 1000;
pthread_mutex_lock(&(cbParam->mtxWord));
while (!cbParam->closed) {
if (ETIMEDOUT == pthread_cond_timedwait(&(cbParam->cvWord), &(cbParam->mtxWord), &outtime)) {
printf("stop timeout\n");
pthread_mutex_unlock(&(cbParam->mtxWord));
NlsClient::getInstance()->releaseTranscriberRequest(request);
delete cbParam;
return NULL;
}
}
pthread_mutex_unlock(&(cbParam->mtxWord));
} else {
}
} else {
printf("stop ret is %d\n", ret);
cbParam->failed = true;
if (!cbParam->closed) request->cancel();
}
NlsClient::getInstance()->releaseTranscriberRequest(request);
tst->result = (!cbParam->failed && cbParam->completed) ? 0 : -1;
delete cbParam;
return NULL;
}
int speechTranscriberFile(const char* appkey) {
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 (generateToken(g_akId, g_akSecret, &g_token, &g_expireTime) < 0) {
return -1;
}
}
ParamStruct pa;
pa.token = g_token;
pa.appkey = appkey;
pa.fileName = "test0.wav";
pthread_t pthreadId;
if (pthread_create(&pthreadId, NULL, &pthreadFunction, (void *)&pa) != 0) return -1;
pthread_join(pthreadId, NULL);
return pa.result;
}
#define AUDIO_FILE_NUMS 2
#define AUDIO_FILE_NAME_LENGTH 32
int speechTranscriberMultFile(const char* appkey) {
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 (generateToken(g_akId, g_akSecret, &g_token, &g_expireTime) < 0) {
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);
int created = 0;
for (; created < AUDIO_FILE_NUMS; ++created) {
if (pthread_create(&pthreadId[created], NULL, &pthreadFunction, &pa[created]) != 0) break;
}
int result = created == AUDIO_FILE_NUMS ? 0 : -1;
for (int j = 0; j < created; ++j) {
pthread_join(pthreadId[j], NULL);
if (pa[j].result != 0) result = -1;
}
return result;
}
int main(int argc, char* argv[]) {
const char* appkeyEnv = getenv("NLS_APPKEY_ENV");
const char* akEnv = getenv("NLS_AK_ENV");
const char* skEnv = getenv("NLS_SK_ENV");
if (!appkeyEnv || !*appkeyEnv || !akEnv || !*akEnv || !skEnv || !*skEnv) {
std::cerr << "Set NLS_APPKEY_ENV, NLS_AK_ENV, and NLS_SK_ENV." << std::endl;
return EXIT_FAILURE;
}
std::string appkey = appkeyEnv;
g_akId = akEnv;
g_akSecret = skEnv;
int ret = NlsClient::getInstance()->setLogConfig(
"log-transcriber", LogError, 10, 3);
if (ret < 0) {
printf("set log failed.\n");
NlsClient::releaseInstance();
return EXIT_FAILURE;
}
if (g_sync_timeout > 0) {
NlsClient::getInstance()->setSyncCallTimeout(g_sync_timeout);
}
NlsClient::getInstance()->startWorkThread(1);
int result = speechTranscriberFile(appkey.c_str());
// To transcribe two files concurrently, replace the preceding call with:
// int result = speechTranscriberMultFile(appkey.c_str());
NlsClient::releaseInstance();
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
This example does not enable the preconnection pool. In the Linux x86_64 Release CXX11 precompiled package for version 3.3.0b, enabling the preconnection pool (for example, by calling setPreconnectedPool(2)) may cause an invalid memory free and terminate the process. Do not enable the preconnection pool when using this precompiled package. To use a preconnection pool, build a Debug library from source.
Add the SDK include and lib directories to the project's compiler and linker settings. With NlsSdk3.X_LINUX in the current directory, compile the example file demo.cpp with the following command:
g++ -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=1 demo.cpp -I NlsSdk3.X_LINUX/include -L NlsSdk3.X_LINUX/lib -lalibabacloud-idst-speech -lpthread -o demo
export LD_LIBRARY_PATH="$PWD/NlsSdk3.X_LINUX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
Usage notes
-
The example calculates sending intervals for 16000 Hz, 16-bit, mono audio. For 8 kHz PCM, wait 100 ms after sending 1600 bytes; for 16 kHz PCM, wait 100 ms after sending 3200 bytes. In OPUS/OPU mode, the input to the SDK is still PCM. The recommendation is 640 bytes followed by a 20 ms wait. Send live recordings at the capture rate; rate limiting is needed when simulating a live recording with a file.
-
sendAudio: stop sending audio if the return value is negative. AfterTranscriptionCompletedorTaskFailed, the SDK closes the channel. Do not continue sending audio. -
In asynchronous mode, a return from
start()does not indicate successful startup. Wait for a started or failure event. A return fromstop()does not indicate that the interaction has ended. Wait for the channel-closed event. CallsetSyncCallTimeoutto enable synchronous mode. -
SDK multithreading uses one thread per audio source, not multiple threads sending the same source. The example provides single-file and two-file concurrent entry points. Release the global client only after all requests have ended.
releaseInstance()is not thread-safe.
Free users cannot exceed two concurrent connections. For fewer than 200 concurrent requests, one worker thread is recommended. See the SDK readme.md for recommendations at higher concurrency.
The sentence silence threshold is the silence duration after an utterance. Its valid range is 200–2000 ms, with a default of 800 ms. Semantic sentence detection overrides silence-based sentence detection and requires intermediate results to be enabled.
Use setPayloadParam to pass custom or advanced parameters as a JSON string, such as {"vad_model":"farfield"}.
Internal network access
For internal network access from an Alibaba Cloud ECS instance in Shanghai, set the following URL after creating the SpeechTranscriberRequest.
request->setUrl("ws://nls-gateway-cn-shanghai-internal.aliyuncs.com/ws/v1");
Key interfaces
NlsClient
NlsClient is the client for short sentence recognition, real-time speech recognition, and speech synthesis. It is thread-safe. We recommend creating one global instance.
|
Method |
Available since |
Description |
|
getInstance |
2.x |
Gets or creates the NlsClient instance. |
|
setLogConfig |
2.x |
Sets the log file and storage path. Supported log levels are LogDebug, LogInfo, LogWarning, and LogError. The size of each log file and the number of rotating files can be configured. |
|
setDirectHost |
3.x |
Sets the server IPv4 address directly, bypassing DNS resolution. Call this method before startWorkThread. |
|
setAddrInFamily |
3.1.12 |
Sets the socket address family. The default is AF_INET, which returns only IPv4 address information. Call this method before startWorkThread. |
|
setUseSysGetAddrInfo |
3.1.13 |
Switches to the system resolver if libevent DNS resolution cannot resolve the address. Call this method before startWorkThread. |
|
setSyncCallTimeout |
3.1.17 |
Sets the synchronous call timeout in milliseconds. The default is 0, which disables synchronous mode. In synchronous mode:
|
|
setPreconnectedPool |
3.3.0 |
Sets a preconnection pool for each domain URL.
|
|
startWorkThread |
3.x |
Starts worker threads. The default is 1. A value of -1 starts as many threads as there are CPU cores and is recommended for high concurrency. This method initializes NlsClient and must be called. |
|
releaseInstance |
3.x |
Destroys the NlsClient instance. |
|
getVersion |
2.x |
Gets the SDK version. |
|
createTranscriberRequest |
2.x |
Creates a real-time speech recognition request. This method is thread-safe and supports high concurrency. |
|
releaseTranscriberRequest |
2.x |
Destroys a real-time speech recognition request. Call this method after the request's closed event. Add exception handling and release the request when an error occurs. Otherwise, resource leaks can disrupt operation, for example by preventing recognition results from being returned. |
NlsToken
NlsToken obtains access tokens. Use getExpireTime to obtain the expiration timestamp and refresh the token shortly before expiration. Requesting a new token does not automatically invalidate an existing token that has not expired.
|
Method |
Description |
|
setAccessKeyId |
Sets the Alibaba Cloud account's AccessKey ID. |
|
setKeySecret |
Sets the Alibaba Cloud account's AccessKey secret. |
|
setDomain |
Sets the domain. Optional. |
|
setServerVersion |
Sets the API version. Optional. |
|
setServerResourcePath |
Sets the service resource path. Optional. |
|
setRegionId |
Sets the service region ID. Optional. |
|
setAction |
Sets the action. Optional. |
|
applyNlsToken |
Requests a token. |
|
getToken |
Gets the token. |
|
getExpireTime |
Gets the token expiration timestamp in seconds. |
|
getErrorMsg |
Gets the error message. |
NlsEvent
NlsEvent provides request status codes, server results, and failure information.
|
Method |
Description |
|
getStatusCode |
Gets the status code: 0 or 20000000 for success, or the corresponding error code for failure. |
|
getErrorMessage |
Gets the error message for a failed NlsRequest operation in the TaskFailed callback. |
|
getTaskId |
Gets the task ID. |
|
getAllResponse |
Gets the recognition result returned by the server. |
|
getResult |
Gets intermediate and final recognition results. |
|
getSentenceIndex |
Gets the sentence index for real-time speech recognition. |
|
getSentenceTime |
Gets the current position in the processed audio, in milliseconds. |
|
getSentenceBeginTime |
Gets the time of the corresponding SentenceBegin event, in milliseconds. |
SpeechTranscriberRequest
SpeechTranscriberRequest represents a real-time recognition request for long audio. See speechTranscriberRequest.h for the interface definitions.
|
Method |
Available since |
Description |
|
setOnTaskFailed |
2.x |
Sets the failure callback. |
|
setOnTranscriptionStarted |
2.x |
Sets the callback for the start of real-time recognition. |
|
setOnSentenceBegin |
2.x |
Sets the sentence-start callback. |
|
setOnSentenceEnd |
2.x |
Sets the sentence-end callback. |
|
setOnTranscriptionResultChanged |
2.x |
Sets the callback for intermediate recognition results. |
|
setOnTranscriptionCompleted |
2.x |
Sets the callback for completion of the service. |
|
setOnChannelClosed |
2.x |
Sets the channel-closed callback. |
|
setOnMessage |
3.1.16 |
Sets an optional callback for all server response messages, which the application must parse. Call setEnableOnMessage to enable it. |
|
setAppKey |
2.x |
Sets the AppKey. |
|
setToken |
2.x |
Sets the authentication token. Every request must be authenticated with setToken before it can be used. |
|
setUrl |
2.x |
Sets the service URL. |
|
setIntermediateResult |
2.x |
Specifies whether to return intermediate recognition results. Default: false. |
|
setPunctuationPrediction |
2.x |
Specifies whether to add punctuation during postprocessing. Default: false. |
|
setInverseTextNormalization |
2.x |
Specifies whether to normalize numbers during postprocessing. Default: false. |
|
setFormat |
2.x |
Sets the audio encoding: PCM (default), OPUS (recommended), or OPU. |
|
setSampleRate |
2.x |
Sets the audio sample rate. Supports 16000 and 8000 Hz. Default: 16000 Hz. |
|
setSemanticSentenceDetection |
2.x |
Specifies whether to use semantic sentence detection. |
|
setMaxSentenceSilence |
2.x |
Sets the VAD threshold. |
|
setCustomizationId |
2.x |
Sets the custom model. |
|
setVocabularyId |
2.x |
Sets the hotword vocabulary ID for the current request.If hotwords are configured in both the console and the SDK, the SDK configuration takes precedence and overrides the console configuration. |
|
setTimeout |
2.x |
Sets the connection timeout. Default: 5000 ms. |
|
setSessionId |
2.x |
Sets the session ID. |
|
setOutputFormat |
2.x |
Sets the output text encoding to UTF-8 or GBK. |
|
setPayloadParam |
2.x |
Sets parameters as a JSON string. |
|
setContextParam |
2.x |
Sets custom parameters as a JSON string. |
|
AppendHttpHeaderParam |
2.x |
Sets custom HTTP headers for the WebSocket handshake. |
|
setSendTimeout |
3.1.14 |
Sets the send timeout. Default: 5000 ms. |
|
setRecvTimeout |
3.1.14 |
Sets the receive timeout. Default: 15000 ms. Takes effect only when enabled with setEnableRecvTimeout. |
|
setEnableRecvTimeout |
3.1.16 |
Enables the receive timeout. The default is false (disabled). When enabled, a prolonged absence of server responses triggers an error. |
|
getOutputFormat |
3.1.16 |
Gets the configured output text encoding. |
|
setEnableOnMessage |
3.1.16 |
Enables the server-message callback. |
|
getTaskId |
3.1.17 |
Gets the task_id of the current request. |
|
start |
2.x |
Starts the SpeechTranscriberRequest. |
|
stop |
2.x |
Stops real-time recognition normally, confirming closure with the server. |
|
cancel |
2.x |
Closes real-time recognition directly, without confirming closure with the server. |
|
control |
2.x |
Requests an update to recognition parameters on the server. |
|
sendAudio |
2.x |
Sends audio data. The recommended size per call is 640–16384 bytes. |
SDK package files
-
scripts/build_linux.sh: sample Linux build script in the SDK source.
-
CMakeLists.txt: CMake project file for the Linux SDK example.
-
demo: integration examples in the SDK package. The Linux examples are listed below.
File
Description
speechRecognizerDemo.cpp
Short sentence recognition example.
speechSynthesizerDemo.cpp
Speech synthesis example.
speechTranscriberDemo.cpp
Real-time speech recognition example.
fileTransferDemo.cpp
Recording file recognition example.
-
resource: sample audio in the SDK source for functional testing.
File
Description
-
test0.wav
-
test1.wav
-
test2.wav
-
test3.wav
Test audio files with a 16 kHz sample rate and 16-bit samples.
-
-
include: SDK header files, as listed below.
File
Description
nlsClient.h
SDK client instance.
nlsEvent.h
Callback events.
nlsGlobal.h
Global SDK header.
nlsToken.h
SDK access token instance.
iNlsRequest.h
Base NLS request header.
speechRecognizerRequest.h
Short sentence recognition.
speechSynthesizerRequest.h
Speech synthesis and long-text speech synthesis.
speechTranscriberRequest.h
Real-time audio stream recognition.
FileTrans.h
Recording file recognition.
-
lib: SDK libraries.
-
readme.md: SDK instructions.
-
release.log: Release notes.
-
version: Version number.
C++ SDK error codes
|
Status code |
Status message |
Cause |
Solution |
|
0 |
Success |
Success |
|
|
-10 |
DefaultError |
Default error |
Not currently used. |
|
-11 |
JsonParseFailed |
Invalid JSON format |
Check whether the input string is valid JSON. |
|
-12 |
JsonObjectError |
Invalid JSON object |
Try again. |
|
-13 |
MallocFailed |
Malloc failed |
Check whether sufficient memory is available. |
|
-14 |
ReallocFailed |
Realloc failed |
Check whether sufficient memory is available. |
|
-15 |
InvalidInputParam |
Invalid input parameter |
Not currently used. |
|
-50 |
InvalidLogLevel |
Invalid log level |
Check the configured log level. |
|
-51 |
InvalidLogFileSize |
Invalid log file size |
Check the log file size parameter. |
|
-52 |
InvalidLogFileNum |
Invalid log file count |
Check the log file count parameter. |
|
-100 |
EncoderExistent |
The NLS encoder already exists |
Try again. |
|
-101 |
EncoderInexistent |
The NLS encoder does not exist |
Reinitialize the encoder. |
|
-102 |
OpusEncoderCreateFailed |
Failed to create the Opus encoder |
Reinitialize the encoder. |
|
-103 |
OggOpusEncoderCreateFailed |
Failed to create the OggOpus encoder |
Reinitialize the encoder. |
|
-104 |
InvalidEncoderType |
Invalid encoder type |
OPUS may have been disabled at compile time but is being used. Check ENCODER_TYPE. |
|
-150 |
EventClientEmpty |
The main worker thread pointer is null because it has been released |
Reinitialize by calling startWorkThread(). |
|
-151 |
SelectThreadFailed |
Failed to select a worker thread because worker threads have not been initialized |
Reinitialize by calling startWorkThread(). |
|
-160 |
StartCommandFailed |
Failed to send the start command |
Try again. |
|
-161 |
InvokeStartFailed |
The request state is invalid for start |
Check whether the request has not been created or has already completed. |
|
-162 |
InvokeSendAudioFailed |
The request state is invalid for sendAudio |
Check whether the request has started (the started callback has been received) or has already completed. |
|
-163 |
InvalidOpusFrameSize |
Invalid Opus frame length; the default is 640 bytes |
In OPU encoding mode, sendAudio accepts only 640 bytes per frame. |
|
-164 |
InvokeStopFailed |
The request state is invalid for stop |
Check whether the request has not started (the started callback has not been received) or has already completed. |
|
-165 |
InvokeCancelFailed |
The request state is invalid for cancel |
Check whether the request has not started (the started callback has not been received) or has already completed. |
|
-166 |
InvokeStControlFailed |
The request state is invalid for stControl |
Check whether the request has not started (the started callback has not been received) or has already completed. |
|
-200 |
NlsEventEmpty |
The NLS event is null |
Internal SDK error: the NlsEvent frame is missing. |
|
-201 |
NewNlsEventFailed |
Failed to create NlsEvent |
Internal SDK error: failed to create the NlsEvent frame. |
|
-202 |
NlsEventMsgEmpty |
The message in the NLS event is empty |
parseJsonMsg() found an empty message string during parsing. |
|
-203 |
InvalidNlsEventMsgType |
Invalid message type in the NLS event |
Internal SDK error: the event type in the NlsEvent frame is invalid. |
|
-204 |
InvalidNlsEventMsgStatusCode |
Invalid message status code in the NLS event |
Internal SDK error: the event message status in the NlsEvent frame is invalid. |
|
-205 |
InvalidNlsEventMsgHeader |
Invalid message header in the NLS event |
Internal SDK error: the event message header in the NlsEvent frame is invalid. |
|
-250 |
CancelledExitStatus |
cancel has been called |
Not currently used. |
|
-251 |
InvalidWorkStatus |
Invalid working state |
Internal SDK error: the internal state of the current request is invalid. |
|
-252 |
InvalidNodeQueue |
Invalid NodeQueue in workThread |
Internal SDK error: the pending request is invalid. Release the current request and try again. |
|
-300 |
InvalidRequestParams |
Invalid request input parameter |
The data passed to sendAudio is empty. |
|
-301 |
RequestEmpty |
The request pointer is null |
Internal SDK error: the current request has been released. Release the current request and try again. |
|
-302 |
InvalidRequest |
Invalid request |
Internal SDK error: the current request has been released. Release the current request and try again. |
|
-303 |
SetParamsEmpty |
The input parameter is empty |
Check whether the input parameter is empty. |
|
-350 |
GetHttpHeaderFailed |
Failed to obtain the HTTP header |
Internal SDK error. Check the logs for details. |
|
-351 |
HttpGotBadStatus |
Invalid HTTP state |
Internal SDK error. Check the logs for details. |
|
-352 |
WsResponsePackageFailed |
Failed to parse the WebSocket response |
Internal SDK error. Check the logs for details. |
|
-353 |
WsResponsePackageEmpty |
The parsed WebSocket response is empty |
Internal SDK error. Check the logs for details. |
|
-354 |
WsRequestPackageEmpty |
The WebSocket request is empty |
Internal SDK error. Check the logs for details. |
|
-355 |
UnknownWsFrameHeadType |
Unknown WebSocket frame header type |
Internal SDK error. Check the logs for details. |
|
-356 |
InvalidWsFrameHeaderSize |
Invalid WebSocket frame header size |
Internal SDK error. Check the logs for details. |
|
-357 |
InvalidWsFrameHeaderBody |
Invalid WebSocket frame header body |
Internal SDK error. Check the logs for details. |
|
-358 |
InvalidWsFrameBody |
Invalid WebSocket frame body |
Internal SDK error. Check the logs for details. |
|
-359 |
WsFrameBodyEmpty |
The frame data is empty, commonly because malformed data was received |
Internal SDK error. Check the logs for details. |
|
-400 |
NodeEmpty |
The node pointer is null |
Release the current request and try again. |
|
-401 |
InvaildNodeStatus |
Invalid node state |
Internal SDK error. Release the current request and try again. |
|
-402 |
GetAddrinfoFailed |
Failed to resolve the address through DNS |
Internal SDK error. Check whether DNS is available in the current environment. |
|
-403 |
ConnectFailed |
Failed to connect to the network |
Check whether the network is available. |
|
-404 |
InvalidDnsSource |
DNS is unavailable on the current device |
Internal SDK error. 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 |
Internal SDK error. Check network availability and try again. |
|
-407 |
SslCtxEmpty |
SSL_CTX is null |
Internal SDK error. Check network availability and try again. |
|
-408 |
SslNewFailed |
SSL_new failed |
Internal SDK error. Check network availability and try again. |
|
-409 |
SslSetFailed |
Failed to set SSL parameters |
Internal SDK error. Check network availability and try again. |
|
-410 |
SslConnectFailed |
SSL_connect failed |
Internal SDK error. Check network availability and try again. |
|
-411 |
SslWriteFailed |
Failed to send data over SSL |
Internal SDK error. Check network availability and try again. |
|
-412 |
SslReadSysError |
A SYSCALL error occurred while receiving data over SSL |
Internal SDK error. Check network availability and try again. |
|
-413 |
SslReadFailed |
Failed to receive data over SSL |
Internal SDK error. Check network availability and try again. |
|
-414 |
SocketFailed |
Failed to create a socket |
Internal SDK error. Check network availability and try again. |
|
-415 |
SetSocketoptFailed |
Failed to set socket parameters |
Internal SDK error. Check network availability and try again. |
|
-416 |
SocketConnectFailed |
Failed to establish a socket connection |
Internal SDK error. Check network availability and try again. |
|
-417 |
SocketWriteFailed |
Failed to send data through the socket |
Internal SDK error. Check network availability and try again. |
|
-418 |
SocketReadFailed |
Failed to receive data through the socket |
Internal SDK error. Check network availability and try again. |
|
-430 |
NlsReceiveFailed |
Failed to receive NLS frame data |
Internal SDK error. Check network availability and try again. |
|
-431 |
NlsReceiveEmpty |
The received NLS frame data is empty |
Internal SDK error. Check network availability and try again. |
|
-432 |
ReadFailed |
Failed to receive data |
Internal SDK error. Check network availability and try again. |
|
-433 |
NlsSendFailed |
Failed to send NLS data |
Internal SDK error. Check network availability and try again. |
|
-434 |
NewOutputBufferFailed |
Failed to create a buffer |
Internal SDK error. Check whether sufficient memory is available. |
|
-435 |
NlsEncodingFailed |
Failed to encode audio |
Internal SDK error. Release the current request and try again. |
|
-436 |
EventEmpty |
The event is null |
Internal SDK error. Release the current request and try again. |
|
-437 |
EvbufferTooMuch |
Too much data in evbuffer |
Internal SDK error: the send buffer is full (maximum 320000 for 16 kHz audio and 160000 for 8 kHz audio). Check whether audio is sent too frequently or too much data is sent at once. |
|
-438 |
EvutilSocketFailed |
Failed to set evutil parameters |
Internal SDK error. Release the current request and try again. |
|
-439 |
InvalidExitStatus |
Invalid exit state |
Check whether the current request has already been canceled. |
|
-450 |
InvalidAkId |
Invalid AccessKey ID for the Alibaba Cloud account |
Check whether the AccessKey ID is empty. |
|
-451 |
InvalidAkSecret |
Invalid AccessKey secret for the Alibaba Cloud account |
Check whether the AccessKey secret is empty. |
|
-452 |
InvalidAppKey |
Invalid project AppKey |
Check whether the project AppKey is empty. |
|
-453 |
InvalidDomain |
Invalid domain |
Check whether the input domain is empty. |
|
-454 |
InvalidAction |
Invalid action |
Check whether the input action is empty. |
|
-455 |
InvalidServerVersion |
Invalid ServerVersion |
Check whether the input ServerVersion is empty. |
|
-456 |
InvalidServerResource |
Invalid ServerResource |
Check whether the input ServerResource is empty. |
|
-457 |
InvalidRegionId |
Invalid RegionId |
Check whether the input RegionId is empty. |
|
-500 |
InvalidFileLink |
Invalid recording file URL |
The recording file URL for transcription is empty. |
|
-501 |
ErrorStatusCode |
Invalid status code |
Recording file transcription returned an error. For more information, see the error code. |
|
-502 |
IconvOpenFailed |
Failed to allocate a conversion descriptor |
Conversion between UTF-8 and GBK failed. |
|
-503 |
IconvFailed |
Encoding conversion failed |
Conversion between UTF-8 and GBK failed. |
|
-504 |
ClientRequestFaild |
The account client request failed |
Recording file transcription failed. |
|
-999 |
NlsMaxErrorCode |
|
Other status codes |
Status message |
Cause |
Solution |
|
10000001 |
NewSslCtxFailed |
SSL: couldn't create a context! |
Reinitialize the encoder. |
|
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. |
Troubleshoot based on the error message returned by the system. |
|
10000004 |
EmptyUrl |
URL: The url is empty. |
The input URL is empty. Specify a valid URL. |
|
10000005 |
InvalidWsUrl |
Could not parse WebSocket url: |
The input URL format is invalid. Specify a valid URL. |
|
10000007 |
JsonStringParseFailed |
JSON: Json parse failed. |
The JSON format is invalid. Check the logs for details. |
|
10000008 |
UnknownWsHeadType |
WEBSOCKET: unkown head type. |
Failed to connect to the network. Check local DNS resolution and the URL. |
|
10000009 |
HttpConnectFailed |
HTTP: connect failed. |
Failed to connect to the server. Check the network and try again. |
|
10000010 |
MemNotEnough |
Insufficient memory. |
Check whether sufficient memory is available. |
|
10000015 |
SysConnectFailed |
connect failed. |
Failed to connect to the network. Check local DNS resolution and the URL. |
|
10000100 |
HttpGotBadStatusWith403 |
Got bad status host=xxxxx line=HTTP/1.1 403 Forbidden |
The connection was rejected. Check the account and, in particular, whether the token has expired. |
|
10000101 |
EvSendTimeout |
Send timeout. socket error: |
The libevent send event timed out. Check for time-consuming tasks in callbacks or excessive concurrency that prevents events from being processed promptly. |
|
10000102 |
EvRecvTimeout |
Recv timeout. socket error: |
The libevent receive event timed out. Check for time-consuming tasks in callbacks or excessive concurrency that 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 keep up with processing. Try again. |
|
10000110 |
TokenHasExpired |
Gateway:ACCESS_DENIED:The token 'xxx' has expired! |
Refresh the token. |
|
10000111 |
TokenIsInvalid |
Meta:ACCESS_DENIED:The token 'xxx' is invalid! |
Check whether the token is valid. |
|
10000112 |
NoPrivilegeToVoice |
Gateway:ACCESS_DENIED:No privilege to this voice! (voice: zhinan, privilege: 0) |
The voice cannot be used with the current permissions. |
|
10000113 |
MissAuthHeader |
Gateway:ACCESS_DENIED:Missing authorization header! |
Check account permissions and whether concurrency is within the limit. |
|
10000120 |
Utf8ConvertError |
utf8ToGbk failed |
UTF-8 conversion failed, commonly due to a system issue. Try again. |
|
20000000 |
SuccessStatusCode |
Success |
Server response status codes
For service status codes, see API reference.
FAQ
Troubleshooting scenarios
How do I resolve {"TaskFailed":"connect failed."} {"channeclClosed": "nls request finished."} when calling the real-time speech recognition API with the C++ SDK?
-
This issue occasionally occurs in C++ SDK 3.0 and earlier and does not require special attention. In 3.1 and later, it may be caused by the network in the runtime environment. Check the local network.
-
If no TaskId is returned, the connection was closed during connection establishment. Repeated API calls are not required for real-time speech interaction and are subject to concurrency and timeout limits. Exceeding the concurrency limit returns a limit error. A WebSocket connection is automatically closed if no audio is sent for more than 10 seconds, but a TaskId is returned in that case.
How do I resolve status_text:Gateway:IDLE_TIMEOUT:Websocket session is idle for too long time, the last directive is 'StartTranscription'! during real-time speech recognition with the C++ SDK?
-
The connection is closed automatically after an idle timeout because no data has been sent to the server for more than 10 seconds. Also check that the URI is correct:
wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1. If this occurs, add a retry mechanism to send the request again. -
A sudden influx of requests to the server may also prevent an instance from processing requests promptly. Retry the request.
How do I resolve error 10000002 when creating multiple recognition channels with the C++ real-time speech recognition SDK integrated into MRCP?
Error code 10000002 is the SDK default error code. For the underlying error, see Resource temporarily unavailable. This generally occurs when no data is sent after connection establishment, causing a WebSocket timeout. The next command sent is StartTranscription.
Can I use a GCC version later than 5.0 with C++ SDK 3.0 and later for speech synthesis and speech recognition?
Yes. GCC 4.8.5 and later are supported on Linux. GCC 4.8.5, 5.5.0, and 8.4.0 have been verified to compile and run successfully.
Why can't I link to the framework?
The framework contains both Objective-C and C++ code. Call it from a file with the .mm extension, and ensure that the project header and library paths are configured correctly.
How do I resolve the DNS resolution error "ali-recog-skd.log:AliSpeech_C++SDK(ERROR): GetInetAddressByHostname:252 DNS: resolved timeout.ali-recog-skd.log:AliSpeech_C++SDK(ERROR): start:76 start failed: DNS: resolved timeout..unimrcpserver_current.log: [ERROR] [[./ali/AliRecogChannel.cpp:772,onTaskFailed]]Ali Task start failed Msg :DNS: resolved timeout., start finised." for a C++ SDK ASR request?
-
Earlier versions (3.0 and earlier): this issue is more likely under high concurrency or when the device DNS is busy. Upgrade to 3.1.X or restart the request.
-
Later versions (3.0 and later): protection against this issue is implemented. If it still occurs occasionally, DNS is busy on the device. Restart the request.
How do I resolve compilation failures after changing add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) to add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) in CMakeLists.txt when integrating the new C++ SDK into another project?
In addition to CMakeLists.txt, update this parameter throughout the project, including config/linux.thirdparty.debug.cmake and config/linux.thirdparty.release.cmake. Search all directories for _GLIBCXX_USE_CXX11_ABI and update it.
What is the difference between the earlier NlsSdkCpp2.0 and the newer NlsSdkCpp3.X?
NlsSdkCpp2.0 uses one thread per request and synchronous interfaces.
NlsSdkCpp3.X uses the third-party libevent library to handle events centrally, provides higher concurrency performance, and uses asynchronous interfaces by default. From 3.1.17, synchronous calls can be enabled with setSyncCallTimeout.
Does the C++ SDK support the C11 standard? How do I resolve SDK linking failures?
The application and SDK must use the same _GLIBCXX_USE_CXX11_ABI. The default build script for the 3.3.0b source selects the ABI based on the GCC major version. The CXX11 precompiled package uses ABI=1 and cannot be mixed directly with an ABI=0 application.
How do I resolve "nls-gateway-cn-shanghai.aliyuncs.com dns failed: nodename nor servname provided, or not known" when the C++ SDK demo works but integration into a project fails?
-
The SDK checks all enabled protocol families (IPv4 and IPv6) on the device when resolving DNS.
nls-gateway-cn-shanghai.aliyuncs.comdoes not support IPv6 and returns a resolution error, causing SDK DNS resolution to fail and exit. Disable IPv6 on the device, or use setAddrInFamily in 3.1.12 and later to configure the address family. -
Upgrade to 3.1.12 or later.
How do I resolve "[dnsEventCallback:465]Node:0x7f087c001030 ai_canonname: nls-gateway-cn-shanghai.aliyuncs.com.gds.alibabadns.com[dnsEventCallback:477]Node:0x7f087c001030 IpV4:106.15.XX.XX[connectProcess:1329]Node:0x7f087c001030 sockFd:41[connectProcess:1347]Node:0x7f087c001030 new Socket ip:106.15.XX.XX port:443 Fd:41.[socketConnect:1458]Node:0x7f087c001030 Connect failed:Network is unreachable. retry..." when the C++ SDK demo works but project integration fails?
This indicates that the network is unreachable. The logs show that the connection to the IP address resolved by DNS failed, and a ping test confirms that the network is unreachable. Local DNS interception causes the SDK's libevent library to obtain an incorrect IP address through its evdns_getaddrinfo function.
Solutions:
-
Before 3.1.12, manually replace evdns_getaddrinfo() with the system getaddrinfo().
-
In version 3.1.12, modify
add_definitions(-DNLS_USE_NATIVE_GETADDRINFO)inCMakeLists.txt. -
In 3.1.12 and later, use setDirectHost() to set a correct IP address resolved outside the SDK.
-
This issue is resolved in 3.1.13 and later. If it still occurs at runtime, call setUseSysGetAddrInfo(true).
What error occurs if the text passed to the C++ SDK for speech synthesis is not UTF-8 encoded?
If the input text is not UTF-8 encoded and contains Chinese characters, the speech synthesis SDK start call fails with Socket recv failed, errorCode: 0. Error code 0 indicates that the server has closed the connection. Check whether the input text is UTF-8 encoded.