Ubuntu 下播放语音提示
目录
一、安装语音库
二、生成音频文件
三、语音播放代码
一、安装语音库
sudo apt update
apt-get install libasound2-dev
二、生成音频文件
# 文字生成 MP3网地:https://www.text-to-speech.cn/# MP3 转 WAV网址:https://www.aconvert.com/cn/audio/mp3-to-wav/
三、语音播放代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alsa/asoundlib.h>#pragma pack(1)
struct tagWavHeader
{char riff[4]; // RIFF标志int chunk_size; // 文件大小char type[4]; // 格式类型(wave)char fmt[4]; // "fmt"int subchunk_size; // sizeof(wave format matex)short audio_format; // 音频格式short channel_nums; // 声道数int sample_rate; // 采样率int byte_rate; // 比特率short block_align; // 块对齐short bits_per_sample; // 每个采样点的位数char data[4]; // ”data“int data_size; // 音频数据的大小
};
#pragma pack()void play_volume_set(long volume) {snd_mixer_t* handle;snd_mixer_open(&handle, 0);snd_mixer_attach(handle, "default");snd_mixer_selem_register(handle, NULL, NULL);snd_mixer_load(handle);snd_mixer_selem_id_t* sid;snd_mixer_selem_id_alloca(&sid);snd_mixer_selem_id_set_index(sid, 0);snd_mixer_selem_id_set_name(sid, "Master");long min = 0, max = 0;snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);snd_mixer_selem_get_playback_volume_range(elem, &min, &max);snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);snd_mixer_close(handle);
}int play_wav_file(const char* wav_file_path) {if (access(wav_file_path, F_OK) != 0) {printf("audio file (%s) not exist.", wav_path);return -1001;}FILE* fp = fopen(wav_file_path, "r+b");if (fp == NULL) {perror("\n fopen() failed: ");return -1002;}struct tagWavHeader wav_header;memset(&wav_header, 0, sizeof(wav_header));int rc = fread(&wav_header, 1, sizeof(wav_header), fp);printf("\n wav_header_size = %d", rc);if (rc == 0) {fclose(fp);return -1003;}snd_pcm_t* dev_handle;print_audio_info(wav_header);rc = snd_pcm_open(&dev_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);if (rc < 0) {perror("\n snd_pcm_open() failed: ");fclose(fp);return -1004;}// 初始化结构体snd_pcm_hw_params_t* dev_params;snd_pcm_hw_params_alloca(&dev_params);rc = snd_pcm_hw_params_any(dev_handle, dev_params);if (rc < 0) {perror("\n snd_pcm_hw_params_any() failed: ");snd_pcm_close(dev_handle);fclose(fp);return -1005;}// 初始化参数权限rc = snd_pcm_hw_params_set_access(dev_handle, dev_params, SND_PCM_ACCESS_RW_INTERLEAVED);if (rc < 0) {perror("\n snd_pcm_hw_params_set_access() failed: ");snd_pcm_close(dev_handle);fclose(fp);return -1006;}// 设置采样的位数int bit = wav_header.bits_per_sample;switch (bit / 8) {case 1:snd_pcm_hw_params_set_format(dev_handle, dev_params, SND_PCM_FORMAT_U8);break;case 2:snd_pcm_hw_params_set_format(dev_handle, dev_params, SND_PCM_FORMAT_S16_LE);break;case 3:snd_pcm_hw_params_set_format(dev_handle, dev_params, SND_PCM_FORMAT_S24_LE);break;}// 设置声道播放(1表示单声>道,2表示立体声)int channel = wav_header.channel_nums;rc = snd_pcm_hw_params_set_channels(dev_handle, dev_params, channel);if (rc < 0) {perror("\n snd_pcm_hw_params_set_channels() failed: ");snd_pcm_close(dev_handle);fclose(fp);return -1007;}// 设置语音的播放频率int frequency = wav_header.sample_rate;int dir = 0; unsigned int freq = frequency;rc = snd_pcm_hw_params_set_rate_near(dev_handle, dev_params, &freq, &dir);if (rc < 0) {perror("\n snd_pcm_hw_params_set_rate_near() failied: ");snd_pcm_close(dev_handle);fclose(fp);return -1008;}// 更新播放参数到设备rc = snd_pcm_hw_params(dev_handle, dev_params);if (rc < 0) {perror("\n snd_pcm_hw_params() failed: ");snd_pcm_close(dev_handle);fclose(fp);return -1009;}// 获取播放周期长度snd_pcm_uframes_t frames = 0;rc = snd_pcm_hw_params_get_period_size(dev_params, &frames, &dir);if (rc < 0) {perror("\n snd_pcm_hw_params_get_period_size() failed: ");snd_pcm_close(dev_handle);fclose(fp);return -1010;}// 定位到音频的数据区fseek(fp, 58, SEEK_SET);snd_pcm_sframes_t frame_num = 0;int size = frames * wav_header.block_align;char* buffer = (char*)malloc(size);while (true) {memset(buffer, 0, size);int rv = fread(buffer, 1, size, fp);if (rv == 0) {printf("\n end of wav audio file");break;}// 下面开始写音频数据到 PCM 设备上进行播放while ((frame_num = snd_pcm_writei(dev_handle, buffer, frames)) < 0) {usleep(2000);if (frame_num == -EPIPE) {// EPIPE means underrunfprintf(stderr, "underrun occurred \n");// 完成参数设置,准备好设备snd_pcm_prepare(dev_handle);} else if (frame_num < 0) {fprintf(stderr, "snd_pcm_writei() failed: %s\n", snd_strerror(frame_num));}}}snd_pcm_drain(dev_handle);snd_pcm_close(dev_handle);free(buffer);fclose(fp);return 0;
}
相关文章:
Ubuntu 下播放语音提示
目录 一、安装语音库 二、生成音频文件 三、语音播放代码 一、安装语音库 sudo apt update apt-get install libasound2-dev二、生成音频文件 # 文字生成 MP3网地:https://www.text-to-speech.cn/# MP3 转 WAV网址:https://www.aconvert.com/cn/aud…...
ubuntu 用户管理
ubuntu 用户管理 用户组管理用户管理VNC 远程桌面参考 用户组管理 # 查看所有组信息 cat /etc/group # 查看当前用户所在组 groups # 添加用户组 sudo groupadd uav# 添加ostest用户到 uav 用户组 需要注销并重新登录 sudo gpasswd -a ostest uav sudo usermod -aG uav ostes…...

轻舟已过万重山,鸿蒙4.0程序员危机
现在是2023年末。自从华为推出的鸿蒙系统到现在已经有4年多。之前的鸿蒙系统只是基于Android套壳,因为这也也被无数人瞧不起,自从华为秋季发布会后,宣布鸿蒙4.0问世。不再兼容Android,华为做独立的系统终于打了翻身仗。 鸿蒙系统…...

【Pytorch】学习记录分享6——PyTorch经典网络 ResNet与手写体识别
【Pytorch】学习记录分享5——PyTorch经典网络 ResNet 1. ResNet (残差网络)基础知识2. 感受野3. 手写体数字识别3. 0 数据集(训练与测试集)3. 1 数据加载3. 2 函数实现:3. 3 训练及其测试: 1. ResNet &…...

Flink1.17实战教程(第三篇:时间和窗口)
系列文章目录 Flink1.17实战教程(第一篇:概念、部署、架构) Flink1.17实战教程(第二篇:DataStream API) Flink1.17实战教程(第三篇:时间和窗口) Flink1.17实战教程&…...

CSS 纵向扩展动画
上干货 <template><!-- mouseenter"startAnimation" 表示在鼠标进入元素时触发 startAnimation 方法。mouseleave"stopAnimation" 表示在鼠标离开元素时触发 stopAnimation 方法。 --><!-- 容器元素 --><div class"container&q…...
Android 12 Token 机制
一、前言 在 android framework 框架中 activity 和 window 是相互关联的,而他们的管理者 AMS 和 WMS 是怎么来实现这种关联关系的,答案就是通过 token。 首先大家需要了解一下 LayoutParams,当然属性很多,简单了解即可…...
TCP与UDP是流式传输协议吗?
TCP(传输控制协议)和UDP(用户数据报协议)是两种主要的传输层协议,它们用于在网络中传输数据。它们不是流式传输协议,而是提供了不同的数据传输特性: 1. TCP(传输控制协议࿰…...
61 贪心算法解救生艇问题
问题描述:第i个人的体重为peaple[i],每个船可以承载的最大重量为limit。每艘船最多可以同时载两人,但条件是这些人的重量之和最多为limit,返回载到每一个人多虚的最小船数,(保证每个人被船载)。 贪心算法求解:先将数组…...

C#高级 01.Net多线程
一.基本概念 1.什么是线程? 线程是操作系统中能独立运行的最小单位,也是程序中能并发执行的一段指令序列线程是进程的一部分,一个进程可以包含多个线程,这些线程共享进程资源进程有线程入口,也可以创建更多的线程 2.…...

Java---泛型讲解
文章目录 1. 泛型类2. 泛型方法3. 泛型接口4. 类型通配符5. 可变参数6. 可变参数的使用 1. 泛型类 1. 格式:修饰符 class 类名 <类型>{ }。例如:public class Generic <T>{ }。 2. 代码块举例: public class Generic <T>{…...

【论文阅读笔记】SegVol: Universal and Interactive Volumetric Medical Image Segmentation
Du Y, Bai F, Huang T, et al. SegVol: Universal and Interactive Volumetric Medical Image Segmentation[J]. arXiv preprint arXiv:2311.13385, 2023.[代码开源] 【论文概述】 本文思路借鉴于自然图像分割领域的SAM,介绍了一种名为SegVol的先进医学图像分割模型…...
Unix/Linux操作系统介绍
1、Unix/Linux操作系统介绍 1.1、操作系统的作用 1)操作系统的目标 方便:使计算机系统易于使用有效:以更有效的方式使用计算机系统资源扩展:方便用户有效开发、测试、引进新功能 2)操作系统的地位 操作系统在计算…...

什么是https证书?
HTTPS证书,也称为SSL(Secure Sockets Layer)证书或TLS(Transport Layer Security)证书,是一种数字证书,用于在网络上建立安全的加密连接。它的主要目的是确保在互联网上进行的数据传输的安全性和…...

C++ DAY2作业
1.课堂struct练习,用class; #include <iostream>using namespace std;class Stu { private:int age;char sex;int high; public:double score;void set_values(int a,char b,int c,double d);int get_age();char get_sex();int get_high(); }; vo…...

RabbitMQ核心概念记录
本文来记录下RabbitMQ核心概念 文章目录 什么叫消息队列为何用消息队列RabbitMQ简介RabbitMQ基本概念RabbitMQ 特点具体特点包括 Rabbitmq的工作过程RabbitMQ集群RabbitMQ 的集群节点包括Rabbit 模式大概分为以下三种单一模式普通模式镜像模式 本文小结 什么叫消息队列 消息&am…...

算法时间空间复杂度计算—空间复杂度
算法时间空间复杂度计算—空间复杂度 空间复杂度定义影响空间复杂度的因素算法在运行过程中临时占用的存储空间讲解 计算方法例子1、空间算法的常数阶2、空间算法的线性阶(递归算法)3、二分查找分析方法一(迭代法)方法二ÿ…...
计算机专业校招常见面试题目总结
博主面试岗位包括:java开发、软件测试、测试开发等岗位,基于之前经历的面试总结出的一些常见题目。仅供参考,互相学习!! 八股:java开发、测试、测开岗位 Java技术栈:Java基础、JVM、数据结构、…...

网络编程『简易TCP网络程序』
🔭个人主页: 北 海 🛜所属专栏: Linux学习之旅、神奇的网络世界 💻操作环境: CentOS 7.6 阿里云远程服务器 文章目录 🌤️前言🌦️正文TCP网络程序1.字符串回响1.1.核心功能1.2.程序…...

java itext5 生成PDF并填充数据导出
java itext5 生成PDF并填充数据导出 依赖**文本勾选框****页眉**,**页脚****图片**实际图 主要功能有文本勾选框,页眉,页脚,图片等功能。肯定没有专业软件画的好看,只是一点儿方法。仅供参考。 依赖 <!--pdf-->&…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...