【音视频|ALSA】基于alsa-lib开发ALSA应用层程序--附带源码

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭基于alsa-lib开发ALSA应用层程序🍭
😎金句分享😎:🍭盖士人读书,第一要有志,第二要有识,第三要有恒。有志则断不甘为下流,有识则知学问无尽,不敢以一得自足,如河伯之观海,如井蛙之窥天,皆无识者也。有恒则断无不成之事,此三者缺一不可。 ——《曾国藩家书》🍭

【音视频|ALSA】ALSA是什么?ALSA框架详细介绍
【音视频|ALSA】SS528开发板编译Linux内核ALSA驱动、移植alsa-lib、采集与播放usb耳机声音

目录

  • 一、ALSA应用层开发基础知识
  • 二、alsa-lib常用函数
  • 三、编写ALSA应用层程序
    • 3.1 alsa播放程序开发--alsa-playback.c
    • 3.2 alsa录制音频程序开发--alsa-capture.c
  • 四、XRUN( underrun和overrun)
  • 五、总结


在这里插入图片描述

一、ALSA应用层开发基础知识

  • sample:样本,采样点。数字音频最小单位,其大小与位宽有关,一般为8bit(1个字节)、16bit(2个字节);
  • channel:声道,一般单声道(mono)和立体声(stereo),还有一些多声道如5.1声道。
  • frame:帧,一个完整的声音单元,即单次采样的所有声道的数据。frame=sample*channel
    例如:48Khz、16位的立体声PCM流的1帧是4个字节。
  • sample rate:采样率,即每秒的采样次数。如果采样率为48kHz,则说明一秒采样48000帧。
  • period size:周期大小,是每次硬件中断之间的帧数。
  • buffer size:缓冲区大小,必须大于一个周期的大小。一般为周期大小的2倍。单位也是帧数。

在这里插入图片描述

例子:
结合上面的知识点,这里以48kHz、16bit的立体声音频流举例:

  • 16bit则每个样本为2个字节,
  • 立体声表示有2个声道,
  • 48kHz 表示每秒有48000个音频帧。

由此可以计算出每秒钟传输的数据大小:2 * 2 * 48000=192000字节;

现在如果ALSA每秒钟产生一个硬件中断,在每秒结束时,我们需要准备好192000字节;
如果它每半秒中断一次,对于同一个流,我们需要在每次中断时准备好192000/2 = 96000字节;
如果每100毫秒发生一次中断,我们需要在每次中断时准备好192000*(0.1/1) = 19200字节。

我们可以通过设置周期大小(以帧为单位)来控制PCM中断的产生时间。
如果我们将48kHz、16bit的立体声音频流的period size设置为4800帧(也就是480022=19200字节),则每19200字节就会产生一个中断,也就是100ms。
相应地,buffer size至少应为2*period_size = 2*4800= 9600帧(960022 = 38400字节)。

实际编程中,可能需要计算一个周期的总字节数period bytes,就是等于period size乘以每一帧的大小。同样的,buffer的总字节数buffer bytes等于buffer size乘以一帧大小。

如果已知音频的采样率、通道数、位宽、周期数,则buffer sizebuffer timeperiod sizeperiod time 这四个值可以相互推断出来:
以48000Hz采样率、2声道、16bit、4周期来举例,这样的音频流一秒钟的帧数是48000帧,如果buffer size是48000,则buffer time刚好就是一秒;如果buffer time是500ms,则buffer size是24000帧。
period size=buffer size/周期数period time=buffer time/周期数

在这里插入图片描述

二、alsa-lib常用函数

alsa-lib的函数声明在pcm.h,总共可以分为16个模块:

  • PCM Interface
  • Stream Information
  • Hardware Parameters
  • Software Parameters
  • Access Mask Functions
  • Format Mask Functions
  • Subformat Mask Functions
  • Status Functions
  • Description Functions
  • Debug Functions
  • Direct Access (MMAP) Functions
  • Helper Functions
  • Hook Extension
  • Scope Plugin Extension
  • Simple setup functions
  • Deprecated Functions

可以在官方文档查看对应的模块函数说明:
https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html
在这里插入图片描述

下表介绍一些常用的函数:

函数说明
snd_pcm_open根据pcm设备名字打开一个pcm设备
snd_pcm_hw_params_malloc使用标准malloc分配无效的snd_pcm_hw_params_t
snd_pcm_hw_params_any用PCM的完整配置空间填充参数。
snd_pcm_hw_params_set_access将配置空间限制为仅包含一种访问类型。
snd_pcm_hw_params_set_format将配置空间限制为仅包含一种格式。
snd_pcm_hw_params_set_channels将配置空间限制为仅包含一个通道计数。
snd_pcm_hw_params_set_rate_near将配置空间限制为具有最接近目标的速率。
snd_pcm_hw_params_get_buffer_time_max从配置空间中提取最大缓冲时间。
snd_pcm_stream获取PCM句柄的流
snd_pcm_hw_params_set_buffer_time_near限制配置空间以使缓冲时间最接近目标。
snd_pcm_hw_params_set_period_time_near限制配置空间以使周期时间最接近目标。
snd_pcm_hw_params安装从配置空间中选择的一个PCM硬件配置,并调用snd_pcm_prepare。
snd_pcm_nonblock设置非阻塞模式
snd_pcm_hw_params_get_period_size从配置空间中提取周期大小。
snd_pcm_hw_params_get_buffer_size从配置空间中提取周期大小。
snd_pcm_format_physical_width返回存储PCM样本所需的位。

更多函数说明参考:
https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___h_w___params.html
https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html
在这里插入图片描述

三、编写ALSA应用层程序

这小节介绍简单的ALSA应用程序开发流程,以及给出例子源码。

在编写代码前,可以先使用cat /proc/asound/card0/stream0查看ALSA设备支持的参数:

# cat /proc/asound/card0/stream0 
Rapoo Gaming Headset at usb-10300000.xhci_0-1.1, full speed : USB AudioPlayback:Status: StopInterface 1Altset 1Format: S16_LEChannels: 2Endpoint: 1 OUT (ADAPTIVE)Rates: 48000, 44100Capture:Status: StopInterface 2Altset 1Format: S16_LEChannels: 1Endpoint: 2 IN (ASYNC)Rates: 48000, 44100

Playback:播放设备
Capture:录音设备
Interface:接口序号
Format:格式
Channels:通道数
Rates:支持的采样率

3.1 alsa播放程序开发–alsa-playback.c

开发流程:

  • 1、打开设备:调用 snd_pcm_open,指定类型为SND_PCM_STREAM_PLAYBACK,以及设备名称,打开设备;
  • 2、设置硬件参数
    设置存取方式、格式、通道数、采样率、缓冲时间、周期时间,最后将参数写入设备;
    如果有一些参数不清楚怎么设置,可以使用命令cat /proc/asound/card0/stream0查看支持的参数:
  • 3、播放音频
    每次往alsa驱动写入一个周期大小的字节,不足一周期的要填0;
  • 4、释放资源,关闭设备

下面是一个非常简单的ALSA播放音频的代码,复制后保存为alsa-playback.c,使用命令aarch64-mix210-linux-gcc alsa-playback.c -I /usr/lib/alsa-lib-1.2.10/include/ -L /usr/lib/alsa-lib-1.2.10/lib/ -l asound -lpthread -ldl -lm -o alsa-playback 已编译通过。

48000Hz-16bit-2ch-ChengDu.pcm 文件下载:https://download.csdn.net/download/wkd_007/88421282

// alsa-playback.c
// aarch64-mix210-linux-gcc alsa-playback.c -I /usr/lib/alsa-lib-1.2.10/include/ -L /usr/lib/alsa-lib-1.2.10/lib/ -l asound -lpthread -ldl -lm -o alsa-playback/*
* snd_pcm_hw_params_alloca 申请的内存在函数返回后会自动释放,不需要手动释放。这个函数会在栈上分配一块内存,函数返回后,栈上的内存会自动被回收。
*/
#include <stdio.h>
#include <alsa/asoundlib.h>#define PCM_NAME	"hw:0,0"
#define PLAYBACK_FILE "48000Hz-16bit-2ch-ChengDu.pcm"snd_pcm_hw_params_t *hw_params;
static unsigned int rate = 48000;           /* stream rate */int set_hw_params(snd_pcm_t *handle, int format, int channels, snd_pcm_uframes_t *period_frames)
{int err = -1;// 分配硬件参数空间,调用 alloca 在栈分配内存,函数结束后自动释放,不需要调用 snd_pcm_hw_params_freesnd_pcm_hw_params_alloca(&hw_params);//1、以默认值填充硬件参数if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) {return err;}//2、 Restrict a configuration space to contain only real hardware rates.if ((err = snd_pcm_hw_params_set_rate_resample(handle, hw_params, 0)) < 0) {return err;}//3、设置存取方式为交叉存储if ((err = snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {return err;}//4、设置格式,S16_LE等if ((err = snd_pcm_hw_params_set_format(handle, hw_params, format)) < 0) {return err;}//5、设置通道if ((err = snd_pcm_hw_params_set_channels(handle, hw_params, channels)) < 0) {return err;}//6、大致设置采样率unsigned int rrate;rrate =rate;if ((err = snd_pcm_hw_params_set_rate_near(handle, hw_params, &rrate, NULL)) < 0) 	   {return err;}//7、设置缓冲时间unsigned int buffer_time, period_time;// 先获取缓存时间if((err = snd_pcm_hw_params_get_buffer_time_max(hw_params, &buffer_time, 0))<0){return err;}if (buffer_time > 500000){buffer_time = 500000; // 500ms读取完整个buffer,结合下面代码一个周期就是 buffer_time/4=125ms,每个周期会产生一个中断printf("[%s %d] buffer_time=%d, irq=%d\n",__FILE__,__LINE__,buffer_time, buffer_time/4);}// 设置缓冲时间if ((err = snd_pcm_hw_params_set_buffer_time_near(handle, hw_params, &buffer_time, 0)) < 0) {return err;}// 8、设置周期时间,也就是中断时间period_time = buffer_time / 4;if ((err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &period_time, 0)) < 0) {return err;}// 9、将参数写入设备if ((err = snd_pcm_hw_params(handle, hw_params)) < 0){return err;}snd_pcm_uframes_t buffer_frames;snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_frames);if(period_frames != NULL) {//获取一个周期有多少帧数据if((err =snd_pcm_hw_params_get_period_size(hw_params, period_frames, 0)) < 0){printf("cannot get period size (%s)\n", snd_strerror(err));return err;}}if(err = (snd_pcm_nonblock(handle, 1) < 0)){return err;}// 10、释放 snd_pcm_hw_params_malloc 分配的内存//snd_pcm_hw_params_free(hw_params);return 0;
}int main()
{int err = -1;snd_pcm_t *playback_handle;snd_pcm_uframes_t period_frames; // 一周期的帧数// 1、打开设备if((err = snd_pcm_open(&playback_handle, PCM_NAME, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {printf("cannot snd_pcm_open (%s)\n",snd_strerror(err));return -1;}// 2、设置硬件参数set_hw_params(playback_handle, SND_PCM_FORMAT_S16_LE, 2, &period_frames);// 3、播放音频// 3.1 打开pcm文件int fd = open(PLAYBACK_FILE,O_RDONLY,0644);if(fd < 0){printf("open %s error!!!\n",PLAYBACK_FILE);return -1;}// 3.2 获取一周期的字节数const int period_bytes = snd_pcm_frames_to_bytes(playback_handle,period_frames);char *playback_buf = malloc(period_bytes);// 3.3 循环播放音频int readframes = 0;while(readframes = read(fd, playback_buf, period_bytes)) {//解决最后一个周期数据问题if(readframes < period_bytes) {memset(playback_buf+readframes, 0, period_bytes-readframes);}//向PCM写入数据,播放err = snd_pcm_writei(playback_handle, playback_buf, period_frames);if(err == -EPIPE) {snd_pcm_prepare(playback_handle);fprintf(stderr, "<<< snd_pcm_writei --> Buffer Underrun >>> \n");err = snd_pcm_writei(playback_handle, playback_buf, period_frames);if(err != period_frames) {printf("write to audio interface failede err:%d (period_frames:%d)\n",err,period_frames);break;}}else if(err != period_frames) {printf("write to audio interface failede err:%d (period_frames:%d)\n",err,period_frames);break;}//printf("process:playback wrote %d frames\n",period_frames);//usleep(100*1000);usleep(130*1000); //测试用,超过 125ms,会报错 Underrun}// 4.释放资源,关闭设备free(playback_buf);close(fd);snd_pcm_close(playback_handle);return 0;
}

3.2 alsa录制音频程序开发–alsa-capture.c

开发流程:

  • 1、打开设备:调用 snd_pcm_open,指定类型为SND_PCM_STREAM_CAPTURE,以及设备名称,打开设备;
  • 2、设置硬件参数
    设置存取方式、格式、通道数、采样率、缓冲时间、周期时间,最后将参数写入设备;
    如果有一些参数不清楚怎么设置,可以使用命令cat /proc/asound/card0/stream0查看支持的参数:
  • 3、读取音频
    每次从alsa驱动读取一个周期大小的字节;
  • 4、释放资源,关闭设备
// alsa-capture.c
// aarch64-mix210-linux-gcc alsa-capture.c -I /usr/lib/alsa-lib-1.2.10/include/ -L /usr/lib/alsa-lib-1.2.10/lib/ -l asound -lpthread -ldl -lm -o alsa-capture/*
* snd_pcm_hw_params_alloca 申请的内存在函数返回后会自动释放,不需要手动释放。这个函数会在栈上分配一块内存,函数返回后,栈上的内存会自动被回收。
*/
#include <stdio.h>
#include <alsa/asoundlib.h>#define PCM_NAME	"hw:0,0"
#define CAPTURE_FILE "alsa-capture.pcm"snd_pcm_hw_params_t *hw_params;
static unsigned int rate = 48000;           /* stream rate */int set_hw_params(snd_pcm_t *handle, int format, int channels, snd_pcm_uframes_t *period_frames)
{int err = -1;// 分配硬件参数空间,调用 alloca 在栈分配内存,函数结束后自动释放,不需要调用 snd_pcm_hw_params_freesnd_pcm_hw_params_alloca(&hw_params);//1、以默认值填充硬件参数if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) {return err;}//2、 Restrict a configuration space to contain only real hardware rates.if ((err = snd_pcm_hw_params_set_rate_resample(handle, hw_params, 0)) < 0) {return err;}//3、设置存取方式为交叉存储if ((err = snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {return err;}//4、设置格式,S16_LE等if ((err = snd_pcm_hw_params_set_format(handle, hw_params, format)) < 0) {return err;}//5、设置通道if ((err = snd_pcm_hw_params_set_channels(handle, hw_params, channels)) < 0) {return err;}//6、大致设置采样率unsigned int rrate;rrate =rate;if ((err = snd_pcm_hw_params_set_rate_near(handle, hw_params, &rrate, NULL)) < 0) 	   {return err;}//7、设置缓冲时间unsigned int buffer_time, period_time;// 先获取缓存时间if((err = snd_pcm_hw_params_get_buffer_time_max(hw_params, &buffer_time, 0))<0){return err;}if (buffer_time > 500000){buffer_time = 500000; // 500ms写完整个buffer,结合下面代码一个周期就是 buffer_time/4=125ms,每个周期会产生一个中断printf("[%s %d] buffer_time=%d, irq=%d\n",__FILE__,__LINE__,buffer_time, buffer_time/4);}// 设置缓冲时间if ((err = snd_pcm_hw_params_set_buffer_time_near(handle, hw_params, &buffer_time, 0)) < 0) {return err;}// 8、设置周期时间,也就是中断时间period_time = buffer_time / 4;if ((err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &period_time, 0)) < 0) {return err;}// 9、将参数写入设备if ((err = snd_pcm_hw_params(handle, hw_params)) < 0){return err;}snd_pcm_uframes_t buffer_frames;snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_frames);if(period_frames != NULL) {//获取一个周期有多少帧数据if((err =snd_pcm_hw_params_get_period_size(hw_params, period_frames, 0)) < 0){printf("cannot get period size (%s)\n", snd_strerror(err));return err;}}if(err = (snd_pcm_nonblock(handle, 1) < 0)){return err;}// 10、释放 snd_pcm_hw_params_malloc 分配的内存//snd_pcm_hw_params_free(hw_params);return 0;
}int main()
{int err = -1;snd_pcm_t *capture_handle;snd_pcm_uframes_t period_frames; // 一周期的帧数// 1、打开设备if((err = snd_pcm_open(&capture_handle, PCM_NAME, SND_PCM_STREAM_CAPTURE, 0)) < 0) {printf("cannot snd_pcm_open (%s)\n",snd_strerror(err));return -1;}// 2、设置硬件参数set_hw_params(capture_handle, SND_PCM_FORMAT_S16_LE, 1, &period_frames);// 3、获取音频// 3.1 打开录制文件int fd = open(CAPTURE_FILE,O_RDWR | O_TRUNC | O_CREAT,0644);if(fd < 0){printf("open %s error!!!\n",CAPTURE_FILE);return -1;}// 3.2 获取一周期的字节数const int period_bytes = snd_pcm_frames_to_bytes(capture_handle,period_frames);char *capture_buf = malloc(period_bytes);int count = 100; // 捕获100个周期int readframes = 0;while(count--) {//向PCM读一周期数据memset(capture_buf,0,period_bytes);if((readframes = snd_pcm_readi(capture_handle, capture_buf, period_frames)) < 0) {if(readframes == -EPIPE)printf("read from audio interface failed (%d), overrun, Need to read faster\n",readframes);elseprintf("read from audio interface failed (%d)\n",readframes);break;}printf("--process:capture read %d frames\n",readframes);write(fd,capture_buf,snd_pcm_frames_to_bytes(capture_handle,readframes));usleep(100*1000); //usleep(130*1000); //测试用,超过 125ms,会报错 overrun}// 4、释放资源,关闭设备free(capture_buf);close(fd);snd_pcm_close(capture_handle);return 0;
}

在这里插入图片描述

四、XRUN( underrun和overrun)

在 ALSA 数据传输中,最容易出现的错误是 underrun 和 overrun。

  • underrun:pcm 播放的时候,接口 snd_pcm_writei 返回 -EPIPE,为 underrun(不足)
    出现这问题原因是应用准备的音频数据不够,比如,驱动需要播放需要 1026 帧数据,但应用只准备好了 1024 帧。可以根据采样率和buffer sizeperiod size去调整;
  • overrun:录制音频的时候, 接口 snd_pcm_readi 返回 -EPIPE, 为 overrun(超载)
    alsa驱动一直往buffer里面写,但应用程序却读取的很慢,例如:驱动写了1026帧,而应用层只读取了1024帧。需要加快读取速度。或者调整buffer sizeperiod size

在这里插入图片描述

五、总结

文章介绍了alsa的基础知识,以及基于alsa-lib开发ALSA应用层程序的开发流程和alsa开发过程钟常见的报错,提供了简单的alsa应用层代码。


参考资料:
ALSA官网资料——FramesPeriods:https://alsa-project.org/main/index.php/FramesPeriods
【Linux&音频】Alsa音频编程【精华】:https://blog.csdn.net/u012183924/article/details/53407668
ALSA 音频数据传输 underrun 和 overrun:https://blog.csdn.net/qq_38350702/article/details/111995039
Linux应用开发【第八章】ALSA应用开发:https://blog.csdn.net/thisway_diy/article/details/121809633

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下等待队列、定时器、中断综合应用——按键控制LED

本文通过按键控制LED的亮灭&#xff0c;按键每按一次&#xff0c;LED的状态就发生一次变化。 等待队列是为了在按键有动作发生时再读取按键值&#xff0c;而不是一直读取按键的值&#xff0c;使得CPU的占用率很高。 定时器在本实验中引入是为了按键消抖&#xff0c;在键值稳定了…

手写一个PrattParser基本运算解析器1: 编译原理概述

点击查看 基于Swift的PrattParser项目 编译原理概述 编译原理是我们每一个程序猿必须要了解的技能, 编译原理实际上并没有啥高深的技术, 我们如果在做业务开发, 也很少会用到编译开发的知识, 但是编译原理又是我们必备的基础知识之一. 所以我们需要对编译原理的内容有一个大概的…

【PXIE301-211】基于PXIE总线的16路并行LVDS数据采集、4路低速、2路隔离RS422数据处理平台

板卡概述 PXIE301-211A是一款基于PXIE总线架构的16路高速LVDS、4路低速LVDS采集、2路隔离RS422数据处理平台&#xff0c;该平台板卡采用Xilinx的高性能Kintex 7系列FPGA XC7K325T作为实时处理器&#xff0c;实现各个接口之间的互联。板载1组64位的DDR3 SDRAM用作数据缓存。板卡…

[Hive] explode

在 Hive 中&#xff0c;explode 函数用于将数组&#xff08;Array&#xff09;或者Map类型的列拆分成多行&#xff0c; 每个元素或键值对为一行。这允许我们在查询中对数组或 Map 进行扁平化操作。 下面是使用 explode 函数的示例&#xff1a; 假设我们有一个包含数组字段的表…

pycharm操作git

pycharm操作git 之前用命令做的所有操作&#xff0c;使用pychrm点点就可以完成 克隆代码 上方工具栏Git ⇢ \dashrightarrow ⇢ Clone ⇢ \dashrightarrow ⇢ 填写地址&#xff08;http、ssh&#xff09; 提交到暂存区&#xff0c;提交到版本库&#xff0c;推送到远程 直接…

HTTP和HTTPS

目录 HTTP协议 1.HTTP协议 2.HTTP请求 URL 方法 GET请求 post请求 header报头 请求正文&#xff08;body&#xff09; 3.HTTP响应 结构 常见的状态码 4.form表单构造HTTP请求 5.通过ajax构造HTTP请求 6.使用工具postman ​编辑 HTTPS 1.对称加密 2.非对称加密…

填充颜色游戏

无语死了这题。 题目描述 小明最近迷上下面一款游戏。游戏开始时&#xff0c; 系统将随机生成一个 N N 的 正方形棋盘&#xff0c; 棋盘的每个格子都由六种颜色中的一种绘制。在每个步骤中&#xff0c; 玩家选择一种颜色&#xff0c; 并将与左上角连接的所有网格更改为该特…

jenkins 安装与使用、用户权限划分

jenkins 安装与使用 安装插件&#xff1a; 开启该插件功能 验证用户管理 创建web01~02 使用web01登录 用户权限划分 安装 Role-Based Strategy 插件后&#xff0c;系统管理 中多了如图下所示的一个功能&#xff0c;用户权限的划分就是靠他来做的 创建角色 重新访问 创建项目…

Zabbix“专家坐诊”第207期问答汇总

问题一 Q&#xff1a;不小心把host表删除了&#xff0c;怎么处理&#xff1f;现在使用的zabbix 4.0.3的server&#xff0c;agent是4.2.1&#xff0c;能不能不动agent的情况下升级server版本&#xff0c;重新部署&#xff1f; A&#xff1a;数据库有备份话恢复即可&#xff0c;…

SSTI模板注入(flask) 学习总结

文章目录 Flask-jinja2 SSTI 一般利用姿势SSTI 中常用的魔术方法内建函数 利用 SSTI 读取文件Python 2Python 3 利用 SSTI 执行命令寻找内建函数 eval 执行命令寻找 os 模块执行命令寻找 popen 函数执行命令寻找 importlib 类执行命令寻找 linecache 函数执行命令寻找 subproce…

windows中elasticsearch7中添加用户名密码验证

1.找到elsatic的bin目录输入cmd 2.生成ca证书 输入 elasticsearch-certutil ca 在es7根目录生成ca证书&#xff0c;输入密码时直接回车即可&#xff0c;否则后面会报错 Please enter the desired output file [elastic-stack-ca.p12]: #这里直接回车即可 Enter password for…

JAVA学习日记1——JAVA简介及第一个java程序

简单记忆 JAVA SE &#xff1a;标准版&#xff0c;核心基础 JAVA EE&#xff1a;企业版&#xff0c;进阶 JDK&#xff1a;Java Development Kit&#xff0c;Java开发工具包&#xff0c;包含JRE JRE&#xff1a;Java Runtime Environment&#xff0c;Java运行时环境&#xff…

手撕 视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (2)

上一篇文章中: 手撕ch7/pose_estimation_3d2d&#xff08;1&#xff09;&#xff0c;我们调用了epnp的方法进行位姿估计&#xff0c;这里我们使用非线性优化的方法来求解位姿&#xff0c;使用g2o进行BA优化 首先介绍g2o&#xff1a;可参考&#xff1a;g2o详细介绍 1.构建g2o图…

加权平均、EMD、小波等方法去噪效果对比

加权平均、EMD、小波等方法去噪效果对比 代码 整体代码如下 %% clear all; clc;load(data_filter120Hz.mat); %可自己生成随机噪声 fs1000;%采样频率是1000Hz %% %生成正弦波信号 tlinspace(0, length(data)/fs-1/fs, length(data)); y1 15*sin(2*pi* 2.8 *t);%生成频率为2.…

Android之使用QBadgeView给TabLayout顶部栏设置数量角标,数值可更新

TabLayout搭配ViewPager、Fragement使用可看另一篇文章&#xff1a; Android中TabLayoutViewPagerFragment实现顶部导航栏 本文主要描述给TabLayout的某一栏添加角标&#xff0c;数值可更新&#xff1a; 一、效果 二、TabLayout使用 1、xml文件中 <com.google.android.m…

通讯协议学习之路:QSPI协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 一、…

【Django 01】环境搭配与项目配置

1. 介绍 https://github.com/Joe-2002/sweettalk-django4.2#readme Django 是一个使用 Python 编写的开源 Web 应用程序框架&#xff0c;它提供了一套用于快速开发安全、 可扩展和高效的 Web 应用程序的工具和功能。Django 基于 MVC&#xff08;Model-View-Controller&#xf…

Windows11家庭版没有本地组策略编辑器解决

1. 新建一个文本文件将下面代码粘到里面&#xff0c;保存后修改后缀为.cmd或者.bat echo off pushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt dir /b C:\Windows\servicing\Packa…

redis(普通连接和连接池、字符串类型、hash类型、列表类型)

1 redis普通连接和连接池 1.1 普通连接 1.2 连接池 2 redis字符串类型 3 redis hash类型 4 redis列表类型 1 redis普通连接和连接池 #1 python 代码作为客户端---》连接# 2 安装模块&#xff1a;pip install redis1.1 普通连接 from redis import Redisconn Redis(host&qu…

Selenium浏览器自动化怎么上传文件

Selenium 封装了现成的文件上传操作。但是随着现代前端框架的发展&#xff0c;文件上传的方式越来越多样。而有一些文件上传的控件&#xff0c;要做自动化控制会更复杂一些&#xff0c;这篇文章主要讨论在复杂情况下&#xff0c;如何通过自动化完成文件上传。 1. input 元素上传…