<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      瑞芯微-I2S | 語(yǔ)音文件格式wav與pcm快速入門(mén)-4

      一口君后面會(huì)陸續(xù)更新基于瑞芯微rk3568的I2S系列文章。

      預(yù)計(jì)10篇左右。有對(duì)語(yǔ)音感興趣的朋友,可以收藏該專題。

      瑞芯微 | I2S-音頻基礎(chǔ) -1

      瑞芯微-I2S | 音頻驅(qū)動(dòng)調(diào)試基本命令和工具-基于rk3568-2

      瑞芯微-I2S | ALSA基礎(chǔ)-3

      調(diào)試I2S,最常用到的測(cè)試文件就是wav格式和pcm格式,本文主要講解語(yǔ)音格式相關(guān)知識(shí)點(diǎn)。

      本文還用到邏輯分析儀,使用方法如下:

      推薦最近在使用的還不錯(cuò)的一款邏輯分析儀

      本文用到的 音頻文件+邏輯分析儀軟件+i2s數(shù)據(jù)波形 后臺(tái)回復(fù):i2s

      一、pcm

      與pcm相關(guān)的幾個(gè)參數(shù):

      1. PCM數(shù)據(jù)常用量化指標(biāo)

      • 采樣率(Sample rate):
        每秒鐘采樣多少次,以Hz為單位。
        采樣率表示音頻信號(hào)每秒的數(shù)字快照數(shù)。該速率決定了音頻文件的頻率范圍。
        采樣率越高,數(shù)字波形的形狀越接近原始模擬波形。
        低采樣率會(huì)限制可錄制的頻率范圍,這可導(dǎo)致錄音表現(xiàn)原始聲音的效果不佳。

      根據(jù) 奈奎斯特采樣定理,為了重現(xiàn)給定頻率,采樣率必須至少是該頻率的兩倍。
      例如,CD 的采樣率為每秒 44,100 個(gè)采樣,因此可重現(xiàn)最高為 22,050 Hz 的頻率,此頻率剛好超過(guò)人類的聽(tīng)力極限 20,000 Hz。

      1. 位深度(Bit-depth):
        表示用多少個(gè)二進(jìn)制位來(lái)描述采樣數(shù)據(jù),一般為16bit。
        位深度決定動(dòng)態(tài)范圍。
        采樣聲波時(shí),為每個(gè)采樣指定最接近原始聲波振幅的振幅值。
        較高的位深度可提供更多可能的振幅值,產(chǎn)生更大的動(dòng)態(tài)范圍、更低的噪聲基準(zhǔn)和更高的保真度。

      2. 字節(jié)序:
        表示音頻PCM數(shù)據(jù)存儲(chǔ)的字節(jié)序是大端存儲(chǔ)(big-endian)還是小端存儲(chǔ)(little-endian),為了數(shù)據(jù)處理效率的高效,通常為小端存儲(chǔ)。

      3. 聲道數(shù)(channel number):
        當(dāng)前PCM文件中包含的聲道數(shù),是單聲道(mono)、雙聲道(stereo)?此外還有5.1聲道等。

      4. 采樣數(shù)據(jù)是否有符號(hào)(Sign):
        要表達(dá)的就是字面上的意思,需要注意的是,使用有符號(hào)的采樣數(shù)據(jù)不能用無(wú)符號(hào)的方式播放。

      以FFmpeg中常見(jiàn)的PCM數(shù)據(jù)格式s16le為例:

      • 它描述的是有符號(hào)16位小端PCM數(shù)據(jù)
      s表示有符號(hào),
      16表示位深,
      le表示小端存儲(chǔ)。
      

      2. PCM數(shù)據(jù)流

      PCM (Pulse Code Modulation) 也被稱為脈沖編碼調(diào)制。PCM 音頻數(shù)據(jù)是未經(jīng)壓縮的音頻采樣數(shù)據(jù)裸流,它是由模擬信號(hào)經(jīng)過(guò)采樣、量化、編碼轉(zhuǎn)換成的標(biāo)準(zhǔn)的數(shù)字音頻數(shù)據(jù)。

      PCM 音頻數(shù)據(jù)的存儲(chǔ)

      如果是單聲道的音頻文件,采樣數(shù)據(jù)按時(shí)間的先后順序依次存入(有的時(shí)候也會(huì)采用 LRLRLR 方式存儲(chǔ),只是另一個(gè)聲道的數(shù)據(jù)為 0),如果是雙聲道的話通常按照 LRLRLR 的方式存儲(chǔ),存儲(chǔ)的時(shí)候還和機(jī)器的大小端有關(guān)。

      小端模式如下圖所示:

       PCM 音頻數(shù)據(jù)是未經(jīng)壓縮的數(shù)據(jù),所以通常都比較大,常見(jiàn)的 MP3 格式都是經(jīng)過(guò)壓縮的,128Kbps 的 MP3 壓縮率可以達(dá)到 1:11

      PCM 音頻數(shù)據(jù)的參數(shù)

      一般我們描述 PCM 音頻數(shù)據(jù)的參數(shù)的時(shí)候有如下描述方式:

      • 44100HZ 16bit stereo:
      每秒鐘有 44100 次采樣, 
      采樣數(shù)據(jù)用 16 位(2 字節(jié))記錄, 
      雙聲道(立體聲)
      

      44100Hz 指的是采樣率,它的意思是每秒取樣 44100 次。采樣率越大,存儲(chǔ)數(shù)字音頻所占的空間就越大。

      16bit 指的是采樣精度,意思是原始模擬信號(hào)被采樣后,每一個(gè)采樣點(diǎn)在計(jì)算機(jī)中用 16 位(兩個(gè)字節(jié))來(lái)表示。采樣精度越高越能精細(xì)地表示模擬信號(hào)的差異。

      Stereo 指的是聲道數(shù),也即采樣時(shí)用到的麥克風(fēng)的數(shù)量,麥克風(fēng)越多就越能還原真實(shí)的采樣環(huán)境(當(dāng)然麥克風(fēng)的放置位置也是有規(guī)定的)。

      其他格式例子:

      • 22050HZ 8bit mono:
      每秒鐘有 22050 次采樣, 采樣數(shù)據(jù)用 8 位(1 字節(jié))記錄, 單聲道
      
      • 48000HZ 32bit 51ch:
      每秒鐘有 48000 次采樣, 采樣數(shù)據(jù)用 32 位(4 字節(jié)浮點(diǎn)型)記錄, 5.1 聲道
      

      二、WAV文件

      WAV 是 Microsoft 和 IBM 為 PC 開(kāi)發(fā)的一種聲音文件格式,它符合 RIFF(Resource Interchange File Format)文件規(guī)范,用于保存 Windows 平臺(tái)的音頻信息資源,被 Windows 平臺(tái)及其應(yīng)用程序所廣泛支持。

      1. wav文件頭

      WAVE 文件通常只是一個(gè)具有單個(gè) “WAVE” 塊的 RIFF 文件,該塊由兩個(gè)子塊(”fmt” 子數(shù)據(jù)塊和 ”data” 子數(shù)據(jù)塊),它的標(biāo)準(zhǔn)格式如下圖所示:

      圖片來(lái)源:

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

      該格式的實(shí)質(zhì)就是在 PCM 文件的前面加了一個(gè)文件頭,各字段含義如下:

      偏移與大小 名稱 說(shuō)明
      0 4 ChunkID 包含 ASCII 形式的字母“RIFF”(0x52494646 大端形式)。
      4 4 ChunkSize 36 + SubChunk2Size,或更準(zhǔn)確地說(shuō):4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)這是此數(shù)字之后的塊的其余部分的大小。這是整個(gè)文件的大小(以字節(jié)為單位)減去未包含在此計(jì)數(shù)中的兩個(gè)字段的 8 字節(jié):ChunkID 和 ChunkSize。
      8 4 格式 包含字母“WAVE”(0x57415645 大端形式)。
      12 4 Subchunk1ID 包含字母“fmt”(0x666d7420 大端格式)。
      16 4 Subchunk1Size 16 用于 PCM。這是該數(shù)字之后的其余子塊的大小。
      20 2 AudioFormat PCM = 1(即線性量化)1 以外的值表示某種形式的壓縮。
      22 2 NumChannels Mono = 1、Stereo = 2 等
      24 4 SampleRate 8000、44100 等
      28 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
      32 2 BlockAlign == NumChannels * BitsPerSample/8 1 的字節(jié)數(shù)樣本包括所有通道。
      34 2 BitsPerSample 8 位 = 8,16 位 = 16,等等
      2 ExtraParamSize 如果是 PCM,則不存在
      X ExtraParams 用于額外參數(shù)的空間
      36 4 Subchunk2ID 包含字母“數(shù)據(jù)”(0x64617461 大端形式)。
      40 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 這是數(shù)據(jù)中的字節(jié)數(shù)。您還可以將其視為該數(shù)字后面的子塊的讀取大小。
      44 * Data 實(shí)際的聲音數(shù)據(jù)。

      2. wav文件頭結(jié)構(gòu)體

      wav文件頭信息對(duì)應(yīng)結(jié)構(gòu)體:

      typedef struct {
          char          ChunkID[4]; //內(nèi)容為"RIFF"
          unsigned long ChunkSize;  //存儲(chǔ)文件的字節(jié)數(shù)(不包含ChunkID和ChunkSize這8個(gè)字節(jié))
          char          Format[4];  //內(nèi)容為"WAVE“
      } WAVE_HEADER;
      
      typedef struct {
         char           Subchunk1ID[4]; //內(nèi)容為"fmt"
         unsigned long  Subchunk1Size;  //存儲(chǔ)該子塊的字節(jié)數(shù)(不含前面的Subchunk1ID和Subchunk1Size這8個(gè)字節(jié))
         unsigned short AudioFormat;    //存儲(chǔ)音頻文件的編碼格式,例如若為PCM則其存儲(chǔ)值為1。
         unsigned short NumChannels;    //聲道數(shù),單聲道(Mono)值為1,雙聲道(Stereo)值為2,等等
         unsigned long  SampleRate;     //采樣率,如8k,44.1k等
         unsigned long  ByteRate;       //每秒存儲(chǔ)的bit數(shù),其值 = SampleRate * NumChannels * BitsPerSample / 8
         unsigned short BlockAlign;     //塊對(duì)齊大小,其值 = NumChannels * BitsPerSample / 8
         unsigned short BitsPerSample;  //每個(gè)采樣點(diǎn)的bit數(shù),一般為8,16,32等。
      } WAVE_FMT;
      
      typedef struct {
         char          Subchunk2ID[4]; //內(nèi)容為“data”
         unsigned long Subchunk2Size;  //接下來(lái)的正式的數(shù)據(jù)部分的字節(jié)數(shù),其值 = NumSamples * NumChannels * BitsPerSample / 8
      } WAVE_DATA;
      
      

      3. WAV 文件頭解析實(shí)例

      下面通過(guò)提供給大家的音頻文件《xiaoniao.wav》來(lái)詳細(xì)講解wav文件格式,該音頻文件格式為:S16_LE

      peng@ubuntu:~/test$ ls -l xiaoniao.wav 
      -rwxrw-rw- 1 peng peng 1764448 May 10 20:41 xiaoniao.wav
      

      用ue打開(kāi)該文件,自動(dòng)顯示為十六進(jìn)制數(shù)字,

      文件頭信息解析如下圖:

       數(shù)據(jù)是小端,比如采樣率4個(gè)字段是 44 AC 00 00
      實(shí)際數(shù)據(jù)是0x0000ac44,轉(zhuǎn)換成10進(jìn)制是44100

      讀者對(duì)照結(jié)構(gòu)體,可以解析出改文件的所有信息。

      三、i2s音頻波形分析

      wav文件格式我們搞清楚了,那么它和i2s是什么關(guān)系呢?

      1. 嵌入式設(shè)備音頻架構(gòu)

      一個(gè)典型的嵌入式設(shè)備的音頻架構(gòu)大致如下【以rk3568為例】,

      當(dāng)我們使用aplay工具播放wav文件時(shí):

      1. 解析wav文件頭,讀取相應(yīng)信息
      2. 然后通過(guò)i2s控制器驅(qū)動(dòng),將pcm音頻流通過(guò)i2s接口發(fā)送給codec rk809,
      3. codec rk809會(huì)將pcm音頻流進(jìn)行DAC轉(zhuǎn)換成對(duì)應(yīng)的模擬信號(hào),并通過(guò)耳機(jī)/喇叭播放出去。

      2. 播放命令

      播放命令:

      root@ATK-DLRK356X:/sdcard# aplay -v xiaoniao.wav
      Playing WAVE 'xiaoniao.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
      ALSA <-> PulseAudio PCM I/O Plugin
      Its setup is:
        stream       : PLAYBACK
        access       : RW_INTERLEAVED
        format       : S16_LE
        subformat    : STD
        channels     : 2
        rate         : 44100
        exact rate   : 44100 (44100/1)
        msbits       : 16
        buffer_size  : 22050
        period_size  : 5512
        period_time  : 125000
        tstamp_mode  : NONE
        tstamp_type  : GETTIMEOFDAY
        period_step  : 1
        avail_min    : 5512
        period_event : 0
        start_threshold  : 22050
        stop_threshold   : 22050
        silence_threshold: 0
        silence_size : 0
        boundary     : 6206523236469964800
      

      3.波形分析

      現(xiàn)在我在圖中i2s控制器與codec之間位置用邏輯分析儀抓取了i2s數(shù)據(jù)波形,

      【該操作需要飛線,建議找硬件工程師幫忙】

      波形文件aplay_xiaoniao.kvdat

      一口君實(shí)際測(cè)試的i2s控制器為24位小端格式。
       由上圖可知:

      1. xiaomiao.wav文件為s16_le格式,所以i2s控制器依次每次讀取data后面2個(gè)字節(jié)的數(shù)據(jù)
      2. 根據(jù)幀時(shí)鐘,依次在左右聲道時(shí)隙,將pcm數(shù)據(jù)放到數(shù)據(jù)線中。
      3. 因?yàn)榭刂破魇?4位,所以各channel會(huì)有24個(gè)bit的時(shí)鐘周期;
      4. 根據(jù)i2s協(xié)議,默認(rèn)有效數(shù)據(jù)靠左,并且空1個(gè)bit的位置;多出來(lái)的8個(gè)bit位置默認(rèn)補(bǔ)充填0。


      5. codec就會(huì)通過(guò)該波形提取對(duì)應(yīng)的pcm數(shù)據(jù),做出相應(yīng)處理之后就可以播放出去了。

      四、如何在各種音頻格式之間進(jìn)行轉(zhuǎn)換

      處于測(cè)試需要,我們還需要經(jīng)常轉(zhuǎn)換文件格式,可以通過(guò)FFmpeg工具

      1. FFmpeg

      對(duì)于其他格式的音頻文件,一般用FFmpeg軟件進(jìn)行轉(zhuǎn)換,先在當(dāng)前的設(shè)備安裝好FFmpeg軟件,然后用命令行就可以進(jìn)行轉(zhuǎn)換了,常用的示范如下:

      • 將mp4視頻提取wav格式:
      ffmpeg -i D:\input.mp4 -vn -acodec pcm_s16le -ar 44100 -ac 2 D:\output.wav
      
      • 將wav格式轉(zhuǎn)變?yōu)閜cm格式:
      ffmpeg -i D:\output.wav -f s16le -acodec pcm_s16le D:\output.pcm
      
      • 將pcm格式轉(zhuǎn)變?yōu)閣av格式:
      ffmpeg -f s16le -ar 44100 -ac 2 -i D:\output.pcm c:\output.wav
      

      注意上面的命令中指定的采樣率為44.1k ,雙聲道,存儲(chǔ)格式是s16le

      2. 編寫(xiě)代碼實(shí)現(xiàn)PCM → WAV 代碼

      下面是一個(gè)實(shí)現(xiàn)將pcm文件轉(zhuǎn)換成wav文件的代碼實(shí)例:

      int simplest_pcm16le_to_wave( const char *pcmpath, int channels, int sample_rate, const char *wavepath )
      { // 省去錯(cuò)誤判斷
          short pcmData;
          FILE* fp = fopen( pcmpath, "rb" );
          FILE* fpout = fopen( wavepath, "wb+" );
          
          // 填充 WAVE_HEADER
          WAVE_HEADER pcmHEADER;
          memcpy( pcmHEADER.ChunkID, "RIFF", strlen( "RIFF" ) );
          memcpy( pcmHEADER.Format, "WAVE", strlen( "WAVE" ) );
          fseek( fpout, sizeof( WAVE_HEADER ), 1 );
          
          //填充 WAVE_FMT 
          WAVE_FMT pcmFMT;
          pcmFMT.SampleRate = sample_rate;
          pcmFMT.ByteRate = sample_rate * sizeof( pcmData );
          pcmFMT.BitsPerSample = 8 * sizeof( pcmData );
          memcpy( pcmFMT.Subchunk1ID, "fmt ", strlen( "fmt " ) );
          pcmFMT.Subchunk1Size = 16;
          pcmFMT.BlockAlign = channels * sizeof( pcmData );
          pcmFMT.NumChannels = channels;
          pcmFMT.AudioFormat = 1;
          fwrite( &pcmFMT, sizeof( WAVE_FMT ), 1, fpout );
      
          //填充 WAVE_DATA;
          WAVE_DATA pcmDATA;
          memcpy( pcmDATA.Subchunk2ID, "data", strlen( "data" ) );
          pcmDATA.Subchunk2Size = 0;
          fseek( fpout, sizeof( WAVE_DATA ), SEEK_CUR );
          fread( &m_pcmData, sizeof( short ), 1, fp );
          while ( !feof( fp ) ) {
               pcmDATA.dwSize += 2;
               fwrite( &m_pcmData, sizeof( short ), 1, fpout );
               fread( &m_pcmData, sizeof( short ), 1, fp );
          }
          
          int headerSize = sizeof( pcmHEADER.Format ) + sizeof( WAVE_FMT ) + sizeof( WAVE_DATA ); // 36
          pcmHEADER.ChunkSize = headerSize + pcmDATA.Subchunk2Size;
      
          rewind( fpout );
          fwrite( &pcmHEADER, sizeof( WAVE_HEADER ), 1, fpout );
          fseek( fpout, sizeof( WAVE_FMT ), SEEK_CUR );
          fwrite( &pcmDATA, sizeof( WAVE_DATA ), 1, fpout );
          fclose( fp );
          fclose( fpout );
          return 0;
      }
      

      大家可以用我提供的sound.pcmxiaoniao.wav語(yǔ)音文件,測(cè)試一下。

      posted @ 2024-08-17 11:18  一口Linux  閱讀(754)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 日韩精品成人一区二区三区| 9久9久热精品视频在线观看 | 亚洲综合在线一区二区三区| 久久精产国品一二三产品| 免费观看日本污污ww网站69| 人人超碰人摸人爱| 国产成人综合久久亚洲av| 国产无码高清视频不卡| 国产熟妇另类久久久久久| 久久er99热精品一区二区| 亚洲线精品一区二区三区| 制服 丝袜 亚洲 中文 综合| 欧美牲交a欧美牲交aⅴ图片| 国产在线啪| www国产亚洲精品久久网站| AV人摸人人人澡人人超碰| 久久精品国产99久久美女| 91密桃精品国产91久久| 看免费的无码区特aa毛片| 欧洲熟妇熟女久久精品综合| 精品免费国产一区二区三区四区介绍 | 成人免费无码av| 国产成人无码A区在线观| 女人腿张开让男人桶爽| 无遮挡aaaaa大片免费看| 国产蜜臀av在线一区在线| 丰满少妇被猛烈进出69影院| 欧美熟妇乱子伦XX视频| 亚洲香蕉免费有线视频| 无码中文字幕热热久久| 久热这里有精品视频在线| 吉水县| 日本亚洲一区二区精品| 骚虎视频在线观看| 亚洲经典在线中文字幕| 国产精品免费中文字幕| 国产精品天天在线午夜更新| 亚洲国产精品综合久久20| 欧美成人精品三级网站| 国产精品日韩精品日韩| 国产又色又爽又高潮免费|