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

Linux 下 alsa 库录音并保存为 WAV 格式

麦克风列表:

[jn@jn build]$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: AudioPCI [Ensoniq AudioPCI], device 0: ES1371/1 [ES1371 DAC2/ADC]Subdevices: 1/1Subdevice #0: subdevice #0
card 1: Camera [2K USB Camera], device 0: USB Audio [USB Audio]Subdevices: 1/1Subdevice #0: subdevice #0
[jn@jn build]$

alsa麦克风录音保存wav代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alsa/asoundlib.h>#define PCM_DEVICE "default"
#define FORMAT SND_PCM_FORMAT_S16_LE
#define CHANNELS 2
#define SAMPLE_RATE 44100
#define BITS_PER_SAMPLE 16
#define WAV_HEADER_SIZE 44// WAV 文件头
typedef struct {char riff[4];                // "RIFF"unsigned int overall_size;   // 文件大小 - 8char wave[4];                // "WAVE"char fmt_chunk_marker[4];    // "fmt "unsigned int length_of_fmt;  // 格式数据块大小unsigned short format_type;  // 格式类别 (PCM = 1)unsigned short channels;     // 通道数unsigned int sample_rate;    // 采样率unsigned int byterate;       // 每秒字节数unsigned short block_align;  // 一个样本的字节数unsigned short bits_per_sample;  // 每个样本的位数char data_chunk_header[4];   // "data"unsigned int data_size;      // 音频数据大小
} wav_header_t;// 生成WAV文件头
void write_wav_header(FILE *file, int channels, int sample_rate, int bits_per_sample, int data_size) {wav_header_t header;// 填写 WAV 文件头memcpy(header.riff, "RIFF", 4);header.overall_size = data_size + WAV_HEADER_SIZE - 8;memcpy(header.wave, "WAVE", 4);memcpy(header.fmt_chunk_marker, "fmt ", 4);header.length_of_fmt = 16;header.format_type = 1;  // PCMheader.channels = channels;header.sample_rate = sample_rate;header.byterate = sample_rate * channels * bits_per_sample / 8;header.block_align = channels * bits_per_sample / 8;header.bits_per_sample = bits_per_sample;memcpy(header.data_chunk_header, "data", 4);header.data_size = data_size;fwrite(&header, 1, sizeof(wav_header_t), file);
}// 主函数
int main() {unsigned int sample_rate = SAMPLE_RATE;int channels = CHANNELS;snd_pcm_uframes_t frames = 32;  // 每次读取32帧// 打开 ALSA PCM 设备snd_pcm_t *pcm_handle;snd_pcm_hw_params_t *params;snd_pcm_uframes_t frames_per_period;int pcm;pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_CAPTURE, 0);if (pcm < 0) {fprintf(stderr, "ERROR: Can't open \"%s\" PCM device. %s\n", PCM_DEVICE, snd_strerror(pcm));return -1;}// 设置硬件参数snd_pcm_hw_params_malloc(&params);snd_pcm_hw_params_any(pcm_handle, params);snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);snd_pcm_hw_params_set_format(pcm_handle, params, FORMAT);snd_pcm_hw_params_set_channels(pcm_handle, params, channels);snd_pcm_hw_params_set_rate_near(pcm_handle, params, &sample_rate, 0);snd_pcm_hw_params_set_period_size_near(pcm_handle, params, &frames, 0);pcm = snd_pcm_hw_params(pcm_handle, params);if (pcm < 0) {fprintf(stderr, "ERROR: Can't set hardware parameters. %s\n", snd_strerror(pcm));return -1;}snd_pcm_hw_params_get_period_size(params, &frames_per_period, 0);// 打开WAV文件并写入头部FILE *file = fopen("output.wav", "wb");if (!file) {fprintf(stderr, "ERROR: Can't open output file.\n");return -1;}write_wav_header(file, channels, sample_rate, BITS_PER_SAMPLE, 0);  // 先写入空的WAV头// 分配缓冲区int buffer_size = frames_per_period * channels * BITS_PER_SAMPLE / 8;char *buffer = (char *) malloc(buffer_size);// 录音循环int total_bytes = 0;while (total_bytes < SAMPLE_RATE * 5 * channels * BITS_PER_SAMPLE / 8) {  // 录音5秒pcm = snd_pcm_readi(pcm_handle, buffer, frames_per_period);if (pcm == -EPIPE) {fprintf(stderr, "XRUN.\n");snd_pcm_prepare(pcm_handle);} else if (pcm < 0) {fprintf(stderr, "ERROR: Can't read from PCM device. %s\n", snd_strerror(pcm));} else {fwrite(buffer, 1, buffer_size, file);total_bytes += buffer_size;}}// 更新 WAV 头部文件大小信息fseek(file, 0, SEEK_SET);write_wav_header(file, channels, sample_rate, BITS_PER_SAMPLE, total_bytes);// 清理free(buffer);fclose(file);snd_pcm_drain(pcm_handle);snd_pcm_close(pcm_handle);return 0;
}

相关文章:

Linux 下 alsa 库录音并保存为 WAV 格式

麦克风列表&#xff1a; [jnjn build]$ arecord -l **** List of CAPTURE Hardware Devices **** card 0: AudioPCI [Ensoniq AudioPCI], device 0: ES1371/1 [ES1371 DAC2/ADC]Subdevices: 1/1Subdevice #0: subdevice #0 card 1: Camera [2K USB Camera], device 0: USB Aud…...

使用stripe进行在线支付、退款、订阅、取消订阅功能(uniapp+h5)

stripe官网:Stripe 登录 | 登录 Stripe 管理平台 然后在首页当中打开测试模式,使用测试的公钥跟私钥进行开发 测试卡号 4242 4242 4242 4242 1234 567 在线支付 stripe的在线支付有两种,第一种就是无代码,第二中就是使用api进行自定义,一般来说推荐第二种进行开发 无…...

深度学习中常见的损失函数

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 深度学习中常见的损失函数 损失函数的作用 损失函数是衡量神经网络输出与真实标签之间差距的指标。在训练过程中&#xff0c;神经网络的目标是最小化损失函数的值。常见的损失函数包括均方误差&#xff08;MS…...

认识Linux及Linux的环境搭建

目录 1、什么是Linux2、Linux环境搭建2.1 下载安装 Xshell2.2 下载安装 VMware Workstation Pro2.3 选择适合自己系统 1、什么是Linux Linux&#xff0c;一般指GNU/Linux&#xff08;单独的Linux内核并不可直接使用&#xff0c;一般搭配GNU套件&#xff0c;故得此称呼&#xff…...

Java之线程篇三

​​​​​​​ 目录 线程状态 观察线程的所有状态 线程状态及其描述 线程状态转换 代码示例1 代码示例2 线程安全 概念 线程不安全的代码示例 线程不安全的原因 线程安全的代码示例-加锁 synchronized关键字 synchronized的特性 小结 形成死锁的四个必要条件 …...

Bootstrap动态设置表格title项

页面searchType <form id"formId"><div class"select-list"><ul><li><select name"searchType" id"searchType"><option value"1">按各节点统计</option><option value"…...

Arrays.sort()方法在Java中的使用:理论与实践

目录 一.概述 二.实现方式 三.具体介绍 1.基本数据类型数组 2.对象数组 1)使对象实现Comparable接口 2)为对象再专门实现一个比较器类 四.进阶技巧 1.基础类型数组实现自定义比较 2.如何进行逆序排序 3.lambda表达式实现比较器类 4.List的排序方法Collection.sort()…...

用AI写论文,千万不要这样用ChatGPT生成参考文献References!!

ChatGPT作为一种先进的语言大模型&#xff0c;被广泛用于生成文本&#xff0c;虽然用ChatGPT辅助论文写作已是大势所趋&#xff0c;但是&#xff0c;用于生成参考文献References的部分还是要谨慎对待。 在学术写作中&#xff0c;参考文献References扮演着至关重要的角色&#…...

Debian 12如何关闭防火墙

在Debian 12中&#xff0c;默认的防火墙管理工具是ufw&#xff08;Uncomplicated Firewall&#xff09;。您可以使用以下命令来关闭防火墙&#xff1a; 关闭防火墙&#xff1a; sudo ufw disable查看防火墙状态&#xff1a; sudo ufw status如果需要重新开启防火墙&#xff1a;…...

windows C++-并行编程-PPL任务并行(二)

延续任务 在异步编程中&#xff0c;一个异步操作在完成时调用另一个操作并将数据传递到其中的情况非常常见。 传统上&#xff0c;这使用回调方法来完成。 在并发运行时中&#xff0c;延续任务提供了同样的功能。 延续任务(也简称为“延续”)是一个异步任务&#xff0c;由另一个…...

快速了解 servlet(SpringMVC 的底层)

Servlet 是 Java EE&#xff08;现 Jakarta EE&#xff09;中用于处理 Web 请求的核心组件。它在 Web 应用程序的服务器端运行&#xff0c;负责接收和处理客户端&#xff08;如浏览器&#xff09;的请求&#xff0c;并生成响应。 尽管现代Web开发更多采用SpringMVC等框架&…...

QT中tr的作用是什么

在Qt框架中&#xff0c;tr() 函数是一个非常重要的宏&#xff0c;它用于国际化和本地化&#xff08;i18n和l10n&#xff09;支持。tr() 函数使得Qt应用程序能够根据不同的语言环境&#xff08;locale&#xff09;显示相应的翻译文本&#xff0c;从而支持多种语言。 具体来说&a…...

OpenCV结构分析与形状描述符(7)计算轮廓的面积的函数contourArea()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算轮廓的面积。 该函数计算轮廓的面积。与 moments 类似&#xff0c;面积是使用格林公式计算的。因此&#xff0c;返回的面积与你使用 drawCo…...

内网环境使用Docker部署Qwen2模型-vLLM篇

在此之前&#xff0c;我们已成功利用Docker与Ollama框架&#xff0c;在内网环境中部署了Qwen2模型。下面我们再来看一下使用Docker与vLLM框架部署Qwen2模型。 准备vLLM镜像 在一台具备网络环境的机器上执行以下命令&#xff0c;拉取vLLM的镜像&#xff1a; # 官方镜像 docke…...

Rust的常数、作用域与所有权

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust到底值不值得学&#xff0c;之一 -CSDN博客 Rust到底值不值得学&#xff0c;之二-CSDN博客 Rust的数据类型-CSDN博客 3.7 常…...

Spring 源码解读:解决循环依赖的三种方式

引言 在复杂的应用开发中&#xff0c;循环依赖是一个常见的问题。简单来说&#xff0c;循环依赖是指两个或多个Bean之间互相依赖&#xff0c;导致程序无法正常实例化这些Bean。Spring容器通过依赖注入&#xff08;DI&#xff09;来管理Bean的创建与生命周期&#xff0c;并在遇…...

Web3 详解

1. 使用 Web3 库 Web3 是一个 JavaScript 库&#xff0c;可用于通过 RPC 通信与以太坊节点通信。 Web3 的工作方式是&#xff0c;公开已通过 RPC 启用的方法&#xff0c;这允许开发利用 Web3 库的用户界面&#xff0c;以便与部署在区块链上的合约进行交互。 一旦 Geth JavaScri…...

Spring 中依赖注入注解的区别详解

一、依赖注入的基本概念 依赖注入是一种设计模式,通过将对象的依赖以参数的形式传入类中,而不是在类中自行创建依赖对象。这样做有几个好处: 降低耦合度:类与类之间的依赖关系变得更清晰,避免了硬编码依赖。提高可测试性:通过依赖注入,可以轻松地进行单元测试,因为可以…...

PTA求一批整数中出现最多的个位数字

作者 徐镜春 单位 浙江大学 给定一批整数&#xff0c;分析每个整数的每一位数字&#xff0c;求出现次数最多的个位数字。例如给定3个整数1234、2345、3456&#xff0c;其中出现最多次数的数字是3和4&#xff0c;均出现了3次。 输入格式&#xff1a; 输入在第1行中给出正整数…...

探索国产编程工具:如何实现工作效率翻倍

在当前软件开发领域&#xff0c;国产编程工具正在迅速发展&#xff0c;它们在功能、性能以及用户体验上都有显著提升&#xff0c;以下是一些国产编程工具&#xff0c;它们可以帮助开发者提升工作效率。 智能代码编辑器 CodeGeeX&#xff1a;这是一款由清华大学和智谱AI合作开…...

Kandinsky-5.0-I2V-Lite-5s后端集成:Node.js环境下的高性能API服务构建

Kandinsky-5.0-I2V-Lite-5s后端集成&#xff1a;Node.js环境下的高性能API服务构建 1. 引言 想象一下&#xff0c;你正在开发一个创意设计平台&#xff0c;用户上传一张图片&#xff0c;几秒钟后就能看到它变成了一段生动的视频。这种从静态图像到动态视频的转换能力&#xf…...

Phi-4-mini-reasoning真实案例:GPT-4对比测试中更优的确定性推理表现

Phi-4-mini-reasoning真实案例&#xff1a;GPT-4对比测试中更优的确定性推理表现 1. 模型介绍 Phi-4-mini-reasoning是一款专注于推理任务的文本生成模型&#xff0c;特别擅长处理需要多步逻辑推导的问题。与通用聊天模型不同&#xff0c;它被设计用来解决数学题、逻辑题等需…...

基于Python的校园便利平台毕设源码

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在构建一个基于Python的校园便利平台&#xff0c;以提升校园生活品质&#xff0c;优化资源配置&#xff0c;增强学生与教职工的互动体验。具体研究目的如…...

Krita AI Diffusion IP-Adapter功能异常深度排查与解决方案

Krita AI Diffusion IP-Adapter功能异常深度排查与解决方案 【免费下载链接】krita-ai-diffusion Streamlined interface for generating images with AI in Krita. Inpaint and outpaint with optional text prompt, no tweaking required. 项目地址: https://gitcode.com/g…...

别再死记公式了!用Multisim仿真软件,10分钟搞懂555定时器的三种工作模式

用Multisim玩转555定时器&#xff1a;可视化学习三种工作模式的终极指南 记得第一次接触555定时器时&#xff0c;我被那些复杂的公式和抽象的工作原理搞得晕头转向。直到一位资深工程师告诉我&#xff1a;"别急着背公式&#xff0c;先看看它怎么工作。"这句话彻底改变…...

激发创意:利用快马平台ai模型辅助设计与优化cmhhc算法

激发创意&#xff1a;利用快马平台AI模型辅助设计与优化CMHHC算法 最近在做一个字符串压缩相关的项目&#xff0c;需要实现一个自定义的压缩算法CMHHC。这个算法的核心思想其实很简单&#xff1a;对于连续出现的相同字符&#xff0c;用该字符加上出现次数来表示。比如"aa…...

Graphormer部署指南:3.7GB纯Transformer图神经网络GPU快速启动

Graphormer部署指南&#xff1a;3.7GB纯Transformer图神经网络GPU快速启动 1. 项目概述 Graphormer是一种基于纯Transformer架构的图神经网络&#xff0c;专门为分子图&#xff08;原子-键结构&#xff09;的全局结构建模与属性预测而设计。这个3.7GB大小的模型在OGB、PCQM4M…...

饭局下半场,别人忙着解酒,我从开局就赢在酒杯里

1. 饭局如战场&#xff0c;后半场才是真正的考验任何一场饭局&#xff0c;都可以被分成两个阶段。前半场&#xff0c;推杯换盏&#xff0c;人人意气风发。酒过三巡&#xff0c;大家还在比拼谁喝得多、谁喝得猛&#xff0c;气氛热烈而体面。但到了后半场&#xff0c;画风开始分裂…...

保姆级教程:NotaGen一键部署,小白也能生成贝多芬风格交响乐

保姆级教程&#xff1a;NotaGen一键部署&#xff0c;小白也能生成贝多芬风格交响乐 1. 引言&#xff1a;AI音乐创作新体验 你是否曾经梦想过创作一首属于自己的交响乐&#xff1f;现在&#xff0c;NotaGen让这个梦想变得触手可及。这个基于大语言模型(LLM)的音乐生成工具&…...

终极网盘下载加速方案:3分钟解锁八大平台极速下载

终极网盘下载加速方案&#xff1a;3分钟解锁八大平台极速下载 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘…...