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 File
        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 << " Hz" << std::endl;
        std::cout << "Bits Per Sample: " << wav.bits_per_sample << " bits" << std::endl;
 
        // Read wave data
        std::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 samples
        const 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_num
        wavfile.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caridle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值