八 音频——C语言生成正弦波并用 I2S 输出

文章目录固定采样率下的正弦波数组I2S 输出 USB 麦克风AP 仪器测试
I2S 输出正弦波PC 端 C 语言生成正弦波数组 原理
三角函数的公式y = A s i n w x y =y=
【八音频——C语言生成正弦波并用 I2S 输出】代码实现 源码
#include #include #include #define SAMPLE_POINT_NUM(64)/* 需要生成的点的个数 */#define SINE_MAX(512)/* sin 函数幅值 */#define PI(3.1415926) /* 数学中的常量:Π */#define POINT_BUFFER_LEN(128)int generate_data[POINT_BUFFER_LEN]; /* 生成的数据放在此数组中 */void get_sin_data(unsigned int point){unsigned int i = 0;float step = 0.0;float data = http://www.kingceram.com/post/0.0;int tem = 0;step = 2 * PI / point; /* 将 sin 函数从 [0-2Π] 等分为 N 个点,则每个点的步长为 2Π/point_num */for (i = 0; i < point; i++){data = SINE_MAX * sin(step * i);tem = (int)data;generate_data[i] = tem;}}int main(int argc, char *argv[]){get_sin_data(SAMPLE_POINT_NUM);for (int i = 0; i < SAMPLE_POINT_NUM; i++){printf("%d ", generate_data[i]);}printf("\r\n");return 0;}
编译
gcc generate_sin_data.c -lm
需要用到数学库中的函数 sin,所以链接的时候需要加上 lm 参数
运行结果
0 50 99 148 195 241 284 324 362 395 425 451 473 489 502 509 512 509 502 489 473 451 425 395 362 324 284 241 195 148 99 50 0 -50 -99 -148 -195 -241 -284 -324 -362 -395 -425 -451 -473 -489 -502 -509 -512 -509 -502 -489 -473 -451 -425 -395 -362 -324 -284 -241 -195 -148 -99 -50
从生成的数据中可以看出,数据的最大最小值分别为 512 和 -512
波形
将上述数据用散点图绘制出来如下图
固定采样率下的正弦波数组
上一节生成的正弦波数组 幅值 及 step 步长并没有考虑实际频率
实际音频输出是需要考虑:采样位数,采样频率,声道数详见音频(一)——基本概念及硬件拓扑
采样位数对应到正弦波中即为幅值
采样频率对应到正弦波中即为频率
基本思路:
源码实现
#include #include #include #define SAMPLE_POINT_NUM(48)/* 需要生成的点的个数,即每 ms 有多少个点,48000Hz - 48个点/ms; 16000 - 16个点/ms*/#define SAMPLE_BIT(16)/* 采样位数 决定幅值 */#define PI(3.1415926) /* 数学中的常量:Π */int generate_data[512]; /* 生成的数据放在此数组中 */int get_sin_max(int sample_bit){int value = http://www.kingceram.com/post/2;for (int i = 0; i < sample_bit - 1; i++){value = value * 2;}return value - 1;}void get_sin_data(unsigned int point){float data = 0.0;int sin_max_data;float step = 0.0;sin_max_data = get_sin_max(SAMPLE_BIT - 1);step = 2 * PI / SAMPLE_POINT_NUM;for (int i = 0; i < point; i++){data = sin_max_data * sin(step * i);generate_data[i] = (int)data;}}int main(int argc, char *argv[]){get_sin_data(SAMPLE_POINT_NUM);for (int i = 0; i < SAMPLE_POINT_NUM; i++){printf("%d, ", generate_data[i]);}printf("\r\n");return 0;}
编译
gcc generate_sin_data.c -lm
需要用到数学库中的函数 sin,所以链接的时候需要加上 lm 参数
运行结果
0, 4276, 8480, 12539, 16383, 19947, 23169, 25995, 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272, 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276, 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995, -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272, -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276,
从生成的数据中可以看出,数据的最大最小值分别为 32767 和 -32767,16 位音频数据的取值范围为? 2 31 —— 2 31 ? 1 -2^{31}——2^{31}-1 ?231——231?1