音频(九)——I2S 输出正弦波

news2025/2/24 9:27:02

I2S 输出正弦波

  • PC 端:先生成一个正弦波数组
  • MCU 端:将正弦波数组使用 I2S 输出
  • AP 端:接受从 MCU I2S 端口出来的正弦波数据并测量 THD+N 等数据

PC 端生成正弦波数组

原理

三角函数的公式 y = A s i n x y = Asinx y=Asinx

  • A 表示幅值

代码实现

源码

#include <stdio.h>
#include <math.h>
#include <stdint.h>

#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 = 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 步长并没有考虑实际频率

实际音频输出是需要考虑:采样位数,采样频率,声道数详见音频(一)——基本概念及硬件拓扑

采样位数对应到正弦波中即为幅值

采样频率对应到正弦波中即为频率

基本思路:

  • 采样频率和需要的采样点控制步长
  • 采样位数控制幅值
    • char 型数据,即 8 位采样位数的取值范围 − 2 7 —— 2 7 − 1 -2^7——2^7-1 27——271
    • short 型数据,即 16 位采样位数的取值范围 − 2 15 —— 2 15 − 1 -2^{15}——2^{15}-1 215——2151
    • int 型数据, 即 32 位采样位数的取值范围 − 2 31 —— 2 31 − 1 -2^{31}——2^{31}-1 231——2311

源码实现

#include <stdio.h>
#include <math.h>
#include <stdint.h>

#define SAMPLE_POINT_NUM        (64)        /* 需要生成的点的个数 */

#define SAMPLE_RATE             (48000)     /* 48KHz */
#define SAMPLE_BIT              (16)        /* 采样位数 */
#define SINE_CHANNEL            (1)         /* 采样声道数 */

#define PI                      (3.1415926) /* 数学中的常量:Π */
#define POINT_BUFFER_LEN        (128)

int generate_data[POINT_BUFFER_LEN];        /* 生成的数据放在此数组中 */

int get_sin_max(int sample_bit)
{
    int value = 2;

    for (int i = 0; i < sample_bit - 1; i++)
    {
        value = value * 2;
    }

    return value - 1;
}

void get_sin_data(unsigned int point)
{
    float step = 0.0;
    float data = 0.0;
    int sin_max_data;

    sin_max_data = get_sin_max(SAMPLE_BIT - 1);

    step = 2 * PI / SAMPLE_RATE; /* 采样频率表示采样数据之间的时间间隔 */
    step *= SAMPLE_RATE / point; /* 只取 point 个点,所以真正的 step 需要乘 SAMPLE_RATE / point */

    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 3211 6392 9511 12539 15446 18204 20787 23169 25329 27244 28897 30272 31356 32137 32609 32767 32609 32137 31356 30272 28897 27244 25329 23169 20787 18204 15446 12539 9511 6392 3211 0 -3211 -6392 -9511 -12539 -15446 -18204 -20787 -23169 -25329 -27244 -28897 -30272 -31356 -32137 -32609 -32767 -32609 -32137 -31356 -30272 -28897 -27244 -25329 -23169 -20787 -18204 -15446 -12539 -9511 -6392 -3211

从生成的数据中可以看出,数据的最大最小值分别为 32767-32767

波形

将上述数据用散点图绘制出来如下图

在这里插入图片描述

I2S 输出

数据通路

flash -> I2S master SDATAO -> AP

AP 仪器测试

波形测试

图片待补充

FFT 测试

图片待补充

THD+N 测试

THD+N 理论值计算
图片待补充

SNR 测试

图片待补充
THD+N 理论值计算

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/362109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP状态详解

TCP Tcp wrappers : Transmission Control Protocol (TCP) Wrappers 为由 inetd 生成的服务提供了增强的安全性。TCP Wrappers 是一种对使用 /etc/inetd.sec 的替换方法。TCP Wrappers 提供防止主机名和主机地址欺骗的保护。欺骗是一种伪装成有效用户或主机以获得对系统进行未…

线程的基本概念

文章目录基础概念线程与进程什么是进程&#xff1f;什么是线程&#xff1f;进程和线程的区别&#xff1a;多线程什么是多线程&#xff1f;多线程的局限性串行、并行、并发同步异步、阻塞非阻塞线程的创建1、继承Thread类&#xff0c;重写run方法2、实现Runnable接口&#xff0c…

Tomcat的类加载机制

不遵循双亲委托 在JVM中并不是一次性地把所有的文件都加载到&#xff0c;而是按需加载&#xff0c;加载机制采用 双亲委托原则&#xff0c;如下图所示&#xff1a; BootStrapClassLoader 引导类加载器ExtClassLoader 扩展类加载器AppClassLoader 应用类加载器CustomClassLoad…

位姿图优化(CeresG2OGTSAM)

0. 简介 作为SLAM中常用的方法&#xff0c;其原因是因为SLAM观测不只考虑到当前帧的情况&#xff0c;而需要加入之前状态量的观测。就比如一个在二维平面上移动的机器人&#xff0c;机器人可以使用一组传感器&#xff0c;例如车轮里程计或激光测距仪。从这些原始测量值中&…

Python用selenium实现自动登录和下单的脚本

前言 学python对selenium应该不陌生吧 Selenium 是最广泛使用的开源 Web UI&#xff08;用户界面&#xff09;自动化测试套件之一。Selenium 支持的语言包括C#&#xff0c;Java&#xff0c;Perl&#xff0c;PHP&#xff0c;Python 和 Ruby。目前&#xff0c;Selenium Web 驱动…

打游戏哪种蓝牙耳机比较好?适合玩游戏的无线蓝牙耳机

2023年耳机市场一如既往地卷&#xff0c;不只是卷音质&#xff0c;还在外观和功能上做了许多的改进&#xff0c;以至于现在哪怕不懂耳机的人从各电商平台都能闭眼入一个款平价品牌耳机且极少会踩雷&#xff0c;玩游戏是当前年轻人的娱乐方式&#xff0c;下面整理了几款适合玩游…

Git push报错DeployKey does not support push code

错误描述用Git从本地仓库上传服务器仓库报错&#xff1a;DeployKey does not support push code错误代码&#xff1a;(通过$ git push origin master命令从本地仓库上传到服务器仓库)错误原因&#xff1a;没有注册ssh公钥解决办法&#xff1a;添加ssh公钥&#xff1a;先生成对应…

滤波算法 | 无迹卡尔曼滤波(UKF)算法及其MATLAB实现

目录简介UKF滤波滤波流程和公式MATLAB程序结论简介 本文接着分享位姿跟踪和滤波算法中用到的一些常用程序&#xff0c;希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章&#xff1a;位姿跟踪 | 相关内容目录和链接总结&#xff08;不断更新中~~~&#xff09; 本…

代码随想录算法训练营第六天 |哈希表理论基础、242.有效的字母异位词、349. 两个数组的交集 、202. 快乐数、 1. 两数之和

打卡第六天&#xff0c;补昨天的卡 今日任务 哈希表理论基础242.有效的字母异位词349.两个数组的交集202.快乐数1.两数之和 哈希表理论基础 哈希表是根据关键码的值而直接进行访问的数据结构。 哈希表能解决什么问题呢? 一般哈希表都是用来快速判断一个元素是否出现集合里。 …

JavaDoc生成API文档(powernode document)(内含源代码和导出的文档)

JavaDoc生成API文档&#xff08;powernode document&#xff09;&#xff08;内含源代码和导出的文档&#xff09; 源代码和导出的文档下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87473296 目录JavaDoc生成API文档&#xff08;powernode do…

恺望数据:解决智驾数据生产痛点,提供自动化生产线和规模化人力

最近Chat GPT引起了一个热点话题&#xff0c;就是人工智能是否真的可以替代人类工作&#xff0c;特别是在需要进行数据标注等需要人力的领域。 自动驾驶数据服务公司恺望数据在最近的一个会议上透露了一些消息&#xff0c;他们已经推出了一个基于自动化的数据生产系统&#xff…

linux下安装minio

获取 MinIO 下载 URL:访问&#xff1a;https://docs.min.io/ 一&#xff0c;进入/opt 目录&#xff0c;创建minio文件夹 cd /optmkdir minio二&#xff0c;wget下载安装包 wget https://dl.minio.io/server/minio/release/linux-amd64/minio三&#xff0c;进入minio文件夹创建…

蓝海创意云vLive虚拟直播亮相2023昆山元宇宙产品展览会

2月15日-19日&#xff0c;由中国计算机行业协会“元宇宙创见未来”2023元宇宙产品展览会在江苏昆山隆重召开&#xff0c;共吸引了省内外32家企业参展&#xff0c;展出近百款元宇宙产品或技术&#xff0c;涵盖芯片、显示、VR、AR等硬件设备&#xff0c;以及工业、文旅、娱乐、教…

golang及goland的安装

1.电脑环境 2.软件下载 链接&#xff1a;https://pan.baidu.com/s/1YHM_jazftwkqRAuxJqMHZg 提取码&#xff1a;cdbm go1.17.5.windows-amd64.msi是go语言的开发及运行环境类似于Java的JDK。 goland-2020.2.2.exe 是go语言的开发工具(IDE),类似于Java的 Intelli J IDEA。 3…

【计算机网络】应用题方法总结

0.前言本篇博客主要记录自己在学习到的部分解决计算机网络应用题方法&#xff0c;主要参考视频如下&#xff1a;计算机网络期末复习 应用题_哔哩哔哩_bilibili【计算机网络】子网划分题型总结_哔哩哔哩_bilibili循环冗余码step 1&#xff1a;确定冗余码长度。多项式最高位即为冗…

阶段二11_面向对象高级_学生管理系统案例1

说明&#xff1a;学生管理系统案例需求和步骤1请查看上一张《阶段二10_面向对象高级_分类分包思想》 一.学生管理系统案例 步骤2&#xff1a;搭建主菜单和学生管理系统菜单 (0).主菜单和学习菜单界面和思路 界面&#xff1a; --------欢迎来到信息管理系统-------- 请输入您的…

CMake编译opencv4.6

openCV系列文章目录 文章目录openCV系列文章目录前言一、准备工作二、使用步骤1.使用CMake编译openCV总结前言 最近在项目中遇到图片处理&#xff0c;一拍脑袋就想到大名鼎鼎的opencv 一、准备工作 1.openCV官网下载 2.CMake官方下载 3.vs2019官方下载 二、使用步骤 1.使用…

[ vulhub漏洞复现篇 ] Drupal XSS漏洞 (CVE-2019-6341)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用

无意中从网络获取一份俄罗斯方块源码,基于图形视图框架(Graphics View Framework)实现的。当然源码的核心从来都不是界面,而是方块的移动、变形和消除等算法。源码非常完整,注释详细,经改动后已能在Qt5中运行,下面是运行效果,背景音乐和音效也是有的。 一.效果 二.原理 …

Spring MVC 源码 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

HandlerMapping 组件HandlerMapping 组件&#xff0c;请求的处理器匹配器&#xff0c;负责为请求找到合适的 HandlerExecutionChain 处理器执行链&#xff0c;包含处理器&#xff08;handler&#xff09;和拦截器们&#xff08;interceptors&#xff09;handler 处理器是 Objec…