mirror of
https://github.com/SineVector241/VoiceCraft-MCBE_Proximity_Chat.git
synced 2024-11-20 10:27:45 +00:00
122 lines
3.6 KiB
C#
122 lines
3.6 KiB
C#
using System.IO;
|
|
using static ATL.AudioData.AudioDataManager;
|
|
using Commons;
|
|
using static ATL.ChannelsArrangements;
|
|
using System.Collections.Generic;
|
|
|
|
namespace ATL.AudioData.IO
|
|
{
|
|
/// <summary>
|
|
/// Class for True Audio files manipulation (extensions : .TTA)
|
|
///
|
|
/// NB : Only supports TTA1
|
|
/// </summary>
|
|
class TTA : IAudioDataIO
|
|
{
|
|
private static readonly byte[] TTA_SIGNATURE = Utils.Latin1Encoding.GetBytes("TTA1");
|
|
|
|
// Private declarations
|
|
private uint bitsPerSample;
|
|
private uint sampleRate;
|
|
private uint samplesSize;
|
|
|
|
|
|
// Public declarations
|
|
public uint Samples => samplesSize;
|
|
|
|
// ---------- INFORMATIVE INTERFACE IMPLEMENTATIONS & MANDATORY OVERRIDES
|
|
|
|
public int SampleRate => (int)sampleRate;
|
|
public bool IsVBR => false;
|
|
public Format AudioFormat
|
|
{
|
|
get;
|
|
}
|
|
public int CodecFamily => AudioDataIOFactory.CF_LOSSY;
|
|
public string FileName { get; }
|
|
|
|
public double BitRate { get; private set; }
|
|
|
|
public int BitDepth => (int)bitsPerSample;
|
|
public double Duration { get; private set; }
|
|
|
|
public ChannelsArrangement ChannelsArrangement { get; private set; }
|
|
|
|
/// <inheritdoc/>
|
|
public List<MetaDataIOFactory.TagType> GetSupportedMetas()
|
|
{
|
|
return new List<MetaDataIOFactory.TagType> { MetaDataIOFactory.TagType.ID3V2, MetaDataIOFactory.TagType.APE, MetaDataIOFactory.TagType.ID3V1 };
|
|
}
|
|
|
|
public long AudioDataOffset { get; set; }
|
|
public long AudioDataSize { get; set; }
|
|
|
|
|
|
// ---------- CONSTRUCTORS & INITIALIZERS
|
|
|
|
private void resetData()
|
|
{
|
|
Duration = 0;
|
|
BitRate = 0;
|
|
|
|
bitsPerSample = 0;
|
|
sampleRate = 0;
|
|
samplesSize = 0;
|
|
|
|
AudioDataOffset = -1;
|
|
AudioDataSize = 0;
|
|
}
|
|
|
|
public TTA(string filePath, Format format)
|
|
{
|
|
this.FileName = filePath;
|
|
AudioFormat = format;
|
|
resetData();
|
|
}
|
|
|
|
|
|
// ---------- SUPPORT METHODS
|
|
|
|
public static bool IsValidHeader(byte[] data)
|
|
{
|
|
return StreamUtils.ArrBeginsWith(data, TTA_SIGNATURE);
|
|
}
|
|
|
|
public bool Read(Stream source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
|
|
{
|
|
resetData();
|
|
source.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin);
|
|
|
|
bool result = false;
|
|
|
|
byte[] buffer = new byte[4];
|
|
source.Read(buffer, 0, buffer.Length);
|
|
if (IsValidHeader(buffer))
|
|
{
|
|
AudioDataOffset = source.Position - 4;
|
|
AudioDataSize = sizeInfo.FileSize - sizeInfo.APESize - sizeInfo.ID3v1Size - AudioDataOffset;
|
|
|
|
source.Seek(2, SeekOrigin.Current); // audio format
|
|
source.Read(buffer, 0, 2);
|
|
ChannelsArrangement = GuessFromChannelNumber(StreamUtils.DecodeUInt16(buffer));
|
|
source.Read(buffer, 0, 2);
|
|
bitsPerSample = StreamUtils.DecodeUInt16(buffer);
|
|
source.Read(buffer, 0, 4);
|
|
sampleRate = StreamUtils.DecodeUInt32(buffer);
|
|
source.Read(buffer, 0, 4);
|
|
samplesSize = StreamUtils.DecodeUInt32(buffer);
|
|
source.Seek(4, SeekOrigin.Current); // CRC
|
|
|
|
BitRate = (sizeInfo.FileSize - sizeInfo.TotalTagSize) * 8.0 / (samplesSize * 1000.0 / sampleRate);
|
|
Duration = samplesSize * 1000.0 / sampleRate;
|
|
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
}
|
|
}
|