三、pcm音频转wav

这篇具有很好参考价值的文章主要介绍了三、pcm音频转wav。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

ffmpeg录制下来的音频为pcm格式(内部存储着十六进制数据),但pcm格式的音频无法直接播放

本文先将pcm转换成wav格式(提要提前了解音频知识)


首先分析wav文件格式(wav的本质是在pcm数据前加上文件头),即在pcm的十六进制数据前加上文件头(文件头也是十六进制数据,但有些内容是固定的,有些内容是变化的)

三、pcm音频转wav

pcm转换成wav基本思路:

首先封装一个方法,该方法需要实现在传入wav文件头后把源pcm文件转为wav文件。具体功能是先将文件头的十六进制数据写入文件(需要记录下变化的地方,等待读取pcm的数据之后才能确定),然后将pcm中的十六进制数据写入wav文件。这些思路都是有wav文件格式确定的

难点:

文件头到底怎么写?(以下是wav文件头的格式,第二张图为文件头十六进制存储的样子,一个十六进制为一个字节,一个ASCII编码占一个字节,文件头总长为44字节)

注意:这里细节的地方太多了,无法每一处都提及

三、pcm音频转wav

三、pcm音频转wav

通过结构的方式来理清文件头

typedef struct {
    // RIFF chunk的id
    uint8_t riffChunkId[4] = {'R', 'I', 'F', 'F'};
    // RIFF chunk的data大小,即文件总长度减去8字节
    uint32_t riffChunkDataSize;

    // "WAVE"
    uint8_t format[4] = {'W', 'A', 'V', 'E'};

    /* fmt chunk */
    // fmt chunk的id
    uint8_t fmtChunkId[4] = {'f', 'm', 't', ' '};
    // fmt chunk的data大小:存储PCM数据时,是16
    uint32_t fmtChunkDataSize = 16;
    // 音频编码,1表示PCM,3表示Floating Point
    uint16_t audioFormat = AUDIO_FORMAT_PCM;
    // 声道数
    uint16_t numChannels;
    // 采样率
    uint32_t sampleRate;
    // 字节率 = sampleRate * blockAlign
    uint32_t byteRate;
    // 一个样本的字节数 = bitsPerSample * numChannels >> 3
    uint16_t blockAlign;
    // 位深度
    uint16_t bitsPerSample;

    /* data chunk */
    // data chunk的id
    uint8_t dataChunkId[4] = {'d', 'a', 't', 'a'};
    // data chunk的data大小:音频数据的总长度,即文件总长度减去文件头的长度(一般是44)
    uint32_t dataChunkDataSize;
} WAVHeader;

直接把结构体写入文件的方式很巧妙,既确定了写入顺序,又记录下了哪些是会变化的地方

注意:结构体中的某些值是根据音频相关数据决定的,而非一成不变。那相关的值到底如何填,可以直接去搜wav的头文件或者自行下载一个wav文件,将其拖入qt中查看其中的头文件中的数据

三、pcm音频转wav

比如audioFormat可能填1可能填3,需要找到相应的含义,按情况而定

三、pcm音频转wav

具体代码:

FFmpegs.h

#ifndef FFMPEGS_H
#define FFMPEGS_H

#include <stdint.h>

#define AUDIO_FORMAT_PCM 1
#define AUDIO_FORMAT_FLOAT 3

// WAV文件头(44字节)
typedef struct {
    // RIFF chunk的id
    uint8_t riffChunkId[4] = {'R', 'I', 'F', 'F'};
    // RIFF chunk的data大小,即文件总长度减去8字节
    uint32_t riffChunkDataSize;

    // "WAVE"
    uint8_t format[4] = {'W', 'A', 'V', 'E'};

    /* fmt chunk */
    // fmt chunk的id
    uint8_t fmtChunkId[4] = {'f', 'm', 't', ' '};
    // fmt chunk的data大小:存储PCM数据时,是16
    uint32_t fmtChunkDataSize = 16;
    // 音频编码,1表示PCM,3表示Floating Point
    uint16_t audioFormat = AUDIO_FORMAT_PCM;
    // 声道数
    uint16_t numChannels;
    // 采样率
    uint32_t sampleRate;
    // 字节率 = sampleRate * blockAlign
    uint32_t byteRate;
    // 一个样本的字节数 = bitsPerSample * numChannels >> 3
    uint16_t blockAlign;
    // 位深度
    uint16_t bitsPerSample;

    /* data chunk */
    // data chunk的id
    uint8_t dataChunkId[4] = {'d', 'a', 't', 'a'};
    // data chunk的data大小:音频数据的总长度,即文件总长度减去文件头的长度(一般是44)
    uint32_t dataChunkDataSize;
} WAVHeader;

class FFmpegs
{
public:
    FFmpegs();
    static void pcm2wav(WAVHeader &header,const char *pcmFilename,const char *wavFilename);
};


#endif // FFMPEGS_H

FFmpegs.cpp

#include "ffmpegs.h"

#include <QFile>
#include <QDebug>

FFmpegs::FFmpegs()
{
    
}

void FFmpegs::pcm2wav(WAVHeader &header, const char *pcmFilename, const char *wavFilename)
{
    header.blockAlign = header.bitsPerSample * header.numChannels >> 3;
    header.byteRate = header.sampleRate * header.blockAlign;
    
    // 打开pcm文件
    QFile pcmFile(pcmFilename);
    if (!pcmFile.open(QFile::ReadOnly)) {
        qDebug() << "文件打开失败" << pcmFilename;
        return;
    }
    header.dataChunkDataSize = pcmFile.size();
    header.riffChunkDataSize = header.dataChunkDataSize
            + sizeof (WAVHeader) - 8;
    
    // 打开wav文件
    QFile wavFile(wavFilename);
    if (!wavFile.open(QFile::WriteOnly)) {
        qDebug() << "文件打开失败" << wavFilename;
        
        pcmFile.close();
        return;
    }
    
    // 写入头部
    wavFile.write((const char *) &header, sizeof (WAVHeader));
    
    // 写入pcm数据
    char buf[1024];
    int size;
    while ((size = pcmFile.read(buf, sizeof (buf))) > 0) {
        wavFile.write(buf, size);
    }
    
    // 关闭文件
    pcmFile.close();
    wavFile.close();
}

封装的代码中也可以看出,基本上头文件中的数据都已经初始化了,还剩下声道数numChannels、采样率sampleRate、位深度bitsPerSample来自行赋值

调用封装的函数:

void MainWindow::on_pushButton_pcm_to_wav_clicked()
{
    // 封装WAV的头部,此处我所有的值是大多数情况下音频都是这些数据
    WAVHeader header;
    header.numChannels = 2;
    header.sampleRate = 44100;
    header.bitsPerSample = 16;

    // 调用函数
    FFmpegs::pcm2wav(header, "E:/media/out.pcm", "E:/media/out.wav");
    QFile file("E:/media/out.wav");
    if(file.exists()){
        qDebug()<<"文件转换成功,wav文件已生成";
    }
}

pcm和wav文件大小对比,wav多了44字节的文件头

三、pcm音频转wav


注意:本文为个人记录,新手照搬可能会出现各种问题,请谨慎使用


码字不易,如果这篇博客对你有帮助,麻烦点赞收藏,非常感谢!有不对的地方文章来源地址https://www.toymoban.com/news/detail-400449.html

到了这里,关于三、pcm音频转wav的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 音频文件PCM、WAV、MP3的区别以及文件合并

    采样率即采样频率,指的一秒内的采样次数,它反映了采样点之间的间隔大小。常说的 44.1KHz 采样率,也即 1 秒采集了 44100 个样本。间隔越小,丢失的信息越少,数字声音就越逼真细腻,要求的存储量也就越大。由于计算机的工作速度和存储容量有限,而且人耳的听觉上限为

    2024年02月15日
    浏览(47)
  • 使用NAudio录制wav音频

    NAudio官网 Unity2019.4.34f1c1 Window10 NAudio 1.10 .Net 3.5 StartRecording方法 启用录制 StopRecording方法 停止录制 DataAvailable 录制中回调 RecordingStopped 录制结束回调 Write方法可存储音频 WaveIn.DeviceCount 返回音频捕获设备数量 台式电脑,可能需要插入耳机才可以启用麦克风 检测到麦克风,显示

    2024年02月12日
    浏览(33)
  • Java Mp3转化WAV/PCM音频数据,解码详细解析,提取每一帧数据集合/比特流/播放,一行代码!

    大家好!我是原子君 1 .因为Java本身只支持,wav,缺少mp3的解码器,所以Java自带的无法对mp3进行处理,这种 MPEG-*音频有损压缩标准编码 ,更不要说使用Java的音频格式和音频流就可以解决。 2 .所以本次转换需要使用到colorful1.1这种纯Java-Pc可跨平台的工具框架。 注意:colorful只支持

    2024年02月15日
    浏览(47)
  • ffmpeg从MP4中取出wav音频

    要从 MP4 文件中提取出 WAV 音频,你可以使用 FFmpeg 工具。请按照以下步骤进行操作: 1. 下载 FFmpeg:首先,你需要下载 FFmpeg 工具。你可以在 FFmpeg 官方网站(https://ffmpeg.org/)上找到适用于 Windows 的预编译版本。下载后,解压缩到一个方便的位置。 2. 打开命令提示符:按下

    2024年02月03日
    浏览(45)
  • 音频——WAV 格式详解

    wav 文件支持多种不同的比特率、采样率、多声道音频。 WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集,用于存储多媒体文件。RIFF(resource interchange file format 资源互换文件格式,以 chunk(块) 为单位组织文件)格式文件。在 windows 上,大部分多媒体文件都是 RIFF 文件。wav 文件由

    2024年02月09日
    浏览(39)
  • WAV格式音频截取

    【功能】 通常我们会拿到例如某个歌手的演唱会完整版的WAV格式的争端音频,而我们想对该音频进行分割或其中某些部分才是我们实际真正想要的音频段落,为此我们需要设计一个可以按照指定时分秒进行截取的程序。 要求实现的功能如下: 1.根据指定的起止时分秒的设置

    2023年04月08日
    浏览(41)
  • 【音频】WAV 格式详解

    wav 文件支持多种不同的比特率、采样率、多声道音频。 WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集,用于存储多媒体文件。RIFF(resource interchange file format 资源互换文件格式,以 chunk(块) 为单位组织文件)格式文件。在 windows 上,大部分多媒体文件都是 RIFF 文件。wav 文件由

    2023年04月08日
    浏览(35)
  • Qt-FFmpeg开发-音频解码为PCM文件(9)

    目录 音视频/FFmpeg #Qt Qt-FFmpeg开发-使用libavcodec API的音频解码示例(MP3转pcm) 1、概述 2、实现效果 3、主要代码 4、完整源代码 更多精彩内容 👉个人内容分类汇总 👈 👉音视频开发 👈 最近研究了一下FFmpeg开发,功能实在是太强大了,网上ffmpeg3、4的文章还是很多的,但是学

    2023年04月08日
    浏览(36)
  • 基于FFMpeg实现音频mp3/aac/wav解码

    编译环境:Ubuntu16.04 64位 交叉编译工具:arm-himix200-linux-gcc 我这里使用的是ffmpeg-5.1.2.tar.gz,下载地址点击下载地址。 这样,/root/ffmpeg-5.1.2/output下面就是咱们要的程序,bin目录下ffmpeg可以在开发板上运行,include下是需要的头文件,lib下是需要的静态库,share/ffmpeg/examples是一些

    2024年02月11日
    浏览(55)
  • 【FFmpeg】音视频录制 ① ( 查询系统中 ffmpeg 可录制的音视频输入设备 | 使用 ffmpeg 命令录制音视频数据 | 录制视频数据命令 |录制音频数据| 同时录制音频和视频数据命令 )

    在 Windows 系统中 , 使用 ffmpeg 命令 录制 音视频 , 需要先获取 系统的 音视频设备 信息 , 录制 音视频 本质上是从 系统音视频设备 中获取数据 ; 执行 命令 , 可以获取 系统中 ffmpeg 可用的 DirectShow 音视频输入设备 ; 命令参数解析 : -list_devices true : 列出所有 ffmpeg 的 指定类型的可

    2024年04月25日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包