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

音频基础知识简述 esp-sr 上手指南

此篇博客先对音频基础知识进行简要叙述,然后帮助读者入门 esp-sr SDK。

1 音频的基本概念

1.1 声音的本质

声音的本质是波在介质中的传播现象,声波的本质是一种波,是一种物理量。 两者不一样,声音是一种抽象的,是声波的传播现象,声波是物理量。

1.2 声音的三要素

  • 响度:人主观上感觉声音的大小(俗称音量),由振幅和人离声源的距离决定,振幅越大响度越大,人和声源的距离越小,响度越大。
  • 音调:频率的不同决定了声音的高低(高音、低音),频率越高音调越高(频率单位为 Hz,赫兹),人耳听觉范围 20~20000 Hz。20 Hz 以下称为次声波,20000 Hz 以上称为超声波)。
  • 音色:由于不同对象材料的特点,声音具有不同的特性,音色本身就是抽象的东西,但波形就是把这种抽象和直观的性能。波形因音调而异,不同的音调可以通过波形来区分。

img

1.3 数字音频的几个基本概念

1.3.1 采样

所谓采样就是只在时间轴上对信号进行数字化。

  • 根据奈奎斯特定律(也称为采样定律),按照比声音最高频率的 2 倍上进行采样。人类听觉的频率(音调)范围为 20 Hz–20 KHz 。所以至少要大于 40 kHz。采样频率一般为 44.1 kHz,这样可保证声音达到 20 kHz 也能被数字化。44.1 kHz 就是代表 1 秒会采样 44100 次。

乐鑫AI语音采用的是 16 kHz 采样率,16 kHz 的采样频率的一半合好对应人类语音的常用频段上限约 8 kHz, 此外 44.1 kHz 采样率是另一种常用的采样率,44.1 kHz 的采样频率的一半对应人耳的可听声频率上限约 20 kHz。因为在同等时间长度内,采样率越高,数据量越大,所以:通常即时通讯类的音频会采用 16 kHz 甚至更低的采样率,以保证信号传输的及时性,但是也会对音频质量造成一定损失(比如声音发闷);而主打高质量音声的记录类音频资源会采用 44.1 kHz 甚至 48 kHz 的采样率,以更多的数据存储量为代价,保证重放信号的高保真度。

img
因此这部分主要包含以下三个参数:

  • 比特率:比特率是每秒传输的比特数。单位为比特(bps 位/秒)。
  • 采样:采样是把连续的时间信号,变成离散的数字信号。
  • 采样率:采样率是每秒采集多少个样本。

1.3.2 量化

量化是指在幅度轴上对信号进行数字化。如果用 16 比特位的二进制信号来表示一个采样,那么一个采样所表示的范围即为【-32768,32767】。

乐鑫 AI 语音采用的是 16 比特的量化。

1.3.3 通道数

通道数即声音的通道数目,常见的有单声道、双声道和立体声道。

  • 单声道的声音只能使用一个扬声器发声,或者也可以处理成两个扬声器输出同一个声道的声音,当通过两个扬声器回放单声道信息的时候,我们可以明显感觉到声音是从两个音箱中间传递到我们耳朵里的,无法判断声源的具体位置。

  • 双声道就是有两个声音通道,其原理是人们听到声音时可以根据左耳和右耳对声音相位差来判断声源的具体位置。声音在录制过程中被分配到两个独立的声道,从而达到了很好的声音定位效果。

1.3.4 音频大小的计算

如:录制一段,时间为:1 s,采样率为 16000 HZ,采样大小为 16,通道数为 2 的音频,所占用的空间大小为 : 16000 * 16 * 2 * 1 s= 500 k

2 声学前端(Audio Front-End ,AFE)

一套乐鑫 AFE 算法框架,可基于功能强大的 ESP32 和 ESP32-S3 SoC 进行声学前端处理,使用户获得高质量且稳定的音频数据,从而构建性能卓越且高性价比的智能语音产品。

2.1 声学回声消除(AEC)

声学回声消除算法通过自适应滤波的方法,消除使用麦克风输入音频时的回声。此算法适用于语音设备通过扬声器播放音频等场景。

算法最多支持双麦处理,能够有效的去除 mic 输入信号中的自身播放声音。从而可以在自身播放音乐的情况下进行很好的语音识别等应用。

2.2 盲源分离(BSS)

盲源分离算法使用多个麦克风检测传入音频的方向,并强化某个方向的音频输入。此算法在噪音环境中提高了所需音频源的声音质量。

2.3 噪声抑制(NS)

噪声抑制算法支持单通道音频信号处理,能够有效消除无用的非人声(如吸尘器或空调声),从而改善所需处理的音频信号。

3 乐鑫 AFE 支持的场景

乐鑫 AFE 的功能针对以下两种不同场景:

  1. 语音识别场景

  2. 语音通话场景

3.1 语音识别场景

模型步骤:

  1. 音频输入

  2. AEC 进行回声消除(消除自身的音频播报,这需要回采通道)

    • 硬回采:通过 IIS 直接读取写入扬声器的数据(可以和麦克风共用一路 IIS)
    • 软回采:软件 copy 写入扬声器的数据(暂未支持,等待开发)
  3. BSS/NS

    • BSS (Blind Source Separation) 算法支持双通道处理,能够很好的将目标声源和其余干扰音进行盲源分离,从而提取出有用音频信号,保证了后级语音的质量。
    • NS (Noise Suppression) 算法支持单通道处理,能够对单通道音频中的非人声噪声进行抑制,尤其针对稳态噪声,具有很好的抑制效果。
    • 具体采用哪一个算法,根据配置的麦克风数量定义。
  4. VAD

    • VAD (Voice Activity Detection) 算法支持实时输出当前帧的语音活动状态
  5. WakeNet

    唤醒词

对应的流程图如下:
请添加图片描述

3.2 语音通话场景

模型步骤:

  1. 音频输入
  2. AEC 进行回声消除(消除自身的音频播报,这需要回采通道)
    • 硬回采:通过 IIS 直接读取写入扬声器的数据(可以和麦克风共用一路 IIS)
    • 软回采:软件 copy 写入扬声器的数据(暂未支持,等待开发)
  3. BSS/NS
    • BSS (Blind Source Separation) 算法支持双通道处理,能够很好的将目标声源和其余干扰音进行盲源分离,从而提取出有用音频信号,保证了后级语音的质量。
    • NS (Noise Suppression) 算法支持单通道处理,能够对单通道音频中的非人声噪声进行抑制,尤其针对稳态噪声,具有很好的抑制效果。
    • 具体采用哪一个算法,根据配置的麦克风数量定义。
  4. MISO
    • MISO (Multi Input Single Output) 算法支持双通道输入,单通道输出。用于在双麦场景,没有唤醒使能的情况下,选择信噪比高的一路音频输出。
  5. AGC
    • AGC (Automatic Gain Control) 动态调整输出音频的幅值,当弱信号输入时,放大输出幅度;当输入信号达到一定强度时,压缩输出幅度。

对应的流程图如下:
请添加图片描述

3.3 配置代码参考

#define AFE_CONFIG_DEFAULT() { \.aec_init = true, \                      	     	//AEC 算法是否使能.se_init = true, \									//BSS/NS 算法是否使能.vad_init = true, \									//VAD 是否使能 ( 仅可在语音识别场景中使用 ).wakenet_init = true, \								//唤醒是否使能..voice_communication_init = false, \				//语音通话是否使能。与 wakenet_init 不能同时使能..voice_communication_agc_init = false, \        	//语音通话中AGC是否使能.voice_communication_agc_gain = 15, \               //AGC的增益值,单位为dB.vad_mode = VAD_MODE_3, \                      	    //VAD 检测的操作模式,越大越激进.wakenet_model_name = NULL, \                       //选择唤醒词模型.wakenet_mode = DET_MODE_2CH_90, \              	//唤醒的模式。对应为多少通道的唤醒,根据mic通道的数量选择.afe_mode = SR_MODE_LOW_COST, \						//SR_MODE_LOW_COST: 量化版本,占用资源较少。 //SR_MODE_HIGH_PERF: 非量化版本,占用资源较多。.afe_perferred_core = 0, \                      	//AFE 内部 BSS/NS/MISO 算法,运行在哪个 CPU 核.afe_perferred_priority = 5, \                  	//AFE 内部 BSS/NS/MISO 算法,运行的task优先级。.afe_ringbuf_size = 50, \                       	//内部 ringbuf 大小的配置.memory_alloc_mode = AFE_MEMORY_ALLOC_MORE_PSRAM, \	//绝大部分从外部psram分配.agc_mode = AFE_MN_PEAK_AGC_MODE_2, \               //线性放大喂给后续multinet的音频,峰值处为 -4dB。.pcm_config.total_ch_num = 3, \                     //total_ch_num = mic_num + ref_num.pcm_config.mic_num = 2, \							//音频的麦克风通道数。目前仅支持配置为 1 或 2。.pcm_config.ref_num = 1, \                          //音频的参考回路通道数,目前仅支持配置为 0 或 1。
}

4 AI语音模型

4.1 WakeNet

4.1.1 通过 menuconfig 选择模型

wn9_hiesp(最新的 wn9 都是默认 8 bit 量化): 版本 9 ,唤醒词是 hi,esp

请添加图片描述

4.2 multinet

4.2.1 通过 menuconfig 选择模型

mn4q8_cn : 版本 4 ,8 bit 量化,中文命令词
请添加图片描述

4.3 添加命令词

4.3.1 通过 menuconfig 添加命令词

  • 中文命令词直接添加拼音:打开空调(da kai kong tiao),也支持多句话支持同一个 COMMAND ID , 最大风速/最高风速

    添加方言命令词:添加对应的发音
    请添加图片描述

  • 英文命令词需要添加对应的音素,通过 python 脚本生成
    请添加图片描述

4.3.2 代码中动态添加命令词

esp_mn_commands_add(i, token);

通过调用 api 实现动态添加命令词。

算法性能

仅消耗约 20% CPU, 30 KB SRAM 和 500 KB PSRAM

5 麦克风设计

5.1 麦克风性能推荐

  1. 麦克类型:全向型 MEMS ⻨克⻛。

  2. 灵敏度:

    • 1 Pa 声压下模拟⻨灵敏度不低于 -38 dBV,数字⻨灵敏度要求不低于 -26 dB
    • 公差控制在 ±2 dB,对于⻨克阵列推荐采⽤ ±1 dB 公差
  3. 信噪比

    信噪⽐不低于 62 dB,推荐 >64 dB :

    ​ 信噪比越高声音越保真

    • Frequency response:频率响应在 50 ~16 kHz 范围内的波动在 ±3 dB 之内
    • 电源抑制比(PSRR):n >55 dB(MEMS MIC)

6 结构设计建议

  1. ⻨克孔孔径或宽度推荐⼤于 1 mm,拾⾳管道尽量短,腔体尽可能⼩,保证⻨克和结构组件配合的谐振频 率在 9 KHz 以上。

  2. 拾⾳孔深度和直径⽐⼩于 2:1,壳体厚度推荐1 mm,如果壳体过厚,需增⼤开孔⾯积。

  3. ⻨克孔上需通过防尘⽹进⾏保护。

  4. ⻨克⻛与设备外壳之间必须加硅胶套或泡棉等进⾏密封和防震,需进⾏过盈配合设计,以保证⻨克的密封性。

  5. ⻨克孔不能被遮挡,底部拾⾳的⻨克孔需结构上增加凸起,避免⻨克孔被桌⾯等遮挡。

  6. ⻨克需远离喇叭等会产⽣噪⾳或振动的物体摆放,且与喇叭⾳腔之间通过橡胶垫等隔离缓冲。

7 代码讲解(CN_SPEECH_COMMANDS_RECOGNITION)

7.1 头文件

#include "esp_wn_iface.h"                   //唤醒词模型的一系列API
#include "esp_wn_models.h"					//根据输入的模型名称得到具体的唤醒词模型
#include "esp_afe_sr_iface.h"				//语音识别的音频前端算法的一系列API
#include "esp_afe_sr_models.h"              //语音前端模型的声明
#include "esp_mn_iface.h"                   //命令词模型的一系列API
#include "esp_mn_models.h"                  //命令词模型的声明
#include "esp_board_init.h"                 //开发板硬件初始化
#include "driver/i2s.h"                     //i2s 驱动
#include "speech_commands_action.h"         //根据识别到的 command 进行语音播报/闪烁 LED
#include "model_path.h"                     //从 spiffs 文件管理中返回模型路径等 API

7.2 app_main

void app_main()
{models = esp_srmodel_init("model");                                //spiffs 中的所有可用模型或  model 默认是从`flash`读ESP_ERROR_CHECK(esp_board_init(AUDIO_HAL_08K_SAMPLES, 1, 16));     //Special config for dev board   // ESP_ERROR_CHECK(esp_sdcard_init("/sdcard", 10));                //初始化 SD card
#if defined CONFIG_ESP32_KORVO_V1_1_BOARDled_init();                                                        //LED 初始化
#endifafe_handle = &ESP_AFE_SR_HANDLE;                                   afe_config_t afe_config = AFE_CONFIG_DEFAULT();					   //音频前端的配置项afe_config.wakenet_model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);;  //从有所可用的模型中找到唤醒词模型的名字
#if defined CONFIG_ESP32_S3_BOX_BOARD || defined CONFIG_ESP32_S3_EYE_BOARDafe_config.aec_init = false;
#endif//afe_config.aec_init = false;                                       //关闭 AEC//afe_config.se_init = false;                                        //关闭 SE//afe_config.vad_init = false;                                       //关闭VAD//afe_config.pcm_config.total_ch_num = 2;                            //设置为单麦单回采//afe_config.pcm_config.mic_num = 1;                                 //麦克风通道一esp_afe_sr_data_t *afe_data = afe_handle->create_from_config(&afe_config);xTaskCreatePinnedToCore(&feed_Task, "feed", 4 * 1024, (void*)afe_data, 5, NULL, 0);        //feed 从 i2s 拿到音频数据xTaskCreatePinnedToCore(&detect_Task, "detect", 8 * 1024, (void*)afe_data, 5, NULL, 1);    //将音频数据喂给模型获取检测结果#if defined  CONFIG_ESP32_S3_KORVO_1_V4_0_BOARD || defined CONFIG_ESP32_KORVO_V1_1_BOARDxTaskCreatePinnedToCore(&led_Task, "led", 2 * 1024, NULL, 5, NULL, 0);                     //开启LED
#endif
#if defined  CONFIG_ESP32_S3_KORVO_1_V4_0_BOARD || CONFIG_ESP32_S3_KORVO_2_V3_0_BOARD || CONFIG_ESP32_KORVO_V1_1_BOARDxTaskCreatePinnedToCore(&play_music, "play", 2 * 1024, NULL, 5, NULL, 1);                  //开启语音播报
#endif
}

7.2 feed 操作

void feed_Task(void *arg)
{esp_afe_sr_data_t *afe_data = arg;int audio_chunksize = afe_handle->get_feed_chunksize(afe_data);int nch = afe_handle->get_channel_num(afe_data);int feed_channel = esp_get_feed_channel();         //3;int16_t *i2s_buff = malloc(audio_chunksize * sizeof(int16_t) * feed_channel);assert(i2s_buff);size_t bytes_read;while (1) {//第一种方式 //audio_chunksize:音频时间 512->32ms 256->16ms//int16_t:16位量化//feed_channel:两麦克风通道数据一回采通道数据esp_get_feed_data(i2s_buff, audio_chunksize * sizeof(int16_t) * feed_channel);//第二种方式i2s_read(I2S_NUM_1, i2s_buff, audio_chunksize * sizeof(int16_t) * feed_channel, &bytes_read, portMAX_DELAY);afe_handle->feed(afe_data, i2s_buff);}afe_handle->destroy(afe_data);vTaskDelete(NULL);
}

7.3 detect 操作

void detect_Task(void *arg)
{esp_afe_sr_data_t *afe_data = arg;int afe_chunksize = afe_handle->get_fetch_chunksize(afe_data);int nch = afe_handle->get_channel_num(afe_data);char *mn_name = esp_srmodel_filter(models, ESP_MN_PREFIX, ESP_MN_CHINESE);       //从模型队列中获取命令词模型名字printf("multinet:%s\n", mn_name);esp_mn_iface_t *multinet = esp_mn_handle_from_name(mn_name);                     //获取命令词模型model_iface_data_t *model_data = multinet->create(mn_name, 5760);                //创建esp_mn_commands_update_from_sdkconfig(multinet, model_data); 					 // Add speech commands from sdkconfigint mu_chunksize = multinet->get_samp_chunksize(model_data);int chunk_num = multinet->get_samp_chunknum(model_data);assert(mu_chunksize == afe_chunksize);printf("------------detect start------------\n");// FILE *fp = fopen("/sdcard/out1", "w");// if (fp == NULL) printf("can not open file\n");while (1) {afe_fetch_result_t* res = afe_handle->fetch(afe_data);                       //获得AEF的处理结果if (!res || res->ret_value == ESP_FAIL) {printf("fetch error!\n");break;}
#if CONFIG_IDF_TARGET_ESP32if (res->wakeup_state == WAKENET_DETECTED) {                                printf("wakeword detected\n");play_voice = -1;detect_flag = 1;afe_handle->disable_wakenet(afe_data);printf("-----------listening-----------\n");}
#elif CONFIG_IDF_TARGET_ESP32S3if (res->wakeup_state == WAKENET_DETECTED) {                          printf("WAKEWORD DETECTED\n");                                           //如果被唤醒将唤醒标志置位True} else if (res->wakeup_state == WAKENET_CHANNEL_VERIFIED) {play_voice = -1;detect_flag = 1;printf("AFE_FETCH_CHANNEL_VERIFIED, channel index: %d\n", res->trigger_channel_id);}
#endifif (detect_flag == 1) {esp_mn_state_t mn_state = multinet->detect(model_data, res->data);       //将AFE处理后的音频数据给命令词模型if (mn_state == ESP_MN_STATE_DETECTING) {continue;}if (mn_state == ESP_MN_STATE_DETECTED) {esp_mn_results_t *mn_result = multinet->get_results(model_data);    //得到结果for (int i = 0; i < mn_result->num; i++) {printf("TOP %d, command_id: %d, phrase_id: %d, prob: %f\n", i+1, mn_result->command_id[i], mn_result->phrase_id[i], mn_result->prob[i]);}printf("\n-----------listening-----------\n");}if (mn_state == ESP_MN_STATE_TIMEOUT) {                                 //超时关闭afe_handle->enable_wakenet(afe_data);detect_flag = 0;printf("\n-----------awaits to be waken up-----------\n");continue;}}}afe_handle->destroy(afe_data);vTaskDelete(NULL);
}

8 乐鑫 AI 相关 Github 参考

  • esp-sr:同时可以参考 esp-sr 文档
  • esp-skainet

相关文章:

音频基础知识简述 esp-sr 上手指南

此篇博客先对音频基础知识进行简要叙述&#xff0c;然后帮助读者入门 esp-sr SDK。 1 音频的基本概念 1.1 声音的本质 声音的本质是波在介质中的传播现象&#xff0c;声波的本质是一种波&#xff0c;是一种物理量。 两者不一样&#xff0c;声音是一种抽象的&#xff0c;是声…...

Flex弹性布局一文通【最全Flex教学】

文章目录一.Flex布局1.1 传统布局和flex布局1.1.1 传统布局1.1.2 flex弹性布局1.2 flex初步体验1.3 布局原理二.常见Flex属性2.1 常见父项属性2.2 flex-direction主轴的方向2.3 justify-content设置主轴上的子元素排列方式2.4 设置子元素是否flex-wrap换行2.5 align-itmes设置侧…...

Navicat使用教程

Navicat&#xff1a;一个可以对别人的数据库进行操作的软件&#xff08;需要与如mysql等数据库配套使用&#xff09; 1. 下载mysql MySQL :: Download MySQL Community Server (Archived Versions) 下载上面那个版本 下载下来是个压缩包&#xff0c;解压 2.配置mysql (1)在…...

35岁测试人该何去何从?10年工作经验的我,只不过是一年的工作经验用了10年......

如果到了这个年龄&#xff0c;还是初级测试&#xff0c;或者只会一些简单的自动化测试&#xff0c;那么真的是不好干了。 35的年龄&#xff0c;企业对员工是有另一层面的考量。 简单来说&#xff0c;就是年龄上去了&#xff0c;能力也要上去&#xff0c;要么是技术专家&#…...

SpringBoot 项目中集成 Prometheus 和 Grafana

项目上线后&#xff0c;除了能保障正常运行以外&#xff0c;也需要服务运行的各个指标进行监控&#xff0c;例如 服务器CPU、内存使用占比&#xff0c;Full GC 执行时间等&#xff0c;针对一些指标出现异常&#xff0c;可以加入一些报警机制能及时反馈给开发运维。这样&#xf…...

红队APT——反朔源流量加密CSMSF证书指纹C2项目CDN域前置

目录 0x01 背景交代 0x02 常见红蓝对抗中红队面临问题 0x03 蓝队发现处置情况...

Linux环境下实现并详细分析c/cpp线程池(附源码)

一、线程池原理 如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c;这样频繁创建线程就会大大降低系统的效率&#xff0c;因为频繁创建线程和销毁线程需要时间。 线程池是一种多线程处理形式&#xff0c;处理过程中将任务添加到…...

移动web(三)

her~~llo&#xff0c;我是你们的好朋友Lyle&#xff0c;是名梦想成为计算机大佬的男人&#xff01; 博客是为了记录自我的学习历程&#xff0c;加强记忆方便复习&#xff0c;如有不足之处还望多多包涵&#xff01;非常欢迎大家的批评指正。 媒体查询 目标&#xff1a;能够根据…...

macbook怎么运行exe文件 mac打开exe文件的三大方法

exe文件是Windows系统的可执行文件&#xff0c;虽然Mac系统上无法直接打开exe文件&#xff0c;但是你可以在Mac电脑上安装双系统或者虚拟机来实现mac电脑上运行exe文件。除了这两种方法之外&#xff0c;你还可以在Mac电脑上使用类虚拟机软件打开exe文件&#xff0c;这三种方法各…...

GoldenGate(OGG)高可用XAG部署

前言: 本文档主要描述通过Oracle Grid Infrastructure Agents (XAG)基于Oracle RAC实现GoldenGate(OGG)软件高可用的实施操作 环境信息&#xff1a; 源端 目标端 节点一IP 节点二IP 192.168.1.84 192.168.1.86 节点一IP 节点二IP 192.168.1.200 192.168.1.210 VIP 192.…...

如何使用Docker容器部署O2OA(翱途)开发平台与OnlyOffice的集成版本?

O2OA(翱途)开发平台[下称O2OA平台或者O2OA]默认可以和OnlyOffice进行集成来实现在线文档编辑以及流程集成。开发者可以直接安装O2OA官网的OnlyOfficeO2Server的Docker版本用于体验。本文将详细介绍如何安装O2OA OnlyOffice的Docker版本。OnlyOffice Docs Sever可以单独安装,O2…...

springboot复习(黑马)(持续更新)

学习目标基于SpringBoot框架的程序开发步骤熟练使用SpringBoot配置信息修改服务器配置基于SpringBoot的完成SSM整合项目开发一、SpringBoot简介1. 入门案例问题导入SpringMVC的HelloWord程序大家还记得吗&#xff1f;SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计…...

K_A16_001 基于STM32等单片机驱动HX711称重模块 串口与OLED0.96双显示

K_A16_001 基于STM32等单片机驱动HX711称重模块 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCHX711称重模块1.2、STM32F103C8T6HX711称重模块五、基础知识学习与相关资料下载六、视频效果展…...

单例模式之饿汉式

目录 1 单例模式的程序结构 2 饿汉式单例模式的实现 3 饿汉式线程安全 4 防止反射破坏单例 5 总结 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。所谓单例就是在系统中只有一个该类的实例&#xff0c;并且提供一个访问该实例的全局…...

软件测试培训三个月,找到工作了11K,面试总结分享给大家

功能方面&#xff1a;问的最多的就是测试流程&#xff0c;测试计划包含哪些内容&#xff0c;公司人员配置&#xff0c;有bug开发认为不是 bug怎么处理&#xff0c;怎样才算是好的用例&#xff0c;测试用例设计方法&#xff08;等价类&#xff0c;边界值等概念方法&#xff09;&…...

Hbase备份与恢复工具Snapshot的基本概念与工作原理

数据库都有相对完善的备份与恢复功能。备份与恢复功能是数据库在数据意外丢失、损坏下的最后一根救命稻草。数据库定期备份、定期演练恢复是当下很多重要业务都在慢慢接受的最佳实践&#xff0c;也是数据库管理者推荐的一种管理规范。HBase数据库最核心的备份与恢复工具——Sna…...

RTOS中事件集的实现原理以及实用应用

事件集的原理 RTOS中事件集的实现原理是通过位掩码来实现的。事件集是一种用于在任务之间传递信号的机制。在RTOS中&#xff0c;事件集通常是一个32位的二进制位向量。每个位都代表一个特定的事件&#xff0c;例如信号、标志、定时器等。 当一个任务等待一个或多个事件时&…...

计及新能源出力不确定性的电气设备综合能源系统协同优化(Matlab代码实现)

运行视频及运行结果&#xff1a; 计及碳排放成本的电-气-热综合能源系纷充节点能价计算方法研究&#xff08;Matlab代码实现&#xff09;目录 第一部分 文献一《计及新能源出力不确定性的电气设备综合能源系统协同优化》 0 引言 &#xff11; 新能源出力不确定性处理 1.1 新…...

推荐几个超实用的开源自动化测试框架

有什么好的开源自动化测试框架可以推荐&#xff1f;为了让大家看文章不蒙圈&#xff0c;文章我将围绕3个方面来阐述&#xff1a; 1、通用自动化测试框架介绍 2、Java语言下的自动化测试框架 3、Python语言下的自动化测试框架 随着计算机技术人员的大量增加&#xff0c;通过编写…...

Mac 上解压缩 RAR 文件

RAR 在十几年前的互联网曾叱咤风云般的存在。在那时&#xff0c;你所能见到的压缩文件几乎都是 RAR 格式&#xff0c;大家在 Windows 上使用的压缩、解压缩软件基本都是 WinRAR。虽然这些年使用 RAR 格式的压缩包的情况在逐渐减少&#xff0c;但是你还是经常能在国内各种网站下…...

C++核心编程<引用>(2)

c核心编程<引用>2.引用2.1引用的基本使用2.2引用注意事项2.3引用做函数参数2.4引用做函数返回值2.5引用的本质2.6常量引用2.引用 2.1引用的基本使用 作用: 给变量起别名语法:数据类型 &别名 原名演示#include<iostream> using namespace std; void func();i…...

零入门kubernetes网络实战-20->golang编程syscall操作tun设备介绍

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 本篇文章主要是使用golang自带的syscall包来创建tun类型的虚拟网络设备。 注意&#xff1a; 目前只能使用syscall包来创建tun类型的虚拟设备。 tun虚拟网…...

springboot之自动配置

文章目录前言一、配置文件及自动配置原理1、配置文件2、yaml1、注解注入方式给属性赋值2、yaml给实体类赋值3、Properties给属性赋值二、springboot的多环境配置四、自动配置总结前言 1、自动装配原理 2、多种方式给属性赋值 3、多环境配置 4、自动配置 一、配置文件及自动配置…...

wxpython设计GUI:wxFormBuilder工具常用布局结构介绍之布局四—面板拼接式

python借助wxFormBuilder工具搭建基础的GUI界面—wxFormBuilder工具使用介绍&#xff1a;https://blog.csdn.net/Logintern09/article/details/126685315 布局四&#xff1a;面板拼接式&#xff0c;先Panel面板构图&#xff0c;再使用程序代码在Frame框架上拼接面板 下面讲一下…...

全网最全之接口测试【加密解密攻防完整版】实战教程详解

看视频讲的更详细&#xff1a;https://www.bilibili.com/video/BV1zr4y1E7V5/? 一、对称加密 对称加密算法是共享密钥加密算法&#xff0c;在加密解密过程中&#xff0c;使用的密钥只有一个。发送和接收双方事先都知道加密的密钥&#xff0c;均使用这个密钥对数据进行加密和解…...

Python - 目录文件(OS模块) 常用操作

目录os模块的方法os.path()模块的方法使用示例示例一&#xff1a;简单使用示例二&#xff1a;获取文件夹下指定条件的文件os模块的方法 方法说明os.listdir(path)取得指定文件夹下的文件列表os.mkdir(path)创建一个名为path的文件夹os.open(file, flags)打开一个文件&#xff…...

把本地代码初始化到远程git仓库

本地代码&#xff0c;推送到远程的git仓库。第一种方法第一步&#xff1a;建立远程的git仓库第二步&#xff1a;拉取git仓库到本地第三步&#xff1a;将本地代码复制到本地的git拉下来的文件夹中第四步&#xff1a;代码提交即可git add . --> git commit -m 初始化 --> g…...

关于angular中的生命周期函数

生命周期函数&#xff0c;也叫生命周期钩子。 Angular的每个组件&#xff08;包括根组件和子组件&#xff09;都存在一个生命周期&#xff0c;从创建、更新、到销毁&#xff0c;Angular提供组件生命周期钩子函数&#xff0c; 组件的生命周期从实例化组件类并渲染组件视图及其…...

【拼图】拼图游戏-微信小程序开发流程详解

还记得小时候玩过的经典拼图游戏吗&#xff0c;上小学时&#xff0c;在路边摊用买个玩具&#xff0c;是一个正方形盒子形状&#xff0c;里面装的是图片分割成的很多块&#xff0c;还差一块&#xff0c;怎么描述好呢&#xff0c;和魔方玩具差不多&#xff0c;有没有听说叫二维的…...

第六章 opengl之光照(颜色)

OpenGL光照颜色创建一个光照场景光照 颜色 颜色由RGB组成&#xff0c;分别是红色&#xff0c;绿色&#xff0c;蓝色。举例定义一个颜色向量&#xff1a; glm::vec3 coral(1.0f, 0.5f, 0.31f);而在现实中&#xff0c;人眼看到的是 物体反射后的颜色&#xff0c;也就是说不能被…...

博彩网站做维护/免费推广引流怎么做

北京户口越来越难搞了&#xff0c;逐步看下非北京户口带来的限制~ 关于养老保险&#xff0c;非北京户口在北京缴纳养老保险&#xff0c;退休后在哪里领取养老金的问题&#xff1a; &#xff08;1&#xff09;最后参保地是北京&#xff0c;且在北京缴纳养老保险超过15年&#x…...

wordpress设置缩略图/搜狗seo刷排名软件

依赖注入(DI)与控制反转(IOC)其本上是一种编码的设计思想&#xff0c;可以理解为一个东西&#xff0c;实现了依赖注入&#xff0c;也就实现了控制反转&#xff0c;其实&#xff0c;我们在编写代码的时候&#xff0c;自已都可以用过了&#xff0c;但是&#xff0c;我们可以不知道…...

dw网站模板免费下载/如何用html制作一个网页

我使用dofile执行APK文件是不行的&#xff0c;比如 dofile("assets/res/flist")只能先拷贝到writablePath然后再dofile拿到数据后再清除这个临时文件虽然满足需求了&#xff0c;但还是略显奇葩 有一个更好的方案&#xff0c;是使用loadstring local function doFile(…...

网页留言板模板/关键词seo排名优化推荐

实现如下图所示的一个页面布局 布局框架 思路讲解&#xff1a; 1.一开始的思路是使用android提供的画布将布局中的内容花下来&#xff0c;之后想了想觉得比较麻烦&#xff0c;所以又开启了另外一条思路。 2.如上图“布局框架”所示。最外部是一个大布局&#xff08;RelativeLay…...

做网站费用分摊入什么科目/网站搜索排名

1、贝宝贝宝&#xff08;PayPal&#xff09;是一个在1998年首次推出的在线支付服务。贝宝在全球200多个国家运营&#xff0c;支持26种货币&#xff0c;允许用户在网站上进行结帐。贝宝通过浏览器&#xff0c;应用程序或阅读器处理付款&#xff0c;并为客户提供信贷服务。2、Due…...

猪八戒网做网站/seo百科大全

目前很多制造型企业开始进行数字化转型&#xff0c;嫁接了很多提高生产效率的设备&#xff0c;比如MES、ERP、SPC等系统。 这些数据能帮助企业看到当下正在发什么&#xff0c;比如在制品多少&#xff1f;库存多少&#xff1f;损耗多少&#xff1f;但是不能告诉企业为什么会形成…...