音频录制以及播放

2023-10-29

音频录制以及播放

象棋小子          1048272975

一般的音频应用中,往往需要支持音频的拾取输入以及音频的播放输出。LPC5411x具有I2S音频接口以及双通道PDM数字麦克风接口,其中数字麦克风接口支持芯片深度睡眠时的语音激活,非常适合于音频,尤其是低功耗音频的应用。

1. I2S

LPC5411x内置了8个Flexcomm接口用于支持串行外设,其中Flexcomm 6和Flexcomm 7可以配置成I2S接口。每个I2S接口只能支持音频的半双工传输,即I2S数据口只能配置成输入或者输出。万利的LCP5411x开发板板载了一颗WM8904音频编解码器,支持Line in输入以及耳机输出,通过Flexcomm 7连接音频输出流,Flexcomm 6连接音频输入流,从而构成I2S的全双工传输。

I2S的初始化过程如下:

a.   在pin_mux.c中初始化I2S的功能引脚。

// I2S FC6

uint32_t i2s_config = {

IOCON_FUNC1 |

IOCON_MODE_INACT|

IOCON_DIGITAL_EN|

IOCON_INPFILT_OFF

};     

IOCON_PinMuxSet(IOCON, 0, 5,i2s_config); // PIO0_5 DATAO

IOCON_PinMuxSet(IOCON, 0, 6,i2s_config); // PIO0_6 WSO

IOCON_PinMuxSet(IOCON, 0, 7,i2s_config); // PIO0_7 BCKO

// FC7

i2s_config = IOCON_FUNC4 |   IOCON_MODE_INACT |

IOCON_DIGITAL_EN | IOCON_INPFILT_OFF;    

IOCON_PinMuxSet(IOCON, 1, 12,i2s_config); // PIO1_12 BCKI

IOCON_PinMuxSet(IOCON, 1, 13,i2s_config); // PIO1_13 DATAI

IOCON_PinMuxSet(IOCON, 1, 14,i2s_config); // PIO1_14 WSI

IOCON_PinMuxSet(IOCON, 1, 17,i2s_config); // PIO1_17 MCKL

b.   设置I2S外设时钟,使用PLL时钟,24.576MHz。

const pll_setup_t pllSetup = {

.syspllctrl =SYSCON_SYSPLLCTRL_BANDSEL_MASK | SYSCON_SYSPLLCTRL_SELP(0x1FU) |SYSCON_SYSPLLCTRL_SELI(0x8U),

.syspllndec =SYSCON_SYSPLLNDEC_NDEC(0x2DU),

.syspllpdec =SYSCON_SYSPLLPDEC_PDEC(0x42U),

.syspllssctrl= {SYSCON_SYSPLLSSCTRL0_MDEC(0x34D3U) | SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK,0x00000000U},

.pllRate =24576000U,

.flags =PLL_SETUPFLAG_WAITLOCK};

 

/* InitializePLL clock */

CLOCK_AttachClk(kFRO12M_to_SYS_PLL);

CLOCK_SetPLLFreq(&pllSetup);

 

/* I2S clocks*/

CLOCK_AttachClk(kSYS_PLL_to_FLEXCOMM6);

CLOCK_AttachClk(kSYS_PLL_to_FLEXCOMM7);

c.   设置I2S的主时钟MCLK输出,1分频,MCLK输出24.576MHz时钟。

/* Attach PLLclock to MCLK for I2S, no divider */

CLOCK_AttachClk(kSYS_PLL_to_MCLK);

SYSCON->MCLKDIV= SYSCON_MCLKDIV_DIV(0U);

SYSCON->MCLKIO= 1U;

d.   设置I2S1为主机模式,相应的数据格式,并初始化。I2S1的寄存器基址对应Flexcomm 7的寄存器基址,在主机模式,由主机产生位时钟、帧时钟这些同步时钟,通过I2STxConfig.divider分频决定I2S的位时钟,在48分频时,位时钟为24.576MHz / 48 =512KHz,16位长,双通道对应的采样率为24.576MHz / 48 / 16 / 2 = 16K。

   /*

    * masterSlave = kI2S_MasterSlaveNormalMaster;

    * mode = kI2S_ModeI2sClassic;

    * rightLow = false;

    * leftJust = false;

    * pdmData = false;

    * sckPol = false;

    * wsPol = false;

    * divider = 1;

    * oneChannel = false;

    * dataLength = 16;

    * frameLength = 32;

    * position = 0;

    * fifoLevel = 4;

    */

I2S_TxGetDefaultConfig(&I2STxConfig);

I2STxConfig.divider = 48; //24576000/16/2/48=16k

I2S_TxInit(I2S1, &I2STxConfig);

e.   设置I2S0为从机模式,相应的数据格式,并初始化。I2S0的寄存器基址对应Flexcomm 6的寄存器基址,在从机模式,从机的位时钟、帧时钟同步到主机的位时钟、帧时钟。

   /*

    * masterSlave = kI2S_MasterSlaveNormalSlave;

    * mode = kI2S_ModeI2sClassic;

    * rightLow = false;

    * leftJust = false;

    * pdmData = false;

    * sckPol = false;

    * wsPol = false;

    * divider = 1;

    * oneChannel = false;

    * dataLength = 16;

    * frameLength = 32;

    * position = 0;

    * watermark = 4;

    * txEmptyZero = false;

    * pack48 = true;

    */

I2S_RxGetDefaultConfig(&I2SRxConfig);

I2S_RxInit(I2S0, &I2SRxConfig);

f.    设置I2S的DMA通道传输,DMA传输可以减少CPU对音频流的参与处理,从而降低CPU的负载。通常音频数据的处理以帧为单位,方便音频编解码,打包传输等处理,当DMA完成一帧缓存传输时,通过中断通知CPU处理下一帧缓存的DMA传输。

DMA_EnableChannel(DMA0, I2S_TX_CHANNEL);

DMA_EnableChannel(DMA0, I2S_RX_CHANNEL);

DMA_SetChannelPriority(DMA0,I2S_TX_CHANNEL, kDMA_ChannelPriority3);

DMA_SetChannelPriority(DMA0,I2S_RX_CHANNEL, kDMA_ChannelPriority2);

DMA_CreateHandle(&I2STxDmaHandle,DMA0, I2S_TX_CHANNEL);

DMA_CreateHandle(&I2SRxDmaHandle,DMA0, I2S_RX_CHANNEL);

I2S_TxTransferCreateHandleDMA(I2S1,&I2STxHandle, &I2STxDmaHandle, I2STxCallback, (void*)&I2STxTransfer);

I2S_RxTransferCreateHandleDMA(I2S0,&I2SRxHandle, &I2SRxDmaHandle, I2SRxCallback, (void*)&I2SRxTransfer);

g.   I2S准备就绪后,可以通过I2S_TxStart()函数启动输出帧缓存到音频输出流的DMA传输,通过I2S_RxStart()函数启动音频输入流到输入帧缓存的DMA传输。

void I2S_TxStart(void)

{

I2SState.TxReadIndex = 0;

I2STxTransfer.data = (volatile uint8_t*)I2SState.TxBuffer[0];

I2STxTransfer.dataSize =sizeof(I2SState.TxBuffer[0]);

I2S_TxTransferSendDMA(I2S1,&I2STxHandle, I2STxTransfer);

I2SState.TxWriteIndex = 1;

I2S_TxTransferSendDMA(I2S1,&I2STxHandle, I2STxTransfer);

}

 

void I2S_RxStart(void)

{

I2SState.RxWriteIndex = 0;

I2SRxTransfer.data = (volatile uint8_t*)I2SState.RxBuffer[0];

I2SRxTransfer.dataSize = sizeof(I2SState.RxBuffer[0]);

I2S_RxTransferReceiveDMA(I2S0,&I2SRxHandle, I2SRxTransfer);

I2SState.RxWriteIndex = 1;

I2SRxTransfer.data = (volatile uint8_t*)I2SState.RxBuffer[1];

I2S_RxTransferReceiveDMA(I2S0,&I2SRxHandle, I2SRxTransfer);

}

2. 音频编解码器

开发板板载了WM8904音频编解码器,通过I2C设置WM8904内部寄存器,设置为从机模式,相应的数据格式。

a.   在pin_mux.c中初始化I2C的功能引脚。

const uint32_t i2c_config = (

IOCON_FUNC5 |

IOCON_DIGITAL_EN|

IOCON_INPFILT_OFF|

IOCON_OPENDRAIN_EN

);

IOCON_PinMuxSet(IOCON,1, 1, i2c_config); // PIO1_1 SCL

IOCON_PinMuxSet(IOCON,1, 2, i2c_config); // PIO1_2 SDA

b.   设置I2C外设时钟,使用FRO时钟12MHz。

/* I2C clock */

CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);

/* reset FLEXCOMM for I2C */

RESET_PeripheralReset(kFC4_RST_SHIFT_RSTn);      

c.   设置I2C为主机模式,相应的波特率,并初始化。

   /*

    * enableMaster = true;

    * baudRate_Hz = 100000U;

    * enableTimeout = false;

    */

I2C_MasterGetDefaultConfig(&i2cConfig);

i2cConfig.baudRate_Bps =WM8904_I2C_BITRATE;

I2C_MasterInit(I2C4, &i2cConfig,12000000);

d.   初始化WM8904音频编解码器。

WM8904_GetDefaultConfig(&codecConfig);

codecHandle.i2c = I2C4;

if (WM8904_Init(&codecHandle,&codecConfig) != kStatus_Success) {

PRINTF("WM8904_Initfailed!\r\n");

return;

}

/* Adjust it to your needs, 0x0006 for-51 dB, 0x0039 for 0 dB etc. */

WM8904_SetVolume(&codecHandle,0x0030, 0x0030);

3. DMIC

DMIC (digital microphoneinterface)支持PDM输出的数字麦克风接口。开发板板载了SPH0641LM4H数字麦克风,从数字麦克风获取的PDM数据可以通过一系列的滤波器还原出相应的波形,再采样获得对应的PCM数据。PCM采样率由DMIC时钟以及过采样率(OSR)决定,采样率公式如下:

例如,DMIC的时钟800KHz,过采样率OSR为25,在2 FS模式,对应的PCM采样率为16K。

a.   在pin_mux.c中初始化DMIC的功能引脚。

const uint32_t dmic_config = (

IOCON_FUNC1| 

IOCON_MODE_INACT|

IOCON_DIGITAL_EN|

IOCON_INPFILT_OFF

);

IOCON_PinMuxSet(IOCON,1, 15, dmic_config); // PIO1_15 PDM0_CLK

IOCON_PinMuxSet(IOCON,1, 16, dmic_config); // PIO1_16 PDM0_DATA

b.   设置DMIC外设时钟FRO时钟12MHz,相应的接口时钟800KHz。

/* DMIC uses 12MHz FRO clock */

CLOCK_AttachClk(kFRO12M_to_DMIC);

 

/*12MHz divided by 15 = 800KHz PDM clock*/

CLOCK_SetClkDiv(kCLOCK_DivDmicClk, 15,false);

c.   设置DMIC过采样率,相应的增益,16位数据,并初始化。

dmic_channel_cfg.divhfclk =kDMIC_PdmDiv1;

dmic_channel_cfg.osr = 25U;

dmic_channel_cfg.gainshft = 3U;

dmic_channel_cfg.preac2coef =kDMIC_CompValueZero;

dmic_channel_cfg.preac4coef =kDMIC_CompValueZero;

dmic_channel_cfg.dc_cut_level =kDMIC_DcCut155;

dmic_channel_cfg.post_dc_gain_reduce =1U;

dmic_channel_cfg.saturate16bit = 1U;

dmic_channel_cfg.sample_rate =kDMIC_PhyFullSpeed;

DMIC_Init(DMIC0);

DMIC_ConfigIO(DMIC0, kDMIC_PdmDual);

DMIC_Use2fs(DMIC0, true);

DMIC_SetOperationMode(DMIC0,kDMIC_OperationModeDma);

DMIC_ConfigChannel(DMIC0,kDMIC_Channel0, kDMIC_Left, &dmic_channel_cfg);

DMIC_FifoChannel(DMIC0, kDMIC_Channel0,FIFO_DEPTH, true, true);

d.   设置DMIC的DMA传输通道。

DMA_EnableChannel(DMA0, DMAREQ_DMIC0);

DMA_CreateHandle(&DmicDmaHandle,DMA0, DMAREQ_DMIC0);

DMIC_TransferCreateHandleDMA(DMIC0,&DmicHandle, DMIC_Callback, &DmicTransfer, &DmicDmaHandle); 

DMA_SetChannelPriority(DMA0,DMAREQ_DMIC0, kDMA_ChannelPriority2);

e.   DMIC准备好后,可以通过Dmic_Start()函数启动DMIC音频输入流到帧输入缓存的DMA传输。

void Dmic_Start(void)

{

DmicTransfer.data = (uint16_t*)DmicState.Buffer;

DmicTransfer.dataSize = sizeof(DmicState.Buffer[0]);

DMIC_TransferReceiveDMA(DMIC0,&DmicHandle, &DmicTransfer, kDMIC_Channel0);

DMIC_EnableChannnel(DMIC0,DMIC_CHANEN_EN_CH0(1));           

}

4. 应用例程

main函数例程实现把音频编解码器输入流DMA传输到音频输入缓存,音频输入缓存不经过任何处理,直接输出到音频输出缓存,DMA再把输出缓存传输到音频编解码器输出流中,实现音频编解码器Line in的回放。也可以把数字麦克分的输入流DMA传输到麦克风输入缓存,并拷贝到音频输出缓存,DMA传输到音频编解码器输出流中,实现数字麦克风的拾取回放。

int main(void)

{    

int i;

int Select;

      

/* Board pin, clock, debug console init*/

CLOCK_EnableClock(kCLOCK_InputMux);

CLOCK_EnableClock(kCLOCK_Gpio0);

CLOCK_EnableClock(kCLOCK_Gpio1);

 

/* USART0 clock */

CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

BOARD_InitPins();

BOARD_BootClockFROHF96M();

BOARD_InitDebugConsole();

      

Gpio_Init();

DMA_Init(DMA0);

I2S_Init();

Codec_Init();

Dmic_Init(); 

I2S_TxStart();

      

Select = 1;

if (Select) {

// codec linein

I2S_RxStart();

       while(1) {

       if(I2SState.RxEvent) {

       for(i=0; i<AUDIO_FRAME_SIZE; i++) {

I2SState.TxBuffer[I2SState.TxWriteIndex][i]= I2SState.RxBuffer[I2SState.RxReadIndex][i];

       }

       if(I2SState.RxReadIndex >= AUDIO_NUM_BUFFERS-1) {

              I2SState.RxReadIndex= 0;

       }else {

              I2SState.RxReadIndex++;

       }

       if(I2SState.TxWriteIndex >= AUDIO_NUM_BUFFERS-1) {

              I2SState.TxWriteIndex= 0;

       }else {

              I2SState.TxWriteIndex++;

       }

              I2SState.RxEvent= 0;

       }

       }

} else {

       //digital mic

       Dmic_Start();

       while(1) {

       if(DmicState.Event) {

              for(i=0; i<AUDIO_FRAME_SIZE; i++) {

I2SState.TxBuffer[I2SState.TxWriteIndex][i]= DmicState.Buffer[DmicState.ReadIndex][i];

              }

              if(DmicState.ReadIndex >= AUDIO_NUM_BUFFERS-1) {

                     DmicState.ReadIndex= 0;

              }else {

                     DmicState.ReadIndex++;

              }

              if(I2SState.TxWriteIndex >= AUDIO_NUM_BUFFERS-1) {

                     I2SState.TxWriteIndex= 0;

              }else {

                     I2SState.TxWriteIndex++;

              }

              DmicState.Event= 0;

       }

       }

}

}

5. 附录

附件为音频录制以及播放的MDK工程,相应的文档。

http://pan.baidu.com/s/1mh7Bbk8

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

音频录制以及播放 的相关文章

  • Linux网络编程:Web服务器

    文章目录 一 超文本编辑语言HTML 二 HTTP超文本传输协议 1 请求和响应消息流程 myhttpd c getline函数 用于读取http协议头 2 错误 2 1 处理出错返回disconnect 2 2 错误页面展示send er
  • 【机器学习】:梯度提升决策树(GBDT)

    综述 GBDT Gradient Boosting Decision Tree 又叫 MART Multiple Additive Regression Tree 是一种迭代的决策树算法 该算法由多棵决策树组成 所有树的结论累加起来做最终答
  • 深度解读Q_D指针与Q_Q指针

    首先是Q D指针 先贴上我们的测试用例 class TEST class TESTPrivate public TESTPrivate TEST parent q ptr parent a 666 cout lt lt TESTPrivat
  • 【C++】初阶 --- 引用(超级详细版!!!)

    文章目录 一 引用的概念 二 引用的特性 1 引用在定义时必须初始化 2 一个变量可以有多个引用 3 引用一旦引用一个实体 再不能引用其他实体 三 常引用 被const 修饰的引用 1 权限的放大 2 权限的平移 3 权限的缩小 4 临时变
  • Java 字符串Base64编码和解码

    编码 String message 我是码农 String encode Base64 getEncoder encodeToString message getBytes StandardCharsets UTF 8 方式一 String
  • 线程与进程的区别

    1 一个程序至少有一个进程 一个进程至少有一个线程 2 线程的划分尺度小于进程 使得多线程程序的并发性高 3 进程在执行过程中拥有独立的内存单元 而多个线程共享内存 从而极大地提高了程序的运行效率 4 每个独立的线程有一个程序运行的入口 顺
  • 老油条表示真干不过,部门新来的00后网络安全工程师已把我卷崩溃,想离职了...

    在程序员职场上 什么样的人最让人反感呢 是技术不好的人吗 并不是 技术不好的同事 我们可以帮他 是技术太强的人吗 也不是 技术很强的同事 可遇不可求 向他学习还来不及呢 真正让人反感的 是技术平平 却急于表现自己的人 每天加班到12点 在老
  • 在Idea中,如何在SpringBoot中使用jsp页面

    在Idea中 如何在SpringBoot中使用jsp页面 1 首先 创建一个SpringBoot工程 选择Spring Initializr 然后点击next 修改工程路径 jdk根据自己安装的具体的jdk版本进行选择 根据项目所需进行选择
  • 刷脸支付彻底解决顾客的支付安全更方便

    创业能成功 其中一项不为人知的关键就在于你无需热爱自己所做的事情 热情当然必需要有 但它可以是因为这个生意能赚钱 而不是对产品的热情 当然这是纯粹的生活选择 不过鉴于赚钱能给自己和他人带来的好处 我希望你发现光是能赚到钱就足以是一种热情 生
  • Unreal4引擎开发学习日志

    Unreal4引擎开发学习笔记1 相关说明 本游戏引擎学习日志是笔者根据网上相关教学视频所写 是对视频内容的精炼与总结 如果您认为笔者所写不清晰明确 可以访问以下链接 Unreal入门第一季 虚幻C 基础训练 虚幻4引擎介绍 虚幻4是一套为
  • 插件编写傻瓜教程>>VC6.0

    gt gt 写在前面本教程主要讲解如何用按键精灵自带的模版编写插件 请大家在教程没全部写完之前不要跟贴 谢谢合作 需要的工具 VC6 0 编辑语言 C gt gt 初步接触1 安装VC6 0 建议不要使用创天的汉化版 2 解压插件自带的模版
  • 软件定价:我们深谙其道吗?

    本文为翻译初稿 更多精彩内容 敬请关注 高效能程序员的修炼 人民邮电出版社 一段时间以来频繁光顾iPhone应用商店 以致于产生了个副作用 我开始从根本上改变了对软件定价的看法 这么多优秀的iPhone应用程序 要么是免费的 要么只卖区区几
  • 关于在windows使用msys2 + mingw + gcc/g++ 编译godot的笔记

    关于在windows使用msys2 mingw gcc g 编译godot的笔记 编译参数 1 target release debug release debug 2 多线程参数 j数字 3 profile是自定义构建参数 可以启用或者禁
  • python中找出numpy array数组的最值及其索引介绍

    转自 微点阅读 https www weidianyuedu com 在list列表中 max list 可以得到list的最大值 list index max list 可以得到最大值对应的索引 但在numpy中的array没有index
  • Echarts饼状图属性设置大全

    1 标题设置 title text 学生生源地来源分布图 subtext 模拟数据 x 设置水平安放位置 默认左对齐 可选值 center left right number x坐标 单位px x center y 设置垂直安放位置 默认全
  • FPGA--IP核之RAM

    RAM 的英文全称是 Random Access Memory 即随机存取存储器 它可以随时把数据写入任一指定地址的存储单元 也可以随时从任一指定地址中读出数据 其读写速度是由时钟频率决定的 RAM主要用来存放程序及程序执行过程中产生的中间

随机推荐

  • 深度学习理论总结(1)

    0 前言 为了在暑假能更好的发展自己 鉴于对深度学习的浓厚兴趣 楼主开始学习深度学习的相关知识 本系列内容是在楼主学习吴恩达老师的深度学习课程后进行的总结 使用的程序软件为python 如有纰漏还请各位大佬指出 我将虚心接受 1 深度学习概
  • Visual Studio Code常用插件详解

    文章目录 前言 VS Code必备插件 1 IntelliCode 2 IntelliCode API Usage Examples 3 Settings Sync 前端必备插件 1 Auto Close Tag 2 Auto Rename
  • USB移植(FLASH)

    USB移植 FLASH 一 说明 准备好USB源文件 可参考正点原子USB读卡器实验例程 下载正点原子资料或光盘资料 例程在 STSW STM32121 STM32 USB FS Device Lib V4 0 0 Projects Mas
  • UID卡、IC卡、ID卡、CUID 卡、FUID 卡、UFUID 卡 有什么区别?

    生活中 我们经常用到门禁卡 考勤卡 电梯卡还有停车卡 这些功能是怎么实现的呢 这是靠卡里封装的芯片和线圈来实现各种功能 不同的芯片频率 容量 读写性各不相同 常见的是IC卡还有ID卡 还有一种叫UID的卡 许多客户不了解UID卡是什么 有什
  • Mac:Split文件分割命令

    1 背景 在宁波银行工作 发现一个包太大传不了 因此要转成小文件 2 分割文件 split b 300m cheetah node v1 1 0 SNAPSHOT tgz cheetah node v1 1 0 SNAPSHOT tgz 那
  • elementUI的下拉框

    效果图 代码
  • [Obsidian]懒人必备插件附使用教程

    最近才知道了Obsidian 就使用Obsidian整理了一下笔记 评价是Obsidian确实是一种挺好的整理笔记的东西 主要就是想复习时候翻书其实挺麻烦 Obsidian提供了链接功能 可以比较好地查找到以前的知识 虽说笔记多了容易不太好
  • 用python实现神经网络

    一 BP神经网络 这里介绍目前常用的BP神经网络 其网络结构及数学模型如下 x为 n 维向量 y 为 n 维向量 隐含层有 q 个神经元 假设 N 有个样本数据 1 2 y t x t t 1 2 N 从输入层到隐含层的权重记为 1 2 1
  • 关于交换机端口的Trunk和Access模式的分析与验证

    1 理论简析 以太网交换机的通信是基于端口的通信 其端口类型分为Trunk port 干道端口 Access port 接入端口 Hybird port 混合端口 三种 Access port一般用于交换机和用户PC主机相连 连接用户主机和
  • MATLAB热力图绘图及颜色更改

    绘制热力图 定义数组p 定义一个数组 p 0 0 249531282218369 0 538162020204790 0 00892397889578578 0 224699560921490 0 000149245738789272 0
  • 使用selenium解决滑块验证的问题

    使用自动化测试时有些网站会使用滑块来阻止 所以如何解决滑块问题已经成为自动化测试不可或缺的 今天以网易易盾网站的滑块举例 https dun 163 com trial sense 要解决滑块问题的关键就是匹配滑块在背景图中的位置所以使用p
  • RobotFramework(一)基本介绍

    前言 本人自2020年11月从制造业转行软测 以此记录点滴学习记录 希望大家多多指导 批评指正 一 RobotFramework是什么 RobotFramework是一款python编写的功能自动化测试框架 具备良好的可扩展性 支持关键字驱
  • 【NLP】一文详解生成式文本摘要经典论文Pointer-Generator

    写在前面 Pointer Generator Network 以及微软的 Unilm 是小喵在20年所研读的自动文本摘要方向系列论文中的两篇 到今天为止个人依旧认为它们是非常值得一读的 今天我们先分享 Pointer Generator N
  • Qt鼠标双击事件mouseDoubleClickEvent(QMouseEvent* event)

    重写mouseDoubleClickEvent QMouseEvent event 1 实例 双击窗口时输出 sss widget h ifndef WIDGET H define WIDGET H include
  • WXS:微信小程序版JavaScript

    完整微信小程序 Java后端 技术贴目录清单页面 必看 WXS WeiXin S 标题cript 是小程序的一套脚本语言 结合 WXML 可以构建出页面的结构 WXS 与 JavaScript 是不同的语言 有自己的语法 并不和 JavaS
  • csdn 登陆入口

    csdn登陆入口 https passport csdn net login code public 刚刚百度CSDN登陆 居然找不到入口
  • 解决cURL error 60: SSL: no alternative certificate subject name matches target host name ‘test.com‘

    按照提示前往libcurl Error Codes说是SSL 证书问题 解决方法 1 前往该路径 下载https curl se ca cacert pem 将文件里的内容全部复制下来 然后替换上图路径的 ca bundle crt 里面的
  • 一文搞定Linux进程和线程(详细图解)

    Linux 进程和线程 本篇文章我们就深入理解一下 Linux 内核来理解 Linux 的基本概念之进程和线程 系统调用是操作系统本身的接口 它对于创建进程和线程 内存分配 共享文件和 I O 来说都很重要 我们将从各个版本的共性出发来进行
  • jenkins从gitlab拉取代码,进行构建

    1 在gitlab平台加入jenkins机器的公钥 2 在jenkins平台加入jenkins机器的私钥 3 在jenkins中新建任务 4 立即构建
  • 音频录制以及播放

    音频录制以及播放 象棋小子 1048272975 一般的音频应用中 往往需要支持音频的拾取输入以及音频的播放输出 LPC5411x具有I2S音频接口以及双通道PDM数字麦克风接口 其中数字麦克风接口支持芯片深度睡眠时的语音激活 非常适合于音