1.什么是wav格式
WAV為
微軟公司(Microsoft)開發的一種聲音文件格式,它符合RIFF(Resource Interchange File Format)文件規范,用於保存Windows平台的
音頻信息資源。 通常使用三個參數來表示聲音,量化位數,取樣頻率和
采樣點振幅。量化位數分為8位,16位,24位三種,聲道有單聲道和
立體聲之分,單聲道振幅數據為n*1矩陣點,立體聲為n*2矩陣點,取樣頻率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三種。
標准格式化的WAV文件和CD格式一樣,也是44.1K的取樣頻率,16位量化數字,因此在聲音文件質量和CD相差無幾。
2. WAV文件的組成
|
偏移地址
|
大小
字節
|
數據塊
類型
|
內容
|
|
00H~03H
|
4
|
4字符
|
資源交換文件標志(RIFF)
|
|
04H~07H
|
4
|
長整數
|
從下個地址開始到文件尾的總字節數
|
|
08H~0BH
|
4
|
4字符
|
WAV文件標志(WAVE)
|
|
0CH~0FH
|
4
|
4字符
|
波形格式標志(fmt ),最后一位空格。
|
|
10H~13H
|
4
|
整數
|
過濾字節(一般為00000010H),若為00000012H則說明數據頭攜帶附加信息(見“附加信息”)。
|
|
14H~15H
|
2
|
整數
|
格式種類(值為1時,表示數據為線性PCM編碼)
|
|
16H~17H
|
2
|
整數
|
通道數,單聲道為1,雙聲道為2
|
|
18H~1BH
|
4
|
長整數
|
采樣頻率
|
|
1CH~1FH
|
4
|
長整數
|
波形數據傳輸速率(每秒平均字節數)
|
|
20H~21H
|
2
|
整數
|
DATA數據塊長度,字節。
|
|
22H~23H
|
2
|
整數
|
PCM位寬
|
|
隨后
2字節
|
2
|
整數
|
附加信息(可選,由上方過濾字節確定)
|
......................以上為對wav格式的基本了解,最近碰到一個需要合並音頻文件的需求,奈何對此文件了解過少,最后借助於
NAudio
git地址:
https://github.com/naudio/NAudio,結合文件流進行處理。
3.話不多說上代碼。首先是安裝Naudio的包。
3.1.上傳音頻文件並調用合並方法【偽代碼】
public void UploadOrCombineAudioFile() { HttpFileCollection files = HttpContext.Current.Request.Files; if (files == null || files.Count < 1) return; string upfileType = HttpContext.Current.Request.Form["upfileType"];//文件格式類型 /*...省略符...*/ int maxSize = 1024 * 1024 * 100;//單文件上傳最大限制 List<string> dirDic = new List<string> { ".mp3", ".mp4", ".pcm", ".wav" };//文件格式限制 string uploadPath = HttpContext.Current.Server.MapPath("~/AudioFile/TempFile/");//臨時路徑 if (!Directory.Exists(uploadPath)) Directory.CreateDirectory(uploadPath); string fileType = string.Empty; for (var i = 0; i < files.Count; i++) { var postedfile = files[i]; var inputStream = postedfile.InputStream; if (inputStream.Length > 0) { string thisfileName = files[i].FileName; fileType = Path.GetExtension(thisfileName); if (postedfile.InputStream == null || postedfile.InputStream.Length > maxSize || !dirDic.Contains(fileType.ToLower())) return; /*...我是省略符...*/ int ReadLen = 0; string uploadFileName = uploadPath + thisfileName; byte[] bytes = new byte[10240]; using (FileStream stream = new FileStream(uploadFileName, FileMode.OpenOrCreate))//保存文件到指定待合並文件路徑下 { while ((ReadLen = inputStream.Read(bytes, 0, bytes.Length)) > 0) { stream.Write(bytes, 0, ReadLen); } } } } List<string> filepaths = new List<string>(Directory.GetFiles(uploadPath));//獲取待合並文件路徑 //文件合並后路徑 string savePath = HttpContext.Current.Server.MapPath("~/AudioFile/ComBineFile/" + DateTime.Now.ToString("yyyyMMdd") + "/"); if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath); /*...我是省略符...*/ byte[] buffer = new byte[10240]; string savefullName = savePath + DateTime.Now.ToString("yyyyMMddHHmmssff") + upfileType; if (upfileType.ToLower().Equals(".mp3")) CombineMp3(filepaths, savefullName);//mp3合並 else if ((upfileType.ToLower().Equals(".wav"))) CombineWav(filepaths, savefullName);//wav合並 /*...我是省略符...*/ return; }
3.2 .mp3格式合並
//命名空間 using System.IO; using NAudio; using NAudio.Wave; /// <summary> /// Mp3格式合並 /// </summary> /// <param name="inputFiles">待合並文件路徑</param> /// <param name="outputfullName">輸出文件名</param> private void CombineMp3(List<string> inputFiles, string outputfullName) { using (FileStream outputStream = new FileStream(outputfullName, FileMode.OpenOrCreate)) { foreach (string file in inputFiles) { Mp3FileReader reader = new Mp3FileReader(file); if ((outputStream.Position == 0) && (reader.Id3v2Tag != null)) { outputStream.Write(reader.Id3v2Tag.RawData, 0, reader.Id3v2Tag.RawData.Length); } Mp3Frame frame; while ((frame = reader.ReadNextFrame()) != null) { outputStream.Write(frame.RawData, 0, frame.RawData.Length); } } } }
3.3.wav格式合並
/// <summary> /// wav格式合並 /// </summary> /// <param name="inputFiles">待合並文件</param> /// <param name="outputfullName">輸出文件名</param> private void CombineWav(List<string> inputFiles, string outputfullName) { WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new WaveFileReader(inputFiles[0])); using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputfullName, waveStream.WaveFormat)) { foreach (string file in inputFiles) { waveStream = WaveFormatConversionStream.CreatePcmStream(new WaveFileReader(file)); byte[] bytes = new byte[waveStream.Length]; waveStream.Position = 0; waveStream.Read(bytes, 0, (int)waveStream.Length); waveFileWriter.Write(bytes, 0, bytes.Length); } } }
未完待續....
