0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于DWC2的USB驅(qū)動(dòng)開發(fā)-UAC之WAV-PCM音頻文件格式詳解

嵌入式USB開發(fā) ? 來(lái)源:嵌入式USB開發(fā) ? 作者:嵌入式USB開發(fā) ? 2023-07-27 09:02 ? 次閱讀

一. 前言

在做UAC,PWM音頻播放的項(xiàng)目,需要解析WAV格式文件,通過(guò)UAC發(fā)送,或接收PCM數(shù)據(jù),驅(qū)動(dòng)喇叭播放。這里對(duì)WAV文件格式相關(guān)內(nèi)容進(jìn)行整理備忘。

僅介紹使用非壓縮的PCM(Puls Code Modulation)脈沖編碼調(diào)制格式,其他壓縮格式這里不描述。

二.參考

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

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

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

三.格式解析

WAVE文件格式是微軟RIFF多媒體文件存儲(chǔ)規(guī)范的一個(gè)子集。RIFF文件從一個(gè)文件頭開始,后面跟著一系列數(shù)據(jù)塊。WAVE文件通常只是一個(gè)RIFF文件,其中包含一個(gè)由兩個(gè)子塊組成的“WAVE”塊——一個(gè)“fmt”塊指定數(shù)據(jù)格式,一個(gè)“data”塊包含實(shí)際的示例數(shù)據(jù)。我們稱這種形式為“規(guī)范形式”。

如下所示由RIFF fmt data三個(gè)chunk組成。

Offset Size Name Description

規(guī)范的WAVE格式以RIFF報(bào)頭開始:

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

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

ChunkSize之后所有內(nèi)容的大小即

整個(gè)文件-8即不包括ChunkID和ChunkSize的大小.

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

"WAVE" 包括以下兩個(gè)subchunks: "fmt " 和 "data":

"fmt " subchunk描述聲音數(shù)據(jù)的格式:

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

16 4 Subchunk1Size 對(duì)于PCM為16.Subchunk1Size后本chunk剩余部分大小.

20 2 AudioFormat 格式:PCM = 1(即線性量化值),其他值為壓縮格式.

22 2 NumChannels 通道數(shù):Mono = 1, Stereo = 2, etc.

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

28 4 ByteRate 字節(jié)速率: SampleRate * NumChannels * BitsPerSample/8

32 2 BlockAlign 塊大小,即一個(gè)采樣所有通道的數(shù)據(jù)量:NumChannels * BitsPerSample/8(是不是應(yīng)該向上取整?)

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

2 ExtraParamSize 其他參數(shù)大小:對(duì)于PCM沒(méi)有

X ExtraParams 其他參數(shù)

"data" subchunk 包括數(shù)據(jù)的大小和實(shí)際的數(shù)據(jù):

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

40 4 Subchunk2Size 后續(xù)數(shù)據(jù)大小:NumSamples * NumChannels * BitsPerSample/8.

44 * Data 實(shí)際的數(shù)據(jù).

以上注意所有整數(shù)是小端格式,字符ID和字符format都是大端(按照字符順序,從低地址開始按順序依次存放)。WAVE數(shù)據(jù)文件的默認(rèn)字節(jié)順序是小端序。使用大端字節(jié)排序方案編寫的文件具有標(biāo)識(shí)符RIFX而不是RIFF。

樣本數(shù)據(jù)必須在偶數(shù)字節(jié)邊界上結(jié)束 。

8位采樣被存儲(chǔ)為無(wú)符號(hào)字節(jié),范圍從0到255。16位采樣被存儲(chǔ)為2補(bǔ)碼有符號(hào)整數(shù),范圍從-32768到32767。

在Wave數(shù)據(jù)流中可能有額外的子塊。

RIFF代表資源交換文件格式。

多媒體應(yīng)用需要存儲(chǔ)和管理各種各樣的數(shù)據(jù),包括位圖、音頻數(shù)據(jù)、視頻數(shù)據(jù)和外圍設(shè)備控制信息。RIFF提供了一種存儲(chǔ)所有這些不同類型數(shù)據(jù)的方法。RIFF文件包含的數(shù)據(jù)類型由文件擴(kuò)展名表示??赡艽鎯?chǔ)在RIFF文件中的數(shù)據(jù)示例如下:

·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)

四.舉例說(shuō)明

一個(gè)WAVE文件的前面72字節(jié)如下

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

另外一個(gè)文件格式解析如下

字節(jié)速率: SampleRate * NumChannels * BitsPerSample/8 = 44100216/2=176,400=0x0002B110

五.音頻處理工具

二進(jìn)制編輯查看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)
# 讀取波形數(shù)據(jù)
str_data = f.readframes(nframes)
f.close()
#將波形數(shù)據(jù)轉(zhuǎn)換為數(shù)組
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 0x01
?
typedef 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;
            /* 解析參數(shù) */
            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;
}

八.測(cè)試文件下載

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

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7945

    瀏覽量

    264622
  • 音頻
    +關(guān)注

    關(guān)注

    29

    文章

    2876

    瀏覽量

    81543
  • 驅(qū)動(dòng)開發(fā)

    關(guān)注

    0

    文章

    130

    瀏覽量

    12077
  • DWC2
    +關(guān)注

    關(guān)注

    0

    文章

    35

    瀏覽量

    131
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于DWC2USB驅(qū)動(dòng)開發(fā)-0x01開篇介紹與新思DWC2 USB2.0控制器簡(jiǎn)介

    本文轉(zhuǎn)自公眾號(hào),歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-0x01開篇介紹與新思DWC2 USB2
    的頭像 發(fā)表于 05-08 18:10 ?4609次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-0x01開篇介紹與新思<b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0控制器簡(jiǎn)介

    基于DWC2USB驅(qū)動(dòng)開發(fā)-0x02 DWC2 USB2.0 IP功能特征介紹

    DWC2即新思(Synopsys )的DesignWare? Cores USB 2.0 HiSpeed On-The-Go (OTG)控制器IP,被大量使用。從linux的內(nèi)核源碼驅(qū)動(dòng)中就帶
    的頭像 發(fā)表于 05-09 10:09 ?9420次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-0x02 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP功能特征介紹

    基于DWC2USB驅(qū)動(dòng)開發(fā)-IAD描述符詳解

    本文轉(zhuǎn)自公眾號(hào),歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-IAD描述符詳解 (qq.com) 一.? 前言 IAD描述符用于一個(gè)設(shè)備功能關(guān)聯(lián)多
    的頭像 發(fā)表于 06-27 08:45 ?14.6w次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-IAD描述符<b class='flag-5'>詳解</b>

    基于DWC2USB驅(qū)動(dòng)開發(fā)-USB復(fù)位詳解

    本文轉(zhuǎn)自公眾號(hào)歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-USB復(fù)位詳解 (qq.com) 一.前言
    的頭像 發(fā)表于 07-07 11:18 ?6.6w次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>USB</b>復(fù)位<b class='flag-5'>詳解</b>

    基于DWC2USB驅(qū)動(dòng)開發(fā)-USB連接詳解

    本文轉(zhuǎn)自公眾號(hào),歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-USB連接詳解 (qq.com) 一.前
    的頭像 發(fā)表于 07-07 08:46 ?3710次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>USB</b>連接<b class='flag-5'>詳解</b>

    基于DWC2USB驅(qū)動(dòng)開發(fā)-設(shè)備類驅(qū)動(dòng)框架

    本文轉(zhuǎn)自公眾號(hào),歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-設(shè)備類驅(qū)動(dòng)框架 (qq.com) 一.前言 從軟件頂層,從數(shù)據(jù)流的角度來(lái)看
    的頭像 發(fā)表于 07-16 15:56 ?1321次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-設(shè)備類<b class='flag-5'>驅(qū)動(dòng)</b>框架

    基于DWC2USB驅(qū)動(dòng)開發(fā)-數(shù)據(jù)不能發(fā)送問(wèn)題分析案例

    本文轉(zhuǎn)自公眾號(hào)歡迎關(guān)注 基于DWC2USB驅(qū)動(dòng)開發(fā)-數(shù)據(jù)不能發(fā)送問(wèn)題分析案例 (qq.com) ? 一.前言 ? ? ? ?對(duì)于驅(qū)動(dòng)
    的頭像 發(fā)表于 08-08 09:43 ?2313次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-數(shù)據(jù)不能發(fā)送問(wèn)題分析案例

    請(qǐng)問(wèn)如何把WAV,MP3格式音頻文件轉(zhuǎn)化為16位的數(shù)據(jù)IIS格式

    你好,請(qǐng)問(wèn)如何把WAV,MP3格式音頻文件轉(zhuǎn)化為16位的數(shù)據(jù)IIS格式?
    發(fā)表于 10-23 07:24

    【NXP LPC54110試用體驗(yàn)】WAV音頻文件

    是錄音時(shí)用的標(biāo)準(zhǔn)Windows文件格式,文件擴(kuò)展名為”.wav”,數(shù)據(jù)本身的格式PCM或壓縮型,它是由微軟與IBM聯(lián)合
    發(fā)表于 10-27 18:07

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

    語(yǔ)音的播放出現(xiàn)問(wèn)題。由于WAV采用PCM編碼,音質(zhì)也十分不錯(cuò),于是考慮用STM32對(duì)WAV格式音頻文件進(jìn)行解碼,上周末開始找資料和編程,其中
    發(fā)表于 12-21 19:55

    WAV格式音頻文件剪切工具軟件下載

    WAV格式音頻文件剪切工具軟件下載:一個(gè)免費(fèi)的音頻編輯工具.可以編輯音頻剪輯,聲音設(shè)計(jì)、控制、記錄等功能。重要的是免費(fèi)呵。
    發(fā)表于 06-17 13:36 ?423次下載
    <b class='flag-5'>WAV</b><b class='flag-5'>格式</b><b class='flag-5'>音頻文件</b>剪切工具軟件下載

    數(shù)字音頻文件格式與接口標(biāo)準(zhǔn)

    數(shù)字化音頻格式的出現(xiàn),是為了滿足復(fù)制、存儲(chǔ)、傳輸?shù)男枨?常用的數(shù)字音頻格式主要有:WAV文件、VOC文件和MP3
    發(fā)表于 04-09 17:53 ?134次下載
    數(shù)字<b class='flag-5'>音頻文件格式</b>與接口標(biāo)準(zhǔn)

    GIF文件格式詳解

    GIF文件格式詳解 GIF文件格式詳解 GIF文件格式詳解
    發(fā)表于 05-24 10:53 ?2次下載

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

    語(yǔ)音的播放出現(xiàn)問(wèn)題。由于WAV采用PCM編碼,音質(zhì)也十分不錯(cuò),于是考慮用STM32對(duì)WAV格式音頻文件進(jìn)行解碼,上周末開始找資料和編程,其中
    的頭像 發(fā)表于 08-01 09:38 ?2.4w次閱讀
    一招教你快速解析<b class='flag-5'>WAV</b><b class='flag-5'>文件格式</b>

    WAV文件格式詳解

    WAV是微軟公司開發(fā)的一種音頻格式文件,用于保存Windows平臺(tái)的音頻信息資源,它符合資源互換文件格式(Resource Intercha
    的頭像 發(fā)表于 10-21 09:52 ?5340次閱讀
    <b class='flag-5'>WAV</b><b class='flag-5'>文件格式</b><b class='flag-5'>詳解</b>