当前位置: 首页 > news >正文

[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文件

//代码&#xff1a;循环播放4首内置的wav音乐&#xff0c;I2S连接d类功放用NS4168芯片 //文件取样格式&#xff1a;Wave PCM 签字的 16bit, 采样频率:16KHz ,比特率705kbps //demo工程打包下载&#xff1a;https://download.csdn.net/download/wabil/89515015 #include <…...

YOLOv8

YOLOv8 设计快速、准确且易于使用&#xff0c;使其成为各种物体检测与跟踪、实例分割、图像分类和姿态估计任务的绝佳选择框架 1.安装YOLOv8 创建虚拟环境 conda create --name ros2 python3.10 激活虚拟环境 conda activate ros2 安装组件 pip install ultralytics -i h…...

协程调度模块

什么是协程和协程调度&#xff1f; 基本概念 协程 协程是一种比线程更轻量级的并发编程结构&#xff0c;它允许在函数执行过程中暂停和恢复执行状态&#xff0c;从而实现非阻塞式编程。协程又被称为用户级线程&#xff0c;这是由于协程包括上下文切换在内的全部执行逻辑都是…...

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的文本处理能力&#xff1a;精通查找与替换 Vim&#xff0c;作为Linux终端下的王牌文本编辑器&#xff0c;以其强大的功能和灵活性深受开发者和系统管理员的喜爱。在Vim中进行查找和替换是文本编辑中的一项基础且重要的操作。本文将详细解释如何在Vim中执行查找和替换文…...

2024.7.4学习日报

1、ppt前三章 5日计划 1、至少做到实验 2、java...

享元模式(Flyweight Pattern)

享元模式&#xff08;Flyweight Pattern&#xff09; 定义 享元模式通过共享技术来支持大量细粒度的对象&#xff0c;以减少内存中的对象数量。其核心思想是将对象的状态分为内部状态和外部状态&#xff0c;内部状态是不变的&#xff0c;可以被多个对象共享&#xff1b;外部状…...

Oracle连接mysql

oracle使用的11g&#xff0c;在一台windows服务器&#xff1b;mysql使用的是5.7版本&#xff0c;在另一台windows服务器&#xff0c;这两个服务器之间的网络是互通的。做BI时&#xff0c;要获取不同数据源的数据&#xff0c;这些数据源可能是Oracle&#xff0c;也可能是sqlserv…...

golang 垃圾回收

gc不回收什么 GC 不负责回收栈中的内存栈是一块专用内存&#xff0c;专门为了函数执行而准备的&#xff0c;存储着函数中的局部变量以及调用栈栈中的数据可以通过简单的编译器指令自动清理&#xff0c;也就不需要通过 GC 来回收了 垃圾回收算法 主流的两类垃圾回收算法有两种&a…...

React 中如何使用 Monaco

Monaco 是微软开源的一个编辑器&#xff0c;VSCode 也是基于 Monaco 进行开发的。如果在 React 中如何使用 Monaco&#xff0c;本文将介绍如何在 React 中引入 Monaco。 安装 React 依赖 yarn add react-app-rewired --dev yarn add monaco-editor-webpack-plugin --dev yarn…...

开源RAG个人知识库项目开发分析

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;这个LLM开发基础阶段已经进入尾声了&#xff0c;本文中我们不介绍更多的理论与知识点&#xff0c;而是通过的分析开源项目的解决方案来帮助各位开发者理…...

事务底层与高可用原理

1.事务底层与高可用原理 事务的基础知识 mysql的事务分为显式事务和隐式事务 默认的事务是隐式事务 显式事务由我们自己控制事务的开启&#xff0c;提交&#xff0c;回滚等操作 show variables like autocommit; 事务基本语法 事务开始 1、begin 2、START TRANSACTION&…...

树状数组基础知识

lowbit: lowbit(x)x&(-x) 树状数组&#xff1a; 树状数组的功能&#xff1a; 数组 在O(1)的时间复杂度实现单点加&#xff1a; 在O(lng n)的时间复杂度实现查询前缀和&#xff1a; 树状数组的定义&#xff1a; 查询前x项的和操作&#xff1a; ll query(int x){ll s0;f…...

【3分钟准备前端面试】vue3

目录 Vue3比vue2有什么优势vue3升级了哪些重要功能生命周期变化Options APIComposition APIreftoRef和toRefstoReftoRefsHooks (代码复用)Vue3 script setupsetupdefineProps和defineEmitsdefineExposeVue3比vue2有什么优势 性能更好体积更小更好的TS支持更好的代码组织更好的逻…...

【数据采集】亮数据浏览器、亮网络解锁器实战指南

前言 继上次我们写了数据采集与AI分析&#xff0c;亮数据通义千问助力跨境电商前行的文章之后&#xff0c;好多小伙伴来后台留言&#xff0c;表示对亮数据的数据采集非常感兴趣&#xff0c;并且感觉用起来非常顺手&#xff0c;大大减少了小白用户获取数据的成本。 在这儿&…...

暑期编程预习指南

暑期编程预习指南 高考结束后&#xff0c;迎来的是一段难得的假期时光。对于那些有志于踏入IT领域的高考生来说&#xff0c;这段时间无疑是一个重要的起点。为了帮助你们更好地利用这个假期&#xff0c;为未来的学习和职业生涯打下坚实的基础&#xff0c;特此提供一份编程预习…...

将带有 商店idr 商品信息的json导入到mongodb后,能不能根据商店id把所有商品全部提取并转为电子表格

当您已经将包含商店ID&#xff08;如realMallId&#xff09;的商品信息导入MongoDB后&#xff0c;确实可以轻松地根据商店ID提取所有相关商品信息并转换为电子表格&#xff08;例如Excel&#xff09;。这里是一个简化的流程&#xff0c;使用Python的pymongo库来查询MongoDB&…...

深入解析 androidx.databinding.BaseObservable

在现代 Android 开发中&#xff0c;数据绑定 (Data Binding) 是一个重要的技术&#xff0c;它简化了 UI 和数据之间的交互。在数据绑定框架中&#xff0c;androidx.databinding.BaseObservable 是一个关键类&#xff0c;用于实现可观察的数据模型。本文将详细介绍 BaseObservab…...

MySQL数据恢复(适用于误删后马上发现)

首先解释一下标题&#xff0c;之所以适用于误删后马上发现是因为太久了之后时间和当时操作的数据表可能会记不清楚&#xff0c;不是因为日志丢失 1.首先确保自己的数据库开启了binlog&#xff08;我的是默认开启的我没有配置过&#xff09; 根据这篇博客查看自己的配置和自己…...

[数据结构】——七种常见排序

文章目录 前言 一.冒泡排序二.选择排序三.插入排序四.希尔排序五.堆排序六.快速排序hoare挖坑法前后指针快排递归实现&#xff1a;快排非递归实现&#xff1a; 七、归并排序归并递归实现&#xff1a;归并非递归实现&#xff1a; 八、各个排序的对比图 前言 排序&#xff1a;所谓…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...