【音乐拼接】WAV格式

来源:互联网 发布:it wizardry 编辑:程序博客网 时间:2024/06/11 06:10

预备知识

必备基础知识用4个字节 表示一个整数每个字节8位 字节可以用无符号整数(十进制)来表示(0-255) 假设有如下4个字节194 021 001 000分别转换成16进制为C2 15 01 00高位在前 于是如下15C2 0001再转 如下000115C2   (这个就是4字节表示的整数对应的16进制)转成10进制如下71106======================================================================================开始 真正内容wav文件 = 文件头 + 数据体文件头  44个字节前12个字节用来说明文件是哪种类型 (如下字节)082 073 070 070 202 043 000 000 087 065 086 069   ------ a.wav082 073 070 070 234 046 000 000 087 065 086 069   ------ b.wav082 073 070 070 120 048 000 000 087 065 086 069   ------ c.wav082 073 070 070 194 021 001 000 087 065 086 069   ------ d.wav这12个字节里面第5-8个字节是不一样的,其他一样,这四个字节就表示一个整数,该整数为:从下一个地址开始到文件尾的总字节数。也就是说,前8个字节加上该整数就等于本wav文件总字节数,不信可以自己算算,百发百中。。。剩下 32 个字节分为两个部分。12-35  字节用来说明文件结构36-43  字节用来说明数据大小44到最后就是数据体刚才分析到前12个字节,继续13-16字节   表示 fmt ,波形格式标志102 109 116 032   ------ a.wav102 109 116 032   ------ b.wav102 109 116 032   ------ c.wav102 109 116 032   ------ d.wav可以看到都一样17-20字节  过滤字节(一般为00000010H)016 000 000 000   ------ a.wav016 000 000 000   ------ b.wav016 000 000 000   ------ c.wav016 000 000 000   ------ d.wav可以看到都一样21-22字节  整数 格式种类(值为1时,表示数据为线性PCM编码)001 000   ------ a.wav001 000   ------ b.wav001 000   ------ c.wav001 000   ------ d.wav也是一样23-24字节  整数 通道数,单声道为1,双声道为2001 000   ------ a.wav001 000   ------ b.wav001 000   ------ c.wav001 000   ------ d.wav表示都是单声道,特意用格式工厂转了一个2声道的,变成 002 000 正确25-28  采样频率034 086 000 000  ------ a.wav   十进制 22050034 086 000 000  ------ b.wav   十进制 22050034 086 000 000  ------ c.wav   十进制 22050034 086 000 000  ------ d.wav   十进制 220504个文件都一样29-32  每次采样的数据块大小  它跟下面的采样精度有关034 086 000 000  ------ a.wav   十进制 22050034 086 000 000  ------ b.wav   十进制 22050034 086 000 000  ------ c.wav   十进制 22050068 172 000 000  ------ d.wav   十进制 44100注意不同的地方33-34  整数  它 = 通道数 * 采样精度 / 8001 000  ------ a.wav001 000  ------ b.wav001 000  ------ c.wav002 000  ------ d.wav35-36 整数   采样精度是多少位008 000  ------ a.wav    8位008 000  ------ b.wav    8位008 000  ------ c.wav    8位016 000  ------ d.wav    16位37-40  表示“data”或者“LIST”四个字符,data表示单个音乐,LIST表示合成?或许是这样,因为我的d.wav 是在格式工厂里用 abc合成的100 097 116 097   ------ a.wav100 097 116 097   ------ b.wav100 097 116 097   ------ c.wav076 073 083 084   ------ d.wav41-44  整数  数据体长度(字节数)166 043 000 000   ------ a.wav    十进制11174  已检验正确197 046 000 000   ------ b.wav    十进制11973  已检验差一个字节  基本正确083 048 000 000   ------ c.wav    十进制12371  已检验差一个字节  基本正确026 000 000 000   ------ d.wav    十进制26     严重错误  格式工厂转换问题


程序代码

using System;using System.Collections.Generic;using System.IO;using System.Text;namespace Wav{    class Program    {        static void Main(string[] args)        {            List<string> ls = new List<string> {                @"C:\Users\Administrator\Desktop\b.wav",                @"C:\Users\Administrator\Desktop\c.wav",                @"C:\Users\Administrator\Desktop\a.wav",                @"C:\Users\Administrator\Desktop\out.wav"            };            Get_wav(ls);        }        static void Get_wav(List<string> l)        {            List<string> ls = l;            int n = ls.Count;            byte[] OUT = File_2_byte(ls[0]);            for (int i = 0; i < n; i++)            {                if (i == n - 2)                {                    using (StreamWriter sw = new StreamWriter(ls[i + 1], false, Encoding.GetEncoding(1252)))                    {                        sw.Write(Encoding.GetEncoding(1252).GetString(OUT));                    }                    return;                }                byte[] tmp = File_2_byte(ls[i + 1]);                OUT = Save_Wav(OUT, tmp);            }        }        static byte[] File_2_byte(string url)        {            long l = new FileInfo(url).Length;            byte[] b = new byte[l];            new FileStream(url, FileMode.Open).Read(b, 0, (int)l);            return b;        }        static byte[] Save_Wav(byte[] buffer1, byte[] buffer2)        {            long len1 = buffer1.Length;            long len2 = buffer2.Length;            byte[] Head1 = Get_small_byte(buffer1, 0, 44);            byte[] Head2 = Get_small_byte(buffer2, 0, 44);            byte[] Data1 = Get_small_byte(buffer1, 44, len1);            byte[] Data2 = Get_small_byte(buffer2, 44, len2);            byte[] DATA = Combine_2_byte(Data1, Data2);            long L = DATA.Length + 44;            byte[] HEAD = new byte[44];            Get_small_byte2(ref HEAD, 0, Head1, 0, 4);   //0-3            Get_small_byte2(ref HEAD, 4, Get_4_byte(L - 8), 0, 4); //4-7            Get_small_byte2(ref HEAD, 8, Head1, 8, 36);   //8-35            Get_small_byte2(ref HEAD, 36, Head1, 36, 40);   //36-39            Get_small_byte2(ref HEAD, 40, Get_4_byte(DATA.Length), 0, 4);   //40-43            return Combine_2_byte(HEAD, DATA);        }        static byte[] Combine_2_byte(byte[] a , byte[] b)        {            long la = a.Length;            long lb = b.Length;            long lc = la + lb;            byte[] c = new byte[lc];            for(int i =0;i< la; i++)            {                c[i] = a[i];            }            for (int i = 0; i < lb; i++)            {                c[i+la] = b[i];            }            return c;        }        static byte[] Get_small_byte(byte[] a,long start,long end)//[start,end)        {            long la = a.Length;            long lc = end - start;            byte[] c = new byte[lc];            for(long i = start;i< end; i++)            {                c[i - start] = a[i];            }            return c;        }        static void Get_small_byte2(ref byte[] HEAD, long f,byte[] a, long start, long end)        {            long la = a.Length;            for (long i = start; i < end; i++)            {                HEAD[i - start + f] = a[i];            }        }        static byte[] Get_4_byte(long a)        {            byte[] b = new byte[4];            b = BitConverter.GetBytes((int)a);            return b;        }    }}



0 0