基于Accord.Audio和百度语言识别

目标需求

 

使用录音形式,模拟微信语音聊天。按住录音,松开发送语音,并完成语音识别。

ps:百度的语言识别有60秒长度限制,需要自己做好控制。

 

实现方案

采用C# winform 程序实现桌面版,采用Accord 实现语音录制停止等基础语音操作,操作停止按钮,

自动调用百度语言识别接口将识别内容显示在文本框中。

备注,语音识别需要配套阵列麦克风,(请先注册百度开发者)百度语音识别接口请参考:http://ai.baidu.com/docs#/ASR-Online-Csharp-SDK/top

 

实现效果展示

 

  


实现过程

 

1、下载Accord 完成语音操作引用

 

accord 官方 地址:http://accord-framework.net/intro.html

官网中有示例demo,笔者的就是在示例demo上做改造的。

 

 

建立自己的项目,引用包中的dll

 

 界面代码:

using System;

using System.Drawing;

using System.IO;

using System.Windows.Forms;

using Accord.Audio;

using Accord.Audio.Formats;

using Accord.DirectSound;

using Accord.Audio.Filters;

using Baidu.Aip.API;


namespace SampleApp

{


    public partial class MainForm : Form

    {

        private MemoryStream stream;


        private IAudioSource source;

        private IAudioOutput output;


        private WaveEncoder encoder;

        private WaveDecoder decoder;


        private float[] current;


        private int frames;

        private int samples;

        private TimeSpan duration;

        /// <summary>

        /// 备注,语音识别需要配套阵列麦克风

        /// </summary>


        public MainForm()

        {

            InitializeComponent();


           

            // Configure the wavechart

            chart.SimpleMode = true;

            chart.AddWaveform("wave", Color.Green, 1, false);


            updateButtons();

           // Application.Idle += ProcessFrame;

        }

     

        void ProcessFrame(object sender, EventArgs e) {


          

        }

        /// <summary>

        ///   从声卡开始录制音频

        /// </summary>

        /// 

        private void btnRecord_Click(object sender, EventArgs e)

        {

            // Create capture device

            source = new AudioCaptureDevice()//这里是核心

            {

                // Listen on 22050 Hz

                DesiredFrameSize = 4096,

                SampleRate = 16000,//采样率 

                //SampleRate = 22050,//采样率

                Channels=1,

                // We will be reading 16-bit PCM

                Format = SampleFormat.Format16Bit

            };


            // Wire up some events

            source.NewFrame += source_NewFrame;

            source.AudioSourceError += source_AudioSourceError;


            // Create buffer for wavechart control

            current = new float[source.DesiredFrameSize];


            // Create stream to store file

            stream = new MemoryStream();

            encoder = new WaveEncoder(stream);


            // Start

            source.Start();

            updateButtons();

        }


        /// <summary>

        ///   播放录制的音频流。

        /// </summary>

        /// 

        private void btnPlay_Click(object sender, EventArgs e)

        {

            // First, we rewind the stream

            stream.Seek(0, SeekOrigin.Begin);


            // Then we create a decoder for it

            decoder = new WaveDecoder(stream);


            // Configure the track bar so the cursor

            // can show the proper current position

            if (trackBar1.Value < decoder.Frames)

                decoder.Seek(trackBar1.Value);

            trackBar1.Maximum = decoder.Samples;


            // Here we can create the output audio device that will be playing the recording

            output = new AudioOutputDevice(this.Handle, decoder.SampleRate, decoder.Channels);


            // Wire up some events

            output.FramePlayingStarted += output_FramePlayingStarted;

            output.NewFrameRequested += output_NewFrameRequested;

            output.Stopped += output_PlayingFinished;


            // Start playing!

            output.Play();


            updateButtons();

        }


        /// <summary>

        /// 停止录制或播放流。

        /// </summary>

        /// 

        private void btnStop_Click(object sender, EventArgs e)

        {

            // Stops both cases

            if (source != null)

            {

                // If we were recording

                source.SignalToStop();

                source.WaitForStop();

            }

            if (output != null)

            {

                // If we were playing

                output.SignalToStop();

                output.WaitForStop();

            }


            updateButtons();


            // Also zero out the buffers and screen

            Array.Clear(current, 0, current.Length);

            updateWaveform(current, current.Length);

            SpeechAPI speechApi = new SpeechAPI();


            string result = speechApi.AsrData(stream,"wav");

            tb_result.Text = "语音识别结果:"+result;

        }




        /// <summary>

        /// 当音频有错误时,将调用这个回调函数。 

        /// 

        ///   

        /// </summary>

        /// 

        private void source_AudioSourceError(object sender, AudioSourceErrorEventArgs e)

        {

            throw new Exception(e.Description);

        }


        /// <summary>

        ///  

        ///  每当有新的输入音频帧时,该方法将被调用。

        ///                                                      

        /// </summary>

        /// 

        private void source_NewFrame(object sender, NewFrameEventArgs eventArgs)

        {

           

            eventArgs.Signal.CopyTo(current);


        

            updateWaveform(current, eventArgs.Signal.Length);


         

            encoder.Encode(eventArgs.Signal);


          

            duration += eventArgs.Signal.Duration;

           

            samples += eventArgs.Signal.Samples;

            frames += eventArgs.Signal.Length;

        }



        private void output_FramePlayingStarted(object sender, PlayFrameEventArgs e)

        {

            updateTrackbar(e.FrameIndex);


            if (e.FrameIndex + e.Count < decoder.Frames)

            {

                int previous = decoder.Position;

                decoder.Seek(e.FrameIndex);


                Signal s = decoder.Decode(e.Count);

                decoder.Seek(previous);


                updateWaveform(s.ToFloat(), s.Length);

            }

        }


     

        private void output_PlayingFinished(object sender, EventArgs e)

        {

            updateButtons();


            Array.Clear(current, 0, current.Length);

            updateWaveform(current, current.Length);

        }


     

        /// 

        private void output_NewFrameRequested(object sender, NewFrameRequestedEventArgs e)

        {

         

            e.FrameIndex = decoder.Position;


           

            Signal signal = decoder.Decode(e.Frames);


            if (signal == null)

            {

                

                e.Stop = true;

                return;

            }


         

            e.Frames = signal.Length;


          

            signal.CopyTo(e.Buffer);

        }





        private void updateWaveform(float[] samples, int length)

        {

            if (InvokeRequired)

            {

                BeginInvoke(new Action(() =>

                {

                    chart.UpdateWaveform("wave", samples, length);

                }));

            }

            else

            {

                chart.UpdateWaveform("wave", current, length);

            }

        }


       

        /// 

        private void updateTrackbar(int value)

        {

            if (InvokeRequired)

            {

                BeginInvoke(new Action(() =>

                {

                    trackBar1.Value = Math.Max(trackBar1.Minimum, Math.Min(trackBar1.Maximum, value));

                }));

            }

            else

            {

                trackBar1.Value = Math.Max(trackBar1.Minimum, Math.Min(trackBar1.Maximum, value));

            }

        }


        private void updateButtons()

        {

            if (InvokeRequired)

            {

                BeginInvoke(new Action(updateButtons));

                return;

            }


            if (source != null && source.IsRunning)

            {

                btnBwd.Enabled = false;

                btnFwd.Enabled = false;

                btnPlay.Enabled = false;

                btnStop.Enabled = true;

                btnRecord.Enabled = false;

                trackBar1.Enabled = false;

            }

            else if (output != null && output.IsRunning)

            {

                btnBwd.Enabled = false;

                btnFwd.Enabled = false;

                btnPlay.Enabled = false;

                btnStop.Enabled = true;

                btnRecord.Enabled = false;

                trackBar1.Enabled = true;

            }

            else

            {

                btnBwd.Enabled = false;

                btnFwd.Enabled = false;

                btnPlay.Enabled = stream != null;

                btnStop.Enabled = false;

                btnRecord.Enabled = true;

                trackBar1.Enabled = decoder != null;


                trackBar1.Value = 0;

            }

        }


        private void MainFormFormClosed(object sender, FormClosedEventArgs e)

        {

            if (source != null) source.SignalToStop();

            if (output != null) output.SignalToStop();

        }


        private void saveFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)

        {

            Stream fileStream = saveFileDialog1.OpenFile();

            stream.WriteTo(fileStream);

            fileStream.Close();

        }


        private void saveToolStripMenuItem_Click(object sender, EventArgs e)

        {

            saveFileDialog1.ShowDialog(this);

        }


       

        private void updateTimer_Tick(object sender, EventArgs e)

        {

            lbLength.Text = String.Format("Length: {0:00.00} sec.", duration.Seconds);

          

        }


        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)

        {

            new AboutBox().ShowDialog(this);

        }


        private void closeToolStripMenuItem_Click(object sender, EventArgs e)

        {

            Close();

        }


        private void btnIncreaseVolume_Click(object sender, EventArgs e)

        {

            adjustVolume(1.25f);

        }


        private void btnDecreaseVolume_Click(object sender, EventArgs e)

        {

            adjustVolume(0.75f);

        }


        private void adjustVolume(float value)

        {

        

            stream.Seek(0, SeekOrigin.Begin);


     

            decoder = new WaveDecoder(stream);


            var signal = decoder.Decode();


           

            var volume = new VolumeFilter(value);

            volume.ApplyInPlace(signal);


   

            stream.Seek(0, SeekOrigin.Begin);

            encoder = new WaveEncoder(stream);

            encoder.Encode(signal);

        }


    }

}

 百度语音识别接口

百度已经提供sdk,对于支持语音格式如下。

支持的语音格式

原始 PCM 的录音参数必须符合 8k/16k 采样率、16bit 位深、单声道,支持的格式有:pcm(不压缩)、wav(不压缩,pcm编码)、amr(压缩格式)。

 

        public string AsrData(string filePath, string format = "pcm", int rate = 16000){         
var data =File.ReadAllBytes(filePath);
var result = _asrClient.Recognize(data, format, 16000);
return result.ToString();}

 

 结果评测:

对于普通的语言识别效果不好,需要阵列麦克风才可以。

原文地址:http://www.cnblogs.com/linbin524/p/8086123.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

欢乐纪中A组周六赛【2019.5.18】

前言 重返纪中之日&#xff0c;又是被虐之时 成绩 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC666(H−1)HJW(H-1)HJW(H−1)HJW191191191100100100919191000999(J−2)WYC(J-2)WYC(J−2)WYC151151151606060909…

Spark入门(十六)之分组求TOP N最小值

一、分组求TOP N最小值 计算文本里面的每个key分组求TOP N最小值&#xff0c;输出结果。 二、maven设置 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.o…

(八)Spring与MyBatis整合

持久层 目录 Mybatis 开发步骤回顾Mybatis 开发中存在的问题Spring 与 Mybatis 整合思路Spring 与 Mybatis 整合的开发步骤Spring 与 Mybatis 整合的编码搭建开发环境 pom.xmlSpring 配置文件的配置编码Spring 与 Mybatis 整合细节持久层整合总述 1、Spring 框架为什么要与持…

Git 企业开发者教程

为什么要写这样一个面向企业开发者的Git教程&#xff1f;这个问题也困扰我自己很久。其实我使用git的时间也不短了&#xff0c;但是就和正在阅读本文的每一位一样&#xff0c;常用的基本就是那么几个(git clone, git push)等等。然而git其实有着非常强大的功能&#xff0c;如果…

P1169-[ZJOI2007]棋盘制作【贪心】

正题 题目链接:https://www.luogu.org/problemnew/show/P1169 题目大意 一个矩阵中求一个最大的子矩阵和子正方形使得它们其中都是01交错。 解题思路 lefti,jleft_{i,j}lefti,j​表示(i,j)(i,j)(i,j)往左扩展多远&#xff0c;righti,jright_{i,j}righti,j​表示(i,j)(i,j)(i,…

(九)Spring 事务开发、事务属性详解

持久层 目录 事务回顾Spring 控制事务的开发Spring 中的事务属性&#xff08;Transaction Attribute&#xff09;隔离属性&#xff08;ISOLATION&#xff09;传播属性&#xff08;PROPAGATION&#xff09;只读属性&#xff08;readOnly&#xff09;超时属性&#xff08;timeo…

基于百度理解与交互技术实现机器问答

一、前言我们都知道现在聊天对话机器是一个很有意思的东西&#xff0c;比如说苹果siri&#xff0c;比如说微软的小冰。聊天对话机器的应用场景也很广泛&#xff0c;比如说&#xff1a;银行的自助办卡机器人、展会讲解解说等等。我们对机器人说句话&#xff0c;机器人从听取&…

Spark入门(十七)之单表关联

一、单表关联 给出child-parent&#xff08;孩子——父母&#xff09;表&#xff0c;要求输出grandchild-grandparent&#xff08;孙子——祖父母&#xff09;表 二、maven设置 <?xml version"1.0" encoding"UTF-8"?><project xmlns"htt…

P3514-[POI2011]LIZ-Lollipop【思路题】

正题 题目链接:https://www.luogu.org/problemnew/show/P3514 题目大意 一个12序列&#xff0c;若干个询问求有没有一个子串之和为kkk 解题思路 首先感谢ZYCdalaoZYCdalaoZYCdalao的温馨提示。 然后进入正题 首先我们考虑一个串的和为kkk 那么最边的数的情况(1,1),(1,2),(2…

(十)Spring 与 MVC 框架整合

Spring 整合 MVC 目录 MVC 框架整合思想为什么要整合 MVC 框架搭建 Web 运行环境Spring 整合 MVC 框架的核心思路1. 准备工厂2. 代码整合Spring 整合 Struts2MVC 框架整合思想 为什么要整合 MVC 框架 MVC 框架提供了控制器&#xff08;Controller&#xff09;调用 Servlet …

Spark入门(十八)之多表关联

一、多表关联 输入是两个文件&#xff0c;一个代表工厂表&#xff0c;包含工厂名列和地址编号列&#xff1b;另一个代表地址表&#xff0c;包含地址名列和地址编号列。要求从输入数据中找出工厂名和地址名的对应关系&#xff0c;输出"工厂名——地址名"表 二、maven…

利用VSTS跟Kubernetes整合进行CI/CD

为什么VSTS要搭配Kubernetes&#xff1f;通常我们在开发管理软件项目的时候都会碰到一个很头痛的问题&#xff0c;就是开发、测试、生产环境不一致&#xff0c;导致开发人员和测试人员甚至和运维吵架。因为常见的物理环境甚至云环境中&#xff0c;这些部署环境都是由运维人员提…

P3112-[USACO14DEC]后卫马克Guard Mark【贪心】

正题 题目链接:https://www.luogu.org/problemnew/show/P3112 题目大意 有nnn只牛&#xff0c;每只牛有hi,wi,sih_i,w_i,s_ihi​,wi​,si​分别表示有多高&#xff0c;有多重&#xff0c;上面最多承载总共多重的牛。 选择一些牛依次摆放要求高度超过TTT且上面还能增加最重的物…

(十一)Spring 基础注解(对象创建相关注解、注入相关注解)

注解编程 目录 注解基础概念注解的作用Spring 注解的发展历程Spring 基础注解&#xff08;Spring 2.x&#xff09;对象创建相关注解ComponentRepository、Service、ContollerScopeLazy生命周期注解 PostConstruct、PreDestroy注入相关注解用户自定义类型 AutowiredJDK 类型注…

Spark Streaming之统计socket单词数

一、统计socket单词数 侦听TCP套接字的数据服务器接收到的文本数据中的单词数。 二、maven配置 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/…

使用 ASP.NET Core, Entity Framework Core 和 ABP 创建N层Web应用 第二篇

介绍这是“使用 ASP.NET Core &#xff0c;Entity Framework Core 和 ASP.NET Boilerplate 创建N层 Web 应用”系列文章的第二篇。以下可以看其他篇目&#xff1a;使用 ASP.NET Core &#xff0c;Entity Framework Core 和 ASP.NET Boilerplate 创建N层 Web 应用 第一篇 &…

jzoj4786-[NOIP2016提高A组模拟9.17]小a的强迫症【数论】

正题 题目大意 nnn个颜色第iii个个数为numinum_inumi​个&#xff0c;然后要求第iii种颜色的最后一个一定在第i1i1i1种的最后一个前面。求方案总数。 解题思路 首先先定义一个1∼n1\sim n1∼n的序列&#xff0c;然后依次将剩下的数插入。 第iii个颜色有z(∑j1i−1numj)1z(\su…

0-MyBatis简介

MyBatis简介 目录 简介MyBatis 历史MyBatis特点为什么要使用 MyBatis&#xff1f;JDBC 缺点Hibernate 缺点MyBatis简介 MyBatis 历史 MyBatis 原是 apache 的一个开源项目 iBatis&#xff1b;2010年6月这个项目由 apache software foundation 迁移到了 google code&#xf…

揭秘微软6万工程师DevOps成功转型的技术「武器」

在微软&#xff0c;通过其自身数年的 DevOps 转型&#xff0c; 6 万名工程师实现了更好的软件平台创新和快速迭代。微软有庞大的技术产品矩阵&#xff0c;同时也具有每天发布的能力&#xff0c;其中&#xff0c;微软研发云是支撑整个开发过程与运维最重要的基础平台。微软研发云…

jzoj4787-[NOIP2016提高A组模拟9.17]数格子【矩阵乘法】

正题 题目大意 求121\times 212的方块铺满4n4\times n4n的方格方案总数。 解题思路 首先 当计算fnf_nfn​时&#xff0c; 显然最后一排可以(−−−−)(∣∣∣∣)(−−∣∣)(∣−−∣)(∣∣−−)(--\ --)(|\ \ |\ \ |\ \ |)(--\ \ |\ \ |)(|\ \ --\ \ |)(|\ \ |--)(−− −−)…