Skip to content

Commit efd4b8a

Browse files
[Dependencies] Add .NET-Ogg-Vorbis-Encoder;
[Audio] Add support for audio compression (WAV only);
1 parent 5a0adb9 commit efd4b8a

File tree

696 files changed

+42615
-191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

696 files changed

+42615
-191
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2016 Steve Lillis
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace OggVorbisEncoder;
4+
5+
internal static class ArrayExtensions
6+
{
7+
public static TElement[] ToFixedLength<TElement>(this TElement[] input, int fixedLength)
8+
{
9+
if (input == null)
10+
throw new ArgumentNullException(nameof(input));
11+
12+
if (input.Length == fixedLength)
13+
return input;
14+
15+
if (input.Length > fixedLength)
16+
throw new IndexOutOfRangeException(
17+
$"{nameof(input)} of size [{input.Length}] is greater than {nameof(fixedLength)} of [{fixedLength}]");
18+
19+
var output = new TElement[fixedLength];
20+
Array.Copy(input, output, input.Length);
21+
22+
return output;
23+
}
24+
}

Dependencies/.NET-Ogg-Vorbis-Encoder/OggVorbisEncoder/Block.cs

Lines changed: 2088 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using OggVorbisEncoder.Setup;
3+
4+
namespace OggVorbisEncoder;
5+
6+
public class CodecSetup
7+
{
8+
public CodecSetup(EncodeSetup encodeSetup)
9+
{
10+
EncodeSetup = encodeSetup;
11+
}
12+
13+
public EncodeSetup EncodeSetup { get; }
14+
15+
public int[] BlockSizes { get; } = new int[2];
16+
17+
public CodeBook[] FullBooks { get; set; }
18+
public IList<IStaticCodeBook> BookParams { get; } = new List<IStaticCodeBook>();
19+
public IList<Mode> ModeParams { get; } = new List<Mode>();
20+
public IList<Mapping> MapParams { get; } = new List<Mapping>();
21+
public IList<Floor> FloorParams { get; } = new List<Floor>();
22+
public IList<ResidueEntry> ResidueParams { get; } = new List<ResidueEntry>();
23+
public IList<PsyInfo> PsyParams { get; } = new List<PsyInfo>();
24+
public PsyGlobal PsyGlobalParam { get; set; }
25+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Collections.Generic;
2+
using System.Text;
3+
4+
namespace OggVorbisEncoder;
5+
6+
public class Comments
7+
{
8+
private readonly List<string> _userComments = new List<string>();
9+
10+
public List<string> UserComments => _userComments;
11+
12+
public void AddTag(string tag, string contents)
13+
{
14+
var stringBuilder = new StringBuilder();
15+
stringBuilder.Append(tag);
16+
stringBuilder.Append('=');
17+
stringBuilder.Append(contents);
18+
_userComments.Add(stringBuilder.ToString());
19+
}
20+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using OggVorbisEncoder.Setup;
3+
4+
namespace OggVorbisEncoder;
5+
6+
public class EncodeBuffer
7+
{
8+
private const int BufferIncrement = 256;
9+
10+
private static readonly uint[] Mask =
11+
{
12+
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
13+
0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
14+
0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
15+
0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
16+
0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
17+
0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff,
18+
0x3fffffff, 0x7fffffff, 0xffffffff
19+
};
20+
21+
private byte[] _buffer;
22+
private int _endBit;
23+
private int _endByte;
24+
25+
public EncodeBuffer()
26+
: this(BufferIncrement)
27+
{
28+
}
29+
30+
public EncodeBuffer(int initialBufferSize)
31+
{
32+
_buffer = new byte[initialBufferSize];
33+
}
34+
35+
private int Bytes => _endByte + (_endBit + 7) / 8;
36+
37+
public void WriteBook(CodeBook book, int a)
38+
{
39+
if ((a < 0) || (a >= book.Entries))
40+
return;
41+
42+
Write(book.CodeList[a], book.StaticBook.LengthList[a]);
43+
}
44+
45+
public void WriteString(string str)
46+
{
47+
foreach (var c in str)
48+
Write(c, 8);
49+
}
50+
51+
public void Write(uint value, int bits)
52+
{
53+
if ((bits < 0) || (bits > 32))
54+
throw new ArgumentException($"{nameof(bits)} must be between 0 and 32");
55+
56+
if (_endByte >= _buffer.Length - 4)
57+
{
58+
if (_buffer.Length > int.MaxValue - BufferIncrement)
59+
throw new InvalidOperationException("Maximum buffer size exceeded");
60+
61+
Array.Resize(ref _buffer, _buffer.Length + BufferIncrement);
62+
}
63+
64+
value &= Mask[bits];
65+
bits += _endBit;
66+
67+
_buffer[_endByte] = (byte)(_buffer[_endByte] | (value << _endBit));
68+
69+
if (bits >= 8)
70+
{
71+
_buffer[_endByte + 1] = (byte)(value >> (8 - _endBit));
72+
if (bits >= 16)
73+
{
74+
_buffer[_endByte + 2] = (byte)(value >> (16 - _endBit));
75+
if (bits >= 24)
76+
{
77+
_buffer[_endByte + 3] = (byte)(value >> (24 - _endBit));
78+
if (bits >= 32)
79+
if (_endBit != 0)
80+
_buffer[_endByte + 4] = (byte)(value >> (32 - _endBit));
81+
else
82+
_buffer[_endByte + 4] = 0;
83+
}
84+
}
85+
}
86+
87+
_endByte += bits / 8;
88+
_endBit = bits & 7;
89+
}
90+
91+
public byte[] GetBytes()
92+
{
93+
Array.Resize(ref _buffer, Bytes);
94+
return _buffer;
95+
}
96+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using OggVorbisEncoder.Setup;
2+
using OggVorbisEncoder.Setup.Templates;
3+
using System;
4+
using System.Collections.Generic;
5+
6+
namespace OggVorbisEncoder;
7+
8+
public class EncodeSetup
9+
{
10+
private static IEnumerable<ISetupTemplate> CreateTemplates()
11+
{
12+
return new ISetupTemplate[]
13+
{
14+
new Stereo44SetupDataTemplate(),
15+
new Uncoupled44SetupDataTemplate(),
16+
new Stereo32SetupDataTemplate(),
17+
new Uncoupled32SetupDataTemplate(),
18+
new Stereo22SetupDataTemplate(),
19+
new Uncoupled22SetupDataTemplate(),
20+
new Stereo16SetupDataTemplate(),
21+
new Uncoupled16SetupDataTemplate(),
22+
new Stereo11SetupDataTemplate(),
23+
new Uncoupled11SetupDataTemplate(),
24+
new Stereo8SetupDataTemplate(),
25+
new Uncoupled8SetupDataTemplate(),
26+
new StereoXSetupDataTemplate(),
27+
new UncoupledXSetupDataTemplate(),
28+
new StereoXXSetupDataTemplate(),
29+
new UncoupledXXSetupDataTemplate()
30+
};
31+
}
32+
33+
34+
private static readonly IEnumerable<ISetupTemplate> SetupTemplates = CreateTemplates();
35+
36+
public EncodeSetup(ISetupTemplate template, double baseSetting)
37+
{
38+
Template = template;
39+
BaseSetting = baseSetting;
40+
41+
var iS = (int)BaseSetting;
42+
var ds = BaseSetting - iS;
43+
44+
LowPassKilohertz = template.PsyLowPass[iS] * (1 - ds) + template.PsyLowPass[iS + 1] * ds;
45+
46+
AthFloatingDecibel = template.PsyAthFloat[iS] * (1 - ds) + template.PsyAthFloat[iS + 1] * ds;
47+
48+
AthAbsoluteDecibel = template.PsyAthAbs[iS] * (1 - ds) + template.PsyAthAbs[iS + 1] * ds;
49+
50+
AmplitudeTrackDbPerSec = -6;
51+
52+
// too low/high an ATH floater is nonsensical, but doesn't break anything
53+
if (AthFloatingDecibel > -80)
54+
AthFloatingDecibel = -80;
55+
56+
if (AthFloatingDecibel < -200)
57+
AthFloatingDecibel = -200;
58+
59+
if (AmplitudeTrackDbPerSec > 0)
60+
AmplitudeTrackDbPerSec = 0;
61+
62+
if (AmplitudeTrackDbPerSec < -99999)
63+
AmplitudeTrackDbPerSec = -99999;
64+
}
65+
66+
public ISetupTemplate Template { get; }
67+
public double BaseSetting { get; }
68+
public double LowPassKilohertz { get; }
69+
public double AthFloatingDecibel { get; }
70+
public double AthAbsoluteDecibel { get; }
71+
public double AmplitudeTrackDbPerSec { get; }
72+
73+
public static EncodeSetup GetBestMatch(
74+
int channels,
75+
int sampleRate,
76+
float quality)
77+
{
78+
foreach (var template in SetupTemplates)
79+
{
80+
if ((template.CouplingRestriction != -1)
81+
&& (template.CouplingRestriction != channels))
82+
continue;
83+
84+
if ((sampleRate < template.SampleRateMinRestriction)
85+
|| (sampleRate > template.SampleRateMaxRestriction))
86+
continue;
87+
88+
var map = template.QualityMapping;
89+
90+
// the template matches. Does the requested quality mode fall within this template's modes?
91+
if ((quality < map[0])
92+
|| (quality > map[template.Mappings]))
93+
continue;
94+
95+
int j;
96+
for (j = 0; j < template.Mappings; ++j)
97+
if ((quality >= map[j]) && (quality < map[j + 1]))
98+
break;
99+
100+
// an all-points match
101+
double baseSetting;
102+
if (j == template.Mappings)
103+
{
104+
baseSetting = j - .001;
105+
}
106+
else
107+
{
108+
var low = map[j];
109+
var high = map[j + 1];
110+
var del = (quality - low) / (high - low);
111+
baseSetting = j + del;
112+
}
113+
114+
return new EncodeSetup(template, baseSetting);
115+
}
116+
117+
throw new InvalidOperationException("No matching template found");
118+
}
119+
}

0 commit comments

Comments
 (0)