Wave文件编码:保存文件

Channel的音频引擎是我自己写的,保存文件一直想找开源库但就是找不着。。

于是就有了以下简单粗暴打点办法:

首先是WAV的文件格式


起始地址


占用空间


本地址数字的含义


00H


4byte


RIFF,资源交换文件标志。


04H


4byte


从下一个地址开始到文件尾的总字节数。高位字节在后面,这里就是001437ECH,换成十进制是1325036byte,算上这之前的8byte就正好1325044byte了。


08H


4byte


WAVE,代表wav文件格式。


0CH


4byte


FMT ,波形格式标志


10H


4byte


00000010H,16PCM,用16bit的数据表示一个量化结果。


14H


2byte


为1时表示线性PCM编码,大于1时表示有压缩的编码。这里是0001H。


16H


2byte


1为单声道,2为双声道,这里是0001H。


18H


4byte


采样频率,这里是00002B11H,也就是11025Hz。


1CH


4byte


Byte率=采样频率*音频通道数*每次采样得到的样本位数/8,00005622H,也就是22050Byte/s=11025*1*16/2。


20H


2byte


块对齐=通道数*每次采样得到的样本位数/8,0002H,也就是2=1*16/8。


22H


2byte


样本数据位数,0010H即16,一个量化样本占2byte。


24H


4byte


data,一个标志而已。


28H


4byte


Wav文件实际音频数据所占的大小,这里是001437C8H即1325000,再加上2CH就正好是1325044,整个文件的大小。


2CH


不定


量化数据。

于是我们可以反着来,做一个写WAV的方法

  1 namespace Channel.Core
  2 {
  3     public class WriteWAVFile
  4     {
  5         #region Public_Properties
  6
  7         public enum WaveBitFormat
  8         {
  9             Bit8=1,
 10             Bit16=2,
 11             Bit32=4
 12         }
 13         public WaveBitFormat Waveformat { get; set; }
 14         public float[] Data { get; set; }
 15         public string Path { get; set; }
 16         public bool zipped { get; set; }
 17         public int zipObject { get; set; }
 18
 19         #endregion
 20
 21         #region MainMethod
 22
 23         public void WriteWave()
 24         {
 25             FileStream fs = new FileStream(Path, FileMode.OpenOrCreate);
 26             //StreamWriter sw = new StreamWriter(fs);
 27             fs.Position = 0;
 28
 29             //写入‘riff’文件标记
 30             byte[] riff = new byte[4];
 31             riff[0]= Convert.ToByte(82);
 32             riff[1] = Convert.ToByte(73);
 33             riff[2] = Convert.ToByte(70);
 34             riff[3] = Convert.ToByte(70);
 35             fs.WriteByte(riff[0]);//fs.Position++;
 36             fs.WriteByte(riff[1]); //fs.Position++;
 37             fs.WriteByte(riff[2]); //fs.Position++;
 38             fs.WriteByte(riff[3]); //fs.Position++;
 39
 40
 41             //写入文件长度
 42             System.Numerics.BigInteger len = 0;
 43             len = (int)Waveformat * Data.Length + 36;
 44             byte[] length = len.ToByteArray();
 45             if(length.Count()==4)
 46             {
 47                 fs.WriteByte(length[0]); //fs.Position++;
 48                 fs.WriteByte(length[1]); //fs.Position++;
 49                 fs.WriteByte(length[2]); //fs.Position++;
 50                 fs.WriteByte(length[3]); //fs.Position++;
 51             }
 52             else if (length.Count() == 3)
 53             {
 54                 fs.WriteByte(length[0]); //fs.Position++;
 55                 fs.WriteByte(length[1]); //fs.Position++;
 56                 fs.WriteByte(length[2]); //fs.Position++;
 57                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 58             }
 59             else if(length.Count()==2)
 60             {
 61                 fs.WriteByte(length[0]); //fs.Position++;
 62                 fs.WriteByte(length[1]); //fs.Position++;
 63                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 64                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 65             }
 66
 67             //写入“wave fmt”
 68             fs.WriteByte(Convert.ToByte(87)); //fs.Position++;
 69             fs.WriteByte(Convert.ToByte(65)); //fs.Position++;
 70             fs.WriteByte(Convert.ToByte(86)); //fs.Position++;
 71             fs.WriteByte(Convert.ToByte(69)); //fs.Position++;
 72
 73             fs.WriteByte(Convert.ToByte(102)); //fs.Position++;
 74             fs.WriteByte(Convert.ToByte(109)); //fs.Position++;
 75             fs.WriteByte(Convert.ToByte(116)); //fs.Position++;
 76             fs.WriteByte(Convert.ToByte(32)); //fs.Position++;
 77
 78             //写入播放位数
 79             switch (Waveformat )
 80             {
 81                 case WaveBitFormat.Bit8:
 82                     fs.WriteByte(Convert.ToByte(8)); //fs.Position++;
 83                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 84                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 85                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 86                     break;
 87                 case WaveBitFormat.Bit16:
 88                     fs.WriteByte(Convert.ToByte(16)); //fs.Position++;
 89                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 90                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 91                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 92                     break;
 93                 case WaveBitFormat.Bit32:
 94                     fs.WriteByte(Convert.ToByte(32)); //fs.Position++;
 95                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 96                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 97                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
 98                     break;
 99                 default:
100                     break;
101             }
102
103             //是否压缩
104             if(zipped)
105             {
106                 fs.WriteByte(Convert.ToByte(zipObject)); //fs.Position++;
107                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
108             }
109             else
110             {
111                 fs.WriteByte(Convert.ToByte(1)); //fs.Position++;
112                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
113             }
114
115             //声道
116             if(ChannelCount==1 )
117             {
118                 fs.WriteByte(Convert.ToByte(1)); //fs.Position++;
119                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
120             }
121             else
122             {
123                 fs.WriteByte(Convert.ToByte(2)); //fs.Position++;
124                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
125             }
126
127             //采样频率  默认 0000AC44H (44100)
128             System.Numerics.BigInteger fre = 0;
129             fre = Frequency;
130             byte[] freq = fre.ToByteArray();
131             if (freq.Count() == 4)
132             {
133                 fs.WriteByte(freq[0]); //fs.Position++;
134                 fs.WriteByte(freq[1]); //fs.Position++;
135                 fs.WriteByte(freq[2]); //fs.Position++;
136                 fs.WriteByte(freq[3]); //fs.Position++;
137             }
138             else if (freq.Count() == 3)
139             {
140                 fs.WriteByte(freq[0]); //fs.Position++;
141                 fs.WriteByte(freq[1]); //fs.Position++;
142                 fs.WriteByte(freq[2]); //fs.Position++;
143                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
144             }
145             else if (freq.Count() == 2)
146             {
147                 fs.WriteByte(freq[0]); //fs.Position++;
148                 fs.WriteByte(freq[1]); //fs.Position++;
149                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
150                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
151             }
152
153             //Freq*Channel*Bit/8
154             System.Numerics.BigInteger res11 = 0;
155             res11 = Frequency*(int)Waveformat*ChannelCount;
156             byte[] res1 = res11.ToByteArray();
157             if (res1.Count() == 4)
158             {
159                 fs.WriteByte(res1[0]); //fs.Position++;
160                 fs.WriteByte(res1[1]); //fs.Position++;
161                 fs.WriteByte(res1[2]); //fs.Position++;
162                 fs.WriteByte(res1[3]); //fs.Position++;
163             }
164             else if (res1.Count() == 3)
165             {
166                 fs.WriteByte(res1[0]); //fs.Position++;
167                 fs.WriteByte(res1[1]); //fs.Position++;
168                 fs.WriteByte(res1[2]); //fs.Position++;
169                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
170             }
171             else if (res1.Count() == 2)
172             {
173                 fs.WriteByte(res1[0]); //fs.Position++;
174                 fs.WriteByte(res1[1]); //fs.Position++;
175                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
176                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
177             }
178
179             //channel*bit/8
180             System.Numerics.BigInteger res22 = 0;
181             res22 =(int)Waveformat * ChannelCount;
182             byte[] res2 = res22.ToByteArray();
183             if (res2.Count() == 2)
184             {
185                 fs.WriteByte(res2[0]); //fs.Position++;
186                 fs.WriteByte(res2[1]); //fs.Position++;
187             }
188             else if (res2.Count() == 1)
189             {
190                 fs.WriteByte(res2[0]); //fs.Position++;
191                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
192             }
193
194             //位数(没错要写两遍)
195             switch (Waveformat)
196             {
197                 case WaveBitFormat.Bit8:
198                     fs.WriteByte(Convert.ToByte(8)); //fs.Position++;
199                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
200                     break;
201                 case WaveBitFormat.Bit16:
202                     fs.WriteByte(Convert.ToByte(16)); //fs.Position++;
203                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
204                     break;
205                 case WaveBitFormat.Bit32:
206                     fs.WriteByte(Convert.ToByte(32));// fs.Position++;
207                     fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
208                     break;
209                 default:
210                     break;
211             }
212
213             //data标记
214             fs.WriteByte(Convert.ToByte(100)); //fs.Position++;
215             fs.WriteByte(Convert.ToByte(97)); //fs.Position++;
216             fs.WriteByte(Convert.ToByte(116)); //fs.Position++;
217             fs.WriteByte(Convert.ToByte(97)); //fs.Position++;
218
219             //数据大小
220             len = (int)Waveformat * Data.Length;
221             byte[] lengthD = len.ToByteArray();
222             if (lengthD.Count() == 4)
223             {
224                 fs.WriteByte(lengthD[0]); //fs.Position++;
225                 fs.WriteByte(lengthD[1]); //fs.Position++;
226                 fs.WriteByte(lengthD[2]); //fs.Position++;
227                 fs.WriteByte(lengthD[3]); //fs.Position++;
228             }
229             else if (lengthD.Count() == 3)
230             {
231                 fs.WriteByte(lengthD[0]); //fs.Position++;
232                 fs.WriteByte(lengthD[1]); //fs.Position++;
233                 fs.WriteByte(lengthD[2]); //fs.Position++;
234                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
235             }
236             else if (lengthD.Count() == 2)
237             {
238                 fs.WriteByte(lengthD[0]); //fs.Position++;
239                 fs.WriteByte(lengthD[1]); //fs.Position++;
240                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
241                 fs.WriteByte(Convert.ToByte(0)); //fs.Position++;
242             }
243
244             //数据
245             foreach (float dataitem in Data)
246             {
247                 byte[] target32;
248                 byte[] target16;
249                 target32 = BitConverter.GetBytes(dataitem);
250                 int i =Convert.ToInt32( dataitem * 32768);
251                 //string h16 = i.ToString("X");
252                 //string h161=h16.Substring(4, 4);
253                 target16 = BitConverter.GetBytes(i);
254
255                 switch (Waveformat)
256                 {
257                     case WaveBitFormat.Bit8:
258                         //fs.WriteByte(Convert.ToByte(8)); fs.Position++;
259                         //fs.WriteByte(Convert.ToByte(0)); fs.Position++;
260                         break;
261                     case WaveBitFormat.Bit16:
262                         fs.WriteByte(target16[0]); //fs.Position++;
263                         fs.WriteByte(target16[1]); //fs.Position++;
264                         break;
265                     case WaveBitFormat.Bit32:
266                         fs.WriteByte(target32[0]); //fs.Position++;
267                         fs.WriteByte(target32[1]); //fs.Position++;
268                         fs.WriteByte(target32[2]); //fs.Position++;
269                         fs.WriteByte(target32[3]); //fs.Position++;
270                         break;
271                     default:
272                         break;
273                 }
274             }
275
276             //Ending
277             fs.Flush();
278             fs.Close();
279         }
280
281         #endregion
282         public int ChannelCount { get; set; }
283         public int Frequency { get; set; }
284     }
285 }

看代码中的注释就知道用处了

下面是如何调用

 1 private void saveToolStripMenuItem_Click(object sender, EventArgs e)
 2         {
 3             SaveFileDialog  o = new SaveFileDialog();
 4             o.ShowDialog();
 5             Channel.Core.WriteWAVFile ww = new Core.WriteWAVFile();//新建实例
 6             ww.ChannelCount = 1;//声道数
 7             ww.Data = wavePainterExtended1.DataProperty;//数据
 8             ww.Frequency = 44100;//采样频率
 9             ww.Path = o.FileName;//保存位置
10             ww.Waveformat = Core.WriteWAVFile.WaveBitFormat.Bit16;//16bit
11             ww.zipObject = 1;//空值
12             ww.zipped = false;//不压缩
13             ww.WriteWave();//执行
14         }

运行图片:

以及保存前后的文件(数据我做了反相处理)

时间: 2024-10-05 02:25:07

Wave文件编码:保存文件的相关文章

Vi之打开文件,新建文件,保存文件

打开文件.新建文件.保存文件 vi 文件名 如果文件存在,输入结束后,:wq保存并退出文件 如果文件不存在,输入结束后,:wq就可以新建并保存文件 在编辑完成时,返回一般模式,1)输入:w则保存文件:如果已保存,输入:q则退出文件 2)输入:wq保存并退出 3)如果不想保存被修改的内容,则输入:q!则强制退出 进入编辑模式: i ( 在光标前插入文本) o (在当前行之下新开一行,并到行首)

vs2005设置打开文件和保存文件编码

一般vs2005打开文件时会自动侦测文件编码,自动以相应的编码格式打开.但是如果不认识的编码,就会出现乱码. Set VS2005 to use without BOM UTF-8 encoding files.   Tools -> Options -> Environment -> Documents -> Save document as Unicode when data cannot be saved in codepage  ——保为unicode码   Tools -

文件编码和文件内的字符串字面值编码是两个概念

我们知道,CALabel的字符串使用的是UTF8编码,通常在xcode下,直接CALabel *p = ...; p->setText("汉字"),显示汉字是没有任何问题的,但是,在VS2013中却显示的是乱码.很多人在群里面问了,我都答:请使用UTF8编码.他说,我的文件是UTF8格式的啊.呵呵,没那么简单好吗,文件编码和字符串字面值编码是两个概念. VS2013的一条预编译指令#pragma execution_character_set("utf-8")

【mfc】使用系统文件对话框打开文件与保存文件、利用StdAfx.h设置全局变量

在<[mfc]利用文件的读写,theApp全局变量来现实登录帐号管理系统>(点击打开链接)中,虽然也使用到文件的打开与保存,但这是在用户打开与关闭对话框的时候就自动进行的.现在设置一个"打开"按钮与一个"保存"按钮,可以让用户自由选择保存的文件的位置,输入文件名,但是,保存的文件格式只能是我们指定的.ifo,因为以后打开文件,我们只接受.ifo的打开.本文亦是<[mfc]不同对话框之间互相操控.全局变量与日期控件>(点击打开链接)的进一步工作

WP8.1 实现Continuation程序(打开文件,保存文件等)

以保存文件为例 首先,在项目中加入ContinuationManager.cs类,以及SuspensionManager.cs类. 其次,在App.xaml.cs中,完成如下步骤: 1. 添加ContinuationManager类的实例作为属性. public ContinuationManager ContinuationManager { get; private set; } 2. 加入如下的方法 // for continuable private Frame CreateRootFr

springboot 头像上传 文件流保存 文件流返回浏览器查看 区分操作系统 windows 7 or linux

1 //我的会员中心 头像上传接口 2 /*windows 调试*/ 3 @Value("${appImg.location}") 4 private String winPathPic; 5 /*linux 使用*/ 6 @Value("${img.location}") 7 private String linuxPathPic; 8 9 @PostMapping(value = "/file") 10 public String file(

数据类型、文件编码、文件处理

一 数据类型 1.什么是数据? x=1u,1u 是我们要存储的数据 2.为什么数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类型 数字        (整形.长整形.浮点型.复数) 字符串 字节串 列表 元祖 字典 集合 二  数字类型 1.整形 int 用途:表示年龄,等级,qq号等 定义方式: age=18     # age=int(18) 整形总结: 只能存一个值,属于不可变类型,可hash 2.浮点型 float 用途:身高,体重,体质参数

C# winform文件批量转编码 选择文件夹

C# winform文件批量转编码 选择文件夹 打开指定目录 private void btnFile_Click(object sender, EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Multiselect = true; fileDialog.Title = "请选择文件"; fileDialog.Filter="所有文件(*.*)|*.*"; if

将UTF-8编码的文件读出,保存到编码为GBK的文件中

1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import