C++builder中的人工智能(22):在C+++中读取WAV格式的音频文件

在这篇文章中,我们将探讨如何在C+++中读取WAV格式的音频文件。音频文件是计算机科学和编程中的一个重要组成部分,正确使用音频可以为娱乐应用程序增添乐趣,或者在业务应用程序中提醒用户重要事件或状态变化。在这篇文章中,我们将解释WAV格式音频文件的基本概念,以及如何在C+中读取WAV格式音频文件。

WAV格式音频文件格式

音频文件有多种格式——存储模拟声音的数字表示方法各不相同。最常用的格式包括MP3、OGG和FLAC文件,这些音频格式使用压缩技术使音频文件更小。最原始的原始格式是WAV文件。WAV格式(*.WAV或*.WAV)是一种记录数字形式的声音,其音量随时间变化的数据。

在C+++ Builder中,使用FMX.Media.hpp头文件,可以轻松录制WAV文件。要录制声音,必须使用MultiDevice应用程序。

如何在C++中录制WAV格式音频文件

录制WAV声音在C+中,我们参考了“Learn How To Easily Record Sound In Powerful Modern C+++ On Windows”文章。

如何在C++中读取WAV格式音频文件

如果你正在读取二进制文件,首先应了解其结构类型,以便正确读取。WAV格式音频文件格式(*.WAV)是音频文件标准,用于记录音频位流在内存或驱动器上的位流。在C+中,可以轻松读取WAV波形音频文件,现在可以显示或编辑波形文件。

Wave File format Ref <a href=httpsoundfilesapporgdocWaveFormat target= blank rel=noopener nofollow title=>httpsoundfilesapporgdocWaveFormat<a> 

Wave File format Ref <a href=httpsoundfilesapporgdocWaveFormat target= blank rel=noopener nofollow title=>httpsoundfilesapporgdocWavFormat<a> 

Wave头的结构定义如下:

 
// WAVE file header structure
struct Twavheader
{char chunk_ID[4];              //  4  riff_mark[4];uint32_t chunk_size;           //  4  file_size;char format[4];                //  4  wave_str[4];char sub_chunk1_ID[4];         //  4  fmt_str[4];uint32_t sub_chunk1_size;      //  4  pcm_bit_num;uint16_t audio_format;         //  2  pcm_encode;uint16_t num_channels;         //  2  sound_channel;uint32_t sample_rate;          //  4  pcm_sample_freq;uint32_t byte_rate;            //  4  byte_freq;uint16_t block_align;          //  2  block_align;uint16_t bits_per_sample;      //  2  sample_bits;char sub_chunk2_ID[4];         //  4  data_str[4];uint32_t sub_chunk2_size;      //  4  sound_size;
};                                 // 44  bytes TOTAL

以下是读取WAV格式音频文件的函数:

void read_wav_file(std::string fname)
{// 打开WAV文件std::ifstream wavfile(fname, std::ios::binary);if(wavfile.is_open()){// 读取WAV头Twavheader wav;wavfile.read(reinterpret_cast<char*&wav), sizeof(Twavheader));// 如果文件是有效的WAV文件if(std::string(wav.format,4)!="WAVE"\|wav.chunk\_ID,4)!="RIFF")wavfile.close();std::cerr<<"Not a WAVE or RIFF!"<<std::endl;return;}// Properties of WAV Filestd::cout << "FileName:" << fname << std::endl;std::cout << "File size:" << wav.chunk_size+8 << std::endl;std::cout << "Resource Exchange File Mark:" << std::string(wav.chunk_ID, 4) << std::endl;std::cout << "Format:" << std::string(wav.format, 4) << std::endl;std::cout << "Channels: " << wav.num_channels << std::endl;std::cout << "Sample Rate: " << wav.sample_rate << " Hz" << std::endl;std::cout << "Bits Per Sample: " << wav.bits_per_sample << " bits" << std::endl;// Read wave datastd::vector<int16_t> audio_data( wav.sub_chunk2_size / sizeof(int16_t) );wavfile.read(reinterpret_cast<char*>( audio_data.data() ), wav.sub_chunk2_size );wavfile.close();  // Close audio file// Display some audio samplesconst size_t numofsample = 20;std::cout <<"Listin first " << numofsample << " Samples:" << std::endl;for (size_t i = 0; i < numofsample && i < audio_data.size(); ++i){std::cout << i << ":" << audio_data[i] << std::endl;}     std::cout << std::endl;}
}

这个函数首先打开WAV文件,然后读取WAV头。如果文件是有效的WAV文件,函数将读取头信息并检查文件是否有效。

最后可以如此使用: 

read_wav_file("D:\\sample.wav");

以下是读取WAV格式音频文件的完整C++示例:

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>struct Twavheader
{char chunk_ID[4]; // 4 riff_mark[4];uint32_t chunk_size; //4 file_size;char format[4]; //4 wave_str[4];char sub_chunk1_ID[4]; //4 fmt_str[4];uint32_t sub_chunk1_size; //4 pcm_bit_num;uint16_t audio_format; //2 pcm_encode;uint16_t num_channels; //2 sound_channel;uint32_t sample_rate; //4 pcm_sample_freq;uint32_t byte_rate; //4 byte_freq;uint16_t block_align; //2 block_align;uint16_t bits_per_sample; //2 sample_bits;char sub_chunk2_ID[4]; //4 data_str[4];uint32_t sub_chunk2_size; //4 sound_size;
};// 444 bytes TOTAL// WAV文件结构
void read_wav_file(std::string fname)
{// 打开WAV文件std::ifstream wavfile(fname, std::ios::binary);if(wavfile.is_open()){// 读取WAV头Twavheader wav;wavfile.read(reinterpret_cast<char*>(&wav), sizeof(Twavheader));// 如果文件是有效的WAV文件if(std::string(wav.format,4)!="WAVE" || std::string(wav.chunk_ID,4)!="RIFF"){wavfile.close();std::cerr << "Not a WAVE or RIFF!" << std::endl;return;}// 属性WAV文件std::cout << "FileName:" << fname << std::endl;std::cout << "File size:" << wav.chunk_size+8 << std::endl;std::cout << "Resource Exchange File Mark:" << std::string(wav.chunk_ID,4) << std::endl;std::cout << "Format:" << std::string(wav.format,4) << std::endl;std::cout << "Channels: " << wav.num_channels << std::endl;std::cout << "Sample Rate: " << wav.sample_rate << std::endl;std::cout << "Bits Per Sample: " << wav.bits_per_sample << std::endl;// 读取波形数据std::vector<int16_t> audio_data(wav.sub_chunk2_size/sizeof(int16_t)); // 4 pcm_bit_numwavfile.read(reinterpret_cast<char*>(audio_data.data()), wav.sub_chunk2_size);wavfile.close(); // 关闭音频文件// 显示一些音频样本const size_t numofsample = 20;std::cout << "Listing first " << numofsample << " Samples:" << std::endl;for(size_t i = 0; i < numofsample && i < audio_data.size(); ++i){std::cout << i << ":" << audio_data[i] << std::endl;}std::cout << std::endl;}
}
//------------------------------------------------------------------------------
int main()
{read_wav_file("D:\\sample.wav");system("pause");return 0;
}

最后输出如下:

FileName:D:\sample.wav
File size:563756
Resource Exchange File Mark:RIFF
Format:WAVE
Channels: 2
Sample Rate: 44100 Hz
Bits Per Sample: 16 bits
Listing first 20 Samples:
0:-1934
1:-1934
2:-1276
3:-1276
4:-241
5:-241
6:598
7:598
8:282
9:282
10:242
11:242
12:314
13:314
14:208
15:208
16:-128
17:-128
18:-1226
19:-1226

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/12495.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

.NET Core 应用程序如何在 Linux 中创建 Systemd 服务 ?

.NET Core 和 Linux 已经成为一个强大的组合&#xff0c;为开发人员提供了一个灵活、高性能的平台来构建和运行应用程序。在 Linux 上部署 .NET Core 应用程序的一个关键方面是利用 systemd 服务来确保应用程序顺利运行&#xff0c;在开机时自动启动&#xff0c;并在失败后重新…

@RestController 源码解读:解决 Web 开发中 REST 服务的疑难杂症

目录 一、RestContrller注解 1.1 查看底层源码 1.2 AliasFor注解说明 1.2.1 注解别名 1.2.2 元数据别名 1.3 value() 方法的作用 一、RestContrller注解 1.1 查看底层源码 首先编写如下内容&#xff1a; RestController public class TestController {} 按住 Ctrl &am…

vs2019托管调试助手 “ContextSwitchDeadlock“错误

错误描述 托管调试助手 "ContextSwitchDeadlock":“CLR 无法从 COM 上下文 0xd183e0 转换为 COM 上下文 0xd18328&#xff0c;这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长…

H.264/H.265播放器EasyPlayer.js RTSP播放器关于webcodecs硬解码H265的问题

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、Mp3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方式&#xff0c…

免费在线图片翻译工具:PicTech

文章目录 简介编辑功能 简介 PicTech是一款免费的在线图片翻译工具。图片翻译&#xff0c;顾名思义就是把图片中的文字翻译成另外一种语言&#xff0c;并以图片的形式输出。这种功能在手机的词典软件中似乎还挺常见的&#xff0c;但作为一种在线工具我还是第一次见。 其使用过…

【Vue】Vue3.0(二十)Vue 3.0 中mitt的使用示例

上篇文章 【Vue】Vue3.0&#xff08;十九&#xff09;Vue 3.0 中一种组件间通信方式-自定义事件 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Vue专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月11日12点23分 文章目录 一、mitt 在…

搭建监控系统Prometheus + Grafana

公司有个技术分享会&#xff0c;但是业务忙&#xff0c;没时间精心准备&#xff0c;所以就匆匆忙忙准备分享一下搭建&#xff08;捂脸哭&#xff09;。技术含量确实不多&#xff0c;但是分享的知识确实没问题。 以下是搭建过程&#xff1a; 一、讲解 Prometheus Prometheus 最…

蓝桥杯真题——班级活动

目录 题目链接&#xff1a;1.班级活动 - 蓝桥云课 题目描述 输入格式 输出格式 样例输入 样例输出 样例说明 评测用例规模与约定 解法一&#xff1a;Map集合处理 举个例子 Java写法&#xff1a; C写法&#xff1a; 运行时间 时间复杂度和空间复杂度 时间复杂度…

Win10下使用Anaconda安装GPU版本PyTorch

一、判断是否有Nvidia(英伟达)显卡 右键开始菜单&#xff0c;在弹出选项中选择任务管理器。 点性能选项&#xff0c;然后点GPU。在右上方会显示GPU名称&#xff0c;只有带NVIDIA的英伟达显卡的电脑才能安装GPU版本&#xff0c;否则其他的就只能安装CPU版本。 二、安装CUDA 首…

精品案例PPT | 企业架构及典型设计方案

本文全面介绍企业架构的理论和实践&#xff0c;包括企业架构的概述、元模型、视图、业务架构、应用架构、数据架构、技术架构以及企业架构管控等内容&#xff0c;有助于企业管理者理解和设计企业级的IT架构&#xff0c;确保架构的全局性、整体性、关联性、可控制性、可实现性和…

java--泛型

欢迎来到我的博客~~欢迎大家对我的博客进行指导~点击进入我的博客主页 目录 一、什么是泛型二、包装类2.1基本数据类型和对应的包装类2.2装箱和拆箱2.3 自动装箱和自动拆箱 三、引出泛型四、泛型类的使用4.1 语法4.2示例 五、泛型如何编译的六、泛型的上界6.1语法6.2 示例 七、…

【CentOS】中的Firewalld:全面介绍与实战应用(下)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、iptables 时代 2、firewalld 时代 二、服务管…

【新人系列】Python 入门(九):数据结构 - 中

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

如何用【钉钉文档】发公告

功能亮点 ✔️借助钉钉文档强大的编辑能力&#xff0c;可以让编写出的公告更加精美。 ✔️将钉钉文档一键导入公告&#xff0c;可以完整保留已经编辑好的格式&#xff0c;无需再手动调整。 ✔️使用钉钉文档&#xff0c;可以将所有公告内容有序沉淀和保存。 &#x1f4a1; 使…

工位管理自动化:Spring Boot企业级工具

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理企业级工位管理系统的相关信息成为必然。开…

相亲小程序(源码+文档+部署+讲解)

最近我在挖掘一些优秀的开源项目时&#xff0c;无意间发现了一个相当给力的系统——相亲小程序管理系统。这个系统不仅功能实用&#xff0c;而且代码结构清晰&#xff0c;易于二次开发。作为一名技术爱好者&#xff0c;我觉得有必要把这个好东西推荐给我的读者们。接下来&#…

Filter and Search 筛选和搜索

Goto Data Grid 数据网格 Filter and Search 筛选和搜索 Filter Drop-down Menus (Excel-style) 筛选器下拉菜单&#xff08;Excel 样式&#xff09; 要调用列的筛选器下拉菜单&#xff0c;请单击列标题中的筛选器图标。在 “Values” 选项卡中&#xff0c;用户可以从 Data …

java项目报错:错误提示Could not initialize class com.jacob.com.ComThread

java项目报错&#xff1a;错误提示Could not initialize class com.jacob.com.ComThread 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;jacob-1.19 链接: https://pan.baidu.com/s/1ouudh7A2-Y2kqPh_q-WYiA?pwdqhr3 提取码: qhr3 –来自百度网盘超级会员v7的分享 安…

Linux服务管理-多路径multipath

多路径Multipath 概述 多路径&#xff08;Multipath&#xff09;技术&#xff0c;特别是在存储系统中&#xff0c;是一种提高可靠性和性能的重要手段。多路径技术允许服务器通过多条物理路径连接到存储设备。这些路径可以是包含独立电缆、交换机和控制器的物理SAN连接。 多路…

省级绿色金融指数数据(1990-2021年)

绿色信贷是指银行在信贷业务中采纳环境标准&#xff0c;对污染企业的资金进行限制&#xff0c;同时对环保企业给予扶持。这种模式旨在促使贷款企业承担环境责任&#xff0c;实现节能减排&#xff0c;优化产业结构&#xff0c;以及改变经济增长方式。 1990-2021年省级绿色金融指…