用c# 随机数/函数 编写简单的.wav文件

用c# 随机数/函数 编写简单的.wav文件

.wav 文件主要由两部分组成:头文件 和 数据文件
这里用了sin函数产生有规律的波型值,模拟声波, byte【】 test。
直接在头文件后部加入模拟声波test的值,随后可用音乐播放器直接读文件。

下面是头文件,所有 readonly 标志的是不能改的部分,是wav的必要格式。
没写 readonly 的,有部分是可选参数,偷懒没用枚举器…可以在构造器内改数值。
因为头部文件必须要输入数据总长,所以构造此结构体要求录入byte数组,读取长度。
注意!作者没有测试有附加信息条件下能否运行!
命名空间:

using System;
using System.IO;
using System.Runtime.InteropServices;

头文件结构体:

[Serializable]
    public struct Wav
    {
        //资源交换文件标志
        public readonly char ResourceSign1;
        public readonly char ResourceSign2;
        public readonly char ResourceSign3;
        public readonly char ResourceSign4;
        //下一个至文件尾长度
        public  int AllLongFromNext;
        //WAV格式
        public readonly char WAVSign1;
        public readonly char WAVSign2;
        public readonly char WAVSign3;
        public readonly char WAVSign4;
        //波形格式
        public readonly char FMTSign1;
        public readonly char FMTSign2;
        public readonly char FMTSign3;
        public readonly char FMTSign4;
        //过滤字节  0x0000 0010 无附加信息     0x0000 0012 有附加信息
        public int Filter;
        //格式种类  1 表示数据为线性PCM编码
        public short Format;
        //通道数   1 单声道   2 立体声
        public short Channel;
        //采样频率  常选: 11025   22050
        public int Sampling;
        //波形数据传输速率(平均每秒字节)  通道数×每秒样本数×每样本的数据位数/8(1*22050*16/8)
        //常选: 22050   44100
        public int Velocity;//32
        //数据块的调整数 字节    通道数×每样本的数据位值/8
        public short BuffTimes;
        //PCM位宽(采样大小)   每个声道 样本大小一样
        //常选: 16   8
        public readonly short PCMWidth;

        /*
        //附加信息
        public readonly short AddInformation = 0;
        //不定长度字符    fact可选部分
        public char[] FactName = {'','','',''};
        public int FactLength = {get{return 1;}}
        public bytes[] FactDate;
        */

        //数据标志
        public readonly char waveDataSign1;
        public readonly char waveDataSign2;
        public readonly char waveDataSign3;
        public readonly char waveDataSign4;
        //Date 数据块总长
        public int waveDataLength;

        public Wav(byte[] waveData)
        {
            waveDataLength = waveData.Length;
            AllLongFromNext = 36 + waveDataLength;

            ResourceSign1 = 'R';
            ResourceSign2 = 'I';
            ResourceSign3 = 'F';
            ResourceSign4 = 'F';
            WAVSign1 = 'W';
            WAVSign2 = 'A';
            WAVSign3 = 'V';
            WAVSign4 = 'E';
            FMTSign1 = 'f';
            FMTSign2 = 'm';
            FMTSign3 = 't';
            FMTSign4 = ' ';
            waveDataSign1 = 'd';
            waveDataSign2 = 'a';
            waveDataSign3 = 't';
            waveDataSign4 = 'a';

            Filter = 16;
            Format = 1;
            Channel = 1;
            Sampling = 11025;
            Velocity = 22050;
            BuffTimes = 2;
            PCMWidth = 8;
        }
    }

其余代码:

static void Main(string[] args)
        {
            byte[] test = new byte[80000];
            //填充方法一:结果为噪音
            //Random random = new Random();
            //random.NextBytes(test);
            //填充方法二:sin(i/w),参数w在【3,15】之间会有声音
            for(int i =0,j = 0;i < 80000; i++,j++)
            {
                j %= 1000;
                test[i] = (byte)(j / 10 * Math.Sin(i / 4f + j));
                test[i] += (byte)(j / 30 * Math.Sin(i / 3f - j));
            }
		//定义头部文件
            Wav wav = new Wav(test);
		//将结构体内容复制到 byte【】
            int size = 0;
            size = Marshal.SizeOf(wav);
            IntPtr intPtr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(wav, intPtr, false);
            byte[] head = new byte[size];
            Marshal.Copy(intPtr, head, 0, size);
            Marshal.FreeHGlobal(intPtr);

		//写出文件
            using (Stream file = new FileStream("test.wav", FileMode.Create))
            {
                file.Write(head, 0, head.Length);
                file.Write(test, 0, test.Length);
            }
		//命令行提示完成
            Console.WriteLine("完成");
            Console.ReadLine();
        }

第一次发文章,小激动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值