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);
}
}