C# NAudio录音和播放音频文件及实时绘制音频波形图(从音频流数据获取,而非设备获取)
下午写了一篇关于NAudio的录音、播放和波形图的博客,不太满意,感觉写的太乱,又总结了下
NAudio是个相对成熟、开源的C#音频开发工具,它包含录音、播放录音、格式转换、混音调整等功能。本次介绍主要功能有音频、录音文件播放、实时音频流波形图显示等。具体如下:
1. 录音
NAudio录音主要使用WaveIn和WaveFileWriter两个类
1.1 WaveIn
WaveIn的功能是对录音的音频参数进行设置以及对数据的采集,参数如通道数、采样率、平均数据传输速率(WaveFormat)、数据回调事件、录音停止回调函数等参数
其中,DataAvailable为数据回调参数,是在录音时实时将录音数据传递出来,有需要使用录音数据的可以订阅该事件进行接收业务和相关处理。
1.2 WaveFileWriter
该类是创建相对应格式的音频文件,并提供想对应的写入数据方法、保存方法等,具体如下:
public class WaveFileWriter : Stream
{
public WaveFileWriter(Stream outStream, WaveFormat format);
public WaveFileWriter(string filename, WaveFormat format); ~WaveFileWriter(); public override long Position { get; set; }
public override bool CanWrite { get; }
public override bool CanRead { get; }
public WaveFormat WaveFormat { get; }
public TimeSpan TotalTime { get; }
public override long Length { get; }
public string Filename { get; }
public override bool CanSeek { get; } public static void CreateWaveFile(string filename, IWaveProvider sourceProvider);
public static void CreateWaveFile16(string filename, ISampleProvider sourceProvider);
public static void WriteWavFileToStream(Stream outStream, IWaveProvider sourceProvider);
public override void Flush();
public override int Read(byte[] buffer, int offset, int count);
public override long Seek(long offset, SeekOrigin origin);
public override void SetLength(long value);
public override void Write(byte[] data, int offset, int count);
[Obsolete("Use Write instead")]
public void WriteData(byte[] data, int offset, int count);
[Obsolete("Use WriteSamples instead")]
public void WriteData(short[] samples, int offset, int count);
public void WriteSample(float sample);
public void WriteSamples(short[] samples, int offset, int count);
public void WriteSamples(float[] samples, int offset, int count);
protected override void Dispose(bool disposing);
protected virtual void UpdateHeader(BinaryWriter writer);
}
在调用上是先调用WaveIn的DataAvailable回调函数,读取其数据并写入流文件,最后保存到本地。
2. 播放录音
播放录音主要用到AudioFileReader、WaveOut三个类和接口
2.1 AudioFileReader
AudioFileReader主要负责读取音频文件,验证音频文件格式,对外部提供读取数据接口,具体如下:
public class AudioFileReader : WaveStream, ISampleProvider
{
public AudioFileReader(string fileName); public string FileName { get; }
public override WaveFormat WaveFormat { get; }
public override long Length { get; }
public override long Position { get; set; }
public float Volume { get; set; } public override int Read(byte[] buffer, int offset, int count);
public int Read(float[] buffer, int offset, int count);
protected override void Dispose(bool disposing);
}
2.2 WaveOut
WaveOut的工作是播放音频,它调用AudioFileReader.Read进行数据读取,对读取的数据进行播放,主要工作流程是从获取数据,并将数据进行播放成音频
public class WaveOut : IWavePlayer, IDisposable, IWavePosition
{
public WaveOut();
public WaveOut(IntPtr windowHandle);
public WaveOut(WaveCallbackInfo callbackInfo); ~WaveOut(); public static int DeviceCount { get; }
public PlaybackState PlaybackState { get; }
public WaveFormat OutputWaveFormat { get; }
public int DeviceNumber { get; set; }
public int NumberOfBuffers { get; set; }
public int DesiredLatency { get; set; }
public float Volume { get; set; } public event EventHandler<StoppedEventArgs> PlaybackStopped; public static WaveOutCapabilities GetCapabilities(int devNumber);
public void Dispose();
public long GetPosition();
public void Init(IWaveProvider waveProvider);
public void Pause();
public void Play();
public void Resume();
public void Stop();
protected void Dispose(bool disposing);
}
3. 波形图绘制
录音时绘制波形图需要在DataAviliable回调函数中获取音频数据并将其从byte[]转换为float[],然后用float[]数据做为波形图的输入即可,这个过程源码上写一个数据包的波形图数据为waveSource.WaveFormat.SampleRate / 100,原理上我还没搞懂,但是的确是这么操作显示是对的,具体如下:
private void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
if (waveFile != null)
{
waveFile.Write(e.Buffer, , e.BytesRecorded);
waveFile.Flush(); float[] sts = new float[e.Buffer.Length / ];
int outIndex = ;
for (int n = ; n < e.Buffer.Length; n += )
{
sts[outIndex++] = BitConverter.ToInt16(e.Buffer, n) / 32768f;
} for (int n = ; n < sts.Length; n += channels)
{
Add(sts[n]);
}
}
}
需要注意的是WaveFormat的通道数设置、PCM的格式设置,上述代码都是基于通道数为2、PCM为16bit的情况下,如这两项修改会发生转换和调用失败等问题
可调试Demo:示例Demo
C# NAudio录音和播放音频文件及实时绘制音频波形图(从音频流数据获取,而非设备获取)的更多相关文章
- C# NAudio录音和播放音频文件-实时绘制音频波形图(从音频流数据获取,而非设备获取)
NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发. 在WaveIn和WaveOut之外还有对 ...
- 解析WAV音频文件----》生成WAV音频文件头
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i WAV音频文件介绍: WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows3.1操作系统 ...
- iOS中音频的录制与播放(本地音频文件的播放)
iOS功能开发涉及到音频处理时,最常见的时进行录音,以及音频文件的播放.停止播放等的操作.在开发中还要避免同一个音频文件,或不同音频文件之间的处理,比如说正在播放A音频时,可以停止播放A音频,也可以播 ...
- 将音频文件转二进制分包存储到Redis(奇淫技巧操作)
功能需求: 一.获取本地音频文件,进行解析成二进制数据音频流 二.将音频流转化成byte[]数组,按指定大小字节数进行分包 三.将音频流分成若干个包,以List列表形式缓存到redis数据库中 四.从 ...
- 浏览器音频兼容和ffmpeg的音频转码使用
浏览器对各音/视频格式的支持问题 浏览器测试效果图 ffmpeg在音频格式转换,和从视频中提取音频的简单实用 1.百度搜索浏览器对于音频文件的兼容,排在前面的文章大部分是复制粘贴很久以前的文章,容易误 ...
- C# 录音和播放录音-NAudio
在使用C#进行录音和播放录音功能上,使用NAudio是个不错的选择. NAudio是个开源,相对功能比较全面的类库,它包含录音.播放录音.格式转换.混音调整等操作,具体可以去Github上看看介绍和源 ...
- S3C2416裸机开发系列19_Fatfs播放录像wav音频文件
S3C2416裸机开发系列19 Fatfs播放录像wav音频文件 国际象棋男孩 1048272975 多媒体资源,一般都是以文件的形式存储在固化存储器中.Fatfs所支持的fat32为windo ...
- IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
本文转载至 http://blog.csdn.net/u014011807/article/details/40187737 在本卷你可以学到什么? 采用四种方法设计应用于各种场合的音频播放器: 基于 ...
- VC++中MCI播放音频文件 【转】
MCI播放mp3音频文件例程 源文件中需要包含头文件 Mmsystem.h,在Project->Settings->Link->Object/libray module中加入库 Wi ...
随机推荐
- zookeeper 实战 - Pymjer 的博客
下载 $ wget http://apache.forsale.plus/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz 配置conf/zoo.cfg ...
- Leetcode 142题 环形链表 II(Linked List Cycle II) Java语言求解
题目描述: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 p ...
- C++走向远洋——35(友元,时间)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:time.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- mysql JOIN查询
查询左表a,并且关联a表在b表中的关联,如果关联不存在也可以查出左表的,注:只查询a的部分列,和b的部分列 SELECT a.id, b.id as my FROM a LEFT JOIN b ON ...
- webpack 手动创建项目
前言: webpack作为当前算是比较流行的打包工具之一,通过设置入口文件开始会把入口文件所依赖的所有文件(js,css,image等)进行对应的打包处理,其实现当时真的是很独特.现在流行的脚手架工具 ...
- Dubbo源码解析之SPI(一):扩展类的加载过程
Dubbo是一款开源的.高性能且轻量级的Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用.智能容错和负载均衡,以及服务自动注册和发现. Dubbo最早是阿里公司内部的RPC框架,于 ...
- [译]HTML&CSS Lesson7: 设置背景和渐变色
背景对网站的设计有重大的影响.它有利于建立网站的整体感觉,设置分组,分配优先级,对网站的可用性也有相当大的影响. 在CSS中,元素的背景可以是一个纯色,一张图,一个渐变色或者它们的组合.在我们决定如何 ...
- 细说集群技术(Cluster)
今天本人给大家讲解一些我对集群技术一个理解,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 集群(Cluster)技术:通过此可以用较低的成本获取较高的性能 ...
- 使用增量备份修复DG中的GAP
问题描述 oracle中DG出现主备不同步现象,alert日志报警有gap信息,但是v$archive_gap视图查不到任何信息.同时主库上的对应归档已经删除且没有备份 解决方案 1.查询备库的scn ...
- 教你高效使用数据可视化BI软件创建医院卫生耗材运营监控大屏
灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件. 本文以医院卫生耗材运营监控大屏 ...