未验证 提交 8340ad54 编写于 作者: 口天人韦月月鸟's avatar 口天人韦月月鸟 提交者: GitHub

add brpc to use paraformer (#3149)

* add brpc to use paraformer
上级 ce4af0e7
#edit-mode: -*- python -*-
#coding:gbk
WORKROOT('../../../')
GCC('gcc82')
CPPFLAGS('-g -DNDEBUG -pipe -W -Wall -Werror -fPIC -Wno-deprecated -Wno-unused-parameter -fno-omit-frame-pointer -D__const__= -std=c++11 -D__STDC_FORMAT_MACROS -DBAIDU_RPC_ENABLE_CPU_PROFILER -DBAIDU_RPC_ENABLE_HEAP_PROFILER')
LDFLAGS('-lpthread -pthread -lrt -ldl -lz')
CONFIGS('baidu/base/baidu-rpc@stable')
CONFIGS('baidu/third-party/openssl@openssl_V1.0.2.10_GCC820_6U3_K2_GEN_PD_BL@git_tag')
CONFIGS('baidu/third-party/tcmalloc@tcmalloc_V2.7.0.7_GCC820_4U3_K3_GEN_PD_BL@git_tag')
CONFIGS("baidu/third-party/protobuf@protobuf_V2.6.1.1_GCC820_4U3_K3_GEN_PD_BL@git_tag")
CONFIGS('baidu/base/ullib@stable')
HEADERS(GLOB_GEN_SRCS('./proto/*.pb.h'), '$INC')
PROTOC(ENV.WorkRoot() + '/third-64/protobuf/bin/protoc')
PROTOFLAGS('-I../../../third-64/protobuf/include')
PROTOFLAGS('--proto_path=.', '--cpp_out=.')
Directory("paraformerCPP")
\ No newline at end of file
## Extra Description
this codes are using BCLOUD to compile, and this method does not satisfy the rule of repos.
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <webrtc_vad.h>
#include "ComDefine.h"
#include "Audio.h"
using namespace std;
class AudioWindow {
private:
int *window;
int in_idx;
int out_idx;
int sum;
int window_size = 0;
public:
AudioWindow(int window_size) : window_size(window_size)
{
window = (int *)calloc(sizeof(int), window_size + 1);
in_idx = 0;
out_idx = 1;
sum = 0;
};
~AudioWindow(){
free(window);
};
int put(int val)
{
sum = sum + val - window[out_idx];
window[in_idx] = val;
in_idx = in_idx == window_size ? 0 : in_idx + 1;
out_idx = out_idx == window_size ? 0 : out_idx + 1;
return sum;
};
};
AudioFrame::AudioFrame(){};
AudioFrame::AudioFrame(int len) : len(len)
{
start = 0;
};
AudioFrame::~AudioFrame(){};
int AudioFrame::set_start(int val)
{
start = val < 0 ? 0 : val;
return start;
};
int AudioFrame::set_end(int val, int max_len)
{
float num_samples = val - start;
float frame_length = 400;
float frame_shift = 160;
float num_new_samples =
ceil((num_samples - frame_length) / frame_shift) * frame_shift + frame_length;
end = start + num_new_samples;
len = (int)num_new_samples;
if (end > max_len){
printf("frame end > max_len!!!!!!!\n");
}
return end;
};
int AudioFrame::get_start()
{
return start;
};
int AudioFrame::get_len()
{
return len;
};
int AudioFrame::disp()
{
printf("not imp!!!!\n");
return 0;
};
Audio::Audio(int data_type) : data_type(data_type)
{
speech_buff = NULL;
align_size = 1360;
}
Audio::Audio(int data_type, int size) : data_type(data_type)
{
speech_buff = NULL;
align_size = (float)size;
}
Audio::~Audio()
{
if (speech_buff != NULL) {
free(speech_buff);
speech_data.clear();
}
}
void Audio::disp()
{
printf("Audio time is %f s. len is %d\n", (float)speech_len / 16000,
speech_len);
}
void Audio::loadwavfrommem(AudioFile<float>audio)
{
if (speech_buff != NULL) {
free(speech_buff);
speech_data.clear();
}
int wav_length = audio.getNumSamplesPerChannel();
int channelNum = audio.getNumChannels();
speech_len = wav_length * channelNum;
printf("wav_length:%d, channelNum: %d", wav_length, channelNum);
speech_align_len = (int)(ceil((float)speech_len / align_size) * align_size);
speech_buff = (int16_t *)malloc(sizeof(int16_t) * speech_align_len);
memset(speech_buff, 0, sizeof(int16_t) * speech_align_len);
for (int i = 0; i < wav_length; i++)
{
for (int channel = 0; channel < channelNum; channel++)
{
speech_buff[i * channelNum + channel] = (int16_t)(audio.samples[channel][i] * 32768);
}
}
for (int i = 0; i < speech_len; i++) {
float temp = (float)speech_buff[i];
speech_data.emplace_back(temp);
}
AudioFrame *frame = new AudioFrame(speech_len);
frame_queue.push(frame);
}
int Audio::fetch(vector<float> &dout, int &len, int &flag)
{
if (frame_queue.size() > 0) {
AudioFrame *frame = frame_queue.front();
frame_queue.pop();
len = frame->get_len();
int speech_len = speech_data.size();
auto last = min(speech_len, frame->get_start() + len);
dout.insert(dout.begin(), speech_data.begin() + frame->get_start(), speech_data.begin() + last);
delete frame;
flag = S_END;
return 1;
} else {
return 0;
}
}
#define UNTRIGGERED 0
#define TRIGGERED 1
#define SPEECH_LEN_5S (16000 * 5)
#define SPEECH_LEN_10S (16000 * 10)
#define SPEECH_LEN_15S (16000 * 15)
#define SPEECH_LEN_20S (16000 * 20)
#define SPEECH_LEN_30S (16000 * 30)
#define SPEECH_LEN_60S (16000 * 60)
void Audio::split()
{
VadInst *handle = WebRtcVad_Create();
WebRtcVad_Init(handle);
WebRtcVad_set_mode(handle, 2);
int window_size = 10;
AudioWindow audiowindow(window_size);
int status = UNTRIGGERED;
int offset = 0;
int fs = 16000;
int step = 160;
AudioFrame *frame;
frame = frame_queue.front();
frame_queue.pop();
delete frame;
while (offset < speech_len - step) {
int n = WebRtcVad_Process(handle, fs, speech_buff + offset, step);
if (status == UNTRIGGERED && audiowindow.put(n) >= window_size - 1) {
frame = new AudioFrame();
int start = offset - step * (window_size - 1);
frame->set_start(start);
status = TRIGGERED;
} else if (status == TRIGGERED) {
int win_weight = audiowindow.put(n);
int voice_len = (offset - frame->get_start());
int gap = 0;
if (voice_len < SPEECH_LEN_5S) {
offset += step;
continue;
} else if (voice_len < SPEECH_LEN_10S) {
gap = 1;
} else if (voice_len < SPEECH_LEN_20S) {
gap = window_size / 5;
} else {
gap = window_size - 1;
}
if (win_weight < gap || voice_len >= SPEECH_LEN_15S) {
status = UNTRIGGERED;
offset = frame->set_end(offset, speech_align_len);
frame_queue.push(frame);
frame = NULL;
}
}
offset += step;
}
if (frame != NULL) {
frame->set_end(speech_len, speech_align_len);
frame_queue.push(frame);
frame = NULL;
}
WebRtcVad_Free(handle);
}
#ifndef AUDIO_H
#define AUDIO_H
#include <queue>
#include <stdint.h>
#include <vector>
#include <AudioFile.h>
using namespace std;
class AudioFrame {
private:
int start;
int end;
int len;
public:
AudioFrame();
AudioFrame(int len);
~AudioFrame();
int set_start(int val);
int set_end(int val, int max_len);
int get_start();
int get_len();
int disp();
};
class Audio {
private:
vector<float> speech_data;
int16_t *speech_buff;
int speech_len;
int speech_align_len;
int16_t sample_rate;
int offset;
float align_size;
int data_type;
queue<AudioFrame *> frame_queue;
public:
vector<float> speech_vec;
Audio(int data_type);
Audio(int data_type, int size);
~Audio();
void disp();
void loadwav(const char *filename);
void loadwavfrommem(AudioFile<float>audio);
int fetch_chunck(float *&dout, int len);
int fetch(vector<float> &dout, int &len, int &flag);
void padding();
void split();
};
#endif
#ifndef COMDEFINE_H
#define COMDEFINE_H
#define S_BEGIN 0
#define S_MIDDLE 1
#define S_END 2
#define S_ALL 3
#define S_ERR 4
#endif
#include "Vocab.h"
#include <fstream>
#include <iostream>
#include <list>
#include <sstream>
#include <string>
using namespace std;
Vocab::Vocab(const char *filename)
{
ifstream in(filename);
string line;
if (in) // 有该文件
{
while (getline(in, line)) // line中不包括每行的换行符
{
vocab.push_back(line);
}
// cout << vocab[1719] << endl;
}
// else // 没有该文件
//{
// cout << "no such file" << endl;
// }
}
Vocab::~Vocab()
{
}
string Vocab::vector2string(vector<int> in)
{
stringstream ss;
for (auto it = in.begin(); it != in.end(); it++) {
ss << vocab[*it];
}
return ss.str();
}
int str2int(string str)
{
const char *ch_array = str.c_str();
if (((ch_array[0] & 0xf0) != 0xe0) || ((ch_array[1] & 0xc0) != 0x80) ||
((ch_array[2] & 0xc0) != 0x80))
return 0;
int val = ((ch_array[0] & 0x0f) << 12) | ((ch_array[1] & 0x3f) << 6) |
(ch_array[2] & 0x3f);
return val;
}
bool Vocab::isChinese(string ch)
{
if (ch.size() != 3) {
return false;
}
int unicode = str2int(ch);
if (unicode >= 19968 && unicode <= 40959) {
return true;
}
return false;
}
string Vocab::vector2stringV2(vector<int> in)
{
int i;
list<string> words;
int is_pre_english = false;
int pre_english_len = 0;
int is_combining = false;
string combine = "";
for (auto it = in.begin(); it != in.end(); it++) {
string word = vocab[*it];
// step1 space character skips
if (word == "<s>" || word == "</s>" || word == "<unk>")
continue;
// step2 combie phoneme to full word
{
int sub_word = !(word.find("@@") == string::npos);
// process word start and middle part
if (sub_word) {
combine += word.erase(word.length() - 2);
is_combining = true;
continue;
}
// process word end part
else if (is_combining) {
combine += word;
is_combining = false;
word = combine;
combine = "";
}
}
// step3 process english word deal with space , turn abbreviation to upper case
{
// input word is chinese, not need process
if (isChinese(word)) {
words.push_back(word);
is_pre_english = false;
}
// input word is english word
else {
// pre word is chinese
if (!is_pre_english) {
word[0] = word[0] - 32;
words.push_back(word);
pre_english_len = word.size();
}
// pre word is english word
else {
// single letter turn to upper case
if (word.size() == 1) {
word[0] = word[0] - 32;
}
if (pre_english_len > 1) {
words.push_back(" ");
words.push_back(word);
pre_english_len = word.size();
}
else {
if (word.size() > 1) {
words.push_back(" ");
}
words.push_back(word);
pre_english_len = word.size();
}
}
is_pre_english = true;
}
}
}
// for (auto it = words.begin(); it != words.end(); it++) {
// cout << *it << endl;
// }
stringstream ss;
for (auto it = words.begin(); it != words.end(); it++) {
ss << *it;
}
return ss.str();
}
string Vocab::vector2stringV3(string in)
{
int i;
list<string> words;
words.push_back(in.c_str());
int is_pre_english = false;
int pre_english_len = 0;
int is_combining = false;
string combine = "";
for (auto it = in.begin(); it != in.end(); it++) {
string word = vocab[*it];
// step1 space character skips
if (word == "<s>" || word == "</s>" || word == "<unk>")
continue;
// step2 combie phoneme to full word
{
int sub_word = !(word.find("@@") == string::npos);
// process word start and middle part
if (sub_word) {
combine += word.erase(word.length() - 2);
is_combining = true;
continue;
}
// process word end part
else if (is_combining) {
combine += word;
is_combining = false;
word = combine;
combine = "";
}
}
// step3 process english word deal with space , turn abbreviation to upper case
{
// input word is chinese, not need process
if (isChinese(word)) {
words.push_back(word);
is_pre_english = false;
}
// input word is english word
else {
// pre word is chinese
if (!is_pre_english) {
word[0] = word[0] - 32;
words.push_back(word);
pre_english_len = word.size();
}
// pre word is english word
else {
// single letter turn to upper case
if (word.size() == 1) {
word[0] = word[0] - 32;
}
if (pre_english_len > 1) {
words.push_back(" ");
words.push_back(word);
pre_english_len = word.size();
}
else {
if (word.size() > 1) {
words.push_back(" ");
}
words.push_back(word);
pre_english_len = word.size();
}
}
is_pre_english = true;
}
}
}
// for (auto it = words.begin(); it != words.end(); it++) {
// cout << *it << endl;
// }
stringstream ss;
for (auto it = words.begin(); it != words.end(); it++) {
ss << *it;
}
return ss.str();
}
int Vocab::size()
{
return vocab.size();
}
#ifndef VOCAB_H
#define VOCAB_H
#include <stdint.h>
#include <string>
#include <vector>
using namespace std;
class Vocab {
private:
vector<string> vocab;
bool isChinese(string ch);
bool isEnglish(string ch);
public:
Vocab(const char *filename);
~Vocab();
int size();
string vector2string(vector<int> in);
string vector2stringV2(vector<int> in);
string vector2stringV2(string in);
};
#endif
\ No newline at end of file
# comlog related params
##########################################
# 进程名
COMLOG_PROCNAME : asr-service
#日志等级
#[默认配置(uint)]
COMLOG_LEVEL : 4
#设备数目
#[默认配置(uint), COMLOG_DEVICE_NUM : 2]
COMLOG_DEVICE_NUM : 2
#设备0 名
#[默认配置(字符串), COMLOG_DEVICE0 : FILE]
COMLOG_DEVICE0 : FILE
#设备0 名
#[默认配置(字符串), COMLOG_DEVICE1 : TTY]
COMLOG_DEVICE1 : TTY
#设备类型, ULLOG
#[默认配置(字符串)]
FILE_TYPE : ULLOG
FILE_SIZE : 2048
FILE_SPLITE_TYPE : DATECUT
FILE_DATA_CRONOCUT : 1
FILE_RESERVED1 : %Y%m%d%H
FILE_QUOTA_DAY : 30
#日志名
#[默认配置(字符串)]
FILE_NAME : asr-service.log
#日志路径
#[默认配置(字符串), FILE_PATH : ./log]
FILE_PATH : ./log
#是否打开这个设备
#[默认配置(uint), FILE_OPEN : 1]
FILE_OPEN : 1
#设备类型, TTY
#[默认配置(字符串), TTY_TYPE : TTY]
TTY_TYPE : TTY
#日志名
#[默认配置(字符串), TTY_NAME : receiver]
TTY_NAME : asr-service
#日志路径
#[默认配置(字符串), TTY_PATH : ./log]
TTY_PATH : ./log
#是否打开这个设备
#[默认配置(uint), TTY_OPEN : 1]
TTY_OPEN : 1
\ No newline at end of file
// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "recognizer.h"
#include <iostream>
#include <string>
using std::vector;
int main(int argc, char* argv[]) {
std::string model_file = argv[1];
std::string word_symbol_file = argv[2];
std::string wav_audio = argv[3];
InitRecognizer(model_file, word_symbol_file);
int idx = AddRecognizerInstance(); // idx == 0
for (int i = 0; i < 50; i++){
AcceptWav(wav_audio, idx);
std::string result = GetResult(idx);
std::cout << "idx:" << idx << "result :" << result << std::endl;
Reset(idx);
}
}
// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "recognizer.h"
#include <iostream>
#include <string>
using std::vector;
int main(int argc, char* argv[]) {
std::string model_file = "model.onnx";
std::string word_symbol_file = "words.txt";
std::string wav_audio = argv[1];
InitRecognizer(model_file, word_symbol_file);
AcceptWav(wav_audio);
std::string result = GetResult();
std::cout << "result :" << result << std::endl;
Reset();
}
// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#include <vector>
bool InitRecognizer(const std::string& model_file,
const std::string& word_symbol_table_file);
int AddRecognizerInstance(); // instance id is from 0 to size - 1
int GetRecognizerInstanceSize(); // return size
void Accept(const std::vector<float>& waves, int instance_id);
void AcceptWav(const std::string wav_file, int instance_id);
std::string GetResult(int instance_id);
void Reset(int instance_id);
export LD_LIBRARY_PATH=./fdlib/lib:$LD_LIBRARY_PATH
../bin/asrcpuserver --port 8765
\ No newline at end of file
// Copyright (c) 2014 baidu-rpc authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// A server to receive EchoRequest and send back EchoResponse.
#include <iostream>
#ifndef _WIN32
#include <sys/time.h>
#else
#include <win_func.h>
#endif
#include <gflags/gflags.h>
#include <baas-lib-c/baas.h>
#include <baas-lib-c/giano_mock_helper.h>
#include <base/logging.h>
#include "base/base64.h"
#include <baidu/rpc/server.h>
#include <baidu/rpc/policy/giano_authenticator.h>
#include "echo.pb.h"
#include <typeinfo>
#include <stdexcept>
#include <fstream>
#include <string>
#include <com_log.h>
#include <vector>
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "recognizer.h"
#include <AudioFile.h>
#include <Audio.h>
#include <cstdlib>
using namespace std;
DEFINE_int32(port, 8857, "TCP Port of this server");
DEFINE_string(modelpath, "/home/bae/sourcecode/paddlespeech_cli", "the path of model");
DEFINE_int32(max_concurrency, 2, "Limit of request processing in parallel");
namespace example {
struct subRes{
int s; // start time
int e; // end time
string t; // text
};
class AudioServiceImpl : public EchoService {
public:
AudioServiceImpl() {};
virtual ~AudioServiceImpl() {};
string to_string(rapidjson::Document& out_doc) {
rapidjson::StringBuffer out_buffer;
rapidjson::Writer<rapidjson::StringBuffer> out_writer(out_buffer);
out_doc.Accept(out_writer);
std::string out_params = out_buffer.GetString();
return out_params;
}
string convertvector(vector<subRes> result){
rapidjson::Document document;
document.SetArray();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
for (const auto sub : result) {
rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("s", sub.s, allocator);
obj.AddMember("e", sub.e, allocator);
obj.AddMember("t", sub.t.c_str(), allocator);
document.PushBack(obj, allocator);
}
rapidjson::StringBuffer strbuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
document.Accept(writer);
return strbuf.GetString();
}
string convertvectorV2(vector<subRes> result){
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value ObjectArray(rapidjson::kArrayType);
for (const auto sub : result) {
rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("s", sub.s, allocator);
obj.AddMember("e", sub.e, allocator);
obj.AddMember("t", sub.t.c_str(), allocator);
ObjectArray.PushBack(obj, allocator);
}
document.AddMember("AllTrans", ObjectArray, allocator);
rapidjson::StringBuffer strbuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
document.Accept(writer);
return strbuf.GetString();
}
virtual void audiorecognition(google::protobuf::RpcController* cntl_base,
const AudioRequest* request,
AudioResponse* response,
google::protobuf::Closure* done) {
// This object helps you to call done->Run() in RAII style. If you need
// to process the request asynchronously, pass done_guard.release().
baidu::rpc::ClosureGuard done_guard(done);
string decode_audio_buffer;
base::Base64Decode(request->audio(), &decode_audio_buffer);
vector<uint8_t> vec;
vec.assign(decode_audio_buffer.begin(), decode_audio_buffer.end());
AudioFile<float> a;
bool res = a.loadFromMemory(vec);
Audio audi(0);
audi.loadwavfrommem(a);
audi.split();
vector<float> buff;
int len = 0;
int flag = 1;
vector<subRes> results;
int tmp_len = 0;
while (audi.fetch(buff, len, flag) > 0) {
int do_idx = rand() % 2; //random number [0,1)
Accept(buff, do_idx);
std::string subtxt = GetResult(do_idx);
Reset(do_idx);
buff.clear();
int start_time = (int)(tmp_len/16000.0 * 1000);
int end_time = (int)((tmp_len + len)/16000.0 * 1000);
struct subRes subres = {
start_time,
end_time,
subtxt.c_str(),
};
tmp_len += len;
results.push_back(subres);
com_writelog(COMLOG_NOTICE, "using process: %d, start: %d, end: %d, result: %s", do_idx, start_time, end_time, subtxt.c_str());
}
// vector<float> inputAudio;
// for (int i = 0; i < a.getNumSamplesPerChannel(); i++)
// {
// float tempval = 0.0;
// for (int channel = 0; channel < a.getNumChannels(); channel++)
// {
// tempval += a.samples[channel][i] * 32768;
// }
// inputAudio.emplace_back(tempval);
// }
// int do_idx = rand() % 2; //random number [0,1)
// Accept(inputAudio, do_idx);
// std::string result = GetResult(do_idx);
// Reset(do_idx);
// com_writelog(COMLOG_NOTICE, "using process: %d, result: %s", do_idx, result.c_str());
// std::cout << "Result: " << result << std::endl;
response->set_err_no(0);
response->set_err_msg("");
string jsonresult = convertvector(results);
response->set_result(jsonresult);
response->set_cost_time(0);
results.clear();
}
};
} // namespace example
int main(int argc, char* argv[]) {
// Parse gflags. We recommend you to use gflags as well.
google::ParseCommandLineFlags(&argc, &argv, true);
bool flag_auth = false;
// Setup for `GianoAuthenticator'.
std::unique_ptr<baidu::rpc::policy::GianoAuthenticator> auth;
if (flag_auth) {
if (baas::BAAS_Init() != 0) {
LOG(ERROR) << "Fail to init BAAS";
return -1;
}
baas::CredentialVerifier
ver = baas::ServerUtility::CreateCredentialVerifier();
auth.reset(new baidu::rpc::policy::GianoAuthenticator(NULL, &ver));
}
int ret = com_loadlog("./", "asr.conf");
if (ret != 0)
{
fprintf(stderr, "load err\n");
return -1;
}
// 打印日志,线程安全
com_writelog(COMLOG_NOTICE, "server start1");
// Generally you only need one Server.
baidu::rpc::Server server;
// Instance of your service.
example::AudioServiceImpl audio_service_impl;
// Add the service into server. Notice the second parameter, because the
// service is put on stack, we don't want server to delete it, otherwise
// use baidu::rpc::SERVER_OWNS_SERVICE.
if (server.AddService(&audio_service_impl,
baidu::rpc::SERVER_DOESNT_OWN_SERVICE,
"/v1/audiorecognition => audiorecognition") != 0) {
LOG(ERROR) << "Fail to add service";
return -1;
}
InitRecognizer("model.onnx", "words.txt");
for (int i =0 ;i<= 1; i++){
int idx = AddRecognizerInstance();
}
srand((unsigned)time(NULL));
// Start the server.
baidu::rpc::ServerOptions options;
options.idle_timeout_sec = -1;
options.auth = auth.get();
options.max_concurrency = FLAGS_max_concurrency;
if (server.Start(FLAGS_port, &options) != 0) {
LOG(ERROR) << "Fail to start EchoServer";
return -1;
}
// Wait until Ctrl-C is pressed, then Stop() and Join() the server.
server.RunUntilAskedToQuit();
return 0;
}
\ No newline at end of file
if(WIN32)
add_definitions(-DWEBRTC_WIN)
else()
add_definitions(-DWEBRTC_POSIX)
endif()
include_directories("..")
file(GLOB_RECURSE files "*.c" "rtc_base/checks.cc")
message("${files}")
add_library(webrtcvad ${files})
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
/* Tables for data buffer indexes that are bit reversed and thus need to be
* swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap
* operations, while index_7[{1, 3, 5, ...}] are for the right side of the
* operation. Same for index_8.
*/
/* Indexes for the case of stages == 7. */
static const int16_t index_7[112] = {
1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104,
12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52,
23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98,
37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70,
51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69,
81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125,
103, 115, 111, 123
};
/* Indexes for the case of stages == 8. */
static const int16_t index_8[240] = {
1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80,
11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20,
40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184,
30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41,
148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76,
51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62,
124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82,
75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87,
234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101,
166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142,
115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131,
193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201,
149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171,
213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227,
203, 211, 207, 243, 215, 235, 223, 251, 239, 247
};
void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) {
/* For any specific value of stages, we know exactly the indexes that are
* bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of
* stages are 7 and 8, so we use tables to save unnecessary iterations and
* calculations for these two cases.
*/
if (stages == 7 || stages == 8) {
int m = 0;
int length = 112;
const int16_t* index = index_7;
if (stages == 8) {
length = 240;
index = index_8;
}
/* Decimation in time. Swap the elements with bit-reversed indexes. */
for (m = 0; m < length; m += 2) {
/* We declare a int32_t* type pointer, to load both the 16-bit real
* and imaginary elements from complex_data in one instruction, reducing
* complexity.
*/
int32_t* complex_data_ptr = (int32_t*)complex_data;
int32_t temp = 0;
temp = complex_data_ptr[index[m]]; /* Real and imaginary */
complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]];
complex_data_ptr[index[m + 1]] = temp;
}
}
else {
int m = 0, mr = 0, l = 0;
int n = 1 << stages;
int nn = n - 1;
/* Decimation in time - re-order data */
for (m = 1; m <= nn; ++m) {
int32_t* complex_data_ptr = (int32_t*)complex_data;
int32_t temp = 0;
/* Find out indexes that are bit-reversed. */
l = n;
do {
l >>= 1;
} while (l > nn - mr);
mr = (mr & (l - 1)) + l;
if (mr <= m) {
continue;
}
/* Swap the elements with bit-reversed indexes.
* This is similar to the loop in the stages == 7 or 8 cases.
*/
temp = complex_data_ptr[m]; /* Real and imaginary */
complex_data_ptr[m] = complex_data_ptr[mr];
complex_data_ptr[mr] = temp;
}
}
}
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the function WebRtcSpl_ComplexFFT().
* The description header can be found in signal_processing_library.h
*
*/
#include "webrtc/common_audio/signal_processing/complex_fft_tables.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/rtc_base/system/arch.h"
#define CFFTSFT 14
#define CFFTRND 1
#define CFFTRND2 16384
#define CIFFTSFT 14
#define CIFFTRND 1
int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
{
int i, j, l, k, istep, n, m;
int16_t wr, wi;
int32_t tr32, ti32, qr32, qi32;
/* The 1024-value is a constant given from the size of kSinTable1024[],
* and should not be changed depending on the input parameter 'stages'
*/
n = 1 << stages;
if (n > 1024)
return -1;
l = 1;
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
depending on the input parameter 'stages' */
if (mode == 0)
{
// mode==0: Low-complexity and Low-accuracy mode
while (l < n)
{
istep = l << 1;
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = kSinTable1024[j + 256];
wi = -kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
qr32 = (int32_t)frfi[2 * i];
qi32 = (int32_t)frfi[2 * i + 1];
frfi[2 * j] = (int16_t)((qr32 - tr32) >> 1);
frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> 1);
frfi[2 * i] = (int16_t)((qr32 + tr32) >> 1);
frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> 1);
}
}
--k;
l = istep;
}
} else
{
// mode==1: High-complexity and High-accuracy mode
while (l < n)
{
istep = l << 1;
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = kSinTable1024[j + 256];
wi = -kSinTable1024[j];
#ifdef WEBRTC_ARCH_ARM_V7
int32_t wri = 0;
__asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
"r"((int32_t)wr), "r"((int32_t)wi));
#endif
for (i = m; i < n; i += istep)
{
j = i + l;
#ifdef WEBRTC_ARCH_ARM_V7
register int32_t frfi_r;
__asm __volatile(
"pkhbt %[frfi_r], %[frfi_even], %[frfi_odd],"
" lsl #16\n\t"
"smlsd %[tr32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
"smladx %[ti32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
:[frfi_r]"=&r"(frfi_r),
[tr32]"=&r"(tr32),
[ti32]"=r"(ti32)
:[frfi_even]"r"((int32_t)frfi[2*j]),
[frfi_odd]"r"((int32_t)frfi[2*j +1]),
[wri]"r"(wri),
[cfftrnd]"r"(CFFTRND));
#else
tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CFFTRND;
ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CFFTRND;
#endif
tr32 >>= 15 - CFFTSFT;
ti32 >>= 15 - CFFTSFT;
qr32 = ((int32_t)frfi[2 * i]) * (1 << CFFTSFT);
qi32 = ((int32_t)frfi[2 * i + 1]) * (1 << CFFTSFT);
frfi[2 * j] = (int16_t)(
(qr32 - tr32 + CFFTRND2) >> (1 + CFFTSFT));
frfi[2 * j + 1] = (int16_t)(
(qi32 - ti32 + CFFTRND2) >> (1 + CFFTSFT));
frfi[2 * i] = (int16_t)(
(qr32 + tr32 + CFFTRND2) >> (1 + CFFTSFT));
frfi[2 * i + 1] = (int16_t)(
(qi32 + ti32 + CFFTRND2) >> (1 + CFFTSFT));
}
}
--k;
l = istep;
}
}
return 0;
}
int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
{
size_t i, j, l, istep, n, m;
int k, scale, shift;
int16_t wr, wi;
int32_t tr32, ti32, qr32, qi32;
int32_t tmp32, round2;
/* The 1024-value is a constant given from the size of kSinTable1024[],
* and should not be changed depending on the input parameter 'stages'
*/
n = ((size_t)1) << stages;
if (n > 1024)
return -1;
scale = 0;
l = 1;
k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
depending on the input parameter 'stages' */
while (l < n)
{
// variable scaling, depending upon data
shift = 0;
round2 = 8192;
tmp32 = WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
if (tmp32 > 13573)
{
shift++;
scale++;
round2 <<= 1;
}
if (tmp32 > 27146)
{
shift++;
scale++;
round2 <<= 1;
}
istep = l << 1;
if (mode == 0)
{
// mode==0: Low-complexity and Low-accuracy mode
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = kSinTable1024[j + 256];
wi = kSinTable1024[j];
for (i = m; i < n; i += istep)
{
j = i + l;
tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
qr32 = (int32_t)frfi[2 * i];
qi32 = (int32_t)frfi[2 * i + 1];
frfi[2 * j] = (int16_t)((qr32 - tr32) >> shift);
frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> shift);
frfi[2 * i] = (int16_t)((qr32 + tr32) >> shift);
frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> shift);
}
}
} else
{
// mode==1: High-complexity and High-accuracy mode
for (m = 0; m < l; ++m)
{
j = m << k;
/* The 256-value is a constant given as 1/4 of the size of
* kSinTable1024[], and should not be changed depending on the input
* parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
*/
wr = kSinTable1024[j + 256];
wi = kSinTable1024[j];
#ifdef WEBRTC_ARCH_ARM_V7
int32_t wri = 0;
__asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
"r"((int32_t)wr), "r"((int32_t)wi));
#endif
for (i = m; i < n; i += istep)
{
j = i + l;
#ifdef WEBRTC_ARCH_ARM_V7
register int32_t frfi_r;
__asm __volatile(
"pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t"
"smlsd %[tr32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
"smladx %[ti32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
:[frfi_r]"=&r"(frfi_r),
[tr32]"=&r"(tr32),
[ti32]"=r"(ti32)
:[frfi_even]"r"((int32_t)frfi[2*j]),
[frfi_odd]"r"((int32_t)frfi[2*j +1]),
[wri]"r"(wri),
[cifftrnd]"r"(CIFFTRND)
);
#else
tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CIFFTRND;
ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CIFFTRND;
#endif
tr32 >>= 15 - CIFFTSFT;
ti32 >>= 15 - CIFFTSFT;
qr32 = ((int32_t)frfi[2 * i]) * (1 << CIFFTSFT);
qi32 = ((int32_t)frfi[2 * i + 1]) * (1 << CIFFTSFT);
frfi[2 * j] = (int16_t)(
(qr32 - tr32 + round2) >> (shift + CIFFTSFT));
frfi[2 * j + 1] = (int16_t)(
(qi32 - ti32 + round2) >> (shift + CIFFTSFT));
frfi[2 * i] = (int16_t)(
(qr32 + tr32 + round2) >> (shift + CIFFTSFT));
frfi[2 * i + 1] = (int16_t)(
(qi32 + ti32 + round2) >> (shift + CIFFTSFT));
}
}
}
--k;
l = istep;
}
return scale;
}
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
#include <stdint.h>
static const int16_t kSinTable1024[] = {
0, 201, 402, 603, 804, 1005, 1206, 1406, 1607,
1808, 2009, 2209, 2410, 2610, 2811, 3011, 3211, 3411,
3611, 3811, 4011, 4210, 4409, 4608, 4807, 5006, 5205,
5403, 5601, 5799, 5997, 6195, 6392, 6589, 6786, 6982,
7179, 7375, 7571, 7766, 7961, 8156, 8351, 8545, 8739,
8932, 9126, 9319, 9511, 9703, 9895, 10087, 10278, 10469,
10659, 10849, 11038, 11227, 11416, 11604, 11792, 11980, 12166,
12353, 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, 15446,
15623, 15799, 15975, 16150, 16325, 16499, 16672, 16845, 17017,
17189, 17360, 17530, 17699, 17868, 18036, 18204, 18371, 18537,
18702, 18867, 19031, 19194, 19357, 19519, 19680, 19840, 20000,
20159, 20317, 20474, 20631, 20787, 20942, 21096, 21249, 21402,
21554, 21705, 21855, 22004, 22153, 22301, 22448, 22594, 22739,
22883, 23027, 23169, 23311, 23452, 23592, 23731, 23869, 24006,
24143, 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, 26318,
26437, 26556, 26673, 26789, 26905, 27019, 27132, 27244, 27355,
27466, 27575, 27683, 27790, 27896, 28001, 28105, 28208, 28309,
28410, 28510, 28608, 28706, 28802, 28897, 28992, 29085, 29177,
29268, 29358, 29446, 29534, 29621, 29706, 29790, 29873, 29955,
30036, 30116, 30195, 30272, 30349, 30424, 30498, 30571, 30643,
30713, 30783, 30851, 30918, 30984, 31049, 31113, 31175, 31236,
31297, 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, 32137,
32176, 32213, 32249, 32284, 32318, 32350, 32382, 32412, 32441,
32468, 32495, 32520, 32544, 32567, 32588, 32609, 32628, 32646,
32662, 32678, 32692, 32705, 32717, 32727, 32736, 32744, 32751,
32757, 32761, 32764, 32766, 32767, 32766, 32764, 32761, 32757,
32751, 32744, 32736, 32727, 32717, 32705, 32692, 32678, 32662,
32646, 32628, 32609, 32588, 32567, 32544, 32520, 32495, 32468,
32441, 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, 31785,
31735, 31684, 31633, 31580, 31525, 31470, 31413, 31356, 31297,
31236, 31175, 31113, 31049, 30984, 30918, 30851, 30783, 30713,
30643, 30571, 30498, 30424, 30349, 30272, 30195, 30116, 30036,
29955, 29873, 29790, 29706, 29621, 29534, 29446, 29358, 29268,
29177, 29085, 28992, 28897, 28802, 28706, 28608, 28510, 28410,
28309, 28208, 28105, 28001, 27896, 27790, 27683, 27575, 27466,
27355, 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, 25329,
25201, 25072, 24942, 24811, 24679, 24546, 24413, 24278, 24143,
24006, 23869, 23731, 23592, 23452, 23311, 23169, 23027, 22883,
22739, 22594, 22448, 22301, 22153, 22004, 21855, 21705, 21554,
21402, 21249, 21096, 20942, 20787, 20631, 20474, 20317, 20159,
20000, 19840, 19680, 19519, 19357, 19194, 19031, 18867, 18702,
18537, 18371, 18204, 18036, 17868, 17699, 17530, 17360, 17189,
17017, 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, 14009,
13827, 13645, 13462, 13278, 13094, 12909, 12724, 12539, 12353,
12166, 11980, 11792, 11604, 11416, 11227, 11038, 10849, 10659,
10469, 10278, 10087, 9895, 9703, 9511, 9319, 9126, 8932,
8739, 8545, 8351, 8156, 7961, 7766, 7571, 7375, 7179,
6982, 6786, 6589, 6392, 6195, 5997, 5799, 5601, 5403,
5205, 5006, 4807, 4608, 4409, 4210, 4011, 3811, 3611,
3411, 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
1607, 1406, 1206, 1005, 804, 603, 402, 201, 0,
-201, -402, -603, -804, -1005, -1206, -1406, -1607, -1808,
-2009, -2209, -2410, -2610, -2811, -3011, -3211, -3411, -3611,
-3811, -4011, -4210, -4409, -4608, -4807, -5006, -5205, -5403,
-5601, -5799, -5997, -6195, -6392, -6589, -6786, -6982, -7179,
-7375, -7571, -7766, -7961, -8156, -8351, -8545, -8739, -8932,
-9126, -9319, -9511, -9703, -9895, -10087, -10278, -10469, -10659,
-10849, -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, -14009,
-14191, -14372, -14552, -14732, -14911, -15090, -15268, -15446, -15623,
-15799, -15975, -16150, -16325, -16499, -16672, -16845, -17017, -17189,
-17360, -17530, -17699, -17868, -18036, -18204, -18371, -18537, -18702,
-18867, -19031, -19194, -19357, -19519, -19680, -19840, -20000, -20159,
-20317, -20474, -20631, -20787, -20942, -21096, -21249, -21402, -21554,
-21705, -21855, -22004, -22153, -22301, -22448, -22594, -22739, -22883,
-23027, -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, -25329,
-25456, -25582, -25707, -25831, -25954, -26077, -26198, -26318, -26437,
-26556, -26673, -26789, -26905, -27019, -27132, -27244, -27355, -27466,
-27575, -27683, -27790, -27896, -28001, -28105, -28208, -28309, -28410,
-28510, -28608, -28706, -28802, -28897, -28992, -29085, -29177, -29268,
-29358, -29446, -29534, -29621, -29706, -29790, -29873, -29955, -30036,
-30116, -30195, -30272, -30349, -30424, -30498, -30571, -30643, -30713,
-30783, -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, -31785,
-31833, -31880, -31926, -31970, -32014, -32056, -32097, -32137, -32176,
-32213, -32249, -32284, -32318, -32350, -32382, -32412, -32441, -32468,
-32495, -32520, -32544, -32567, -32588, -32609, -32628, -32646, -32662,
-32678, -32692, -32705, -32717, -32727, -32736, -32744, -32751, -32757,
-32761, -32764, -32766, -32767, -32766, -32764, -32761, -32757, -32751,
-32744, -32736, -32727, -32717, -32705, -32692, -32678, -32662, -32646,
-32628, -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
-32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, -32137,
-32097, -32056, -32014, -31970, -31926, -31880, -31833, -31785, -31735,
-31684, -31633, -31580, -31525, -31470, -31413, -31356, -31297, -31236,
-31175, -31113, -31049, -30984, -30918, -30851, -30783, -30713, -30643,
-30571, -30498, -30424, -30349, -30272, -30195, -30116, -30036, -29955,
-29873, -29790, -29706, -29621, -29534, -29446, -29358, -29268, -29177,
-29085, -28992, -28897, -28802, -28706, -28608, -28510, -28410, -28309,
-28208, -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
-27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, -26318,
-26198, -26077, -25954, -25831, -25707, -25582, -25456, -25329, -25201,
-25072, -24942, -24811, -24679, -24546, -24413, -24278, -24143, -24006,
-23869, -23731, -23592, -23452, -23311, -23169, -23027, -22883, -22739,
-22594, -22448, -22301, -22153, -22004, -21855, -21705, -21554, -21402,
-21249, -21096, -20942, -20787, -20631, -20474, -20317, -20159, -20000,
-19840, -19680, -19519, -19357, -19194, -19031, -18867, -18702, -18537,
-18371, -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
-16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, -15446,
-15268, -15090, -14911, -14732, -14552, -14372, -14191, -14009, -13827,
-13645, -13462, -13278, -13094, -12909, -12724, -12539, -12353, -12166,
-11980, -11792, -11604, -11416, -11227, -11038, -10849, -10659, -10469,
-10278, -10087, -9895, -9703, -9511, -9319, -9126, -8932, -8739,
-8545, -8351, -8156, -7961, -7766, -7571, -7375, -7179, -6982,
-6786, -6589, -6392, -6195, -5997, -5799, -5601, -5403, -5205,
-5006, -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
-3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, -1607,
-1406, -1206, -1005, -804, -603, -402, -201};
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
/* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */
void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
const int16_t* seq1,
const int16_t* seq2,
size_t dim_seq,
size_t dim_cross_correlation,
int right_shifts,
int step_seq2) {
size_t i = 0, j = 0;
for (i = 0; i < dim_cross_correlation; i++) {
int32_t corr = 0;
for (j = 0; j < dim_seq; j++)
corr += (seq1[j] * seq2[j]) >> right_shifts;
seq2 += step_seq2;
*cross_correlation++ = corr;
}
}
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains implementations of the divisions
* WebRtcSpl_DivU32U16()
* WebRtcSpl_DivW32W16()
* WebRtcSpl_DivW32W16ResW16()
* WebRtcSpl_DivResultInQ31()
* WebRtcSpl_DivW32HiLow()
*
* The description header can be found in signal_processing_library.h
*
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/rtc_base/sanitizer.h"
uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
{
// Guard against division with 0
if (den != 0)
{
return (uint32_t)(num / den);
} else
{
return (uint32_t)0xFFFFFFFF;
}
}
int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
{
// Guard against division with 0
if (den != 0)
{
return (int32_t)(num / den);
} else
{
return (int32_t)0x7FFFFFFF;
}
}
int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
{
// Guard against division with 0
if (den != 0)
{
return (int16_t)(num / den);
} else
{
return (int16_t)0x7FFF;
}
}
int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
{
int32_t L_num = num;
int32_t L_den = den;
int32_t div = 0;
int k = 31;
int change_sign = 0;
if (num == 0)
return 0;
if (num < 0)
{
change_sign++;
L_num = -num;
}
if (den < 0)
{
change_sign++;
L_den = -den;
}
while (k--)
{
div <<= 1;
L_num <<= 1;
if (L_num >= L_den)
{
L_num -= L_den;
div++;
}
}
if (change_sign == 1)
{
div = -div;
}
return div;
}
int32_t RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
{
int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
int32_t tmpW32;
approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
// result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
// tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1);
// tmpW32 = den * approx
tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
// UBSan: 2147483647 - -2 cannot be represented in type 'int'
// Store tmpW32 in hi and low format
tmp_hi = (int16_t)(tmpW32 >> 16);
tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
// tmpW32 = 1/den in Q29
tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1;
// 1/den in hi and low format
tmp_hi = (int16_t)(tmpW32 >> 16);
tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
// Store num in hi and low format
num_hi = (int16_t)(num >> 16);
num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
// num * (1/den) by 32 bit multiplication (result in Q28)
tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) +
(num_low * tmp_hi >> 15);
// Put result in Q31 (convert from Q28)
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
return tmpW32;
}
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/common_audio/signal_processing/dot_product_with_scale.h"
#include "webrtc/rtc_base/numerics/safe_conversions.h"
int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
const int16_t* vector2,
size_t length,
int scaling) {
int64_t sum = 0;
size_t i = 0;
/* Unroll the loop to improve performance. */
for (i = 0; i + 3 < length; i += 4) {
sum += (vector1[i + 0] * vector2[i + 0]) >> scaling;
sum += (vector1[i + 1] * vector2[i + 1]) >> scaling;
sum += (vector1[i + 2] * vector2[i + 2]) >> scaling;
sum += (vector1[i + 3] * vector2[i + 3]) >> scaling;
}
for (; i < length; i++) {
sum += (vector1[i] * vector2[i]) >> scaling;
}
return rtc::saturated_cast<int32_t>(sum);
}
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
// Calculates the dot product between two (int16_t) vectors.
//
// Input:
// - vector1 : Vector 1
// - vector2 : Vector 2
// - vector_length : Number of samples used in the dot product
// - scaling : The number of right bit shifts to apply on each term
// during calculation to avoid overflow, i.e., the
// output will be in Q(-|scaling|)
//
// Return value : The dot product in Q(-scaling)
int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
const int16_t* vector2,
size_t length,
int scaling);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/sanitizer.h"
// TODO(Bjornv): Change the function parameter order to WebRTC code style.
// C version of WebRtcSpl_DownsampleFast() for generic platforms.
int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
size_t data_in_length,
int16_t* data_out,
size_t data_out_length,
const int16_t* __restrict coefficients,
size_t coefficients_length,
int factor,
size_t delay) {
int16_t* const original_data_out = data_out;
size_t i = 0;
size_t j = 0;
int32_t out_s32 = 0;
size_t endpos = delay + factor * (data_out_length - 1) + 1;
// Return error if any of the running conditions doesn't meet.
if (data_out_length == 0 || coefficients_length == 0
|| data_in_length < endpos) {
return -1;
}
rtc_MsanCheckInitialized(coefficients, sizeof(coefficients[0]),
coefficients_length);
for (i = delay; i < endpos; i += factor) {
out_s32 = 2048; // Round value, 0.5 in Q12.
for (j = 0; j < coefficients_length; j++) {
// Negative overflow is permitted here, because this is
// auto-regressive filters, and the state for each batch run is
// stored in the "negative" positions of the output vector.
rtc_MsanCheckInitialized(&data_in[(ptrdiff_t) i - (ptrdiff_t) j],
sizeof(data_in[0]), 1);
// out_s32 is in Q12 domain.
out_s32 += coefficients[j] * data_in[(ptrdiff_t) i - (ptrdiff_t) j];
}
out_s32 >>= 12; // Q0.
// Saturate and store the output.
*data_out++ = WebRtcSpl_SatW32ToW16(out_s32);
}
RTC_DCHECK_EQ(original_data_out + data_out_length, data_out);
rtc_MsanCheckInitialized(original_data_out, sizeof(original_data_out[0]),
data_out_length);
return 0;
}
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the function WebRtcSpl_Energy().
* The description header can be found in signal_processing_library.h
*
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
int32_t WebRtcSpl_Energy(int16_t* vector,
size_t vector_length,
int* scale_factor)
{
int32_t en = 0;
size_t i;
int scaling =
WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length);
size_t looptimes = vector_length;
int16_t *vectorptr = vector;
for (i = 0; i < looptimes; i++)
{
en += (*vectorptr * *vectorptr) >> scaling;
vectorptr++;
}
*scale_factor = scaling;
return en;
}
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file contains the function WebRtcSpl_GetScalingSquare().
* The description header can be found in signal_processing_library.h
*
*/
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector,
size_t in_vector_length,
size_t times)
{
int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t)times);
size_t i;
int16_t smax = -1;
int16_t sabs;
int16_t *sptr = in_vector;
int16_t t;
size_t looptimes = in_vector_length;
for (i = looptimes; i > 0; i--)
{
sabs = (*sptr > 0 ? *sptr++ : -*sptr++);
smax = (sabs > smax ? sabs : smax);
}
t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));
if (smax == 0)
{
return 0; // Since norm(0) returns 0
} else
{
return (t > nbits) ? 0 : nbits - t;
}
}
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
#include <stdint.h>
// For ComplexFFT(), the maximum fft order is 10;
// WebRTC APM uses orders of only 7 and 8.
enum { kMaxFFTOrder = 10 };
struct RealFFT;
#ifdef __cplusplus
extern "C" {
#endif
struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
// Compute an FFT for a real-valued signal of length of 2^order,
// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
// specification structure, which must be initialized prior to calling the FFT
// function with WebRtcSpl_CreateRealFFT().
// The relationship between the input and output sequences can
// be expressed in terms of the DFT, i.e.:
// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
// n=0,1,2,...N-1
// N=2^order.
// The conjugate-symmetric output sequence is represented using a CCS vector,
// which is of length N+2, and is organized as follows:
// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
// where R[n] and I[n], respectively, denote the real and imaginary components
// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
// the foldover frequency.
//
// Input Arguments:
// self - pointer to preallocated and initialized FFT specification structure.
// real_data_in - the input signal. For an ARM Neon platform, it must be
// aligned on a 32-byte boundary.
//
// Output Arguments:
// complex_data_out - the output complex signal with (2^order + 2) 16-bit
// elements. For an ARM Neon platform, it must be different
// from real_data_in, and aligned on a 32-byte boundary.
//
// Return Value:
// 0 - FFT calculation is successful.
// -1 - Error with bad arguments (null pointers).
int WebRtcSpl_RealForwardFFT(struct RealFFT* self,
const int16_t* real_data_in,
int16_t* complex_data_out);
// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
// the specification structure, which must be initialized prior to calling the
// FFT function with WebRtcSpl_CreateRealFFT().
// For a transform of length M, the input sequence is represented using a packed
// CCS vector of length M+2, which is explained in the comments for
// WebRtcSpl_RealForwardFFTC above.
//
// Input Arguments:
// self - pointer to preallocated and initialized FFT specification structure.
// complex_data_in - the input complex signal with (2^order + 2) 16-bit
// elements. For an ARM Neon platform, it must be aligned on
// a 32-byte boundary.
//
// Output Arguments:
// real_data_out - the output real signal. For an ARM Neon platform, it must
// be different to complex_data_in, and aligned on a 32-byte
// boundary.
//
// Return Value:
// 0 or a positive number - a value that the elements in the |real_data_out|
// should be shifted left with in order to get
// correct physical values.
// -1 - Error with bad arguments (null pointers).
int WebRtcSpl_RealInverseFFT(struct RealFFT* self,
const int16_t* complex_data_in,
int16_t* real_data_out);
#ifdef __cplusplus
}
#endif
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册