C# wav语音文件合并
开发完成语音播报产品,由于客户所使用的播放产品种类繁多,在使用HDMI接口播放音频时,由于采用的声卡不同,个别机器会出现播报声音过小,或者不播报的情况。所以采用将语音文件合并播放的方式,来解决此问题。
/// <summary>
/// 合并语音流
/// </summary>
/// <param name="pPlayStreamsList">语音流集合</param>
public void MergeAndPlayWavFile(ObservableCollection<Stream> pPlayStreamsList)
{
try
{
if (pPlayStreamsList.Count > 0)
{
int dataFileBeginIndex = 0;
int formatSize;
List<byte[]> bInfoList = new List<byte[]>();
List<int> fileSizeList = new List<int>();
List<int> dataSizeList = new List<int>();
foreach (Stream fs in pPlayStreamsList)
{
fs.Position = 0;
byte[] bInfo = new byte[46];
fs.Read(bInfo, 0, 46);
formatSize = BitConverter.ToInt32(bInfo, 16);
//Wave = RIFF_WAVE_Chunk + Format_Chunk + Data_Chunk(RIFF)/Fact_Chunk(FACT)
//RIFF_WAVE_Chunk(文件头,12个字节)+
//Format_Chunk(声音内容定义,根据第16到20个字节得到剩下区块大小,16或者18个字节)+
//Data_Chunk(数据区)
dataFileBeginIndex = formatSize + 20 + 4;
bInfoList.Add(bInfo);
fileSizeList.Add(System.BitConverter.ToInt32(bInfo, 4));
dataSizeList.Add(System.BitConverter.ToInt32(bInfo, dataFileBeginIndex));
}
//计算所有WAV文件大小
int fileSize = 0;
foreach (int fSize in fileSizeList)
{
fileSize += fSize;
}
byte[] totalFileSize = System.BitConverter.GetBytes(fileSize);
//计算所有WAV数据大小
int dataSize = 0;
foreach (int dSize in dataSizeList)
{
dataSize += dSize;
}
byte[] totalDataSize = System.BitConverter.GetBytes(dataSize);
using (Stream toFile = new MemoryStream())
{
//Stream toFile = new MemoryStream();
BinaryWriter bWriter = new BinaryWriter(toFile);
//获取最后一个wav文件的详细内容
int lastWaveFile = pPlayStreamsList.Count - 1;
for (int i = 4, j = 0; i < 8; i++, j++)
{
bInfoList[lastWaveFile][i] = totalFileSize[j];
}
for (int i = dataFileBeginIndex, j = 0; i < dataFileBeginIndex + 4; i++, j++)
{
bInfoList[lastWaveFile][i] = totalDataSize[j];
}
bWriter.Write(bInfoList[lastWaveFile]);
int k = 0;
foreach (Stream fs in pPlayStreamsList)
{
int readLength;
fs.Position = dataFileBeginIndex + 4;
if (k < dataSizeList.Count)
{
readLength = dataSizeList[k] - 40;
byte[] dushu = new byte[readLength];
fs.Read(dushu, 0, readLength);
bWriter.Write(dushu, 0, readLength);
k++;
}
}
SoundPlayer player = new SoundPlayer();
if (toFile != null)
{
player.Stream = null;
player.Stream = toFile;
toFile.Position = 0;
player.LoadAsync();
for (int i = 0; i < playTimes; i++)
{ player.PlaySync(); }
}
bWriter.Flush();
bWriter.Close();
toFile.Flush();
toFile.Close();
player.Dispose();
bWriter.Dispose();
toFile.Dispose();
}
}
}
catch (Exception e)
{
LogInfo.saveLog("合并语音流报错,方法MergeAndPlayWavFile():" + e.Message);
}
}
C# wav语音文件合并的更多相关文章
- [Audio processing] wav音频文件合并
合并多个文件,需要包含1.文件读取和写入功能,2.数组合并 package com.audioprocessingbox.myfunc; import java.io.File; import jav ...
- 多个wav音频文件合并(连接)成一个文件
场景:一段声音从浏览器麦克风缓冲上一段一段发给服务器,按照时间戳生成很多文件. 目的:把他们按时间顺序连到一个时间轴上. 命令如下: ffmpeg -f concat -i list.txt out. ...
- Python网页正文转换语音文件的操作方法
天气真的是越来越冷啦,有时候我们想翻看网页新闻,但是又冷的不想把手拿出来,移动鼠标翻看.这时候,是不是特别想电脑像讲故事一样,给我们念出来呢?人生苦短,我有python啊,试试用 Python 来朗读 ...
- WAV格式文件无损合并&帧头数据体解析(python)(原创)
一,百度百科 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频 ...
- C# 使用NAudio合并mp3、wav音频文件
1.什么是wav格式 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windo ...
- asp.net使用SpeechSynthesizer类生成语音文件部署到iis遇到的几个坑
首先需要引入命名空间System.Speech.Synthesis,代码如下: using (var speechSyn = new SpeechSynthesizer()) { speechSyn. ...
- 解析WAV音频文件----》生成WAV音频文件头
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i WAV音频文件介绍: WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows3.1操作系统 ...
- CDN的combo技术能把多个资源文件合并引用,减少请求次数
CDN的combo技术能把多个资源文件合并引用,减少请求次数.比如淘宝的写法: <link rel="stylesheet" href="//g.alicdn.co ...
- linux 两个文件合并
可以使用cat命令,有两种实现的方式,一种将两个文件合并的到一个新的文件,另一种将一个文件追加到另一个文件的末尾. 方法一:使用cat命令从文件中读入两个文件,然后将重定向到一个新的文件.这种方法可以 ...
随机推荐
- 使用log4net日志组件经验分享
常见步骤: 第一:在项目中引用log4net组件. 第二:配置log4net,一般都写在web.config中. 第三:调用部分. 具体怎么配置,大家可以参考博客其它博友写的,这里我只写我 ...
- 使用websocket实现在线聊天功能
很早以前为了快速达到效果,使用轮询实现了在线聊天功能,后来无意接触了socket,关于socket我的理解是进程间通信,首先要有服务器跟客户端,服务的启动监听某ip端口定位该进程,客户端开启socke ...
- ajax调用handler,使用HttpWebRequest访问WCF服务
引言 随着手机及移动设备的普及,移动端的应用也进入了热潮.以前PC端的门户网站,大多也均推出了适配移动设备的网站或者APP,再差的也注册了个公众号.在移动应用开发中,目前据我所了解到的解决方案有:1. ...
- Quartz动态改变任务时间
基于quartz-2.2 的动态任务调度 Quartz是一个完全由java编写的开源作业调度框架. 调度器 Quartz框架的核心是调度器.调度器负责管理Quartz应用运行时环境.调度器不是靠自己做 ...
- php get_called_class()函数与get_class()函数的区别
get_class (): 获取当前调用方法的类名: get_called_class():获取静态绑定后的类名: class Foo{ public function test(){ var_dum ...
- IDA学习笔记 函数调用约定
stdcall和cdecl: stdcall和cdecl 压栈方向都是从右到左 区别在于c约定是调用方在函数返回后add esp,n指令清除堆栈中的参数,而stdcall在被调函数内使用ret n来清 ...
- sql必知必会笔记
1.DISTINCT 用于剔除重复的值, 如果后跟多个列, 则要求所有列的值都相同才会被剔除. SELECT DISTINCT ven_id, prod_price FROM Products; ...
- aria2 加速百度网盘下载
准备工作: chrome浏览器: BaiduExporter插件(下载地址:https://github.com/acgotaku/BaiduExporter): aria2工具(下载地址:http: ...
- XP环境下的网络证书问题
项目过程中,由于是收银系统需要从服务器获取支付二维码,会产生SSL连接的问题,在win7.win10上都没有问题,放到WIN XP上出现了The underlying connection was c ...
- 在Centos环境下安装兼容Apache2.4高版本SVN服务
在阿里云Centos环境下,搭建PHP运行环境,PHP选择了php7版本,Mysql选择了5.7版本,Apache选择了2.4版本,在搭建SVN版本控制服务过程中出现了不兼容问题,当前环境下Apach ...