音視頻 day12播放WAV_錄製WAV_錄音時長

1. 下面兩種方式,都能獲取一個 AVPacket 實例對象,請問有什麼不一樣?如何取捨呢?

AVPacket pkt; // 方式一
AVPacket *pkt2 = av_packet_alloc(); // 方式二
複製代碼
  • AVPacket pkt; 是在棧空間建立了一個實例對象 pkt
  • AVPacket *pkt2 = av_packet_alloc();pkt2 這個指針在棧空間,而 pkt2 所指向的實例對象堆空間
  • 取捨:若是實例對象所須要的內存比較大時,建議使用方法二,將實例對象放在堆空間,由於棧空間的大小比較有限

2. 在 C 語言或者 C++中的方法,常常返回值是 0 或者負數,請問分別表明什麼?

  • 這種方法經常存在於對資源調度的方法,0一般表示成功,負數一般表示失敗。
  • 負數的具體值,好比 -一、-2 則是錯誤的具體錯誤碼

3. 使用 SDL 播放 WAV 文件,核心代碼以下

// 音頻參數
SDL_AudioSpec spec;
// 指向 PCM 數據
Uint8 *data = nullptr;
// PCM 數據長度
Uint32 len = 0;
// 調用 SDL_LoadWAV 方法,對 WAV 進行解析,得到採樣率、聲道、採樣格式等參數數據
if (!SDL_LoadWAV(FILENAME, &spec, &data, &len)) {
 qDebug() << "SDL_LoadWAV error" << SDL_GetError();
 // 清除全部的子系統
 SDL_Quit();
 return;
}
複製代碼

4. file.write(&data,len)file.seek(sizeof(WAVHeader)) 這兩個函數有什麼做用?

  • file.write(&data,len) , 是將 data 中的數據取 len 長度,並寫入文件流中,默認是寫到文件尾部
  • file.seek(sizeof(WAVHeader)),是將 file 寫入位置定位到 sizeof(WAVHeader),配合file.write(&data,len)能夠修改指定數據

5. 代碼錄音,直接生成 WAV 文件,說一下核心思想?

  • 核心思想:先往文件頭部寫入 WAVHeader數據,而後寫入 PCM 數據,最後修正 WAVHeader數據 中的 ChunkSize 和 PCMSize 便可。
file.seek(sizeof (WAVHeader) - sizeof (header.dataChunkDataSize));
file.write((char *) &header.dataChunkDataSize, sizeof (header.dataChunkDataSize));

// 寫入riffChunkDataSize
header.riffChunkDataSize = file.size() - sizeof (header.riffChunkId) - sizeof (header.riffChunkDataSize);
file.seek(sizeof (header.riffChunkId));
file.write((char *) &header.riffChunkDataSize, sizeof (header.riffChunkDataSize));

複製代碼

6. 展現錄音時長的核心思想是什麼?

  • 核心思想:子線程根據錄製的 PCM 數據算出錄音時長 → 子線程發射信號 → 主線程槽接收信號,更新展現時間
// 計算錄音時長
header.dataChunkDataSize += pkt.size;
unsigned long long ms = 1000.0 * header.dataChunkDataSize / header.byteRate;
emit timeChanged(ms);
複製代碼

7. 立體聲的樣本幀,在 PCM 中是如何排布的?

image.png

8. 正常的 PCMPlanar 版本的 PCM 有什麼區別?

  • 正常的 PCM 是左右聲道爲一個樣本幀
  • Planar 版本的 PCM 左右聲道分開存儲,左聲道於左聲道連續,右聲道於右聲道連續

image.png

相關文章
相關標籤/搜索