当前位置: 首页 > news >正文

Java jni调用nnom rnn-denoise 降噪

介绍:https://github.com/majianjia/nnom/blob/master/examples/rnn-denoise/README_CN.md

默认提供了一个wav的例子


#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>#include "nnom.h"
#include "denoise_weights.h"#include "mfcc.h"
#include "wav.h"// the bandpass filter coefficiences
#include "equalizer_coeff.h" #define NUM_FEATURES NUM_FILTER#define _MAX(x, y) (((x) > (y)) ? (x) : (y))
#define _MIN(x, y) (((x) < (y)) ? (x) : (y))#define NUM_CHANNELS 	1
#define SAMPLE_RATE 	16000
#define AUDIO_FRAME_LEN 512// audio buffer for input
float audio_buffer[AUDIO_FRAME_LEN] = {0};
int16_t audio_buffer_16bit[AUDIO_FRAME_LEN] = {0};// buffer for output
int16_t audio_buffer_filtered[AUDIO_FRAME_LEN/2] = { 0 };// mfcc features and their derivatives
float mfcc_feature[NUM_FEATURES] = { 0 };
float mfcc_feature_prev[NUM_FEATURES] = { 0 };
float mfcc_feature_diff[NUM_FEATURES] = { 0 };
float mfcc_feature_diff_prev[NUM_FEATURES] = { 0 };
float mfcc_feature_diff1[NUM_FEATURES] = { 0 };
// features for NN
float nn_features[64] = {0};
int8_t nn_features_q7[64] = {0};// NN results, which is the gains for each frequency band
float band_gains[NUM_FILTER] = {0};
float band_gains_prev[NUM_FILTER] = {0};// 0db gains coefficient
float coeff_b[NUM_FILTER][NUM_COEFF_PAIR] = FILTER_COEFF_B;
float coeff_a[NUM_FILTER][NUM_COEFF_PAIR] = FILTER_COEFF_A;
// dynamic gains coefficient
float b_[NUM_FILTER][NUM_COEFF_PAIR] = {0};// update the history
void y_h_update(float *y_h, uint32_t len)
{for (uint32_t i = len-1; i >0 ;i--)y_h[i] = y_h[i-1];
}//  equalizer by multiple n order iir band pass filter. 
// y[i] = b[0] * x[i] + b[1] * x[i - 1] + b[2] * x[i - 2] - a[1] * y[i - 1] - a[2] * y[i - 2]...
void equalizer(float* x, float* y, uint32_t signal_len, float *b, float *a, uint32_t num_band, uint32_t num_order)
{// the y history for each bandstatic float y_h[NUM_FILTER][NUM_COEFF_PAIR] = { 0 };static float x_h[NUM_COEFF_PAIR * 2] = { 0 };uint32_t num_coeff = num_order * 2 + 1;// i <= num_coeff (where historical x is involved in the first few points)// combine state and new data to get a continual x input. memcpy(x_h + num_coeff, x, num_coeff * sizeof(float));for (uint32_t i = 0; i < num_coeff; i++){y[i] = 0;for (uint32_t n = 0; n < num_band; n++){y_h_update(y_h[n], num_coeff);y_h[n][0] = b[n * num_coeff] * x_h[i+ num_coeff];for (uint32_t c = 1; c < num_coeff; c++)y_h[n][0] += b[n * num_coeff + c] * x_h[num_coeff + i - c] - a[n * num_coeff + c] * y_h[n][c];y[i] += y_h[n][0];}}// store the x for the state of next roundmemcpy(x_h, &x[signal_len - num_coeff], num_coeff * sizeof(float));// i > num_coeff; the rest data not involed the x historyfor (uint32_t i = num_coeff; i < signal_len; i++){y[i] = 0;for (uint32_t n = 0; n < num_band; n++){y_h_update(y_h[n], num_coeff);y_h[n][0] = b[n * num_coeff] * x[i];for (uint32_t c = 1; c < num_coeff; c++)y_h[n][0] += b[n * num_coeff + c] * x[i - c] - a[n * num_coeff + c] * y_h[n][c];y[i] += y_h[n][0];}	}
}// set dynamic gains. Multiple gains x b_coeff
void set_gains(float *b_in, float *b_out,  float* gains, uint32_t num_band, uint32_t num_order)
{uint32_t num_coeff = num_order * 2 + 1;for (uint32_t i = 0; i < num_band; i++)for (uint32_t c = 0; c < num_coeff; c++)b_out[num_coeff *i + c] = b_in[num_coeff * i + c] * gains[i]; // only need to set b. 
}void quantize_data(float*din, int8_t *dout, uint32_t size, uint32_t int_bit)
{float limit = (1 << int_bit); for(uint32_t i=0; i<size; i++)dout[i] = (int8_t)(_MAX(_MIN(din[i], limit), -limit) / limit * 127);
}void log_values(float* value, uint32_t size, FILE* f)
{char line[16];for (uint32_t i = 0; i < size; i++) {snprintf(line, 16, "%f,", value[i]);fwrite(line, strlen(line), 1, f);}fwrite("\n", 2, 1, f);
}int main(int argc, char* argv[])
{wav_header_t wav_header; size_t size;char* input_file = "sample.wav";char* output_file = "filtered_sample.wav";FILE* src_file;FILE* des_file;char* log_file = "log.csv";FILE* flog = fopen(log_file, "wb");// if user has specify input and output files. if (argc > 1)input_file = argv[1];if (argc > 2)output_file = argv[2];src_file = fopen(input_file, "rb");des_file = fopen(output_file, "wb");if (src_file == NULL) {printf("Cannot open wav files, default input:'%s'\n", input_file);printf("Or use command to specify input file: xxx.exe [input.wav] [output.wav]\n");return -1;}if (des_file == NULL){fclose(src_file); return -1; }// read wav file header, copy it to the output file.  fread(&wav_header, sizeof(wav_header), 1, src_file);fwrite(&wav_header, sizeof(wav_header), 1, des_file);// lets jump to the "data" chunk of the WAV file.if (strncmp(wav_header.datachunk_id, "data", 4)){wav_chunk_t chunk = { .size= wav_header.datachunk_size};// find the 'data' chunkdo {char* buf = malloc(chunk.size);fread(buf, chunk.size, 1, src_file);fwrite(buf, chunk.size, 1, des_file);free(buf);fread(&chunk, sizeof(wav_chunk_t), 1, src_file);fwrite(&chunk, sizeof(wav_chunk_t), 1, des_file);} while (strncmp(chunk.id, "data", 4));}// NNoM modelnnom_model_t *model = model = nnom_model_create();// 26 features, 0 offset, 26 bands, 512fft, 0 preempha, attached_energy_to_band0mfcc_t * mfcc = mfcc_create(NUM_FEATURES, 0, NUM_FEATURES, 512, 0, true);printf("\nProcessing file: %s\n", input_file);while(1) {// move buffer (50%) overlapping, move later 50% to the first 50, then fill memcpy(audio_buffer_16bit, &audio_buffer_16bit[AUDIO_FRAME_LEN/2], AUDIO_FRAME_LEN/2*sizeof(int16_t));// now read the new datasize = fread(&audio_buffer_16bit[AUDIO_FRAME_LEN / 2], AUDIO_FRAME_LEN / 2 * sizeof(int16_t), 1, src_file);if(size == 0)break;// get mfccmfcc_compute(mfcc, audio_buffer_16bit, mfcc_feature);//log_values(mfcc_feature, NUM_FEATURES, flog);// get the first and second derivative of mfccfor(uint32_t i=0; i< NUM_FEATURES; i++){mfcc_feature_diff[i] = mfcc_feature[i] - mfcc_feature_prev[i];mfcc_feature_diff1[i] = mfcc_feature_diff[i] - mfcc_feature_diff_prev[i];}memcpy(mfcc_feature_prev, mfcc_feature, NUM_FEATURES * sizeof(float));memcpy(mfcc_feature_diff_prev, mfcc_feature_diff, NUM_FEATURES * sizeof(float));// combine MFCC with derivatives memcpy(nn_features, mfcc_feature, NUM_FEATURES*sizeof(float));memcpy(&nn_features[NUM_FEATURES], mfcc_feature_diff, 10*sizeof(float));memcpy(&nn_features[NUM_FEATURES+10], mfcc_feature_diff1, 10*sizeof(float));//log_values(nn_features, NUM_FEATURES+20, flog);// quantise them using the same scale as training data (in keras), by 2^n. quantize_data(nn_features, nn_features_q7, NUM_FEATURES+20, 3);// run the mode with the new inputmemcpy(nnom_input_data, nn_features_q7, sizeof(nnom_input_data));model_run(model);// read the result, convert it back to float (q0.7 to float)for(int i=0; i< NUM_FEATURES; i++)band_gains[i] = (float)(nnom_output_data[i]) / 127.f;log_values(band_gains, NUM_FILTER, flog);// one more step, limit the change of gians, to smooth the speech, per RNNoise paperfor(int i=0; i< NUM_FEATURES; i++)band_gains[i] = _MAX(band_gains_prev[i]*0.8f, band_gains[i]); memcpy(band_gains_prev, band_gains, NUM_FEATURES *sizeof(float));// apply the dynamic gains to each frequency band. set_gains((float*)coeff_b, (float*)b_, band_gains, NUM_FILTER, NUM_ORDER);// convert 16bit to float for equalizerfor (int i = 0; i < AUDIO_FRAME_LEN/2; i++)audio_buffer[i] = audio_buffer_16bit[i + AUDIO_FRAME_LEN / 2] / 32768.f;// finally, we apply the equalizer to this audio frame to denoiseequalizer(audio_buffer, &audio_buffer[AUDIO_FRAME_LEN / 2], AUDIO_FRAME_LEN/2, (float*)b_,(float*)coeff_a, NUM_FILTER, NUM_ORDER);// convert the filtered signal back to int16for (int i = 0; i < AUDIO_FRAME_LEN / 2; i++)audio_buffer_filtered[i] = audio_buffer[i + AUDIO_FRAME_LEN / 2] * 32768.f *0.6f; // write the filtered frame to WAV file. fwrite(audio_buffer_filtered, 256*sizeof(int16_t), 1, des_file);}// print some model infomodel_io_format(model);model_stat(model);model_delete(model);fclose(flog);fclose(src_file);fclose(des_file);printf("\nNoisy signal '%s' has been de-noised by NNoM.\nThe output is saved to '%s'.\n", input_file, output_file);return 0;
}

去掉wav的信息就能解析pcm了

创建cmake 文件 编译dll

cmake_minimum_required(VERSION 3.10)project(RnnDenoise)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include_directories(nnom-master/port/)
include_directories(nnom-master/inc/) 
include_directories(nnom-master/examples/rnn-denoise/)
include_directories(D:/java/jdk1.8x64/include/)
include_directories(D:/java/jdk1.8x64/include/win32/)
set(EXPLICIT_SOURCESRnnDenoise.cnnom-master/examples/rnn-denoise/mfcc.c
)
file(GLOB_RECURSE SRC_FILES "nnom-master/src/*/*.c")
set(SOURCES ${EXPLICIT_SOURCES} ${SRC_FILES})add_library(RnnDenoise SHARED ${SOURCES})


java 库封装示例

package com.lilin.demoasr.nnom;public class RnnDenoise implements AutoCloseable{private long rnndenoise;public long getRnndenoise() {return rnndenoise;}public void setRnndenoise(long rnndenoise) {this.rnndenoise = rnndenoise;}private static final Object globalLock = new Object();/***https://github.com/majianjia/nnom/blob/master/examples/rnn-denoise/**** @throws Exception*/public RnnDenoise() throws Exception {synchronized (globalLock) {RnnLoad.load("RnnDenoise");}this.rnndenoise = createRnnDenoise0();}private static native long createRnnDenoise0();private native short[] denoise0(long rnndenoise,short[] var1);/*** 固定320 每次 可以修改c 改大* @param input* @return*/public   short[] denoise(short[] input) {// synchronized (this) {return this.denoise0(this.rnndenoise ,input);// }}private native long destroyRnnDenoise0();public void close() {synchronized (this) {this.destroyRnnDenoise0();this.rnndenoise = 0L;}}public boolean isClosed() {synchronized (this) {return this.rnndenoise == 0L;}}
}

test:

 public static void main (String[] args) {String sList []= new String[]{"G:\\work\\ai\\ZipEnhancer\\r1.pcm","C:\\Users\\\\lilin\\Desktop\\16k.pcm"};// String sList []= new String[]{"C:\\Users\\\\lilin\\Desktop\\16k.pcm"};List< Thread> lts= new ArrayList<>();for (int i = 0; i < sList.length; i++) {String file =sList[i];int finalI = i;lts.add(new Thread(new Runnable() {@Overridepublic void run() {try {RnnDenoise rnnDenoise = new RnnDenoise();System.out.println(rnnDenoise.getRnndenoise());FileInputStream f = new FileInputStream(file);FileOutputStream f1 = new FileOutputStream("C:\\Users\\\\lilin\\Desktop\\"+ finalI +".pcm");int n=0;byte[] z = new byte[640];while ((n = f.read(z)) != -1) {short [] sa = new short[320];ByteBuffer.wrap(z).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(sa);short[] denoisedAudio = rnnDenoise.denoise(sa);byte[] z1 = new byte[640];ByteBuffer.wrap(z1).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(denoisedAudio);f1.write(z1);}System.out.println(finalI+"end.");rnnDenoise.close();f1.close();}catch (Exception e){e.printStackTrace();}}}));}for (Thread  y:  lts  ) {y.start();}for (Thread  y:  lts  ) {try{ y.join();}catch (Exception e){e.printStackTrace();}}System.out.println("end...");}
}

nnom 默认的denoise_weights.h 是单例的无法同时创建多个实例 所以java无法在多线程使用,  可以自己更改下  主要涉及static变量和nnom_tensor_t 需要改用malloc的方式创建。

测试速度挺快的 ,几十分钟的很快降噪完成 ,也可以和freeswitch对接多路实时降噪 在识别,

如果模块或流程觉得麻烦可以到 

https://item.taobao.com/item.htm?id=653611115230

 视频教程yuexiajiayan的个人空间-yuexiajiayan个人主页-哔哩哔哩视频

相关文章:

Java jni调用nnom rnn-denoise 降噪

介绍&#xff1a;https://github.com/majianjia/nnom/blob/master/examples/rnn-denoise/README_CN.md 默认提供了一个wav的例子 #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h>#include …...

C++软件设计模式之状态模式

在C设计模式中&#xff0c;状态模式&#xff08;State Pattern&#xff09;是一种行为设计模式&#xff0c;它允许对象在内部状态改变时改变其行为&#xff0c;使对象看起来似乎修改了其类。状态模式的主要动机、意图和适用场合如下&#xff1a; 动机 在面向对象的设计中&…...

Microsoft Visual Studio中的/MT, /MTd,/MD,/MDd分别是什么意思?

1. /MT&#xff0c;/MTd&#xff0c;/MD&#xff0c;/MDd的含义 /MT&#xff0c;/MTd&#xff0c;/MD&#xff0c;/MDd是 Microsoft Visual C 编译器的运行时库链接选项。它们决定了程序如何链接 C 运行时库&#xff08;CRT&#xff09;。具体含义如下&#xff1a; /MT&#x…...

谷粒商城项目125-spring整合high-level-client

新年快乐! 致2025年还在努力学习的你! 你已经很努力了&#xff0c;今晚就让自己好好休息一晚吧! 在后端中选用哪种elasticsearch客户端&#xff1f; elasticsearch可以通过9200或者9300端口进行操作 1&#xff09;9300&#xff1a;TCP spring-data-elasticsearch:transport-…...

日期时间选择(设置禁用状态)

目录 1.element文档需要 2.禁用所有过去的时间 3.设置指定日期的禁用时间 <template><div class"block"><span class"demonstration">起始日期时刻为 12:00:00</span><el-date-pickerv-model"value1"type"dat…...

基于SpringBoot的题库管理系统的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…...

钉钉h5微应用安卓报错error29 ios报错error3 加上报错52013,签名校验失败 (前端)

这两个都是应为 免登报错52013&#xff0c;签名校验失败 用户后端签名使用的url地址和前端访问地址需要严格一致&#xff0c;包括端口号。前端部分可以用alert显示出当前的location.href&#xff0c;后端部分请在签名的时候打印日志。 访问通过反向代理服务器、各种NAT等场景下…...

Vue.js组件开发-客户端如何限制刷新Token次数

在Vue.js组件开发中&#xff0c;限制刷新Token的次数是一个重要的安全措施&#xff0c;可以防止恶意用户或攻击者无限次尝试刷新Token。 客户端限制 在客户端&#xff0c;可以通过Vuex、localStorage或sessionStorage等存储机制来跟踪刷新Token的尝试次数。以下是一个基本的实…...

Linux上安装jdk

在线环境的话&#xff0c;通过命令下载&#xff0c;离线环境的话&#xff0c;组要自行去oracle官网下载后上传 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jd…...

Ardunio BLE keyboard 库的使用

为了开发一个 ardunio 的蓝牙选歌器&#xff0c;网络上普遍推荐使用&#xff1a; https://github.com/T-vK/ESP32-BLE-Keyboard 结果搞了好几天&#xff0c;就是不行。最后发现&#xff0c;下面两点非常重要&#xff1a; 使用 NimBle-ardunio 库这个库目前是2.1.2 &#xff…...

django --递归查询评论

表数据 树状结构 action(methods(GET, ), detailFalse) def get_info_pinglun(self, request, *args, **kwargs) -> Response:根据评论id查所有回复params wenxian_pinglun_id --> 评论id;wenxian_pinglun_id self.request.GET.get(wenxian_pinglun_id)results se…...

【开源免费】基于SpringBoot+Vue.JS音乐网站(JAVA毕业设计)

本文项目编号 T 109 &#xff0c;文末自助获取源码 \color{red}{T109&#xff0c;文末自助获取源码} T109&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

SUBSTRING_INDEX()在MySQL中的用法

语法&#xff1a; SUBSTRING_INDEX() 是 MySQL 中的一个字符串函数&#xff0c;它返回一个字符串&#xff0c;该字符串包含从字符串的开始或结束到指定的子字符串出现指定次数为止的部分。这个函数的语法如下&#xff1a; SUBSTRING_INDEX(string, delimiter, count)string&a…...

对45家“AI+安全”产品/方案的分析

一. 关键洞察 “AI+安全”创新非常活跃,一片百家争鸣之势,赛道选择上,以事件分诊Incident Triage、 安全辅助Security Copilots、自动化Automation三者为主为主,这充分反映了当前安全运营的主要需求,在产品理念选择上以 AI 和 自动化为主,这确实又切合上了在关键…...

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述

Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Dataguard 概述 目录 Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Data…...

Pycharm 中 virtualenv、pipenv、conda 虚拟环境的用法

文章目录 前言虚拟环境的通俗介绍虚拟环境和非虚拟环境该怎么选?通过 Virtualenv 方式创建虚拟环境通过 Pipenv 方式创建虚拟环境通过 Conda 方式创建虚拟环境前言 在网上找了好一些资料,发现介绍 Pycharm 虚拟环境的不多,查了一些资料,并做个总结。 本文主要是介绍 Pycha…...

UNI-APP弹窗

组件代码 <template><view><!-- 蒙版 --><view class"mask" click"close()" v-show"tanchuang"></view><!-- 弹窗 --><view class"pop" :style"{height:height*0.8 px,top:tanchuang?…...

【大模型实战篇】LLaMA Factory微调ChatGLM-4-9B模型

1. 背景介绍 虽然现在大模型微调的文章很多&#xff0c;但纸上得来终觉浅&#xff0c;大模型微调的体感还是需要自己亲自上手实操过&#xff0c;才能有一些自己的感悟和直觉。这次我们选择使用llama_factory来微调chatglm-4-9B大模型。 之前微调我们是用两块3090GPU显卡&…...

【Cesium】三、实现开场动画效果

文章目录 实现效果实现方法实现代码组件化 实现效果 实现方法 Cesium官方提供了Camera的flyTo方法实现了飞向目的地的动画效果。 官方API&#xff1a;传送门 这里只需要用到目的地&#xff08;destination&#xff09;和持续时间&#xff08;duration&#xff09;这两个参数…...

#渗透测试#红蓝攻防#红队打点web服务突破口总结01

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

短视频 SEO 如何提高网站的搜索排名

为什么短视频 SEO 是提高网站搜索排名的关键 在当今数字化时代&#xff0c;短视频平台已经成为人们获取信息和娱乐的主要渠道。短视频的流行不仅改变了人们的观看习惯&#xff0c;还深刻影响了网络营销的方式。如何利用短视频 SEO&#xff08;搜索引擎优化&#xff09;来提高网…...

M2LOrder模型Python爬虫实战:应对动态渲染与数据加密网站

M2LOrder模型Python爬虫实战&#xff1a;应对动态渲染与数据加密网站 最近有个朋友找我帮忙&#xff0c;说他们公司需要从某个网站上抓取一些商品数据&#xff0c;但试了好几个爬虫工具都搞不定。我一看&#xff0c;好家伙&#xff0c;这网站不仅数据是页面加载完才动态生成的…...

亚洲美女-造相Z-Turbo可部署方案:适配信创环境(麒麟OS+昇腾910B)可行性验证

亚洲美女-造相Z-Turbo可部署方案&#xff1a;适配信创环境&#xff08;麒麟OS昇腾910B&#xff09;可行性验证 今天我们来聊聊一个挺有意思的话题&#xff1a;怎么把一个专门生成亚洲美女图片的AI模型&#xff0c;部署到咱们国产的信创环境里。这个模型叫“亚洲美女-造相Z-Tur…...

LosslessCut:解锁无损视频编辑的5个专业技巧

LosslessCut&#xff1a;解锁无损视频编辑的5个专业技巧 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字内容创作领域&#xff0c;视频质量与处理效率往往难以兼…...

惊艳展示:MedGemma医学影像分析系统,自然语言提问生成专业报告

惊艳展示&#xff1a;MedGemma医学影像分析系统&#xff0c;自然语言提问生成专业报告 1. 引言&#xff1a;当AI能“看懂”医学影像&#xff0c;并“说”出专业见解 想象一下&#xff0c;你手里有一张肺部X光片&#xff0c;但你不是放射科医生。你看着那些黑白影像和复杂的结…...

iOS开发效率工具:设备支持文件管理完全指南 - 无需升级Xcode的解决方案

iOS开发效率工具&#xff1a;设备支持文件管理完全指南 - 无需升级Xcode的解决方案 【免费下载链接】iOSDeviceSupport All versions of iOS Device Support 项目地址: https://gitcode.com/gh_mirrors/ios/iOSDeviceSupport 作为iOS开发者&#xff0c;你是否曾遭遇这样…...

我的实用设计模式之 关于Policy-based design在Windows Mobile网络连接管理的应用

Raw Data&#xff08;原数据&#xff09;使用不要的分析器&#xff08;分析器使用不同的算法&#xff09;分析出关心的Event&#xff08;事件&#xff0c;对象&#xff0c;告警等等&#xff09;。同时作为behavior模式之一&#xff0c;stragety模式也可以使用在 定义多个behavi…...

炉石传说HsMod插件终极指南:55项免费功能解锁全新游戏体验

炉石传说HsMod插件终极指南&#xff1a;55项免费功能解锁全新游戏体验 【免费下载链接】HsMod Hearthstone Modify Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod 你是否厌倦了炉石传说中冗长的动画等待&#xff1f;是否想要更流畅的游戏体…...

RobotStudio机器人轨迹规划:从工件坐标到流畅路径的实战指南

1. 工件坐标系的创建与校准 在RobotStudio中规划机器人轨迹的第一步&#xff0c;就是建立准确的工件坐标系。这就像盖房子前要先打好地基&#xff0c;坐标系就是机器人运动的"地基"。我见过不少新手直接开始示教点位&#xff0c;结果发现机器人总是跑偏&#xff0c;就…...

【科研必备】Elsevier Tracker:5分钟搞定学术投稿监控的终极解决方案

【科研必备】Elsevier Tracker&#xff1a;5分钟搞定学术投稿监控的终极解决方案 【免费下载链接】Elsevier-Tracker 项目地址: https://gitcode.com/gh_mirrors/el/Elsevier-Tracker 你是否也曾为了追踪Elsevier期刊的审稿状态而反复刷新页面&#xff1f;每天登录系统…...