C# 获取系统声卡音频数据,并绘制波形
//by wgscd
//date:2022/11/7
UI:
<Path Stroke="Red" Data="{Binding path}" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
Code:
using NAudio.CoreAudioApi;
using NAudio.Wave.SampleProviders;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using NAudio.Wave.Compression;
using System.Runtime.Remoting.Channels;
using System.ComponentModel;
using System.Collections.ObjectModel;
using HandyControl.Collections;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.CodeDom; namespace DouyuDanmu
{
//by wgscd
//date:2022/11/7
public class NAudioHelper
{ public static SampleData pathData = new SampleData();
public static void GetSampleData() {
// Redefine the capturer instance with a new instance of the LoopbackCapture class
WasapiLoopbackCapture _waveIn = new WasapiLoopbackCapture();
_waveIn.WaveFormat = new WaveFormat(16000, 16, 2); // Redefine the audio writer instance with the given configuration
//WaveFileWriter RecordedAudioWriter = new WaveFileWriter(outputFilePath, CaptureInstance.WaveFormat);
// When the capturer receives audio, start writing the buffer into the mentioned file
_waveIn.DataAvailable += (s, a) =>
{
// Write buffer into the file of the writer instance
AnalyzeVoice(a.Buffer); }; _waveIn.StartRecording(); } private static void SampleChannel_PreVolumeMeter(object sender, StreamVolumeEventArgs e)
{
Debug.Print(""+ e.MaxSampleValues[0]); } private static void waveIn_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
{
AnalyzeVoice(e.Buffer);
} static bool isbusy = false ;
/// <summary>
/// 语音分析
/// </summary>
/// <param name="buf"></param>
private async static void AnalyzeVoice(byte[] buffer)
{
if (isbusy) { return; } isbusy = true;
await Task.Delay(10); float[] sts = new float[buffer.Length / 2];
int outIndex = 0;
for (int n = 0; n < buffer.Length; n += 2)
{
sts[outIndex++] = BitConverter.ToInt16(buffer, n) / 32768f;
}
int channels = 20;//值越大提取的越稀疏
float value = 0;
List<Point> listPoint = new List<Point>(); float p=0;
float x = 0;
for (int n = 0; n < sts.Length; n += channels)
{ value = sts[n] > 0.0f ? sts[n] *400: 1f;//sts[n] * 400 是为了转化成有用的高度值
Debug.Print(""+value );//这个就是大概的波形图
p = value;
x += 2;
listPoint.Add(new Point(x,p));
}
UpdatePath(listPoint);//listPoint 更新一个类似贝塞尔曲线的效果
isbusy = false ;
} private static void UpdatePath(List<Point> points)
{ StringBuilder data = new StringBuilder("M");
data.AppendFormat("{0},{1} C", points[0].X, points[0].Y); for (int i = 1; i < points.Count; i++)
{
Point pre = new Point((points[i - 1].X + points[i].X) / 2, points[i - 1].Y); //控制点
Point next = new Point((points[i - 1].X + points[i].X) / 2, points[i].Y); //控制点
data.AppendFormat(" {0},{1} {2},{3} {4},{5}", pre.X, pre.Y, next.X, next.Y, points[i].X, points[i].Y);
}
// pathData.path = new Path { Stroke = Brushes.DodgerBlue, StrokeThickness = 1, Data = Geometry.Parse(data.ToString()) };
pathData.path = Geometry.Parse(data.ToString()); } } public class SampleData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
float _value = 0;
public float value
{
get
{ return _value;
}
set
{
_value = value;
NotifyPropertyChanged(nameof(value));
}
} Geometry _path ;
public Geometry path
{
get
{ return _path;
}
set
{
_path = value;
NotifyPropertyChanged(nameof(path));
}
} } }
C# 获取系统声卡音频数据,并绘制波形的更多相关文章
- Android 获取系统的联系人
本文主要介绍android中怎样获取系统的联系人数据 首先打开模拟器 点击联系人图标按钮 说明系统联系人数据库是空的,打开File explorer,找到data/data下面的文件夹: 将conta ...
- C# NAudio录音和播放音频文件-实时绘制音频波形图(从音频流数据获取,而非设备获取)
NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发. 在WaveIn和WaveOut之外还有对 ...
- iOS 获取系统相册数据(不是调系统的相册)
Framework:AssetsLibrary.framework 主要目的是获取到系统相册的数据,并把系统相册里的照片显示出来. 1.创建一个新的项目: 2.将AssetsLibrary.frame ...
- DirectSound播放PCM(可播放实时采集的音频数据)
前言 该篇整理的原始来源为http://blog.csdn.net/leixiaohua1020/article/details/40540147.非常感谢该博主的无私奉献,写了不少关于不同多媒体库的 ...
- 使用AudioTrack播放PCM音频数据(android)
众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...
- Android音频系统之音频框架
1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段 ...
- Android 音视频开发(二):使用 AudioRecord 采集音频数据并保存到文件
版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7457321.html 一.AudioRecord API详解 AudioRecord是Android系统提 ...
- RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)
===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...
- 获取系统中所有进程&线程信息
读书笔记--[计算机病毒解密与对抗] 目录: 遍历进程&线程程序 终止进程 获取进程信息 获取进程内模块信息 获取进程命令行参数 代码运行环境:Win7 x64 VS2012 Update3 ...
- 如何用 ajax 连接mysql数据库,并且获取从中返回的数据。ajax获取从mysql返回的数据。responseXML分别输出不同数据的方法。
开讲前,先说下网上,大部分的关于这方面的博文或者其他什么的,就我自己的感觉,第一说得不详细,第二语言不能很好的被初学者了解. 我这篇博文的标题之所以用了三句,是为了方便其他人好查找: 这里介绍的方法有 ...
随机推荐
- 题解:洛谷P3745 期末考试(整数三分)
题解:洛谷P3745 期末考试(整数三分) 题目传送门 题目大意:给出 \(n\) 个同学期望出成绩的时间限制 \(a_i\) 和 \(m\) 个学科公布成绩的初始时间 \(t_i\) ,1个同学每多 ...
- Abp源码分析之虚拟文件系统Volo.Abp.VirtualFileSystem
前言 Volo.Abp.VirtualFileSystem 是ABP(ASP.NET Boilerplate)框架中的一个重要组件,它提供了一种抽象文件系统的方式,使得应用程序可以轻松地访问和管理文件 ...
- FFmpeg转码音视频时间戳设置分析
音频时间戳设置 以下代码基于FFmpeg n5.1.2进行分析 以下文档中有关音频的具体时间戳数据来自以下转码命令: ./ffmpeg_g -rw_timeout 5000000 -i 'rtmp:/ ...
- Chrome 浏览器 131 版本新特性
Chrome 浏览器 131 版本新特性 一.Chrome 浏览器 131 版本新特性 1. 在 iOS 上使用 Google Lens 搜索 自 Chrome 126 版本以来,用户可以通过 Goo ...
- npm安装包出现Invalid Version,npm list报错UNMET DEPENDENCY报错
执行 npm install 出现报错 2097 verbose stack TypeError: Invalid Version: 2097 verbose stack at new SemVer ...
- Java通用分页
一. 要分页我们必须要有数据库,所以我们先准备下数据库,其数据库脚步如下: --以下是创建数据库和数据库表以及向数据库插入数据 use master Go if exists(select ...
- SSL免费证书之Let’s Encrypt
官网:https://letsencrypt.org/zh-cn 官网建议使用Certbot的方式进行安装,所以首先我们需要安装Certbot Certbot) 官网:Certbot (eff.org ...
- 从解决Github TimeOut到经典面试题:从输入URL到浏览器显示页面发生了什么?
问题描述 在Windows 操作系统上,push代码到git的时候,出现了Failed to connect to github.com port 443: Timed out的错误.一脸懵逼,浏览器 ...
- 使用nginx 解决开发过程中的跨域问题
遇到的问题 在开发vue 前端程序时,我们会创建多个项目,比如用户管理为一个应用,系统管理为一个应用,这样多个应用势必需要开多个端口,这样问题就来了,我们在登录后会生成一个token,这个token我 ...
- 0. RyuJIT Tutorials - RyuJIT 的历史和架构
目录 上一篇:无 下一篇:待更新 正文 RyuJIT - 即 .NET 的 JIT 编译器,负责将 IL 代码编译为最终用于执行的机器代码. 本系列为 RyuJIT 教程,将分为多篇进行更新发布,旨在 ...