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-->&…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...

性能优化中,多面体模型基本原理
1)多面体编译技术是一种基于多面体模型的程序分析和优化技术,它将程序 中的语句实例、访问关系、依赖关系和调度等信息映射到多维空间中的几何对 象,通过对这些几何对象进行几何操作和线性代数计算来进行程序的分析和优 化。 其中࿰…...