forked from SteveLillis/.NET-Ogg-Vorbis-Encoder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEncoder.cs
120 lines (100 loc) · 4.37 KB
/
Encoder.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
using System;
using System.IO;
namespace OggVorbisEncoder.Example
{
public class Encoder
{
private const int SampleSize = 1024;
[STAThread]
private static void Main()
{
var stdin = new FileStream(@"unencoded.raw", FileMode.Open, FileAccess.Read);
var stdout = new FileStream(@"encoded.ogg", FileMode.Create, FileAccess.Write);
// StripWavHeader(stdin);
// Stores all the static vorbis bitstream settings
var info = VorbisInfo.InitVariableBitRate(2, 44100, 0.1f);
// set up our packet->stream encoder
var serial = new Random().Next();
var oggStream = new OggStream(serial);
// =========================================================
// HEADER
// =========================================================
// Vorbis streams begin with three headers; the initial header (with
// most of the codec setup parameters) which is mandated by the Ogg
// bitstream spec. The second header holds any comment fields. The
// third header holds the bitstream codebook.
var headerBuilder = new HeaderPacketBuilder();
var comments = new Comments();
comments.AddTag("ARTIST", "TEST");
var infoPacket = headerBuilder.BuildInfoPacket(info);
var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
var booksPacket = headerBuilder.BuildBooksPacket(info);
oggStream.PacketIn(infoPacket);
oggStream.PacketIn(commentsPacket);
oggStream.PacketIn(booksPacket);
// Flush to force audio data onto its own page per the spec
OggPage page;
while (oggStream.PageOut(out page, true))
{
stdout.Write(page.Header, 0, page.Header.Length);
stdout.Write(page.Body, 0, page.Body.Length);
}
// =========================================================
// BODY (Audio Data)
// =========================================================
var processingState = ProcessingState.Create(info);
var buffer = new float[info.Channels][];
buffer[0] = new float[SampleSize];
buffer[1] = new float[SampleSize];
var readbuffer = new byte[SampleSize*4];
while (!oggStream.Finished)
{
var bytes = stdin.Read(readbuffer, 0, readbuffer.Length);
if (bytes == 0)
{
processingState.WriteEndOfStream();
}
else
{
var samples = bytes/4;
for (var i = 0; i < samples; i++)
{
// uninterleave samples
buffer[0][i] = (short) ((readbuffer[i*4 + 1] << 8) | (0x00ff & readbuffer[i*4]))/32768f;
buffer[1][i] = (short) ((readbuffer[i*4 + 3] << 8) | (0x00ff & readbuffer[i*4 + 2]))/32768f;
}
processingState.WriteData(buffer, samples);
}
OggPacket packet;
while (!oggStream.Finished
&& processingState.PacketOut(out packet))
{
oggStream.PacketIn(packet);
while (!oggStream.Finished
&& oggStream.PageOut(out page, false))
{
stdout.Write(page.Header, 0, page.Header.Length);
stdout.Write(page.Body, 0, page.Body.Length);
}
}
}
stdin.Close();
stdout.Close();
}
/// <summary>
/// we cheat on the WAV header; we just bypass the header and never
/// verify that it matches 16bit/stereo/44.1kHz.This is just an
/// example, after all.
/// </summary>
private static void StripWavHeader(BinaryReader stdin)
{
var tempBuffer = new byte[6];
for (var i = 0; (i < 30) && (stdin.Read(tempBuffer, 0, 2) > 0); i++)
if ((tempBuffer[0] == 'd') && (tempBuffer[1] == 'a'))
{
stdin.Read(tempBuffer, 0, 6);
break;
}
}
}
}