0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于DWC2的USB驱动开发-UAC之WAV-PCM音频文件格式详解

嵌入式USB开发 来源:嵌入式USB开发 作者:嵌入式USB开发 2023-07-27 09:02 次阅读

一. 前言

在做UAC,PWM音频播放的项目,需要解析WAV格式文件,通过UAC发送,或接收PCM数据,驱动喇叭播放。这里对WAV文件格式相关内容进行整理备忘。

仅介绍使用非压缩的PCM(Puls Code Modulation)脉冲编码调制格式,其他压缩格式这里不描述。

二.参考

http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf

http://soundfile.sapp.org/doc/WaveFormat/

http://www.lightlink.com/tjweber/StripWav/WAVE.html

三.格式解析

WAVE文件格式是微软RIFF多媒体文件存储规范的一个子集。RIFF文件从一个文件头开始,后面跟着一系列数据块。WAVE文件通常只是一个RIFF文件,其中包含一个由两个子块组成的“WAVE”块——一个“fmt”块指定数据格式,一个“data”块包含实际的示例数据。我们称这种形式为“规范形式”。

如下所示由RIFF fmt data三个chunk组成。

Offset Size Name Description

规范的WAVE格式以RIFF报头开始:

0 4 ChunkID ASCII的"RIFF" 0x52494646 大端

4 4 ChunkSize 36+SubChunk2Size即 4+(8+SubChunk1Size)+(8+SubChunk2Size)

ChunkSize之后所有内容的大小即

整个文件-8即不包括ChunkID和ChunkSize的大小.

8 4 Format ASCII的"WAVE"(0x57415645 大端).

"WAVE" 包括以下两个subchunks: "fmt " 和 "data":

"fmt " subchunk描述声音数据的格式:

12 4 Subchunk1ID ASCII的 "fmt "(0x666d7420 大端).

16 4 Subchunk1Size 对于PCM为16.Subchunk1Size后本chunk剩余部分大小.

20 2 AudioFormat 格式:PCM = 1(即线性量化值),其他值为压缩格式.

22 2 NumChannels 通道数:Mono = 1, Stereo = 2, etc.

24 4 SampleRate 采样率:8000, 44100, etc.

28 4 ByteRate 字节速率: SampleRate * NumChannels * BitsPerSample/8

32 2 BlockAlign 块大小,即一个采样所有通道的数据量:NumChannels * BitsPerSample/8(是不是应该向上取整?)

34 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.

2 ExtraParamSize 其他参数大小:对于PCM没有

X ExtraParams 其他参数

"data" subchunk 包括数据的大小和实际的数据:

36 4 Subchunk2ID ASCII的"data"(0x64617461 大端).

40 4 Subchunk2Size 后续数据大小:NumSamples * NumChannels * BitsPerSample/8.

44 * Data 实际的数据.

以上注意所有整数是小端格式,字符ID和字符format都是大端(按照字符顺序,从低地址开始按顺序依次存放)。WAVE数据文件的默认字节顺序是小端序。使用大端字节排序方案编写的文件具有标识符RIFX而不是RIFF。

样本数据必须在偶数字节边界上结束

8位采样被存储为无符号字节,范围从0到255。16位采样被存储为2补码有符号整数,范围从-32768到32767。

在Wave数据流中可能有额外的子块。

RIFF代表资源交换文件格式。

多媒体应用需要存储和管理各种各样的数据,包括位图、音频数据、视频数据和外围设备控制信息。RIFF提供了一种存储所有这些不同类型数据的方法。RIFF文件包含的数据类型由文件扩展名表示。可能存储在RIFF文件中的数据示例如下:

·Audio/visual interleaved data (.AVI)

·Waveform data (.WAV)

·Bitmapped data (.RDI)

·MIDI information (.RMI)

·Color palette (.PAL)

·Multimedia movie (.RMN)

·Animated cursor (.ANI)

·A bundle of other RIFF files (.BND)

四.举例说明

一个WAVE文件的前面72字节如下

52 49 46 46** 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00** 02 00** 22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 **00 08 00 00 00 00 00 00 24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d

另外一个文件格式解析如下

字节速率: SampleRate * NumChannels * BitsPerSample/8 = 44100216/2=176,400=0x0002B110

五.音频处理工具

二进制编辑查看010Editor

Sox:https://sox.sourceforge.net/Main/HomePage

六.WAV文件曲线显示

# -*- coding: utf-8 -*-
import wave
import pylab as pl
import numpy as np
# 打开WAV文档
f = wave.open(r"1.wav", "rb")
# 读取格式信息
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
print(params)
# 读取波形数据
str_data = f.readframes(nframes)
f.close()
#将波形数据转换为数组
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data.shape = -1, 2
wave_data = wave_data.T
time = np.arange(0, nframes) * (1.0 / framerate)
# 绘制波形
pl.subplot(211) 
pl.plot(time, wave_data[0])
pl.subplot(212) 
pl.plot(time, wave_data[1], c="g")
pl.xlabel("time (seconds)")
pl.show()

七.解析C代码

#define CHUNK_RIFF "RIFF"
#define CHUNK_WAVE "WAVE"
#define CHUNK_FMT "fmt "
#define CHUNK_DATA "data"#define AUDIO_FORMAT_PCM 0x01typedef struct
{
    uint32_t off;
    uint32_t chunksize;
    uint16_t audioformat;
    uint16_t numchannels;
    uint32_t samplerate;
    uint32_t byterate;
    uint16_t blockalign;
    uint16_t bitspersample;
    uint32_t datasize;
}wav_t;
​
int wav_decode(uint8_t* addr, wav_t* wav);
​
int wav_decode(uint8_t* addr, wav_t* wav)
{
    uint8_t* p = addr;
    uint32_t chunksize;
    uint32_t subchunksize;
    if(0 != memcmp(p,CHUNK_RIFF,4))
    {
        return -1;
    }
    p += 4;
    chunksize = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
    wav- >chunksize = chunksize;
    p += 4;
    if(0 != memcmp(p,CHUNK_WAVE,4))
    {
        return -2;
    }
    p += 4;
​
    do
    {
        if(0 == memcmp(p,CHUNK_FMT,4))
        {
            p += 4;
            subchunksize = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
            p += 4;
            /* 解析参数 */
            wav- >audioformat = (uint16_t)p[0] | ((uint16_t)p[1]< < 8);
            if(wav- >audioformat == 0x0001)
            {
                p += 2;
                wav- >numchannels = (uint16_t)p[0] | ((uint16_t)p[1]< < 8);
                p += 2;
                wav- >samplerate = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
                p += 4;
                wav- >byterate = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
                p += 4;
                wav- >blockalign = (uint16_t)p[0] | ((uint16_t)p[1]< < 8);
                p += 2;
                wav - >bitspersample = (uint16_t)p[0] | ((uint16_t)p[1]< < 8);
                p += 2;
            }
            else
            {
                p += subchunksize;
            }
        }
        else if(0 == memcmp(p,CHUNK_DATA,4))
        {
            p += 4;
            subchunksize = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
            wav- >datasize = subchunksize;
            p += 4;
            wav- >off = (uint32_t)(p- addr);
            return 0;
        }
        else
        {
            p += 4;
            subchunksize = (uint32_t)p[0] | ((uint32_t)p[1]< < 8) | ((uint32_t)p[2]< < 16) | ((uint32_t)p[3]< < 24);
            p += 4;
            p += subchunksize;
        }
    }while((uint32_t)(p - addr) < (chunksize + 8));
    return -3;
}

八.测试文件下载

https://samplelib.com/zh/sample-wav.html

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • usb
    usb
    +关注

    关注

    60

    文章

    7888

    浏览量

    263916
  • 音频
    +关注

    关注

    29

    文章

    2832

    浏览量

    81327
  • 驱动开发
    +关注

    关注

    0

    文章

    130

    浏览量

    12061
  • DWC2
    +关注

    关注

    0

    文章

    35

    浏览量

    119
收藏 人收藏

    评论

    相关推荐

    基于DWC2USB驱动开发-0x01开篇介绍与新思DWC2 USB2.0控制器简介

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-0x01开篇介绍与新思DWC2 USB2
    的头像 发表于 05-08 18:10 4489次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-0x01开篇介绍与新思<b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0控制器简介

    基于DWC2USB驱动开发-0x02 DWC2 USB2.0 IP功能特征介绍

    DWC2即新思(Synopsys )的DesignWare® Cores USB 2.0 HiSpeed On-The-Go (OTG)控制器IP,被大量使用。从linux的内核源码驱动中就带
    的头像 发表于 05-09 10:09 9031次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-0x02 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP功能特征介绍

    基于DWC2USB驱动开发-IAD描述符详解

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-IAD描述符详解 (qq.com) 一.  前言 IAD描述符用于一个设备功能关联多
    的头像 发表于 06-27 08:45 5.2w次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-IAD描述符<b class='flag-5'>详解</b>

    基于DWC2USB驱动开发-USB复位详解

    本文转自公众号欢迎关注 基于DWC2USB驱动开发-USB复位详解 (qq.com) 一.前言
    的头像 发表于 07-07 11:18 5.7w次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>USB</b>复位<b class='flag-5'>详解</b>

    基于DWC2USB驱动开发-USB连接详解

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-USB连接详解 (qq.com) 一.前
    的头像 发表于 07-07 08:46 3551次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>USB</b>连接<b class='flag-5'>详解</b>

    基于DWC2USB驱动开发-设备类驱动框架

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-设备类驱动框架 (qq.com) 一.前言 从软件顶层,从数据流的角度来看
    的头像 发表于 07-16 15:56 1277次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-设备类<b class='flag-5'>驱动</b>框架

    基于DWC2USB驱动开发-数据不能发送问题分析案例

    本文转自公众号欢迎关注 基于DWC2USB驱动开发-数据不能发送问题分析案例 (qq.com)   一.前言        对于驱动
    的头像 发表于 08-08 09:43 2114次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-数据不能发送问题分析案例

    请问如何把WAV,MP3格式音频文件转化为16位的数据IIS格式

    你好,请问如何把WAV,MP3格式音频文件转化为16位的数据IIS格式
    发表于 10-23 07:24

    【NXP LPC54110试用体验】WAV音频文件

    是录音时用的标准Windows文件格式文件扩展名为”.wav”,数据本身的格式PCM或压缩型,它是由微软与IBM联合
    发表于 10-27 18:07

    基于STM32的WAV音频格式播放器

    语音的播放出现问题。由于WAV采用PCM编码,音质也十分不错,于是考虑用STM32对WAV格式音频文件进行解码,上周末开始找资料和编程,其中
    发表于 12-21 19:55

    WAV格式音频文件剪切工具软件下载

    WAV格式音频文件剪切工具软件下载:一个免费的音频编辑工具.可以编辑音频剪辑,声音设计、控制、记录等功能。重要的是免费呵。
    发表于 06-17 13:36 423次下载
    <b class='flag-5'>WAV</b><b class='flag-5'>格式</b><b class='flag-5'>音频文件</b>剪切工具软件下载

    数字音频文件格式与接口标准

    数字化音频格式的出现,是为了满足复制、存储、传输的需求 常用的数字音频格式主要有:WAV文件、VOC文件和MP3
    发表于 04-09 17:53 134次下载
    数字<b class='flag-5'>音频文件格式</b>与接口标准

    GIF文件格式详解

    GIF文件格式详解 GIF文件格式详解 GIF文件格式详解
    发表于 05-24 10:53 2次下载

    一招教你快速解析WAV文件格式

    语音的播放出现问题。由于WAV采用PCM编码,音质也十分不错,于是考虑用STM32对WAV格式音频文件进行解码,上周末开始找资料和编程,其中
    的头像 发表于 08-01 09:38 2.4w次阅读
    一招教你快速解析<b class='flag-5'>WAV</b><b class='flag-5'>文件格式</b>

    WAV文件格式详解

    WAV是微软公司开发的一种音频格式文件,用于保存Windows平台的音频信息资源,它符合资源互换文件格式(Resource Intercha
    的头像 发表于 10-21 09:52 5143次阅读
    <b class='flag-5'>WAV</b><b class='flag-5'>文件格式</b><b class='flag-5'>详解</b>