-
Notifications
You must be signed in to change notification settings - Fork 1
/
WaveWriter.cs
134 lines (108 loc) · 3.78 KB
/
WaveWriter.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
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.IO;
using System.Text;
namespace Doit.Media.Audio.Amr {
public class WaveWriter {
private FileInfo wavFile;
private BinaryWriter binaryWriter;
private string filePath;
private int sampleRate;
private int channels;
private int bitsPerSample;
private int dataLength;
/**
* Constructor; initializes WaveWriter with file name and path
*
* @param path output file path
* @param name output file name
* @param sampleRate output sample rate
* @param channels number of channels
* @param sampleBits number of bits per sample (S8LE, S16LE)
*/
public WaveWriter(String path, int sampleRate,
int bitsPerSample, int channels) {
this.filePath = path;
this.sampleRate = sampleRate;
this.channels = channels;
this.bitsPerSample = bitsPerSample;
this.dataLength = 0;
}
/**
* Create output WAV file
*
* @return whether file creation succeeded
*
* @throws IOException if file I/O error occurs allocating header
*/
public bool CreateFile() {
try {
wavFile = new FileInfo(filePath);
if (wavFile.Exists) {
wavFile.Delete();
}
UTF8Encoding utf8 = new UTF8Encoding(false);
binaryWriter = new BinaryWriter(wavFile.Create(), utf8);
binaryWriter.Seek(0, SeekOrigin.Begin);
this.WriteHeader();
} catch (Exception ex) {
return false;
}
return true;
}
/**
* Write audio data to output file (mono). Does
* nothing if output file is not mono channel.
*
* @param littleendian mono audio data input buffer
* @param offset offset into src buffer
* @param length buffer size in number of samples
*
* @throws IOException if file I/O error occurs
*/
public void Write(byte[] littleendian, int length) {
if (this.binaryWriter == null) {
return;
}
this.dataLength += length;
this.binaryWriter.Write(littleendian);
}
/**
* Close output WAV file and write WAV header. WaveWriter
* cannot be used again following this call.
*
* @throws IOException if file I/O error occurs writing WAV header
*/
public void CloseFile() {
if (this.binaryWriter == null) {
return;
}
this.binaryWriter.Seek(0, SeekOrigin.Begin);
WriteHeader();
this.binaryWriter.Close();
}
private void WriteHeader() {
// rewind to beginning of the file
if (this.binaryWriter == null) {
return;
}
int bytesPerFrame;
int bytesPerSec;
binaryWriter.Write(UTF8Encoding.UTF8.GetBytes("RIFF")); // WAV chunk header
binaryWriter.Write(4 + 8 + 16 + 8 + this.dataLength); // WAV chunk size
binaryWriter.Write(UTF8Encoding.UTF8.GetBytes("WAVE")); // WAV format
binaryWriter.Write(UTF8Encoding.UTF8.GetBytes("fmt ")); // format subchunk header
binaryWriter.Write(16); // format subchunk size
bytesPerFrame = this.bitsPerSample / 8 * this.channels;
bytesPerSec = bytesPerFrame * this.sampleRate;
binaryWriter.Write((short)1); // audio format
binaryWriter.Write((short)this.channels); // number of channels
binaryWriter.Write(this.sampleRate); // sample rate
binaryWriter.Write(bytesPerSec); // byte rate
binaryWriter.Write((short)bytesPerFrame); // block align
binaryWriter.Write((short)this.bitsPerSample); // bits per sample
binaryWriter.Write(UTF8Encoding.UTF8.GetBytes("data")); // data subchunk header
binaryWriter.Write(this.dataLength); // data subchunk size
binaryWriter.Flush();
}
}
}