[ESP32] I2S播放wav文件
//代码:循环播放4首内置的wav音乐,I2S连接d类功放用NS4168芯片
//文件取样格式:Wave PCM 签字的 16bit, 采样频率:16KHz ,比特率705kbps
//demo工程打包下载:https://download.csdn.net/download/wabil/89515015
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "esp_system.h"
#include "esp_check.h"
#include "esp_log.h"/* Example configurations */
#define EXAMPLE_SAMPLE_RATE (16000) // 16KHZ
#define EXAMPLE_MCLK_MULTIPLE (384) // If not using 24-bit data width, 256 should be enough
#define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE)
#define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME/* I2S port and GPIOs */
#define I2S_NUM (0)
#define I2S_MCK_IO (GPIO_NUM_1) //[No used]
#define I2S_BCK_IO (GPIO_NUM_36) // SerialCK
#define I2S_WS_IO (GPIO_NUM_35) // LRCK
#define I2S_DO_IO (GPIO_NUM_37) // SDATA out
#define I2S_DI_IO (GPIO_NUM_19) // SDATA in for micphone [No used]static const char *TAG = "i2s_ns4168";
static const char err_reason[][30] = {"input param is invalid", "operation timeout"};
static i2s_chan_handle_t tx_handle = NULL;
static i2s_chan_handle_t rx_handle = NULL;/* Import music file as buffer */#define DECLARE_WAV_START(SND) extern const uint8_t SND##_wav_start[] asm("_binary_" #SND "_wav_start")
#define DECALARE_WAV_END(SND) extern const uint8_t SND##_wav_end[] asm("_binary_" #SND "_wav_end")DECLARE_WAV_START(Snd01);
DECALARE_WAV_END(Snd01);DECLARE_WAV_START(Snd02);
DECALARE_WAV_END(Snd02);DECLARE_WAV_START(Snd03);
DECALARE_WAV_END(Snd03);DECLARE_WAV_START(Snd_Hotel); // california_hotel
DECALARE_WAV_END(Snd_Hotel);const uint8_t *music_group[][2] = {{&Snd01_wav_start, &Snd01_wav_end},{&Snd02_wav_start, &Snd02_wav_end},{&Snd03_wav_start, &Snd03_wav_end},{&Snd_Hotel_wav_start, &Snd_Hotel_wav_end},};esp_err_t play_snd_id(uint8_t snd_id, uint32_t timeout_ms)
{uint8_t *data_ptr_start = (uint8_t *)music_group[snd_id][0];uint8_t *data_ptr_end = (uint8_t *)music_group[snd_id][1];size_t data_len = data_ptr_end - data_ptr_start;uint32_t bytes_write = 0;// ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));vTaskDelay(150 / portTICK_PERIOD_MS);uint32_t tick1 = esp_log_timestamp();printf("[%ld] read to play:%d ,length:%d bytes.\n", tick1, snd_id, data_len);esp_err_t ret = i2s_channel_write(tx_handle, data_ptr_start, data_len, &bytes_write, timeout_ms);uint32_t tick2 = esp_log_timestamp();printf("[%ld] end play,written:%ld,take:%ld ms\n", tick2,bytes_write, tick2 - tick1);vTaskDelay(150 / portTICK_PERIOD_MS);// ESP_ERROR_CHECK(i2s_channel_disable(tx_handle));if (ret != ESP_OK){ESP_LOGE(TAG, "[music] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);abort();}if (bytes_write <= 0){ESP_LOGE(TAG, "[music] i2s music play failed.");abort();}return ret;
}static esp_err_t i2s_driver_init(void)
{i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA bufferESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));i2s_std_config_t std_cfg = {.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),.gpio_cfg = {.mclk = I2S_MCK_IO,.bclk = I2S_BCK_IO,.ws = I2S_WS_IO,.dout = I2S_DO_IO,.din = I2S_DI_IO,.invert_flags = {.mclk_inv = false,.bclk_inv = false,.ws_inv = false,},},};std_cfg.clk_cfg.mclk_multiple = EXAMPLE_MCLK_MULTIPLE;ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg));ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg));ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));return ESP_OK;
}static void i2s_music_task(void *args)
{esp_err_t ret = ESP_OK;size_t bytes_write = 0;uint8_t *data_ptr = (uint8_t *)Snd01_wav_start;bytes_write = Snd01_wav_end - Snd01_wav_start;printf("the music bin data length:%d bytes.start_addr:%p\n", bytes_write, data_ptr);/* (Optional) Disable TX channel and preload the data before enabling the TX channel,* so that the valid data can be transmitted immediately */ESP_ERROR_CHECK(i2s_channel_disable(tx_handle));ESP_ERROR_CHECK(i2s_channel_preload_data(tx_handle, data_ptr, Snd01_wav_end - data_ptr, &bytes_write));// data_ptr += bytes_write; // Move forward the data pointerprintf("preload data length:%d.EXAMPLE_SAMPLE_RATE=%d\n", bytes_write, EXAMPLE_SAMPLE_RATE);/* Enable the TX channel */ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));vTaskDelay(5000 / portTICK_PERIOD_MS);uint8_t snd_id = 0;while (1){play_snd_id(snd_id, portMAX_DELAY);snd_id = (snd_id + 1) % 4; // 共4个wav音效vTaskDelay(3000 / portTICK_PERIOD_MS);}vTaskDelete(NULL);
}void app_main(void)
{// 634240 bytes are writtenprintf("I2S_NS4168: BCK=%d,WS=%d,DAT_IO=%d.\n", I2S_BCK_IO, I2S_WS_IO, I2S_DO_IO);/* Initialize i2s peripheral */if (i2s_driver_init() != ESP_OK){ESP_LOGE(TAG, "i2s driver init failed");abort();}else{ESP_LOGI(TAG, "i2s driver init success");}xTaskCreate(i2s_music_task, "i2s_music_task", 4096, NULL, 5, NULL);
}
相关文章:
[ESP32] I2S播放wav文件
//代码:循环播放4首内置的wav音乐,I2S连接d类功放用NS4168芯片 //文件取样格式:Wave PCM 签字的 16bit, 采样频率:16KHz ,比特率705kbps //demo工程打包下载:https://download.csdn.net/download/wabil/89515015 #include <…...
YOLOv8
YOLOv8 设计快速、准确且易于使用,使其成为各种物体检测与跟踪、实例分割、图像分类和姿态估计任务的绝佳选择框架 1.安装YOLOv8 创建虚拟环境 conda create --name ros2 python3.10 激活虚拟环境 conda activate ros2 安装组件 pip install ultralytics -i h…...
协程调度模块
什么是协程和协程调度? 基本概念 协程 协程是一种比线程更轻量级的并发编程结构,它允许在函数执行过程中暂停和恢复执行状态,从而实现非阻塞式编程。协程又被称为用户级线程,这是由于协程包括上下文切换在内的全部执行逻辑都是…...
2024 最新docker仓库镜像,6月,7月
目前下面的docker仓库镜像源还能使用。 vi /etc/docker/daemon.json添加如下配置{"registry-mirrors": ["https://hub.uuuadc.top", "https://docker.anyhub.us.kg", "https://dockerhub.jobcher.com", "https://dockerhub.icu&…...
探索Vim的文本处理能力:精通查找与替换
探索Vim的文本处理能力:精通查找与替换 Vim,作为Linux终端下的王牌文本编辑器,以其强大的功能和灵活性深受开发者和系统管理员的喜爱。在Vim中进行查找和替换是文本编辑中的一项基础且重要的操作。本文将详细解释如何在Vim中执行查找和替换文…...
2024.7.4学习日报
1、ppt前三章 5日计划 1、至少做到实验 2、java...
享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 定义 享元模式通过共享技术来支持大量细粒度的对象,以减少内存中的对象数量。其核心思想是将对象的状态分为内部状态和外部状态,内部状态是不变的,可以被多个对象共享;外部状…...
Oracle连接mysql
oracle使用的11g,在一台windows服务器;mysql使用的是5.7版本,在另一台windows服务器,这两个服务器之间的网络是互通的。做BI时,要获取不同数据源的数据,这些数据源可能是Oracle,也可能是sqlserv…...
golang 垃圾回收
gc不回收什么 GC 不负责回收栈中的内存栈是一块专用内存,专门为了函数执行而准备的,存储着函数中的局部变量以及调用栈栈中的数据可以通过简单的编译器指令自动清理,也就不需要通过 GC 来回收了 垃圾回收算法 主流的两类垃圾回收算法有两种&a…...
React 中如何使用 Monaco
Monaco 是微软开源的一个编辑器,VSCode 也是基于 Monaco 进行开发的。如果在 React 中如何使用 Monaco,本文将介绍如何在 React 中引入 Monaco。 安装 React 依赖 yarn add react-app-rewired --dev yarn add monaco-editor-webpack-plugin --dev yarn…...
开源RAG个人知识库项目开发分析
前言 Hello,大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者,这个LLM开发基础阶段已经进入尾声了,本文中我们不介绍更多的理论与知识点,而是通过的分析开源项目的解决方案来帮助各位开发者理…...
事务底层与高可用原理
1.事务底层与高可用原理 事务的基础知识 mysql的事务分为显式事务和隐式事务 默认的事务是隐式事务 显式事务由我们自己控制事务的开启,提交,回滚等操作 show variables like autocommit; 事务基本语法 事务开始 1、begin 2、START TRANSACTION&…...
树状数组基础知识
lowbit: lowbit(x)x&(-x) 树状数组: 树状数组的功能: 数组 在O(1)的时间复杂度实现单点加: 在O(lng n)的时间复杂度实现查询前缀和: 树状数组的定义: 查询前x项的和操作: ll query(int x){ll s0;f…...
【3分钟准备前端面试】vue3
目录 Vue3比vue2有什么优势vue3升级了哪些重要功能生命周期变化Options APIComposition APIreftoRef和toRefstoReftoRefsHooks (代码复用)Vue3 script setupsetupdefineProps和defineEmitsdefineExposeVue3比vue2有什么优势 性能更好体积更小更好的TS支持更好的代码组织更好的逻…...
【数据采集】亮数据浏览器、亮网络解锁器实战指南
前言 继上次我们写了数据采集与AI分析,亮数据通义千问助力跨境电商前行的文章之后,好多小伙伴来后台留言,表示对亮数据的数据采集非常感兴趣,并且感觉用起来非常顺手,大大减少了小白用户获取数据的成本。 在这儿&…...
暑期编程预习指南
暑期编程预习指南 高考结束后,迎来的是一段难得的假期时光。对于那些有志于踏入IT领域的高考生来说,这段时间无疑是一个重要的起点。为了帮助你们更好地利用这个假期,为未来的学习和职业生涯打下坚实的基础,特此提供一份编程预习…...
将带有 商店idr 商品信息的json导入到mongodb后,能不能根据商店id把所有商品全部提取并转为电子表格
当您已经将包含商店ID(如realMallId)的商品信息导入MongoDB后,确实可以轻松地根据商店ID提取所有相关商品信息并转换为电子表格(例如Excel)。这里是一个简化的流程,使用Python的pymongo库来查询MongoDB&…...
深入解析 androidx.databinding.BaseObservable
在现代 Android 开发中,数据绑定 (Data Binding) 是一个重要的技术,它简化了 UI 和数据之间的交互。在数据绑定框架中,androidx.databinding.BaseObservable 是一个关键类,用于实现可观察的数据模型。本文将详细介绍 BaseObservab…...
MySQL数据恢复(适用于误删后马上发现)
首先解释一下标题,之所以适用于误删后马上发现是因为太久了之后时间和当时操作的数据表可能会记不清楚,不是因为日志丢失 1.首先确保自己的数据库开启了binlog(我的是默认开启的我没有配置过) 根据这篇博客查看自己的配置和自己…...
[数据结构】——七种常见排序
文章目录 前言 一.冒泡排序二.选择排序三.插入排序四.希尔排序五.堆排序六.快速排序hoare挖坑法前后指针快排递归实现:快排非递归实现: 七、归并排序归并递归实现:归并非递归实现: 八、各个排序的对比图 前言 排序:所谓…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
