单片机如何生成周期正弦波

一,简介

在某些场景需要使用单片机的IIS等外设播放正弦波音频数据。本文介绍一种“笨方法”来生成固定频率和固定幅度的正弦波定点型数据,记录总结学习使用。

二,步骤简介

总体步骤概述:
1,使用Audition生成制定波形,并转成pcm格式;
2,写个main函数将所需要的数据读取并打印,然后运行重定向到txt中;
3,将txt中的数据复制到IIS的播放buffer中进行播放即可;

本篇文章使用采样率48K,幅值-6db ,频率1KHz的正弦信号来举例说明。

2.1 使用Audition生成制定波形,并转成pcm格式

打开Audition,生成音调:
单片机如何生成周期正弦波_第1张图片
新建音频文件,点击确定:
单片机如何生成周期正弦波_第2张图片
设置波形信号开始的频率和幅值:
单片机如何生成周期正弦波_第3张图片
设置波形信号结束的频率和幅值:
单片机如何生成周期正弦波_第4张图片
点击“确定”,一个立体声的指定音源就做好了:
单片机如何生成周期正弦波_第5张图片
使用Audition快捷键“Alt+Z”查看生成波形信号频率,点击“扫描选区”看到左右声道的频率都是1KHz:
单片机如何生成周期正弦波_第6张图片
将当前的浮点型数据转换成定点数据,使用快捷键“Ctrl + S”,将文件另存为.pcm格式,并保存到指定的路径:
单片机如何生成周期正弦波_第7张图片

至此,我们的音源文件已经生成并准备完毕。

2,写个main函数将所需要的数据读取并打印,然后运行重定向到txt中

main函数代码如下所示:
这里IN_32BITPCM_FILE使用刚才生成的pcm文件;
DATA_SAMPLE_LEN设置为96,原因是因为1KHz频率周期是1ms,48K采样率1ms采样点个数为48,又因为是立体音,所以这里读取96个采样点。

#include 

#define IN_32BITPCM_FILE "-6db_1K_48KSr.pcm"
#define READ_DATA_SAMPLE_LEN    96

int main()
{
	int ret = -1;
	FILE *fp = NULL;
	int buffer[READ_DATA_SAMPLE_LEN] = {0};

	fp = fopen(IN_32BITPCM_FILE,"rb");
	if(fp == NULL) {
		printf("%s: open file failed \n",__func__);
		return -1;
	}

	fseek(fp,0,SEEK_SET);
	ret = fread(buffer,sizeof(char),READ_DATA_SAMPLE_LEN*sizeof(buffer[0]),fp);
	if(ret <=0 ) {
		printf("%s: ERROR:read file data failed \n",__func__);
		fclose(fp);
		return -1;
	}

	for(int i=0; i< READ_DATA_SAMPLE_LEN; i++){
		printf("0x%08X, ", buffer[i]);
		if(((i+1)%8) == 0){
			printf("\n");
		}
	}
	fclose(fp);

	return ret;
}

打开MINGW64把刚才的main函数进行编译,默认生成a.exe:
单片机如何生成周期正弦波_第8张图片
运行a.exe并把打印输出结果重定向到test.txt:
单片机如何生成周期正弦波_第9张图片
打开test.txt查看生成的正弦波定点数据,发现我们想要的数据已经整齐的排列好:
单片机如何生成周期正弦波_第10张图片

2.3 接下来就把这些数据拷贝到指定的数组中

备注:为了使生成的数据和音频播放的缓存buffer进行匹配,这里可将该周期数据多复制几份,然后循环从存放生成完整周期的数据的数组中去取数据复制到音频播放的缓存数组即可。

三,总结

本文主要介绍了一种笨方法生成定点数据的正弦波,供参考使用。后续会介绍如何使用CORDIC算法生成各种频率和幅值及采样率的正弦波形。欢迎一起讨论交流~

你可能感兴趣的:(STM32,数字信号处理,工具使用,单片机,嵌入式硬件)