1
0
mirror of https://github.com/SineVector241/VoiceCraft-MCBE_Proximity_Chat.git synced 2024-11-20 10:27:45 +00:00
VoiceCraft-MCBE_Proximity_Chat/ATL/AudioData/IO/AC3.cs
2024-07-13 11:16:08 +10:00

130 lines
3.8 KiB
C#

using System.Collections.Generic;
using System.IO;
using static ATL.AudioData.AudioDataManager;
using static ATL.ChannelsArrangements;
namespace ATL.AudioData.IO
{
/// <summary>
/// Class for Dolby Digital files manipulation (extension : .AC3)
/// </summary>
class AC3 : IAudioDataIO
{
// Standard bitrates (KBit/s)
private static readonly int[] BITRATES = new int[] { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160,
192, 224, 256, 320, 384, 448, 512, 576, 640 };
// Private declarations
private uint sampleRate;
private ChannelsArrangement channelsArrangement;
// ---------- INFORMATIVE INTERFACE IMPLEMENTATIONS & MANDATORY OVERRIDES
/// <inheritdoc/>
public bool IsVBR => false;
/// <inheritdoc/>
public Format AudioFormat
{
get;
}
/// <inheritdoc/>
public int CodecFamily => AudioDataIOFactory.CF_LOSSY;
/// <inheritdoc/>
public string FileName { get; }
/// <inheritdoc/>
public double BitRate { get; private set; }
/// <inheritdoc/>
public double Duration { get; private set; }
/// <inheritdoc/>
public int SampleRate => (int)this.sampleRate;
/// <inheritdoc/>
public int BitDepth => -1; // Irrelevant for lossy formats
/// <inheritdoc/>
public ChannelsArrangement ChannelsArrangement => channelsArrangement;
/// <inheritdoc/>
public List<MetaDataIOFactory.TagType> GetSupportedMetas()
{
return new List<MetaDataIOFactory.TagType> { MetaDataIOFactory.TagType.APE };
}
/// <inheritdoc/>
public long AudioDataOffset { get; set; }
/// <inheritdoc/>
public long AudioDataSize { get; set; }
// ---------- CONSTRUCTORS & INITIALIZERS
protected void resetData()
{
sampleRate = 0;
Duration = 0;
BitRate = 0;
AudioDataOffset = -1;
AudioDataSize = 0;
}
public AC3(string filePath, Format format)
{
this.FileName = filePath;
AudioFormat = format;
resetData();
}
// ---------- SUPPORT METHODS
public static bool IsValidHeader(byte[] data)
{
return 30475 == StreamUtils.DecodeUInt16(data);
}
public bool Read(Stream source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
{
resetData();
byte[] buffer = new byte[2];
source.Seek(0, SeekOrigin.Begin);
source.Read(buffer, 0, 2);
if (!IsValidHeader(buffer)) return false;
AudioDataOffset = source.Position - 2;
AudioDataSize = sizeInfo.FileSize - sizeInfo.APESize - sizeInfo.ID3v1Size - AudioDataOffset;
source.Seek(2, SeekOrigin.Current);
source.Read(buffer, 0, 1);
sampleRate = (buffer[0] & 0xC0) switch
{
0 => 48000,
0x40 => 44100,
0x80 => 32000,
_ => 0
};
BitRate = BITRATES[(buffer[0] & 0x3F) >> 1];
source.Seek(1, SeekOrigin.Current);
source.Read(buffer, 0, 1);
channelsArrangement = (buffer[0] & 0xE0) switch
{
0 => DUAL_MONO,
0x20 => MONO,
0x40 => STEREO,
0x60 => ISO_3_0_0,
0x80 => ISO_2_1_0,
0xA0 => ISO_3_1_0,
0xC0 => ISO_2_2_0,
0xE0 => ISO_3_2_0,
_ => UNKNOWN
};
Duration = sizeInfo.FileSize * 8.0 / BitRate;
return true;
}
}
}