谁用过,stm32的DAC直接播放声音,不知道音质如何???

2019-07-20 23:12发布

谁用过,stm32的DAC直接播放声音,不知道音质如何???
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
29条回答
lxj19901115
2019-07-22 14:05
/*
核心思想,配置定时器,DA,频率为16K,32K等
在读取数据的时候,使用双BUFFER切换,两个缓冲区的大小为64字节,
主循环一直填充BUFFER里面的数据
定时器中断则在BUFFER里面,读取数据
双通道
*/
//idx 要播放的文件编号
//DA_ChNum 要使用的PCM通道编号
void cm_PlayInit(unsigned int idx,unsigned int DA_ChNum)
{
/*
首先获取要播放的PCM音频的数据的起始地址和文件长度
*/
g_ReadSpiStartAdd[DA_ChNum] = cm_PlayInitAddr(idx);

g_ReadSpiEndAdd[DA_ChNum] = cm_PlayInitAddr(idx + 1);
/*
判断DA通道,将两个BUFFER都读取数据
*/
if(!DA_ChNum)
{
SPI_ReadNWords(gb_PCMBuffer1,c_ReadSpiSize_Byte,ReadSpiPcmOffset_Ch1);
g_ReadSpiOffset[DA_ChNum]+=c_ReadSpiSize_Byte;
SPI_ReadNWords(gb_PCMBuffer2,c_ReadSpiSize_Byte,ReadSpiPcmOffset_Ch1);
}
else
{
SPI_ReadNWords(R_DataBuffer1,c_ReadSpiSize_Byte,ReadSpiPcmOffset_Ch2);
g_ReadSpiOffset[DA_ChNum]+=c_ReadSpiSize_Byte;
SPI_ReadNWords(R_DataBuffer2,c_ReadSpiSize_Byte,ReadSpiPcmOffset_Ch2);
}
g_ReadSpiOffset[DA_ChNum] = c_BitClear;
/*
判断是否有DA播放正在进行,
*/
if(!(g_PcmDA_Sts[c_PCM_ID_CH1] | g_PcmDA_Sts[c_PCM_ID_CH2]))//无播放任务,初始化定时器
{
SACM_PCM_Init();
SACM_A1800_DAC_Timer_X1();
}
g_PcmDA_Sts[DA_ChNum] = c_PCM_Playing;//设置某个通道为播放状态
g_FlagPcmEn |= (c_BitSet << DA_ChNum);//使能某个播放通道,为DA输出
}


/*
此函数为主程序调用
*/
void cm_ChangeBuffer(void)
{
if(!g_FlagPcmEn)//判断是否有DA播放那个使能
{
g_FlagPcmEn = c_BitClear;
}
if(g_FlagBufferPcmInit & c_PCM_UpdataCH1)//DA通道1
{
g_FlagBufferPcmInit &=~c_PCM_UpdataCH1;//清楚数据更新标记
g_ReadSpiOffset[c_PCM_ID_CH1]+=c_ReadSpiSize_Byte;//文件长度偏移
g_PcmDA_Sts[c_PCM_UpdataCH1] = c_PCM_Playing;//设置为播放状态
if(g_SendBufferIdx[c_PCM_ID_CH1] == 0)//双BUFFER切换,读取
{
SPI_ReadNWords(gb_PCMBuffer2,c_SendPCM_BufferSize,ReadSpiPcmOffset_Ch1);
}
else
{
SPI_ReadNWords(gb_PCMBuffer1,c_SendPCM_BufferSize,ReadSpiPcmOffset_Ch1);
}
}
if(g_FlagBufferPcmInit & c_PCM_UpdataCH2)
{
g_FlagBufferPcmInit &=~c_PCM_UpdataCH2;
g_ReadSpiOffset[c_PCM_ID_CH2]+=c_ReadSpiSize_Byte;
g_PcmDA_Sts[c_PCM_UpdataCH2] = c_PCM_Playing;
if(g_SendBufferIdx[c_PCM_ID_CH2] == 0)
{
SPI_ReadNWords(R_DataBuffer2,c_SendPCM_BufferSize,ReadSpiPcmOffset_Ch2);
}
else
{
SPI_ReadNWords(R_DataBuffer1,c_SendPCM_BufferSize,ReadSpiPcmOffset_Ch2);
}
}
}
void cm_MainLoop(void)
{
Pcm_ChangeBuffer();
}

void SendIrqBuffer(void)
{
if(!g_FlagPcmEn)
{
g_FlagPcmEn = c_BitClear;
}
if(g_FlagPcmEn & c_PCM_DA_En_Ch1)
{
//大于文件长度,设置播放状态为停止
if(g_ReadSpiOffset[c_PCM_ID_CH1] + g_ReadSpiStartAdd[c_PCM_ID_CH1]  >= g_ReadSpiEndAdd[c_PCM_ID_CH1])
{
g_ReadSpiOffset[c_PCM_ID_CH1] = c_BitClear;
g_PcmDA_Sts[0] = c_PCM_Stop;
return;
}

if(g_IrqSendBufferIdx[c_PCM_ID_CH1] >= c_SendPCM_BufferSize)//数据发送
{//双BUFFER切换
g_IrqSendBufferIdx[c_PCM_ID_CH1] = c_BitClear;
g_SendBufferIdx[c_PCM_ID_CH1]++;
if(g_SendBufferIdx[c_PCM_ID_CH1] >= c_BufferNum)
{
g_SendBufferIdx[c_PCM_ID_CH1] = c_BitClear;
}
g_FlagBufferPcmInit = c_BitSet;
}
if(g_SendBufferIdx[c_PCM_ID_CH1] == 1)
{
*P_DAC_CH1_Data = gb_PCMBuffer2[g_IrqSendBufferIdx[c_PCM_ID_CH1]];//往DA输出数据
}
else
{
*P_DAC_CH1_Data = gb_PCMBuffer1[g_IrqSendBufferIdx[c_PCM_ID_CH1]];
}
g_IrqSendBufferIdx[c_PCM_ID_CH1]++;
}
//ch2
if(g_FlagPcmEn & c_PCM_DA_En_Ch2)
{
if(g_ReadSpiOffset[c_PCM_ID_CH2] + g_ReadSpiStartAdd[c_PCM_ID_CH2]  >= g_ReadSpiEndAdd[c_PCM_ID_CH2])
{
g_ReadSpiOffset[c_PCM_ID_CH2] = c_BitClear;
g_PcmDA_Sts[1] = c_PCM_Stop;
return;
}

if(g_IrqSendBufferIdx[c_PCM_ID_CH2] >= c_SendPCM_BufferSize)
{
g_IrqSendBufferIdx[c_PCM_ID_CH2] = c_BitClear;
g_SendBufferIdx[c_PCM_ID_CH2]++;
if(g_SendBufferIdx[c_PCM_ID_CH2] >= c_BufferNum)
{
g_SendBufferIdx[c_PCM_ID_CH2] = c_BitClear;
}
g_FlagBufferPcmInit |= 2;
}
if(g_SendBufferIdx[c_PCM_ID_CH2] == 1)
{
*P_DAC_CH2_Data = R_DataBuffer2[g_IrqSendBufferIdx[c_PCM_ID_CH2]];
}
else
{
*P_DAC_CH2_Data = R_DataBuffer1[g_IrqSendBufferIdx[c_PCM_ID_CH2]];
}
g_IrqSendBufferIdx[c_PCM_ID_CH2]++;
}
}

一周热门 更多>