teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2017/04/25 12:25

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -6,4 +6,67 @@
6
6
 
7
7
  kinectからの波形データはIEEE 32bitモノラルだと思います。よって、上記サイトの波形フォーマットのWAVE_FORMAT_IEEE_FLOATでチャネル数=1で出力することになると思いまs。
8
8
 
9
- float->short(符号付16bit)に変換してやればWAVE_FORMAT_PCMで出力することも可能だと思います。(floatの波形データ範囲は-1.0~1.0であり、shortへ変換する際には-32768~32767の範囲へ変換するという点に注意してください。)
9
+ float->short(符号付16bit)に変換してやればWAVE_FORMAT_PCMで出力することも可能だと思います。(floatの波形データ範囲は-1.0~1.0であり、shortへ変換する際には-32768~32767の範囲へ変換するという点に注意してください。)
10
+
11
+ ---
12
+
13
+ 追記:PCM形式(16bit signed integer)のWAVファイルはよく見ますが、IEEE floatを試したことがなかったのでやってみました。結果Windows 10で再生できましたのでサンプルコードを載せておきます。この例では波形は計算で求めたもの(440Hz,正弦波)で、0.5秒分の波形データとしています。
14
+
15
+ ```C#
16
+ using System;
17
+ using System.IO;
18
+ using System.Text;
19
+
20
+ class MainClass {
21
+ public static void Main() {
22
+ SaveRiff("a.wav");
23
+ Console.WriteLine("Save done");
24
+ }
25
+
26
+ static ushort WAVE_FORMAT_PCM = (ushort)0x0001;//未使用
27
+ static ushort WAVE_FORMAT_IEEE_FLOAT = (ushort)0x0003;
28
+ static uint BYTES_PER_SAMPLE_IEEE_FLOAT = 4U;
29
+
30
+ static void SaveRiff(string path) {
31
+ uint sampleRate = 44100; // 44.1 KHz
32
+ ushort numChannels = 1; // モノラル
33
+ uint numSamples = 22050; // 0.5 sec
34
+ ushort waveFormat = WAVE_FORMAT_IEEE_FLOAT;
35
+ uint bytesPerSample = BYTES_PER_SAMPLE_IEEE_FLOAT;
36
+
37
+ using (var fs = new FileStream(path, FileMode.Create))
38
+ using (var wr = new BinaryWriter(fs)) {
39
+ // RIFF header
40
+ wr.Write(MagicToBytes("RIFF")); //+00
41
+ wr.Write(36U + bytesPerSample * numChannels * numSamples); //+04
42
+ wr.Write(MagicToBytes("WAVE")); //+08
43
+ // fmt chunk
44
+ wr.Write(MagicToBytes("fmt ")); //+0C
45
+ wr.Write(16U); //+10: chunk length
46
+ wr.Write((ushort)waveFormat); //+14
47
+ wr.Write((ushort)numChannels); //+16
48
+ wr.Write(sampleRate); //+18
49
+ wr.Write(bytesPerSample * numChannels * sampleRate); //+1C
50
+ wr.Write((ushort)(bytesPerSample * numChannels)); //+20
51
+ wr.Write((ushort)(8U * bytesPerSample)); //+22
52
+ // data chunk
53
+ wr.Write(MagicToBytes("data")); //+24
54
+ wr.Write(bytesPerSample * numSamples); //+28
55
+ //+2C
56
+ // 以降は波形データ。(この例では440Hzの正弦波)
57
+ float amplitude = (float)0.25;
58
+ float freq = 440;
59
+
60
+ for (uint i = 0; i < numSamples; i++) {
61
+ double th = i * Math.PI * freq / sampleRate;
62
+ double w = amplitude * Math.Sin(th);
63
+ wr.Write((float)w);
64
+ }
65
+ }
66
+ }
67
+
68
+ static byte[] MagicToBytes(string magic) {
69
+ return Encoding.ASCII.GetBytes(magic);
70
+ }
71
+ }
72
+ ```