■ WAV 파일을 생성하는 방법을 보여준다.
▶ WAVERIFF.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
namespace TestProject { /// <summary> /// WAVE RIFF /// </summary> public class WAVERIFF { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 청크 ID /// </summary> /// 4바이트 : 빅 엔디안 /// 'RIFF' 문자를 저장한다. /// <remarks> /// </remarks> public string ChunkID; /// <summary> /// 청크 크기 /// </summary> /// <remarks> /// 4바이트 : 리틀 엔디안 /// 전체 파일 크기 - 8 /// </remarks> public uint ChunkSize; /// <summary> /// 포맷 /// </summary> /// <remarks> /// 4바이트 : 빅 엔디안 /// 파일 형식을 나타낸다. /// WAVE 파일의 경우 'WAVE' 문자를 저장한다. /// </remarks> public string Format; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - WAVERIFF() /// <summary> /// 생성자 /// </summary> public WAVERIFF() { ChunkID = "RIFF"; ChunkSize = 0; Format = "WAVE"; } #endregion } } |
▶ WAVEFMT.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
namespace TestProject { /// <summary> /// WAVE FMT /// </summary> public class WAVEFMT { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 청크 ID /// </summary> /// <remarks> /// 4바이트 : 빅 엔디안 /// 'fmt '라는 문자를 저장한다. /// </remarks> public string ChunkID; /// <summary> /// 청크 크기 /// </summary> /// <remarks> /// 4바이트 : 리틀 엔디안 /// ChunkSize 항목 이후 항목들의 크기를 저장한다. /// 고정 값 16을 저장한다. /// </remarks> public uint ChunkSize; /// <summary> /// 오디오 포맷 /// </summary> /// <remarks> /// 2바이트 : 리틀 엔디안 /// PCM의 경우 1을 저장한다. /// </remarks> public ushort AudioFormat; /// <summary> /// 채널 수 /// </summary> /// <remarks> /// 2바이트 : 리틀 엔디안 /// 모노 : 1, [data][data][data]... /// 스테레오 : 2, [left][right]... /// 3 채널 : 3, [left][right][center]... /// 쿼드 : 4, [front left][front right][rear left][rear right]... /// 4 채널 : 5, [left][center][right][surround]... /// 6 채널 : 6, [left center][left][center][right center][right][surround]... /// </remarks> public ushort ChannelCount; /// <summary> /// 초당 샘플 수 /// </summary> /// <remarks> /// 4바이트 : 리틀 엔디안 /// </remarks> public uint SampleCountPerSecond; /// <summary> /// 초당 평균 바이트 수 /// </summary> /// <remarks> /// 4바이트 : 리틀 엔디안 /// </remarks> public uint AverageByteCountPerSecond; /// <summary> /// 블럭 정렬 /// </summary> /// <remarks> /// 2바이트 : 리틀 엔디안 /// 샘플 프레임 크기 /// 모노 : 샘플 크기 * 1 /// 스테렝 : 샘플 크기 * 2 /// </remarks> public ushort BlockAlignment; /// <summary> /// 샘플당 비트 수 /// </summary> /// <remarks> /// 2바이트 : 리틀 엔디안 /// </remarks> public ushort BitCountPerSample; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - WAVEFMT() /// <summary> /// 생성자 /// </summary> public WAVEFMT() { ChunkID = "fmt "; ChunkSize = 16; AudioFormat = 1; ChannelCount = 2; SampleCountPerSecond = 44100; BitCountPerSample = 16; BlockAlignment = (ushort)(ChannelCount * (BitCountPerSample / 8)); AverageByteCountPerSecond = SampleCountPerSecond * BlockAlignment; } #endregion } } |
▶ WAVEDATA.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
namespace TestProject { /// <summary> /// WAVE 데이터 /// </summary> public class WAVEDATA { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 청크 ID /// </summary> /// <remarks> /// 4바이트 : 빅 엔디안 /// 'data' 문자를 저장한다. /// </remarks> public string ChunkID; /// <summary> /// 청크 크기 /// </summary> /// <remarks> /// 4바이트 : 리틀 엔디안 /// </remarks> public uint ChunkSize; /// <summary> /// 값 배열 /// </summary> public short[] ValueArray; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - WAVEDATA() /// <summary> /// 생성자 /// </summary> public WAVEDATA() { ChunkID = "data"; ChunkSize = 0; ValueArray = new short[0]; } #endregion } } |
▶ WaveGenerator.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
using System; using System.IO; namespace TestProject { /// <summary> /// WAVE 제너레이터 /// </summary> public class WaveGenerator { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 헤더 /// </summary> private WAVERIFF header; /// <summary> /// 포맷 /// </summary> private WAVEFMT format; /// <summary> /// 데이터 /// </summary> private WAVEDATA data; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - WaveGenerator() /// <summary> /// 생성자 /// </summary> public WaveGenerator() { this.header = new WAVERIFF(); this.format = new WAVEFMT(); this.data = new WAVEDATA(); uint sampleCount = this.format.SampleCountPerSecond * this.format.ChannelCount; this.data.ValueArray = new short[sampleCount]; int amplitude = 32760; // 16비트 오디오용 최대 진폭 double frequency = 440.0d; // Concert A : 440Hz double tone = (Math.PI * 2 * frequency) / sampleCount; for(uint i = 0; i < sampleCount - 1; i++) { for(int channel = 0; channel < this.format.ChannelCount; channel++) { this.data.ValueArray[i + channel] = Convert.ToInt16(amplitude * Math.Sin(tone * i)); } } this.data.ChunkSize = (uint)(this.data.ValueArray.Length * (this.format.BitCountPerSample / 8)); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 저장하기 - Save(filePath) /// <summary> /// 저장하기 /// </summary> /// <param name="filePath">파일 경로</param> public void Save(string filePath) { FileStream stream = new FileStream(filePath, FileMode.Create); BinaryWriter writer = new BinaryWriter(stream); // RIFF writer.Write(header.ChunkID.ToCharArray()); writer.Write(header.ChunkSize); writer.Write(header.Format.ToCharArray()); // FMT writer.Write(format.ChunkID.ToCharArray()); writer.Write(format.ChunkSize); writer.Write(format.AudioFormat); writer.Write(format.ChannelCount); writer.Write(format.SampleCountPerSecond); writer.Write(format.AverageByteCountPerSecond); writer.Write(format.BlockAlignment); writer.Write(format.BitCountPerSample); // DATA writer.Write(data.ChunkID.ToCharArray()); writer.Write(data.ChunkSize); foreach(short value in data.ValueArray) { writer.Write(value); } writer.Seek(4, SeekOrigin.Begin); uint filesize = (uint)writer.BaseStream.Length; writer.Write(filesize - 8); writer.Close(); stream.Close(); } #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { WaveGenerator generator = new WaveGenerator(); generator.Save("d:\\test.wav"); } #endregion } } |