回答編集履歴

1

追記

2017/04/25 12:25

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -15,3 +15,129 @@
15
15
 
16
16
 
17
17
  float->short(符号付16bit)に変換してやればWAVE_FORMAT_PCMで出力することも可能だと思います。(floatの波形データ範囲は-1.0~1.0であり、shortへ変換する際には-32768~32767の範囲へ変換するという点に注意してください。)
18
+
19
+
20
+
21
+ ---
22
+
23
+
24
+
25
+ 追記:PCM形式(16bit signed integer)のWAVファイルはよく見ますが、IEEE floatを試したことがなかったのでやってみました。結果Windows 10で再生できましたのでサンプルコードを載せておきます。この例では波形は計算で求めたもの(440Hz,正弦波)で、0.5秒分の波形データとしています。
26
+
27
+
28
+
29
+ ```C#
30
+
31
+ using System;
32
+
33
+ using System.IO;
34
+
35
+ using System.Text;
36
+
37
+
38
+
39
+ class MainClass {
40
+
41
+ public static void Main() {
42
+
43
+ SaveRiff("a.wav");
44
+
45
+ Console.WriteLine("Save done");
46
+
47
+ }
48
+
49
+
50
+
51
+ static ushort WAVE_FORMAT_PCM = (ushort)0x0001;//未使用
52
+
53
+ static ushort WAVE_FORMAT_IEEE_FLOAT = (ushort)0x0003;
54
+
55
+ static uint BYTES_PER_SAMPLE_IEEE_FLOAT = 4U;
56
+
57
+
58
+
59
+ static void SaveRiff(string path) {
60
+
61
+ uint sampleRate = 44100; // 44.1 KHz
62
+
63
+ ushort numChannels = 1; // モノラル
64
+
65
+ uint numSamples = 22050; // 0.5 sec
66
+
67
+ ushort waveFormat = WAVE_FORMAT_IEEE_FLOAT;
68
+
69
+ uint bytesPerSample = BYTES_PER_SAMPLE_IEEE_FLOAT;
70
+
71
+
72
+
73
+ using (var fs = new FileStream(path, FileMode.Create))
74
+
75
+ using (var wr = new BinaryWriter(fs)) {
76
+
77
+ // RIFF header
78
+
79
+ wr.Write(MagicToBytes("RIFF")); //+00
80
+
81
+ wr.Write(36U + bytesPerSample * numChannels * numSamples); //+04
82
+
83
+ wr.Write(MagicToBytes("WAVE")); //+08
84
+
85
+ // fmt chunk
86
+
87
+ wr.Write(MagicToBytes("fmt ")); //+0C
88
+
89
+ wr.Write(16U); //+10: chunk length
90
+
91
+ wr.Write((ushort)waveFormat); //+14
92
+
93
+ wr.Write((ushort)numChannels); //+16
94
+
95
+ wr.Write(sampleRate); //+18
96
+
97
+ wr.Write(bytesPerSample * numChannels * sampleRate); //+1C
98
+
99
+ wr.Write((ushort)(bytesPerSample * numChannels)); //+20
100
+
101
+ wr.Write((ushort)(8U * bytesPerSample)); //+22
102
+
103
+ // data chunk
104
+
105
+ wr.Write(MagicToBytes("data")); //+24
106
+
107
+ wr.Write(bytesPerSample * numSamples); //+28
108
+
109
+ //+2C
110
+
111
+ // 以降は波形データ。(この例では440Hzの正弦波)
112
+
113
+ float amplitude = (float)0.25;
114
+
115
+ float freq = 440;
116
+
117
+
118
+
119
+ for (uint i = 0; i < numSamples; i++) {
120
+
121
+ double th = i * Math.PI * freq / sampleRate;
122
+
123
+ double w = amplitude * Math.Sin(th);
124
+
125
+ wr.Write((float)w);
126
+
127
+ }
128
+
129
+ }
130
+
131
+ }
132
+
133
+
134
+
135
+ static byte[] MagicToBytes(string magic) {
136
+
137
+ return Encoding.ASCII.GetBytes(magic);
138
+
139
+ }
140
+
141
+ }
142
+
143
+ ```