【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动

2023-11-08

相关文章

1.《【Audio】I2S传输PCM音频数据分析总结(一)》
2.《【Audio】I2S传输PCM音频数据分析总结(二)》
3.《【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动》

1. WM8978简介

WM8978是一款低功耗,高质量的立体声编解码器,专为便携式应用,如数码相机或数码摄像机等。

该芯片集成了立体声差分麦克风的前置放大器,并包括扬声器、耳机和差分或立体声线输出的驱动器。外部组件要求减少,因为不需要单独的麦克风或耳机放大器。

WM8978的功能框图如下所示:
在这里插入图片描述

2. WM8978硬件连接

使用STM32F429+WM8978硬件平台,通过I2S接口来读写音频数据,I2C接口发送写命令控制WM8978相关功能。
在这里插入图片描述
STM32F429与WM8978的引脚连接如下:

STM32引脚名称 WM8978引脚名称 功能 描述
GPIOB12 LRC I2S WS 字选择,是音频数据控制信号输出,0:左声道的数据,1:右声道的数据
GPIOD3 BCLK I2S BCLK 串行时钟,也叫位时钟,对应数字音频的每一位数据。
GPIOC2 ADCDAT I2S EXT_SD 控制 I2S 全双工模式的附加串行数据引脚,用于接收音频数据。
GPIOI3 DACDAT I2S SD 串行数据,用于发送音频数据。
GPIOC6 MCLK I2S MCLK 当 I2S 配置为主模式时,使用主时钟(单独映射)输出此附加时钟。

(备注:I2C不是本篇文章的重点,这里会忽略对它的介绍。重点:WM8978的I2C只能写,不能读。)

3. STM32 I2S的配置

STM32 I2S的配置主要是:

  1. I2S相关GPIO的初始化
  2. I2S相关寄存器的初始化
  3. I2S TX和RX的DMA的初始化
  • I2S相关GPIO的初始化
    STM32的I2S和SPI是公用的pin脚,所以这里需要将IO设置为I2S模式。这些I2S的引脚的相关功能在上面的表格中有详细描述,下面是具体初始化的代码:
/**
	* I2S总线传输音频数据口线
	* WM8978_LRC    -> PB12/I2S2_WS
	* WM8978_BCLK   -> PD3/I2S2_CK
	* WM8978_ADCDAT -> PC2/I2S2ext_SD
	* WM8978_DACDAT -> PI3/I2S2_SD
	* WM8978_MCLK   -> PC6/I2S2_MCK
	*/
static void I2S_Gpio_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/* Enable GPIO clock */
	RCC_AHB1PeriphClockCmd(I2S_WS_GPIO_CLK|I2S_BCLK_GPIO_CLK| \
                         I2S_ADCDAT_GPIO_CLK|I2S_DACDAT_GPIO_CLK| \
	                       I2S_MCLK_GPIO_CLK, ENABLE);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

	GPIO_InitStructure.GPIO_Pin = I2S_WS_PIN;
	GPIO_Init(I2S_WS_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = I2S_BCLK_PIN;
	GPIO_Init(I2S_BCLK_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = I2S_ADCDAT_PIN;
	GPIO_Init(I2S_ADCDAT_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = I2S_DACDAT_PIN;
	GPIO_Init(I2S_DACDAT_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = I2S_MCLK_PIN;
	GPIO_Init(I2S_MCLK_PORT, &GPIO_InitStructure);
	
	/* Connect pins to I2S peripheral  */
	GPIO_PinAFConfig(I2S_WS_PORT,     I2S_WS_SOURCE,     I2S_WS_AF);
	GPIO_PinAFConfig(I2S_BCLK_PORT,   I2S_BCLK_SOURCE,   I2S_BCLK_AF);
	GPIO_PinAFConfig(I2S_ADCDAT_PORT, I2S_ADCDAT_SOURCE, I2S_ADCDAT_AF);
	GPIO_PinAFConfig(I2S_DACDAT_PORT, I2S_DACDAT_SOURCE, I2S_DACDAT_AF);
	GPIO_PinAFConfig(I2S_MCLK_PORT,   I2S_MCLK_SOURCE,   I2S_MCLK_AF);
}
  • I2S相关寄存器的初始化
    主要是设置:

    • I2S_AudioFreq = I2S_AudioFreq_44k //音频数据的采样率为44.1KHz
    • I2S_DataFormat = I2S_DataFormat_16b // 音频数据的数据宽度为16bit
    • I2S_Standard = I2S_Standard_Phillips // I2S传输音频数据采用Phillips I2S的标准

    具体配置代码如下:

void I2S_Mode_Config(const uint16_t _usStandard,const uint16_t _usWordLen,const uint32_t _usAudioFreq)
{
	I2S_InitTypeDef I2S_InitStructure;
	uint32_t n = 0;
	FlagStatus status = RESET;

	/**
	 *   For I2S mode, make sure that either:
	 * 	  - I2S PLL is configured using the functions RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S),
	 * 	    RCC_PLLI2SCmd(ENABLE) and RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY).
	 */
	RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
	RCC_PLLI2SCmd(ENABLE);
	for (n = 0; n < 500; n++)
	{
		status = RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY);
		if (status == 1)break;
	}

	/* Enable the CODEC_I2S peripheral clock */
	RCC_APB1PeriphClockCmd(I2S2_CLK, ENABLE);

	/* CODEC_I2S peripheral configuration */
	SPI_I2S_DeInit(I2S2_SPI);
	I2S_InitStructure.I2S_AudioFreq = _usAudioFreq;
	I2S_InitStructure.I2S_Standard = _usStandard;
	I2S_InitStructure.I2S_DataFormat = _usWordLen;
	I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
	I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;

	/* Initialize the I2S peripheral with the structure above */
	I2S_Init(I2S2_SPI, &I2S_InitStructure);
	I2S_Cmd(I2S2_SPI, ENABLE);

	/* Configures the full duplex mode for the I2S2 */
	I2S_FullDuplexConfig(I2S2_ext, &I2S_InitStructure);
	I2S_Cmd(I2S2_ext, ENABLE);
}
  • I2S TX和RX的DMA的初始化
    WM8978 Audio Codec驱动需要实现2个功能:播放和录音,所以这里将会很多的数据需要发送和接收。为了减轻CPU的负担,这里需要使用I2S的TX和RX的DMA。
    在这里插入图片描述
    ???为什么选择的是DMA1 Stream4 Channel0和Stream3 Channel3???
    下面的截图是DMA的功能框图,我们需要使用它将I2S外设数据接收到内存,将内存的数据发送到I2S外设。我们需要根据硬件的外设来选择对应DMA的stream和channel。
    在这里插入图片描述
    根据硬件连接,使用的是SPI2硬件接口复用的I2S2。由于使用了I2S全双工功能,并且通过I2S2_EXT来接收数据,所以这里选择DMA1的I2S2_EXT_RX接收数据。I2S2_SD_TX引脚复用了SPI2_TX,所以这里选择SPI2_TX发送数据。到这里就解释了为什么选择的是DMA1 Stream4 Channel0和Stream3 Channel3?下面是SMT32 DMA1映射表:
    在这里插入图片描述
    下面是TX DMA的初始化的例子,RX DMA初始化是同样的过程。主要是步骤如下:
    • 使能DMA的时钟
    • 指定外设和内存的数据存放地址
    • 配置DMA的相关属性参数
    • 设置DMA中断参数,通过中断来指示数据是否传送完成。
void I2Sx_TX_DMA_Init(const uint16_t *dmaM0Addr,const uint16_t *dmaM1Addr,const uint32_t num)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	DMA_InitTypeDef  DMA_InitStructure;

	/* Enable the DMA clock */
	RCC_AHB1PeriphClockCmd(I2Sx_DMA_CLK, ENABLE); 

	/* Configure the DMA Stream */
	DMA_DeInit(I2Sx_TX_DMA_STREAM);
	while (DMA_GetCmdStatus(I2Sx_TX_DMA_STREAM) != DISABLE){}//等待DMA1_Stream4可配置 
		
	DMA_ClearITPendingBit(I2Sx_TX_DMA_STREAM,DMA_IT_FEIF4|DMA_IT_DMEIF4|DMA_IT_TEIF4|DMA_IT_HTIF4|DMA_IT_TCIF4);//清空DMA1_Stream4上所有中断标志

	/* 配置 DMA Stream */
	DMA_InitStructure.DMA_Channel = I2Sx_TX_DMA_CHANNEL;  //通道0 SPIx_TX通道 
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&I2S2_SPI->DR;//外设地址为:(u32)&SPI2->DR
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dmaM0Addr;//DMA 存储器0地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
	DMA_InitStructure.DMA_BufferSize = num;//数据传输量 
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据长度:16位 
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式 
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不使用FIFO模式		
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//外设突发单次传输
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//存储器突发单次传输
	DMA_Init(I2Sx_TX_DMA_STREAM, &DMA_InitStructure);//初始化DMA Stream

	DMA_DoubleBufferModeConfig(I2Sx_TX_DMA_STREAM, (uint32_t)dmaM0Addr, DMA_Memory_0);//双缓冲模式配置
	DMA_DoubleBufferModeConfig(I2Sx_TX_DMA_STREAM, (uint32_t)dmaM1Addr, DMA_Memory_1);//双缓冲模式配置

	DMA_DoubleBufferModeCmd(I2Sx_TX_DMA_STREAM, ENABLE);//双缓冲模式开启

	DMA_ITConfig(I2Sx_TX_DMA_STREAM,DMA_IT_TC,ENABLE);//开启传输完成中断

	SPI_I2S_DMACmd(I2S2_SPI,SPI_I2S_DMAReq_Tx,ENABLE);//SPI2 TX DMA请求使能.

	NVIC_InitStructure.NVIC_IRQChannel = I2Sx_TX_DMA_STREAM_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
	NVIC_Init(&NVIC_InitStructure);//配置
}

4. WM8978 Audio Codec的配置

下面介绍关于WM8978主要的寄存器的设置:

  • wm8978_SetOUT1Volume()
  • wm8978_SetMicGain()
  • wm8978_SetLineGain()
  • wm8978_CfgAudioIF()
  • wm8978_CfgAudioPath()

4.1 wm8978_SetOUT1Volume()

wm8978_SetOUT1Volume()函数主要是修改输出通道1音量,具体设置WM8978的功能框图如下:
在这里插入图片描述
具体设置代码如下:

/**
 * @brief  修改输出通道1音量
 * @param  _ucVolume :音量值, 0-63
 * @retval 无
 */
void wm8978_SetOUT1Volume(uint8_t _ucVolume)
{
	uint16_t regL;
	uint16_t regR;

	if (_ucVolume > VOLUME_MAX)
	{
		_ucVolume = VOLUME_MAX;
	}

	regL = _ucVolume;
	regR = _ucVolume;

	/*
		R52	LOUT1 Volume control
		R53	ROUT1 Volume control
	*/
	/* 先更新左声道缓存值 */
	wm8978_WriteReg(WM8978_LOUT1_HP_CONTROL, regL | 0x00);

	/* 再同步更新左右声道的音量 */
	wm8978_WriteReg(WM8978_ROUT1_HP_CONTROL, regR | 0x100);	/* 0x180表示 在音量为0时再更新,避免调节音量出现的“嘎哒”声 */
}

4.2 wm8978_SetMicGain()

wm8978_SetMicGain()函数主要是设置MIC的增益,具体设置WM8978的功能框图如下:
在这里插入图片描述
具体设置代码如下:

/**
 * @brief  设置增益
 * @param  _ucGain :增益值, 0-63
 * @retval 无
 */
void wm8978_SetMicGain(uint8_t _ucGain)
{
	if (_ucGain > GAIN_MAX)
	{
		_ucGain = GAIN_MAX;
	}

	/* PGA 音量控制  R45, R46 
		Bit8	INPPGAUPDATE
		Bit7	INPPGAZCL		过零再更改
		Bit6	INPPGAMUTEL		PGA静音
		Bit5:0	增益值,010000是0dB
	*/
	wm8978_WriteReg(WM8978_LEFT_INP_PGA_CONTROL,  _ucGain);
	wm8978_WriteReg(WM8978_RIGHT_INP_PGA_CONTROL, _ucGain | (1 << 8));
}

4.3 wm8978_SetLineGain()

wm8978_SetLineGain()函数主要是设置输入通道的增益,具体设置WM8978的功能框图如下:
在这里插入图片描述
具体设置代码如下:

/**
 * @brief  设置Line输入通道的增益
 * @param  _ucGain :音量值, 0-7. 7最大,0最小。 可衰减可放大。
 * @retval 无
 */
void wm8978_SetLineGain(uint8_t _ucGain)
{
	uint16_t usRegValue;

	if (_ucGain > 7)
	{
		_ucGain = 7;
	}

	/*
		Mic 输入信道的增益由 PGABOOSTL 和 PGABOOSTR 控制
		Aux 输入信道的输入增益由 AUXL2BOOSTVO[2:0] 和 AUXR2BOOSTVO[2:0] 控制
		Line 输入信道的增益由 LIP2BOOSTVOL[2:0] 和 RIP2BOOSTVOL[2:0] 控制
	*/
	/*	R47(左声道),R48(右声道), MIC 增益控制寄存器
		R47 (R48定义与此相同)
		B8		PGABOOSTL	= 1,   0表示MIC信号直通无增益,1表示MIC信号+20dB增益(通过自举电路)
		B7		= 0, 保留
		B6:4	L2_2BOOSTVOL = x, 0表示禁止,1-7表示增益-12dB ~ +6dB  (可以衰减也可以放大)
		B3		= 0, 保留
		B2:0`	AUXL2BOOSTVOL = x,0表示禁止,1-7表示增益-12dB ~ +6dB  (可以衰减也可以放大)
	*/

	usRegValue = wm8978_ReadReg(WM8978_LEFT_ADC_BOOST_CONTROL);
	usRegValue &= 0x8F;/* 将Bit6:4清0   1000 1111*/
	usRegValue |= (_ucGain << 4);
	wm8978_WriteReg(WM8978_LEFT_ADC_BOOST_CONTROL, usRegValue);	/* 写左声道输入增益控制寄存器 */

	usRegValue = wm8978_ReadReg(WM8978_RIGHT_ADC_BOOST_CONTROL);
	usRegValue &= 0x8F;/* 将Bit6:4清0   1000 1111*/
	usRegValue |= (_ucGain << 4);
	wm8978_WriteReg(WM8978_RIGHT_ADC_BOOST_CONTROL, usRegValue);	/* 写右声道输入增益控制寄存器 */
}

4.4 wm8978_CfgAudioIF()

wm8978_CfgAudioIF()函数主要是配置WM8978的I2S接口和时钟,具体设置WM8978的功能框图如下:
在这里插入图片描述
具体设置代码如下:

/**
 * @brief  配置WM8978的音频接口(I2S)
 * @param  _usStandard : 接口标准,I2S_Standard_Phillips, I2S_Standard_MSB 或 I2S_Standard_LSB
 * @param  _ucWordLen : 字长,16、24、32  (丢弃不常用的20bit格式)
 * @retval 无
 */
void wm8978_CfgAudioIF(uint16_t _usStandard, uint8_t _ucWordLen)
{
	uint16_t usReg;

	/* WM8978(V4.5_2011).pdf 73页,寄存器列表 */

	/*	REG R4, 音频接口控制寄存器
		B8		BCP	 = X, BCLK极性,0表示正常,1表示反相
		B7		LRCP = x, LRC时钟极性,0表示正常,1表示反相
		B6:5	WL = x, 字长,00=16bit,01=20bit,10=24bit,11=32bit (右对齐模式只能操作在最大24bit)
		B4:3	FMT = x,音频数据格式,00=右对齐,01=左对齐,10=I2S格式,11=PCM
		B2		DACLRSWAP = x, 控制DAC数据出现在LRC时钟的左边还是右边
		B1 		ADCLRSWAP = x,控制ADC数据出现在LRC时钟的左边还是右边
		B0		MONO	= 0,0表示立体声,1表示单声道,仅左声道有效
	*/
	usReg = 0;
	if (_usStandard == I2S_Standard_Phillips)	/* I2S飞利浦标准 */
	{
		usReg |= WM8978_R4_FMT_I2S_FORMAT;
	}
	else if (_usStandard == I2S_Standard_MSB)	/* MSB对齐标准(左对齐) */
	{
		usReg |= WM8978_R4_FMT_LEFT_JUSTIFIED;
	}
	else if (_usStandard == I2S_Standard_LSB)	/* LSB对齐标准(右对齐) */
	{
		usReg |= WM8978_R4_FMT_RIGHT_JUSTIFIED;
	}
	else	/* PCM标准(16位通道帧上带长或短帧同步或者16位数据帧扩展为32位通道帧) */
	{
		usReg |= WM8978_R4_FMT_PCM_MODE;
	}

	if (_ucWordLen == 24)
	{
		usReg |= WM8978_R4_WORD_LEN_24_BITS;
	}
	else if (_ucWordLen == 32)
	{
		usReg |= WM8978_R4_WORD_LEN_32_BITS;
	}
	else
	{
		usReg |= WM8978_R4_WORD_LEN_16_BITS;		/* 16bit */
	}
	wm8978_WriteReg(WM8978_AUDIO_INTERFACE, usReg);


	/*
		R6,时钟产生控制寄存器
		MS = 0,  WM8978被动时钟,由MCU提供MCLK时钟
	*/
	wm8978_WriteReg(WM8978_CLOCKING, 0x000);
}

4.5 wm8978_CfgAudioPath()

wm8978_CfgAudioPath()函数主要是配置WM8978的音频通道,我这里demo实现的功能是MIC录音耳机输出,具体设置WM8978的功能框图如下:
在这里插入图片描述
配置音频通道涉及到很多寄存器,这里就不一一列举,需要查看的可以下载完成的代码来分析(备注:文章最后会列出Demo工程的下载路径)。具体涉及到的代码如下:

/**
	* @brief  配置wm8978音频通道
	* @param  _InPath : 音频输入通道配置
	* @param  _OutPath : 音频输出通道配置
	* @retval 无
	*/
void wm8978_CfgAudioPath(uint16_t _InPath, uint16_t _OutPath)
{
	/* 查看WM8978数据手册的 REGISTER MAP 章节, 第89页 */

	if ((_InPath == IN_PATH_OFF) && (_OutPath == OUT_PATH_OFF))
	{
		wm8978_PowerDown();
		return;
	}

	wm8978_Set_R1_Power_Manage_1(_InPath, _OutPath);
	wm8978_Set_R2_Power_Manage_2(_InPath, _OutPath);
	wm8978_Set_R3_Power_Manage_3(_InPath, _OutPath);

	wm8978_Set_R14_ADC_Ctrl(_InPath);
	wm8978_Set_R27_30_Notch_Filter(_InPath);
	wm8978_Set_R32_35_ALC_Ctrl();
	wm8978_Set_R47_48_Input_Boost_Ctrl(_InPath);
	wm8978_Set_R15_16_ADC_Digital_Vol();
	wm8978_Set_R43_Beep_Ctrl(_InPath, _OutPath);
	wm8978_Set_R49_Output_Ctrl(_InPath, _OutPath);
	wm8978_Set_R50_51_Output_Mixer_Ctrl(_InPath);
	wm8978_Set_R56_OUT3_Mixer_Ctrl(_OutPath);
	wm8978_Set_R57_OUT4_Mixer_Ctrl(_OutPath);
	wm8978_Set_R11_12_DAC_Digital_Vol(_InPath);
	wm8978_Set_R10_DAC_Ctrl(_InPath);
}

5. 验证测试

运行WM8978 Demo可以正常的录音和播放,测试成功:
在这里插入图片描述
下面是通过WM8978 Demo播放采样率44.1KHz 16bit双声道正弦波1KHz的PCM音频数据时,用逻辑分析仪抓取的I2S数据图如下:
在这里插入图片描述

6. 资料下载

移植成功的完整工程代码下载路径如下:
https://download.csdn.net/download/ZHONGCAI0901/18375355

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

【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动 的相关文章

  • 谷歌colab录音,如何实现更精确的方式告诉用户开始对着麦克风说话

    我正在尝试创建一个为机器学习项目录制音频的程序 我想使用 google colab 这样人们就不必在他们的系统上安装或运行任何东西 我在网上找到了这个录制和播放音频的示例 单元格 1 包含用于录制音频的 js 代码和用于将其转换为字节对象的
  • HTML5 音频暂停不起作用

    document getElementById s currentRadio currentSong pause 目前这并没有暂停音频 而播放它效果很好 document getElementById s currentRadio curr
  • 使用 iOS 修剪音频

    我想实现一项功能 让用户修剪他之前录制的音频文件 caf 录音部分已经可以工作了 但是我如何添加类似于 Voicememos 应用程序中的修剪功能 苹果使用的音频修剪器有API吗 任何帮助都会很棒 使用 AVFoundation 怎么样 将
  • AVAudioPlayer 重置当前播放的声音并从头开始播放

    我在使用 AVAudioPlayer 时遇到问题 我想重置当前正在播放的播放器并再次播放 我尝试以下但没有运气 声音播放一次 但第二次我选择按钮时它会停止声音 第三次再次启动声音 Stop the player and restart it
  • 如何将 G.726 ADPCM 信号转换为 PCM 信号?

    我通常会使用 SoX 或 Windows 内置的音频库来获取这些内容 但似乎两者都没有 G 726 编解码器 因此 我有一个字节序列 我知道它被编码为 G 726 尽管目前尚不知道比特率以及它是 mu law 还是 A law 实验将确定这
  • 需要在状态改变时关闭MediaRecorder播放的声音

    我已尝试在下面的链接中找到的更改 但没有效果 如何在状态改变时关闭 MediaRecorder 播放的声音 https stackoverflow com questions 6804205 how to shut off the soun
  • 如何通过触摸按钮在 swift 2 中播放 m4a 文件?

    当我触摸按钮时 如何播放音频文件 我在网上找不到任何东西 因为它都是 swift 1 我想要音频代码original功能 import UIKit import AVFoundation class ViewController UIVie
  • iOS 音频修剪

    我搜索了很多 找不到任何相关的东西 我正在处理 iOS 音频文件 这就是我想做的 录制音频并保存剪辑 已检查 我使用AVAudioRecorder 改变音高 已检查 是用狄拉克做的吗 修剪 我有两个标记 即开始和结束偏移 并使用此信息我想修
  • Web 浏览器中的高品质音频录制

    一行版本 什么开源软件 WAMI Recorder 网络浏览器 通过 getUserMedia 将为我提供最佳质量的录音 高质量定义为 44 1 或 48 采样率 和 16 位样本大小 更多信息 目前我的解决方案是 WAMI Recorde
  • 在Python中创建32位浮点wav文件?

    我想在 Python 2 x 中创建 32 位浮动 WAV 文件 虽然 标准 WAV 文件通常使用 int 但许多专业音频应用程序将音频数据处理 并保存 为 float 标准波形模块无法执行此操作 http bugs python org
  • 如何在Android中设置音频均衡器

    我正在制作一个媒体播放器 其中需要使用 搜索栏 将均衡器效果设置为 低音 可怕 摇滚 流行 中 我得到了一个链接 其中使用了一些 NDK 库来执行此操作 是否有任何 Java 库可以执行此操作 请解释执行此操作的逻辑是什么 Override
  • 如何在声音输入时触发振动?

    我正在尝试创建一个 Android 应用程序 在其中过滤蜂鸣声的一个特定频率并使手机振动 我正在从移动设备的 MIC 获取输入并使用 MediaRecorder 类 通过使用该类 我可以录制 保存和播放输入 现在我需要我的手机在发出蜂鸣声
  • 音乐分析软件[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 问候 我可能已经想到了这一点 但有人知道 Last fm 之前是否使用某种形式的开源项目对音乐进行分析
  • 我在 android 上使用 java 时遇到异常 (java.lang.NoClassDefFoundError),为什么?

    这是我运行的线路 AudioInputStream clip1 AudioSystem getAudioInputStream new File wavFile1 这是我得到的异常 来自 LogCat 错误 AndroidRuntime 3
  • PlaySystemSound 静音开关打开

    我知道 我必须设置AudioSession到 播放 类别 即使静音开关打开也允许播放音频 这就是我所做的 但打开开关时声音仍然静音 UInt32 sessionCategory kAudioSessionCategory MediaPlay
  • 如何在Python中获取声音级别?

    对于我正在进行的项目 我需要获取麦克风的实时分贝级别 我见过阴谋家 Print out realtime audio volume as ascii bars import sounddevice as sd import numpy as
  • C# 音频库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • Xamarin Android:检测设备当前是否正在播放音频

    在应用程序启动时 是否可以检测设备的音频播放器或其他应用程序当前是否正在播放音乐 您可以使用AudioManager http developer android com reference android media AudioManag
  • AUGraphInitialize添加kAudioUnitSubType_Reverb2到AUGraph时出现错误代码-10868

    我正在尝试添加 AudioUnit 类型kAudioUnitSubType Reverb2 to an AUGraph我得到了 10868 kAudioUnitErr FormatNotSupported 支持的错误AUGraphIniti

随机推荐

  • 技术栈

    1 微服务技术栈 微服务条目 技术 备注 服务开发 Springboot Spring SpringMVC 服务配置与管理 Netflix公司的Archaius 阿里的Diamond等 服务注册与发现 Eureka Consul Zooke
  • 翻转等价二叉树

    leetcode 翻转等价二叉树 我们可以为二叉树 T 定义一个翻转操作 如下所示 选择任意节点 然后交换它的左子树和右子树 只要经过一定次数的翻转操作后 能使 X 等于 Y 我们就称二叉树 X 翻转等价于二叉树 Y 编写一个判断两个二叉树
  • C API向MySQL插入批量数据的快速方法——关于mysql_autocommit

    MySQL默认的数据提交操作模式是自动提交模式 autocommit 这就表示除非显式地开始一个事务 否则每个查询都被当做一个单独的事务自动执行 我们可以通过设置autocommit的值改变是否是自动提交autocommit模式 查询当前数
  • 浏览器打不开网页 服务器停止响应怎么办,浏览器打不开未响应怎么办

    相信还有不少用ie浏览器的朋友 偶尔会遇到ie浏览器打不开或未响应的问题 那么对于浏览器打不开未响应的问题该怎么解决呢 接下来小编为大家分享解决方法 解决浏览器打不开问题 可以直接使用金山毒霸的电脑医生进行快速修复 以IE浏览器为例 下面就
  • 2. eMMC概述

    0 前言 本文主要参考eMMC规范 从总体上对eMMC 进行简要介绍 主要包含如下的内容 1 eMMC系统的总体架构 2 eMMC的总线协议 3 device controller 4 flash memory 1 eMMC系统总体架构 图
  • 无法启动 IIS express

    问题描述 1 在启动VS2013 调试项目的时候 提示 无法启动 IIS Exress 2 此问题只在打开某个项目时 提示此信息 3 打开事件查看器 看到错误内容为 在要求开始处理 http 请求时 应用程序池 Clr4Integrated
  • javaweb开发环境搭建-mac版

    一 安装jdk 1 检查 终端输入 java version mac自带jdk 但版本较低 如果自带版本满足需求 请跳过23步 2 安装或升级 官网下载 MAC OS版本的jdk安装 3 配置jdk环境变量 其实就是修改 bash prof
  • Ubuntu和树莓派的远程连接

    文章目录 一 Linux Ubuntu和树莓派 的远程连接操作 一 远程登录 1 Ubuntu远程登录 2 树莓派远程登录 二 Windows使用ftp远程登录实现上传和下载文件 1 Ubuntu系统 2 树莓派系统 三 Windows使用
  • 【计算机组成原理】——知识点复习(期末不挂科版)

    课本 考试题型 题型一 计算题 30分 1 定点数表示 用原码 反码 补码 移码表示十进制数 5分 2 浮点数表示 十进制数 单精度浮点数 5分 3 加减运算 变形补码 10分 4 乘除运算 补码一位乘法 Booth算法 原码加减交替法 不
  • 关于将本地jar包引入到项目中的方法。

    1 直接将下载的jar包通过配置引入到项目中 不推荐 比较限制 1 1 首先将自己所需要引入的jar包下载 1 2 打开idea 进入到项目中 在自己所需要引入jar包的模块下新建一个lib文件夹 跟src同级 1 3 将下载好的jar复制
  • 二进制多实例MYSQL

    上一篇部署了3306单实例mysql 先接上一篇部署多实例 一 创建多实例数据目录 mkdir p linux0224 mysql 3307 mkdir p linux0224 mysql 3308 二 初始化3307 3308数据库 my
  • React报错之React hook ‘useState‘ cannot be called in a class component

    优质资源分享 学习路线指引 点击解锁 知识定位 人群定位 Python实战微信订餐小程序 进阶级 本课程是python flask 微信小程序的完美结合 从项目搭建到腾讯云部署上线 打造一个全栈订餐系统 Python量化交易实战 入门级 手
  • Qt程式异常崩溃处理技巧(Win)

    文章转载来自 http www cnblogs com lcchuguo p 5177715 html 作者 lcchuguo 这篇文章谈的是 Qt4 程式在视窗系统下的异常崩溃处理技巧 所以须要在头文件里包括 include
  • Python3.6 异常处理和assert

    Author tyran Date 17 11 13 异常处理 try 代码逻辑 只要其中任意一行报错都会被捕捉 i int aaa print i except Exception as e 如果出错执行 捕捉错误 print e inv
  • awk从放弃到入门(1):awk基础 (通俗易懂,快进来看)

    我们先来用专业的术语描述一下awk是什么 如果你看不懂 没关系 我们会再用 大白话 解释一遍 awk是一个报告生成器 它拥有强大的文本格式化的能力 这就是专业的说法 你可能不理解所谓的报告生成器中的 报告 是什么 你可以把 报告 理解为 报
  • 智能家居创意DIY-智能触摸面板开关

    触摸开关 即通过触摸方式控制的墙壁开关 其感官场景如同我们的触屏手机 只需手指轻轻一点即可达到控制电器的目的 随着人们生活品质的提高 触摸开关将逐渐将换代传统机械按键开关 触摸开关控制原理 触摸开关我们把它理解为三部分构成 信号控制单元 开
  • VS Code 安装

    前端开发工具 VSCode HBuilder sublime WebStorm VS Code 一 介绍 Visual Studio Code 简称 VS Code 是 Microsoft 于2015年4月发布的一款代码编辑器 VS Cod
  • 非华为电脑安装华为电脑管家多屏协同

    1 转载声明 本文转载自 http www hankeer org article non huawei computer install pcmanager html 使用工具为上述链接内的博文的博主所开发 常见问题在其博客主页有所介绍
  • python怎么搭建免费代理IP池,免费代理IP适合爬虫工作吗

    Python可以使用一些第三方库和工具来搭建免费代理IP池 简单来说 搭建代理IP池的步骤如下 1 获取代理IP 从一些免费或付费代理IP网站上爬取并验证IP地址和端口信息 2 验证代理IP 使用代理IP访问一些网站或服务 验证代理IP的可
  • 【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动

    相关文章 1 Audio I2S传输PCM音频数据分析总结 一 2 Audio I2S传输PCM音频数据分析总结 二 3 Audio 基于STM32 I2S移植WM8978 Audio Codec驱动 1 WM8978简介 WM8978是一