日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

音频之声道那些事

發(fā)布時間:2023/12/19 综合教程 38 生活家
生活随笔 收集整理的這篇文章主要介紹了 音频之声道那些事 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  在PCM音頻初見 - blackstar666 - 博客園 (cnblogs.com)中我們概況性地討論PCM中幾個重要的參數(shù),接下來就好好聊聊聲道的一些事情。

一、聲道是什么

  聲道是指在不同空間位置錄制或播放聲音時采集或播放的獨立音頻信號。通俗的講就是:聲道數(shù)就是聲源總數(shù),比如:錄制棚內(nèi)在不同方位上安放的錄音器,最后錄制的音頻就是多聲道的;播放多聲道的音頻文件,不同聲道的音頻信號通過對應(yīng)聲道的揚聲器播放出來。

二、聲道類型

  單聲道

  單聲道的音頻只有一個音源,它是一種比較原始的再現(xiàn)聲音的方式;它的主要目的是讓人感覺聲音只在一個地方發(fā)出來。單聲道音頻在雙聲道或多聲道設(shè)備上播放,每個聲道的音頻信號完全一致,沒有一點點差異,起不到立體效果。

  立體聲

  立體聲是使用兩個或多個獨立音頻通道的聲音再現(xiàn),其方式可產(chǎn)生從各個方向聽到的聲音的感覺,就像在自然聽覺中一樣。將不同的揚聲器插入到不同的聲道上,揚聲器中就會播放對應(yīng)的聲道音頻信號。現(xiàn)實中使用最多的是雙聲道的耳機,有時候我們會感覺耳機左右的聲音信號強弱不同,聲音也有差別,這說明當前播放的音頻是立體聲的;如果聽起來完全沒什么區(qū)別,就是單聲道的音頻。

  4.0環(huán)繞聲

4.0環(huán)繞聲也就是四聲道,4.0環(huán)繞聲在將四個揚聲器放置到四個角落的場景非常有用。聽眾可以聽到四個方位傳入耳朵的聲音。該環(huán)繞聲系統(tǒng)設(shè)備放置方位如下:

  

  5.1環(huán)繞聲

  5.1環(huán)繞聲系統(tǒng)使用6個通道,其中5個標準通道和1個超低音通道。該環(huán)繞聲系統(tǒng)設(shè)備放置方位圖如下:

  

  7.1環(huán)繞聲

  7.1環(huán)繞聲系統(tǒng)使用8個聲道,其中7個標準聲道和1個超低音聲道。該環(huán)繞聲系統(tǒng)設(shè)備放置方位圖如下:

  

三、編程中的聲道

  在實際編程中(如下操作的音頻文件參數(shù):44100HZ + 16bits + 2channels),當聲卡通道和被渲染的音頻聲道不同的時候,就需要我們進行聲道轉(zhuǎn)換。比如:2聲道轉(zhuǎn)換為單聲道。

 1  void SplitChannel()
 2     {
 3         const auto originalFilename = R"(C:UserscvterDesktopaudiosorigin_audio_1_2.pcm)";
 4         const auto splitChannelFilename1 = R"(C:UserscvterDesktopaudiossplit_channel_2.pcm)";
 5         ifstream inStream(originalFilename, ios_base::binary);
 6         if (!inStream.is_open()) {
 7             return;
 8         }
 9         ofstream outStream(splitChannelFilename1, ios_base::binary);
10         if (!outStream.is_open()) {
11             return;
12         }
13 
14         auto fileBuf1 = inStream.rdbuf();
15         auto fileBuf2 = outStream.rdbuf();
16         auto buf = make_unique<char[]>(kSampleBytes);
17         while (!inStream.eof()){
18             memset(buf.get(), 0xff, kSampleBytes);
19             auto len = fileBuf1->sgetn(buf.get(), kSampleBytes);
20             if (len != kSampleBytes) {
21                 break;
22             }
23             fileBuf2->sputn(buf.get() + kSampleBytes / kChannels, kDstSampleBytes);
24             fileBuf2->pubsync();
25         }
26 
27         inStream.close();
28         outStream.close();
29     }

  分離效果圖如下:

  將單聲道音頻合并成雙聲道,其中將分離出來的單聲道作為雙聲道左聲道,右聲道完全靜音:

 1  void InsertBlankPCMData(const std::string& filename)
 2     {
 3         ifstream inStream(filename, ios_base::binary);
 4         auto fileBuf1 = inStream.rdbuf();
 5         if (!fileBuf1->is_open()) {
 6             return;
 7         }
 8         constexpr auto kInsertBlankFilename = R"(C:UserscvterDesktopaudiossplit_channel_1_blank.pcm)";
 9         ofstream outStream(kInsertBlankFilename, ios_base::binary);
10         auto fileBuf2 = outStream.rdbuf();
11         if (!fileBuf2->is_open()) {
12             return;
13         }
14         int cnt = 0;
15         auto buf = make_unique<char[]>(kSampleBytes);
16         while (true){
17             memset(buf.get(), 0xff, kSampleBytes);
18             auto len = fileBuf1->sgetn(buf.get(), kDstSampleBytes);
19             if (len == 0) {
20                 break;
21             }
22             fileBuf2->sputn(buf.get(), kDstSampleBytes);
23             fileBuf2->sputn(buf.get() + kDstSampleBytes, kDstSampleBytes);
24             fileBuf2->pubsync();
25         }
26 
27         inStream.close();
28         outStream.close();
29     }

  

  如果你用耳機聽的話,左邊聲道是有聲音的,右聲道沒有,不要以為自己的耳機壞了。

   那么我們還可以將兩首單聲道音頻合并成一首雙聲道音頻,實現(xiàn)代碼如下:

 1 void MakeStereoDifferentSources(const std::string& filenameL, const std::string& filenameR)
 2     {
 3         ifstream inStream1(filenameL, ios_base::binary);
 4         ifstream inStream2(filenameR, ios_base::binary);
 5         if (!inStream1.is_open() || !inStream2.is_open()) {
 6             return;
 7         }
 8 
 9         const auto kStereoFilename = R"(C:UserscvterDesktopaudiosstereo.pcm)";
10         ofstream outStream(kStereoFilename, ios_base::binary);
11         if (!outStream.is_open()) {
12             return;
13         }
14 
15         auto fileBuf1 = inStream1.rdbuf();
16         auto fileBuf2 = inStream2.rdbuf();
17         auto fileBuf3 = outStream.rdbuf();
18         auto buf = make_unique<char[]>(kSampleBytes);
19         while (!inStream1.eof() || !inStream2.eof()){
20             memset(buf.get(), 0xff, kSampleBytes);
21             auto len1 = fileBuf1->sgetn(buf.get(), kDstSampleBytes);
22             auto len2 = fileBuf2->sgetn(buf.get() + kDstSampleBytes, kDstSampleBytes);
23             if (len1 == 0 && len2 == 0) {
24                 break;
25             }
26             fileBuf3->sputn(buf.get(), kSampleBytes);
27             
28         }
29     }

  當然,大家也可以將多個單聲道音頻組合成多聲道的,但是沒有對應(yīng)的設(shè)備進行播放,就不驗證了。我在實際開發(fā)中出來過8通道的,就是將8首音頻重采樣為單聲道后,合并成8聲道的音頻,然后塞入到該設(shè)備聲卡上。由于博客不支持上傳壓縮文件,這里我推送到github上:git@github.com:blackStar1314/resources.git

參考:6 types of sound channels | GearBest Blog

總結(jié)

以上是生活随笔為你收集整理的音频之声道那些事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。