OMCS 使用技巧 -- 分贝显示器,实时显示声音强度

使用 摄像头、麦克风、扬声器 测试程序 一文中提到的方法,我们可以基本实现QQ的语音视频测试向导的功能了。但是,语音测试这块的体验还可以做得更好一点,就像QQ语音测试一样,实时显示麦克风采集到的声音的强度:

      

接下来,我们做个小demo,来实现类似的功能。先上demo运行起来的截图:

        

(界面确实比较丑,我们这里的重点在于技术方面如何实现,如果你愿意花点时间,可以将其美化得跟QQ的那个一样漂亮^_^)

 

1.实现思路

实现这个小例子的主要思路如下:

(1)使用OMCS采集和播放从麦克风的输入数据(PCM)。

(2)对采集到的数据进行傅立叶变换,变换的结果就可以反应声音的强度。

(3)使用ProgressBar控件来实时显示声音的强度信息。

2.具体实现

(1)傅立叶变换算法 

    public static class FourierTransformer
    {
        public static double[] FFTDb(double[] source)
        {          
            int sourceLen = source.Length;
            int nu = (int)(Math.Log(sourceLen) / Math.Log(2));
            int halfSourceLen = sourceLen / 2;
            int nu1 = nu - 1;
            double[] xre = new double[sourceLen];
            double[] xim = new double[sourceLen];
            double[] decibel = new double[halfSourceLen];
            double tr, ti, p, arg, c, s;
            for (int i = 0; i < sourceLen; i++)
            {
                xre[i] = source[i];
                xim[i] = 0.0f;
            }
            int k = 0;
            for (int l = 1; l <= nu; l++)
            {
                while (k < sourceLen)
                {
                    for (int i = 1; i <= halfSourceLen; i++)
                    {
                        p = BitReverse(k >> nu1, nu);
                        arg = 2 * (double)Math.PI * p / sourceLen;
                        c = (double)Math.Cos(arg);
                        s = (double)Math.Sin(arg);
                        tr = xre[k + halfSourceLen] * c + xim[k + halfSourceLen] * s;
                        ti = xim[k + halfSourceLen] * c - xre[k + halfSourceLen] * s;
                        xre[k + halfSourceLen] = xre[k] - tr;
                        xim[k + halfSourceLen] = xim[k] - ti;
                        xre[k] += tr;
                        xim[k] += ti;
                        k++;
                    }
                    k += halfSourceLen;
                }
                k = 0;
                nu1--;
                halfSourceLen = halfSourceLen / 2;
            }
            k = 0;
            int r;
            while (k < sourceLen)
            {
                r = BitReverse(k, nu);
                if (r > k)
                {
                    tr = xre[k];
                    ti = xim[k];
                    xre[k] = xre[r];
                    xim[k] = xim[r];
                    xre[r] = tr;
                    xim[r] = ti;
                }
                k++;
            }
            for (int i = 0; i < sourceLen / 2; i++)
            {
                decibel[i] = 10.0 * Math.Log10((float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i]))));
            }

            return decibel;
        }

        private static int BitReverse(int j, int nu)
        {
            int j2;
            int j1 = j;
            int k = 0;
            for (int i = 1; i <= nu; i++)
            {
                j2 = j1 / 2;
                k = 2 * k + j1 - 2 * j2;
                j1 = j2;
            }
            return k;
        }
    }

(2)初始化OMCS服务器、设备管理器、麦克风设备 

        //获取麦克风列表
         IList<MicrophoneInformation> microphones = SoundDevice.GetMicrophones();
        this.comboBox2.DataSource = microphones;
        if (microphones.Count > 0)
        {
            this.comboBox2.SelectedIndex = 0;
        }

        //初始化OMCS服务器
         OMCSConfiguration configuration = new OMCSConfiguration(10, 1, EncodingQuality.High, 16000, 800, 600);
        this.multimediaServer = new MultimediaServer(9000, new DefaultUserVerifier(), configuration, false, null);

        this.multimediaManager.DeviceErrorOccurred += new CbGeneric<MultimediaDeviceType, string>(multimediaManager_DeviceErrorOccurred);
        this.multimediaManager.AudioCaptured += new CbGeneric<byte[]>(multimediaManager_AudioCaptured);
        this.microphoneConnector1.ConnectEnded += new CbGeneric<ConnectResult>(microphoneConnector1_ConnectEnded);

(3)连接麦克风,开始采集

    if (!SoundDevice.IsSoundCardInstalled())
    {
        this.label_error.Visible = true;
        this.label_error.Text = "声卡没有安装";
    }

    //初始化多媒体管理器 
    this.multimediaManager.MicrophoneDeviceIndex = this.comboBox2.SelectedIndex;                  
    this.multimediaManager.Initialize("tester", "", "127.0.0.1", 9000); //与OMCS服务器建立连接,并登录

    //尝试连接麦克风              
    this.microphoneConnector1.BeginConnect("tester");

首先,初始化本地多媒体设备管理器,然后使用麦克风连接器连接到当前登录用户“tester”(即“自己”)麦克风设备。如果连接成功,多媒体管理器将会触发AudioCaptured事件,我们通过这个事件来截获音频数据。

(4)处理采集到的音频数据,并显示结果 

        void multimediaManager_AudioCaptured(byte[] data)
        {
            double[] wave = new double[data.Length / 2];
            int h = 0;
            for (int i = 0; i < wave.Length; i += 2)
            {
                wave[h] = (double)BitConverter.ToInt16(data, i); //采样位数为16bit
                ++h;
            }

            double[] res = FourierTransformer.FFTDb(wave);

            double kk = 0;
            foreach (double dd in res)
            {
                kk += dd;
            }
            if (kk < 0)
            {
                kk = 0;
            }
            this.showResult(kk / res.Length);
        }
        
        private void showResult(double rs)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbGeneric<double>(this.showResult), rs);
            }
            else
            {
                int rss = (int)(rs * 2);
                   if (rss < 40)
                {
                    rss = 40;
                }
                if (rss > 100)
                {
                    rss = 100;
                }

                this.progressBar1.Value = rss;
            }
        }

注意:由于OMCS音频采样的位数为16bit,这样,一个单位的语音样本的字节数为2个字节。所以,傅立叶变换前,先要将原始的PCM数据(byte[])转为Int16的数组。 

3.Demo程序

    源码下载

  

下载免费版本的OMCS以及 demo源码

阅读 更多OMCS开发手册系列文章

Q Q:168757008

官网:www.oraycn.com

导航

首页

官方网站

联系我们

站内搜索

OrayTalk 企业即时通讯系统

傲瑞通官网

详细说明

客户端下载

OrayMeeting 视频会议系统

详细说明

客户端下载

ESFramework 通信框架

详细说明

SDK与Demo下载

ESFramework FAQ

版本变更记录

OMCS 语音视频框架

详细说明

SDK与Demo下载

OMCS FAQ

版本变更记录

OVCS 视频会议Demo

详细说明

源码下载

傲瑞实用组件

SDK下载

H5Media 纯网页音视频交互

NPusher 推流组件

MCapture 语音视频采集组件

MFile 语音视频录制组件

MPlayer 语音视频播放组件

OAUS 自动升级系统

StriveEngine 轻量级的通信引擎

傲瑞组件 FAQ

授权

授权流程

产品选购指南

授权方案说明

授权SDK使用说明

其它

支持信创国产化

SDK使用技巧

联系我们