获取麦克风音量分贝值

实习公司让我用C++ vs编辑工具做一个获取电脑麦克风分贝值的工具。我在网上查了一下相关的源码很少,几乎不能用。我就试着写了一个。其实没有什么技术含量,只不过就是调用一下windowAPI。重要的还是计算分贝的算法。

我先展现一下计算分贝的代码:

复制代码
 1 int CMicDlg:: getPcmDB(const unsigned char* pcmdata, size_t size) 
 2 {
 3 
 4     int db = 0;
 5     short int value = 0;
 6     double sum = 0;
 7     for (int i = 0; i < size; i += 2)
 8     {
 9         memcpy(&value, pcmdata + i, 2); //获取2个字节的大小(值)  
10         sum += abs(value); //绝对值求和  
11     }
12     sum = sum / (size / 2); //求平均值(2个字节表示一个振幅,所以振幅个数为:size/2个)  
13     if (sum > 0)
14     {
15         db = (int)(20.0 * log10(sum));
16     }
17     return db;
18 }
View Code
复制代码

这是计算声音分贝值的函数

用到的公式  

公式说明

参数:Pref:就是声音总的振幅最大值;Prms:就是当前声音的振幅值;Lp:就是我们需要的声音分贝值了。

计算分贝值我有一个很好的链接他写比较好https://www.cnblogs.com/waimen/p/9062814.html

其实分贝值的计算本就没有什么物理意义。它只不过就是把很大数简短的表示出来。

这是录音的代码:

变量定义:

复制代码
HWAVEIN hWaveIn;  //输入设备
WAVEFORMATEX waveform; //采集音频的格式,结构体
BYTE* pBuffer1;//采集音频时的数据缓存
WAVEHDR wHdr1; //采集音频时包含数据缓存的结构体
HANDLE          wait;
View Code
复制代码

初始化变量:

复制代码
1     waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCM
2     waveform.nSamplesPerSec = 8000;//采样率,16000次/秒
3     waveform.wBitsPerSample = 16;//采样比特,16bits/次
4     waveform.nChannels = 1;//采样声道数,2声道
5     waveform.nAvgBytesPerSec = 16384;//每秒的数据率,就是每秒能采集多少字节的数据
6     waveform.nBlockAlign = 2;//一个块的大小,采样bit的字节数乘以声道数
7     waveform.cbSize = 0;//一般为0
View Code
复制代码

开始录音

复制代码
 1 int CMicDlg::GetAudio()
 2 {   
 3     
 4     wait = CreateEvent(NULL, 0, 0, NULL);
 5     //使用waveInOpen函数开启音频采集
 6     waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
 7     //建立两个数组(这里可以建立多个数组)用来缓冲音频数据
 8     DWORD bufsize = 1024;//每次开辟1k的缓存存储录音数据
 9    
10         //结合音频解码和网络传输可以修改为实时录音播放的机制以实现对讲功能
11         pBuffer1 = new BYTE[bufsize];
12         wHdr1.lpData = (LPSTR)pBuffer1;
13         wHdr1.dwBufferLength = bufsize;
14         wHdr1.dwBytesRecorded = 0;
15         wHdr1.dwUser = 0;
16         wHdr1.dwFlags = 0;
17         wHdr1.dwLoops = 1;
18         waveInPrepareHeader(hWaveIn, &wHdr1, sizeof(WAVEHDR));//准备一个波形数据块头用于录音
19         waveInAddBuffer(hWaveIn, &wHdr1, sizeof(WAVEHDR));//指定波形数据块为录音输入缓存
20         waveInStart(hWaveIn);//开始录音
21         Sleep(1000);
22       
23         CString mic;
24         int sum = getPcmDB(pBuffer1, 1024);
25         mic.Format(_T("%d"), sum );
26         edit.SetWindowTextW(mic);
27         waveInReset(hWaveIn);//重置输入
28         delete[]pBuffer1;
29    // waveInClose(hWaveIn);
30     return 0;
31 }
View Code
复制代码

代码逻辑:

我用公式计算出声波一段的分贝值,每一秒计算一次。

我用的是mfc里的onTimer()函数来实现的。

posted @   joker_2255  阅读(2573)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示