-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWavExporter.cs
More file actions
67 lines (57 loc) · 2.53 KB
/
Copy pathWavExporter.cs
File metadata and controls
67 lines (57 loc) · 2.53 KB
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
using System.Text;
using PrettyConsole;
using SharpMod;
using static PrettyConsole.Color;
namespace SharpModConsolePlayer {
internal static class WavExporter {
private const int BufferLength = 6000;
internal static int Export(SoundFile sf, string outPath, int sampleRate, int bitDepth, int channels) {
int blockAlign = channels * (bitDepth / 8);
uint totalPositions = sf.PositionCount;
Console.WriteLineInterpolated($"{Yellow}Exporting{Default} to {Cyan}{outPath}{Default}");
Console.WriteLineInterpolated($" {DarkGray}{sampleRate} Hz, {bitDepth}-bit, {(channels == 2 ? "stereo" : "mono")}{Default}");
using FileStream fs = File.Create(outPath);
using BinaryWriter bw = new(fs);
WriteHeader(bw, sampleRate, bitDepth, channels, dataSize: 0);
byte[] buffer = new byte[BufferLength];
long bytesWritten = 0;
int zeroReads = 0;
while(true) {
uint read = sf.Read(buffer, (uint)buffer.Length);
if(read == 0) {
if(++zeroReads >= 2) break;
continue;
}
zeroReads = 0;
bw.Write(buffer, 0, (int)read);
bytesWritten += read;
if(sf.Position >= totalPositions) break;
}
bw.Flush();
fs.Position = 4;
bw.Write((uint)(bytesWritten + 36));
fs.Position = 40;
bw.Write((uint)bytesWritten);
double seconds = bytesWritten / (double)(sampleRate * blockAlign);
Console.WriteLineInterpolated($" {Green}Wrote{Default} {White}{bytesWritten:N0}{Default} bytes ({White}{seconds:F2}{Default} s)");
return 0;
}
private static void WriteHeader(BinaryWriter bw, int rate, int bits, int channels, uint dataSize) {
int byteRate = rate * channels * (bits / 8);
short blockAlign = (short)(channels * (bits / 8));
bw.Write(Encoding.ASCII.GetBytes("RIFF"));
bw.Write(dataSize + 36u);
bw.Write(Encoding.ASCII.GetBytes("WAVE"));
bw.Write(Encoding.ASCII.GetBytes("fmt "));
bw.Write(16u);
bw.Write((short)1); // PCM
bw.Write((short)channels);
bw.Write((uint)rate);
bw.Write((uint)byteRate);
bw.Write(blockAlign);
bw.Write((short)bits);
bw.Write(Encoding.ASCII.GetBytes("data"));
bw.Write(dataSize);
}
}
}