1. 程式人生 > 其它 >音訊音量調節淺談

音訊音量調節淺談

  音樂播放器一般通過調節揚聲器的音量來改變音訊的播放音量,如果在不調節揚聲器的情況下,如何改變音訊的播放音量呢?

一、音訊的音量的控制引數

  不改變輸出裝置的音量,那麼就必須改變音訊資料達到控制音量的目的。音訊的音量大小由音訊振幅決定,而音訊振幅的PCM音訊格式中的名稱為:位深,即:8bits,16bits等。

二、編碼實現

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 namespace pcm {
 8 
 9     namespace amplitude {
10 
11
template 12 void Adjust(const std::string& pcmFile, int channels, float gain) 13 { 14 using namespace std; 15 constexpr auto kMax = numeric_limits::max(); 16 constexpr auto kMin = numeric_limits::min(); 17 18 ifstream inputStream(pcmFile, ios::binary);
19 assert(inputStream.is_open() && "not open pcm file!!!"); 20 auto originBuf = inputStream.rdbuf(); 21 ofstream outputStream("./adjust.pcm", ios::binary); 22 assert(outputStream.is_open() && "not open pcm file!!!"); 23 24 auto sampleSize = channels * sizeof
(BitDeepth); 25 auto buf = std::make_unique<BitDeepth[]>(channels); 26 27 while (true) { 28 29 std::memset(buf.get(), 0x00, sampleSize); 30 auto readSize = originBuf->sgetn(reinterpret_cast<char*>(buf.get()), sampleSize); 31 if (readSize == 0) break; 32 if (readSize != sampleSize) continue; 33 for (auto channel = 0; channel < channels; ++channel) { 34 auto& originPcmVol = buf[channel]; 35 auto gainPcmVol = static_cast(originPcmVol * gain); 36 if (gainPcmVol > kMax) gainPcmVol = kMax; 37 if (gainPcmVol < kMin) gainPcmVol = kMin; 38 auto size = sizeof(BitDeepth); 39 std::memcpy(&originPcmVol, &gainPcmVol, size); 40 } 41 outputStream.write(reinterpret_cast<char*>(buf.get()), sampleSize); 42 outputStream.flush(); 43 } 44 } 45 46 } 47 } 48 49 int main() 50 { 51 // PCM 格式儲存方式(一個取樣) 52 // 1通道 8bit 53 // -------- 54 // | 8bit | 55 // -------- 56 57 // 2通道 8bit 58 // --------------- 59 // | 8bit | 8bit | 60 // --------------- 61 62 // 1通道 16bit 63 // --------- 64 // | 16bit | 65 // --------- 66 67 // 2通道 16bit 68 // ----------------- 69 // | 16bit | 16bit | 70 // ----------------- 71 constexpr auto kPcmFile = R"(.\test_16_1.pcm)"; 72 pcm::amplitude::Adjust<int16_t>(kPcmFile, 1, 0.01f); 73 74 system("pause"); 75 return 0; 76 }

三、測試樣例

下載地址:https://files.cnblogs.com/files/smartNeo/sample.zip

或者使用ffmpeg 工具轉換想要的pcm樣例。ffmpeg : mp3 -> pcm命令:ffmpeg.exe -i file.mp3 -f s16le -ar 44100 -ac 2 -acodec pcm_s16le test_16_2.pcm

參考:

  • https://blog.jianchihu.net/pcm-volume-control.html
  • http://blog.jianchihu.net/pcm-vol-control-advance.html
  • https://docs.microsoft.com/en-us/windows/win32/coreaudio/audio-tapered-volume-controls