Initial commit
This commit is contained in:
commit
262601edb8
2025 files changed
+218754
No files matched your search
@@ -0,0 +1,415 @@
|
||||
//
|
||||
// AudioHeader.cs: Provides information about an ADTS AAC audio stream.
|
||||
//
|
||||
// Copyright (C) 2009 Patrick Dehne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version
|
||||
// 2.1 as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace TagLib.Aac
|
||||
{
|
||||
/// <summary>
|
||||
/// This structure implements <see cref="IAudioCodec" /> and provides
|
||||
/// information about an ADTS AAC audio stream.
|
||||
/// </summary>
|
||||
public class AudioHeader : IAudioCodec
|
||||
{
|
||||
#region Private Static Value Arrays
|
||||
|
||||
/// <summary>
|
||||
/// Contains a sample rate table for ADTS AAC audio.
|
||||
/// </summary>
|
||||
static readonly int[] sample_rates = new int[13] {
|
||||
96000, 88200, 64000, 48000, 44100, 32000,
|
||||
24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Contains a channel table for ADTS AAC audio.
|
||||
/// </summary>
|
||||
static readonly int[] channels = new int[8] {
|
||||
0, 1, 2, 3, 4, 5, 6, 8
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Contains the audio stream length.
|
||||
/// </summary>
|
||||
long stream_length;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the audio stream duration.
|
||||
/// </summary>
|
||||
TimeSpan duration;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the number of channels in the audio
|
||||
/// </summary>
|
||||
readonly int audiochannels;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the bitrate of the audio stream
|
||||
/// </summary>
|
||||
readonly int audiobitrate;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the samplerate of the audio stream
|
||||
/// </summary>
|
||||
readonly int audiosamplerate;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>
|
||||
/// An empty and unset header.
|
||||
/// </summary>
|
||||
public static readonly AudioHeader Unknown = new AudioHeader ();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new empty instance of <see
|
||||
/// cref="AudioHeader" />
|
||||
/// </summary>
|
||||
AudioHeader ()
|
||||
{
|
||||
stream_length = 0;
|
||||
duration = TimeSpan.Zero;
|
||||
audiochannels = 0;
|
||||
audiobitrate = 0;
|
||||
audiosamplerate = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AudioHeader" /> by populating it with specified
|
||||
/// values.
|
||||
/// </summary>
|
||||
/// <param name="channels">
|
||||
/// A <see cref="int" /> value indicating the number
|
||||
/// of channels in the audio stream
|
||||
/// </param>
|
||||
/// <param name="bitrate">
|
||||
/// A <see cref="int" /> value indicating the bitrate
|
||||
/// of the audio stream
|
||||
/// </param>
|
||||
/// <param name="samplerate">
|
||||
/// A <see cref="int" /> value indicating the samplerate
|
||||
/// of the audio stream
|
||||
/// </param>
|
||||
/// <param name="numberofsamples">
|
||||
/// A <see cref="int" /> value indicating the number
|
||||
/// of samples in the audio stream
|
||||
/// </param>
|
||||
/// <param name="numberofframes">
|
||||
/// A <see cref="int" /> value indicating the number
|
||||
/// of frames in the audio stream
|
||||
/// </param>
|
||||
AudioHeader (int channels, int bitrate, int samplerate, int numberofsamples, int numberofframes)
|
||||
{
|
||||
duration = TimeSpan.Zero;
|
||||
stream_length = 0;
|
||||
audiochannels = channels;
|
||||
audiobitrate = bitrate;
|
||||
audiosamplerate = samplerate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets a text description of the media represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing a description
|
||||
/// of the media represented by the current instance.
|
||||
/// </value>
|
||||
public string Description {
|
||||
get {
|
||||
return "ADTS AAC";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the types of media represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="MediaTypes.Audio" />.
|
||||
/// </value>
|
||||
public MediaTypes MediaTypes {
|
||||
get { return MediaTypes.Audio; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the media represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TimeSpan" /> containing the duration of the
|
||||
/// media represented by the current instance.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// If <see cref="SetStreamLength" /> has not been called, this
|
||||
/// value will not be correct.
|
||||
/// </remarks>
|
||||
public TimeSpan Duration {
|
||||
get {
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitrate of the audio represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="int" /> value containing a bitrate of the
|
||||
/// audio represented by the current instance.
|
||||
/// </value>
|
||||
public int AudioBitrate {
|
||||
get {
|
||||
return audiobitrate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sample rate of the audio represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="int" /> value containing the sample rate of
|
||||
/// the audio represented by the current instance.
|
||||
/// </value>
|
||||
public int AudioSampleRate {
|
||||
get {
|
||||
return audiosamplerate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of channels in the audio represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="int" /> value containing the number of
|
||||
/// channels in the audio represented by the current
|
||||
/// instance.
|
||||
/// </value>
|
||||
public int AudioChannels {
|
||||
get { return audiochannels; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Sets the length of the audio stream represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <param name="streamLength">
|
||||
/// A <see cref="long" /> value specifying the length in
|
||||
/// bytes of the audio stream represented by the current
|
||||
/// instance.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// The this value has been set, <see cref="Duration" /> will
|
||||
/// return an incorrect value.
|
||||
/// </remarks>
|
||||
public void SetStreamLength (long streamLength)
|
||||
{
|
||||
stream_length = streamLength;
|
||||
duration = TimeSpan.FromSeconds (stream_length * 8.0 / audiobitrate);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// Searches for an audio header in a <see cref="TagLib.File"
|
||||
/// /> starting at a specified position and searching through
|
||||
/// a specified number of bytes.
|
||||
/// </summary>
|
||||
/// <param name="header">
|
||||
/// A <see cref="AudioHeader" /> object in which the found
|
||||
/// header will be stored.
|
||||
/// </param>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object to search.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specifying the seek position
|
||||
/// in <paramref name="file" /> at which to start searching.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the maximum number
|
||||
/// of bytes to search before aborting.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not a
|
||||
/// header was found.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
public static bool Find (out AudioHeader header, TagLib.File file, long position, int length)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
|
||||
long end = position + length;
|
||||
header = Unknown;
|
||||
|
||||
file.Seek (position);
|
||||
|
||||
ByteVector buffer = file.ReadBlock (3);
|
||||
|
||||
if (buffer.Count < 3)
|
||||
return false;
|
||||
|
||||
do {
|
||||
file.Seek (position + 3);
|
||||
buffer = buffer.Mid (buffer.Count - 3);
|
||||
buffer.Add (file.ReadBlock (
|
||||
(int)TagLib.File.BufferSize));
|
||||
|
||||
for (int i = 0; i < buffer.Count - 3 &&
|
||||
(length < 0 || position + i < end); i++)
|
||||
if (buffer[i] == 0xFF
|
||||
&& buffer[i + 1] >= 0xF0) // 0xFFF
|
||||
try {
|
||||
BitStream bits = new BitStream (buffer.Mid (i, 7).Data);
|
||||
|
||||
// 12 bits sync header
|
||||
bits.ReadInt32 (12);
|
||||
|
||||
// 1 bit mpeg 2/4
|
||||
bits.ReadInt32 (1);
|
||||
|
||||
// 2 bits layer
|
||||
bits.ReadInt32 (2);
|
||||
|
||||
// 1 bit protection absent
|
||||
bits.ReadInt32 (1);
|
||||
|
||||
// 2 bits profile object type
|
||||
bits.ReadInt32 (2);
|
||||
|
||||
// 4 bits sampling frequency index
|
||||
int samplerateindex = bits.ReadInt32 (4);
|
||||
if (samplerateindex >= sample_rates.Length)
|
||||
return false;
|
||||
long samplerate = sample_rates[samplerateindex];
|
||||
|
||||
// 1 bit private bit
|
||||
bits.ReadInt32 (1);
|
||||
|
||||
// 3 bits channel configuration
|
||||
int channelconfigindex = bits.ReadInt32 (3);
|
||||
if (channelconfigindex >= channels.Length)
|
||||
return false;
|
||||
|
||||
// 4 copyright bits
|
||||
bits.ReadInt32 (4);
|
||||
|
||||
// 13 bits frame length
|
||||
long framelength = bits.ReadInt32 (13); // double check framelength
|
||||
if (framelength < 7)
|
||||
return false;
|
||||
|
||||
// 11 bits buffer fullness
|
||||
bits.ReadInt32 (11);
|
||||
|
||||
// 2 bits number of raw data blocks in frame
|
||||
int numberofframes = bits.ReadInt32 (2) + 1;
|
||||
|
||||
long numberofsamples = numberofframes * 1024;
|
||||
long bitrate = framelength * 8 * samplerate / numberofsamples;
|
||||
|
||||
header = new AudioHeader (channels[channelconfigindex],
|
||||
(int)bitrate,
|
||||
(int)samplerate,
|
||||
(int)numberofsamples,
|
||||
numberofframes);
|
||||
|
||||
return true;
|
||||
} catch (CorruptFileException) {
|
||||
}
|
||||
|
||||
position += TagLib.File.BufferSize;
|
||||
} while (buffer.Count > 3 && (length < 0 || position < end));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for an audio header in a <see cref="TagLib.File"
|
||||
/// /> starting at a specified position and searching to the
|
||||
/// end of the file.
|
||||
/// </summary>
|
||||
/// <param name="header">
|
||||
/// A <see cref="AudioHeader" /> object in which the found
|
||||
/// header will be stored.
|
||||
/// </param>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object to search.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specifying the seek position
|
||||
/// in <paramref name="file" /> at which to start searching.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not a
|
||||
/// header was found.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Searching to the end of the file can be very, very slow
|
||||
/// especially for corrupt or non-MPEG files. It is
|
||||
/// recommended to use <see
|
||||
/// cref="M:AudioHeader.Find(AudioHeader,TagLib.File,long,int)" />
|
||||
/// instead.
|
||||
/// </remarks>
|
||||
public static bool Find (out AudioHeader header, TagLib.File file, long position)
|
||||
{
|
||||
return Find (out header, file, position, -1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a70f4e38ac189d2389cf4717f5a1869a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// BitStream.cs: Helper to read bits from a byte array.
|
||||
//
|
||||
// Copyright (C) 2009 Patrick Dehne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version
|
||||
// 2.1 as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TagLib.Aac
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to help reading arbitary number of bits from
|
||||
/// a fixed array of bytes
|
||||
/// </summary>
|
||||
public class BitStream
|
||||
{
|
||||
readonly BitArray bits;
|
||||
int bitindex;
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new <see cref="BitStream"/>.
|
||||
/// </summary>
|
||||
/// <param name="buffer">
|
||||
/// A <see cref="T:System.Byte[]"/>, must be 7 bytes long.
|
||||
/// </param>
|
||||
public BitStream (byte[] buffer)
|
||||
{
|
||||
Debug.Assert (buffer.Length == 7, "buffer.Length == 7", "buffer size invalid");
|
||||
|
||||
if (buffer.Length != 7)
|
||||
throw new ArgumentException ("Buffer size must be 7 bytes");
|
||||
|
||||
// Reverse bits
|
||||
bits = new BitArray (buffer.Length * 8);
|
||||
for (int i = 0; i < buffer.Length; i++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
bits[i * 8 + y] = ((buffer[i] & (1 << (7 - y))) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
bitindex = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Reads an Int32 from the bitstream
|
||||
/// </summary>
|
||||
/// <param name="numberOfBits">
|
||||
/// A <see cref="int" /> value containing the number
|
||||
/// of bits to read from the bitstream
|
||||
/// </param>
|
||||
public int ReadInt32 (int numberOfBits)
|
||||
{
|
||||
Debug.Assert (numberOfBits > 0, "numberOfBits < 1");
|
||||
Debug.Assert (numberOfBits <= 32, "numberOfBits <= 32");
|
||||
|
||||
if (numberOfBits <= 0)
|
||||
throw new ArgumentException ("Number of bits to read must be >= 1");
|
||||
|
||||
if (numberOfBits > 32)
|
||||
throw new ArgumentException ("Number of bits to read must be <= 32");
|
||||
|
||||
int value = 0;
|
||||
int start = bitindex + numberOfBits - 1;
|
||||
for (int i = 0; i < numberOfBits; i++) {
|
||||
value += bits[start] ? (1 << i) : 0;
|
||||
bitindex++;
|
||||
start--;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8284bad068f4283f29df4c52751a79cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// File.cs: Provides tagging and properties support for ADTS AAC files
|
||||
//
|
||||
// Here is the ADTS Header description used for implementation:
|
||||
// http://www.hydrogenaudio.org/forums/lofiversion/index.php/t21617.html
|
||||
//
|
||||
// Copyright (C) 2009 Patrick Dehne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version
|
||||
// 2.1 as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace TagLib.Aac
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="TagLib.NonContainer.File" /> to
|
||||
/// provide tagging and properties support for ADTS AAC audio files.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A <see cref="TagLib.Id3v1.Tag" /> and <see
|
||||
/// cref="TagLib.Id3v2.Tag" /> will be added automatically to any
|
||||
/// file that doesn't contain one. This change does not effect the
|
||||
/// file until it is saved and can be reversed using the following
|
||||
/// method:
|
||||
/// <code>file.RemoveTags (file.TagTypes & ~file.TagTypesOnDisk);</code>
|
||||
/// </remarks>
|
||||
[SupportedMimeType ("taglib/aac", "aac")]
|
||||
[SupportedMimeType ("audio/aac")]
|
||||
public class File : TagLib.NonContainer.File
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the first audio header.
|
||||
/// </summary>
|
||||
AudioHeader first_header;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified path in the local
|
||||
/// file system and specified read style.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// A <see cref="string" /> object containing the path of the
|
||||
/// file to use in the new instance.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="path" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
public File (string path, ReadStyle propertiesStyle)
|
||||
: base (path, propertiesStyle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified path in the local
|
||||
/// file system with an average read style.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// A <see cref="string" /> object containing the path of the
|
||||
/// file to use in the new instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="path" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
public File (string path) : base (path)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified file abstraction and
|
||||
/// specified read style.
|
||||
/// </summary>
|
||||
/// <param name="abstraction">
|
||||
/// A <see cref="TagLib.File.IFileAbstraction" /> object to use when
|
||||
/// reading from and writing to the file.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="abstraction" /> is <see langword="null"
|
||||
/// />.
|
||||
/// </exception>
|
||||
public File (IFileAbstraction abstraction, ReadStyle propertiesStyle)
|
||||
: base (abstraction, propertiesStyle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified file abstraction with
|
||||
/// an average read style.
|
||||
/// </summary>
|
||||
/// <param name="abstraction">
|
||||
/// A <see cref="TagLib.File.IFileAbstraction" /> object to use when
|
||||
/// reading from and writing to the file.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="abstraction" /> is <see langword="null"
|
||||
/// />.
|
||||
/// </exception>
|
||||
public File (IFileAbstraction abstraction)
|
||||
: base (abstraction)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a tag of a specified type from the current instance,
|
||||
/// optionally creating a new tag if possible.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// A <see cref="TagLib.TagTypes" /> value indicating the
|
||||
/// type of tag to read.
|
||||
/// </param>
|
||||
/// <param name="create">
|
||||
/// A <see cref="bool" /> value specifying whether or not to
|
||||
/// try and create the tag if one is not found.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="Tag" /> object containing the tag that was
|
||||
/// found in or added to the current instance. If no
|
||||
/// matching tag was found and none was created, <see
|
||||
/// langword="null" /> is returned.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// If a <see cref="TagLib.Id3v2.Tag" /> is added to the
|
||||
/// current instance, it will be placed at the start of the
|
||||
/// file. On the other hand, <see cref="TagLib.Id3v1.Tag" />
|
||||
/// <see cref="TagLib.Ape.Tag" /> will be added to the end of
|
||||
/// the file. All other tag types will be ignored.
|
||||
/// </remarks>
|
||||
public override Tag GetTag (TagTypes type, bool create)
|
||||
{
|
||||
Tag t = (Tag as TagLib.NonContainer.Tag).GetTag (type);
|
||||
|
||||
if (t != null || !create)
|
||||
return t;
|
||||
|
||||
switch (type) {
|
||||
case TagTypes.Id3v1:
|
||||
return EndTag.AddTag (type, Tag);
|
||||
|
||||
case TagTypes.Id3v2:
|
||||
return StartTag.AddTag (type, Tag);
|
||||
|
||||
case TagTypes.Ape:
|
||||
return EndTag.AddTag (type, Tag);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Reads format specific information at the start of the
|
||||
/// file.
|
||||
/// </summary>
|
||||
/// <param name="start">
|
||||
/// A <see cref="long" /> value containing the seek position
|
||||
/// at which the tags end and the media data begins.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// This method only searches for an audio header in the
|
||||
/// first 16384 bytes of code to avoid searching forever in
|
||||
/// corrupt files.
|
||||
/// </remarks>
|
||||
protected override void ReadStart (long start, ReadStyle propertiesStyle)
|
||||
{
|
||||
// Only check the first 16 bytes so we're not stuck
|
||||
// reading a bad file forever.
|
||||
if ((propertiesStyle & ReadStyle.Average) != 0 &&
|
||||
!AudioHeader.Find (out first_header, this, start, 0x4000))
|
||||
throw new CorruptFileException ("ADTS audio header not found.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads format specific information at the end of the
|
||||
/// file.
|
||||
/// </summary>
|
||||
/// <param name="end">
|
||||
/// A <see cref="long" /> value containing the seek position
|
||||
/// at which the media data ends and the tags begin.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
protected override void ReadEnd (long end, ReadStyle propertiesStyle)
|
||||
{
|
||||
// Make sure we have ID3v1 and ID3v2 tags.
|
||||
GetTag (TagTypes.Id3v1, true);
|
||||
GetTag (TagTypes.Id3v2, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the audio properties from the file represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <param name="start">
|
||||
/// A <see cref="long" /> value containing the seek position
|
||||
/// at which the tags end and the media data begins.
|
||||
/// </param>
|
||||
/// <param name="end">
|
||||
/// A <see cref="long" /> value containing the seek position
|
||||
/// at which the media data ends and the tags begin.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="TagLib.Properties" /> object describing the
|
||||
/// media properties of the file represented by the current
|
||||
/// instance.
|
||||
/// </returns>
|
||||
protected override Properties ReadProperties (long start, long end, ReadStyle propertiesStyle)
|
||||
{
|
||||
first_header.SetStreamLength (end - start);
|
||||
return new Properties (TimeSpan.Zero, first_header);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ea5a2b9978c53a708489187d4f05f90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user