2016年5月1日 星期日

產生各種 sample rate 的 5khz 方波的程式:

using System;
using System.IO;
using System.Text;

namespace WavGen {
    class Program {
        static void Main(string[] args) {
            for(Int32 i = 1; i <= 8; i *= 2) {
                GenSquareWave(44100 * i);
                GenSquareWave(48000 * i);
            }
        }
        public static void GenSquareWave(int samplesPerSecond, short bitsPerSample = 16, Int16 frequency = 5000, int msDuration = 30*1000, UInt16 volume = 16383) {
            const int FORMAT_CHUNK_SIZE = 16;
            const int HEADER_SIZE = 8;
            const short FORMAT_TYPE = 1;
            const short TRACKS = 1;
            using(var memoryStream = new MemoryStream()) {
                using(var binaryWriter = new BinaryWriter(memoryStream)) {
                    short frameSize = (short)(TRACKS * ((bitsPerSample + 7) / 8));
                    int bytesPerSecond = samplesPerSecond * frameSize;
                    int waveSize = 4;
                    int samples = (int)((decimal)samplesPerSecond * msDuration / 1000);
                    int dataChunkSize = samples * frameSize;
                    int fileSize = waveSize + HEADER_SIZE + FORMAT_CHUNK_SIZE + HEADER_SIZE + dataChunkSize;

                    binaryWriter.Write(Encoding.UTF8.GetBytes("RIFF"));
                    binaryWriter.Write(fileSize);
                    binaryWriter.Write(Encoding.UTF8.GetBytes("WAVE"));
                    binaryWriter.Write(Encoding.UTF8.GetBytes("fmt "));
                    binaryWriter.Write(FORMAT_CHUNK_SIZE);
                    binaryWriter.Write(FORMAT_TYPE);
                    binaryWriter.Write(TRACKS);
                    binaryWriter.Write(samplesPerSecond);
                    binaryWriter.Write(bytesPerSecond);
                    binaryWriter.Write(frameSize);
                    binaryWriter.Write(bitsPerSample);
                    binaryWriter.Write(Encoding.UTF8.GetBytes("data"));
                    binaryWriter.Write(dataChunkSize);

                    double theta = frequency * 2 * Math.PI / (double)samplesPerSecond;
                    double amp = volume >> 2;
                    for(int step = 0; step < samples; step++) {
                        short s = (short)(amp * (Math.Sin(theta * (double)step) > 0 ? 1: -1));
                        binaryWriter.Write(s);
                    }

                    String filename = "SQ" + samplesPerSecond.ToString() + ".WAV";
                    using(FileStream file = new FileStream(path: filename, mode: FileMode.Create)) {
                        file.Write(array: memoryStream.ToArray(), offset: 0, count: (int)memoryStream.Length);
                    }
                    Console.WriteLine(filename + " generated!");
                }
            }
        }
    }
}

沒有留言:

張貼留言