Initial commit
This commit is contained in:
commit
262601edb8
2025 files changed
+218754
No files matched your search
@@ -0,0 +1,287 @@
|
||||
//
|
||||
// AviHeaderList.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Generic;
|
||||
|
||||
namespace TagLib.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class provides support for reading an AVI header list to
|
||||
/// extract stream information.
|
||||
/// </summary>
|
||||
public class AviHeaderList
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Contains the AVI codec information.
|
||||
/// </summary>
|
||||
readonly List<ICodec> codecs = new List<ICodec> ();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AviHeaderList" /> by reading the contents of a raw
|
||||
/// RIFF list from a specified position in a <see
|
||||
/// cref="TagLib.File"/>.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object containing the file
|
||||
/// from which the contents of the new instance is to be
|
||||
/// read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the list.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the number of bytes
|
||||
/// to read.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The list does not contain an AVI header or the AVI header
|
||||
/// is the wrong length.
|
||||
/// </exception>
|
||||
public AviHeaderList (TagLib.File file, long position, int length)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
|
||||
if (length < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (length));
|
||||
|
||||
if (position < 0 || position > file.Length - length)
|
||||
throw new ArgumentOutOfRangeException (nameof (position));
|
||||
|
||||
List list = new List (file, position, length);
|
||||
|
||||
if (!list.ContainsKey ("avih"))
|
||||
throw new CorruptFileException ("Avi header not found.");
|
||||
|
||||
ByteVector header_data = list["avih"][0];
|
||||
if (header_data.Count != 0x38)
|
||||
throw new CorruptFileException ("Invalid header length.");
|
||||
|
||||
Header = new AviHeader (header_data, 0);
|
||||
|
||||
foreach (ByteVector list_data in list["LIST"]) {
|
||||
if (list_data.StartsWith ("strl")) {
|
||||
AviStream stream = AviStream.ParseStreamList (list_data);
|
||||
if (stream != null)
|
||||
codecs.Add (stream.Codec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the header for the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="AviHeader" /> object containing the header
|
||||
/// for the current instance.
|
||||
/// </value>
|
||||
public AviHeader Header { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the codecs contained in the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:ICodec[]" /> containing the codecs contained
|
||||
/// in the current instance.
|
||||
/// </value>
|
||||
public ICodec[] Codecs {
|
||||
get { return codecs.ToArray (); }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This structure provides a representation of a Microsoft
|
||||
/// AviMainHeader structure, minus the first 8 bytes.
|
||||
/// </summary>
|
||||
public struct AviHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AviHeader" /> by reading the raw structure from the
|
||||
/// beginning of a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 40 bytes.
|
||||
/// </exception>
|
||||
[Obsolete ("Use AviHeader(ByteVector,int)")]
|
||||
public AviHeader (ByteVector data) : this (data, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AviStreamHeader" /> by reading the raw structure
|
||||
/// from a specified position in a <see cref="ByteVector" />
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// A <see cref="int" /> value specifying the index in
|
||||
/// <paramref name="data"/> at which the structure begins.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="offset" /> is less than zero.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 40 bytes at
|
||||
/// <paramref name="offset" />.
|
||||
/// </exception>
|
||||
public AviHeader (ByteVector data, int offset)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (offset));
|
||||
|
||||
if (offset + 40 > data.Count)
|
||||
throw new CorruptFileException ("Expected 40 bytes.");
|
||||
|
||||
MicrosecondsPerFrame = data.Mid (offset, 4).ToUInt (false);
|
||||
MaxBytesPerSecond = data.Mid (offset + 4, 4).ToUInt (false);
|
||||
Flags = data.Mid (offset + 12, 4).ToUInt (false);
|
||||
TotalFrames = data.Mid (offset + 16, 4).ToUInt (false);
|
||||
InitialFrames = data.Mid (offset + 20, 4).ToUInt (false);
|
||||
Streams = data.Mid (offset + 24, 4).ToUInt (false);
|
||||
SuggestedBufferSize = data.Mid (offset + 28, 4).ToUInt (false);
|
||||
Width = data.Mid (offset + 32, 4).ToUInt (false);
|
||||
Height = data.Mid (offset + 36, 4).ToUInt (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of microseconds per frame.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying number of
|
||||
/// microseconds per frame.
|
||||
/// </value>
|
||||
public uint MicrosecondsPerFrame { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum number of bytes per second.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying maximum number of
|
||||
/// bytes per second.
|
||||
/// </value>
|
||||
public uint MaxBytesPerSecond { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file flags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying file flags.
|
||||
/// </value>
|
||||
public uint Flags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of frames in the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the number of
|
||||
/// frames in the file.
|
||||
/// </value>
|
||||
public uint TotalFrames { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets how far ahead audio is from video.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying how far ahead
|
||||
/// audio is from video.
|
||||
/// </value>
|
||||
public uint InitialFrames { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of streams in the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the number of
|
||||
/// streams in the file.
|
||||
/// </value>
|
||||
public uint Streams { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the suggested buffer size for the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the buffer size.
|
||||
/// </value>
|
||||
public uint SuggestedBufferSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the video in the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the width of the
|
||||
/// video.
|
||||
/// </value>
|
||||
public uint Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height of the video in the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the height of the
|
||||
/// video.
|
||||
/// </value>
|
||||
public uint Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the media in the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TimeSpan" /> value containing the duration
|
||||
/// of the file.
|
||||
/// </value>
|
||||
public TimeSpan Duration {
|
||||
get {
|
||||
return TimeSpan.FromMilliseconds (TotalFrames * (double)MicrosecondsPerFrame / 1000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6e2f945ab4b69792bad77daa3649ff8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,458 @@
|
||||
//
|
||||
// AviStream.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This abstract class provides basic support for parsing a raw AVI
|
||||
/// stream list.
|
||||
/// </summary>
|
||||
public abstract class AviStream
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and intializes a new instance of <see
|
||||
/// cref="AviStream" /> with a specified stream header.
|
||||
/// </summary>
|
||||
/// <param name="header">
|
||||
/// A <see cref="AviStreamHeader"/> object containing the
|
||||
/// stream's header.
|
||||
/// </param>
|
||||
protected AviStream (AviStreamHeader header)
|
||||
{
|
||||
Header = header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a stream list item.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// ID.
|
||||
/// </param>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// data.
|
||||
/// </param>
|
||||
/// <param name="start">
|
||||
/// A <see cref="uint" /> value specifying the index in
|
||||
/// <paramref name="data" /> at which the item data begins.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="uint" /> value specifying the length of the
|
||||
/// item.
|
||||
/// </param>
|
||||
public virtual void ParseItem (ByteVector id, ByteVector data, int start, int length)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream header.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="AviStreamHeader" /> object containing the
|
||||
/// header information for the stream.
|
||||
/// </value>
|
||||
public AviStreamHeader Header { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the codec information.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ICodec" /> object containing the codec
|
||||
/// information for the stream.
|
||||
/// </value>
|
||||
public ICodec Codec { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parses a raw AVI stream list and returns the stream
|
||||
/// information.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing raw stream
|
||||
/// list.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="AviStream" /> object containing stream
|
||||
/// information.
|
||||
/// </returns>
|
||||
public static AviStream ParseStreamList (ByteVector data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (!data.StartsWith ("strl"))
|
||||
return null;
|
||||
|
||||
AviStream stream = null;
|
||||
int pos = 4;
|
||||
|
||||
while (pos + 8 < data.Count) {
|
||||
ByteVector id = data.Mid (pos, 4);
|
||||
int block_length = (int)data.Mid (pos + 4, 4).ToUInt (false);
|
||||
|
||||
if (id == "strh" && stream == null) {
|
||||
var stream_header = new AviStreamHeader (data, pos + 8);
|
||||
if (stream_header.Type == "vids")
|
||||
stream = new AviVideoStream (stream_header);
|
||||
else if (stream_header.Type == "auds")
|
||||
stream = new AviAudioStream (stream_header);
|
||||
} else if (stream != null) {
|
||||
stream.ParseItem (id, data, pos + 8, block_length);
|
||||
}
|
||||
|
||||
pos += block_length + 8;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class extends <see cref="AviStream" /> to provide support
|
||||
/// for reading audio stream data.
|
||||
/// </summary>
|
||||
public class AviAudioStream : AviStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs and intializes a new instance of <see
|
||||
/// cref="AviAudioStream" /> with a specified stream header.
|
||||
/// </summary>
|
||||
/// <param name="header">
|
||||
/// A <see cref="AviStreamHeader"/> object containing the
|
||||
/// stream's header.
|
||||
/// </param>
|
||||
public AviAudioStream (AviStreamHeader header)
|
||||
: base (header)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a stream list item.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// ID.
|
||||
/// </param>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// data.
|
||||
/// </param>
|
||||
/// <param name="start">
|
||||
/// A <see cref="uint" /> value specifying the index in
|
||||
/// <paramref name="data" /> at which the item data begins.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="uint" /> value specifying the length of the
|
||||
/// item.
|
||||
/// </param>
|
||||
public override void ParseItem (ByteVector id, ByteVector data, int start, int length)
|
||||
{
|
||||
if (id == "strf")
|
||||
Codec = new WaveFormatEx (data, start);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class extends <see cref="AviStream" /> to provide support
|
||||
/// for reading video stream data.
|
||||
/// </summary>
|
||||
public class AviVideoStream : AviStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs and intializes a new instance of <see
|
||||
/// cref="AviVideoStream" /> with a specified stream header.
|
||||
/// </summary>
|
||||
/// <param name="header">
|
||||
/// A <see cref="AviStreamHeader"/> object containing the
|
||||
/// stream's header.
|
||||
/// </param>
|
||||
public AviVideoStream (AviStreamHeader header)
|
||||
: base (header)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a stream list item.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// ID.
|
||||
/// </param>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the item's
|
||||
/// data.
|
||||
/// </param>
|
||||
/// <param name="start">
|
||||
/// A <see cref="uint" /> value specifying the index in
|
||||
/// <paramref name="data" /> at which the item data begins.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="uint" /> value specifying the length of the
|
||||
/// item.
|
||||
/// </param>
|
||||
public override void ParseItem (ByteVector id, ByteVector data, int start, int length)
|
||||
{
|
||||
if (id == "strf")
|
||||
Codec = new BitmapInfoHeader (data, start);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This structure provides a representation of a Microsoft
|
||||
/// AviStreamHeader structure, minus the first 8 bytes.
|
||||
/// </summary>
|
||||
public struct AviStreamHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AviStreamHeader" /> by reading the raw structure
|
||||
/// from the beginning of a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 56 bytes.
|
||||
/// </exception>
|
||||
[Obsolete ("Use WaveFormatEx(ByteVector,int)")]
|
||||
public AviStreamHeader (ByteVector data) : this (data, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="AviStreamHeader" /> by reading the raw structure
|
||||
/// from a specified position in a <see cref="ByteVector" />
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// A <see cref="int" /> value specifying the index in
|
||||
/// <paramref name="data"/> at which the structure begins.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="offset" /> is less than zero.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 56 bytes at
|
||||
/// <paramref name="offset" />.
|
||||
/// </exception>
|
||||
public AviStreamHeader (ByteVector data, int offset)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (offset));
|
||||
|
||||
if (offset + 56 > data.Count)
|
||||
throw new CorruptFileException ("Expected 56 bytes.");
|
||||
|
||||
Type = data.Mid (offset, 4);
|
||||
Handler = data.Mid (offset + 4, 4);
|
||||
Flags = data.Mid (offset + 8, 4).ToUInt (false);
|
||||
Priority = data.Mid (offset + 12, 4).ToUInt (false);
|
||||
InitialFrames = data.Mid (offset + 16, 4).ToUInt (false);
|
||||
Scale = data.Mid (offset + 20, 4).ToUInt (false);
|
||||
Rate = data.Mid (offset + 24, 4).ToUInt (false);
|
||||
Start = data.Mid (offset + 28, 4).ToUInt (false);
|
||||
Length = data.Mid (offset + 32, 4).ToUInt (false);
|
||||
SuggestedBufferSize = data.Mid (offset + 36, 4).ToUInt (false);
|
||||
Quality = data.Mid (offset + 40, 4).ToUInt (false);
|
||||
SampleSize = data.Mid (offset + 44, 4).ToUInt (false);
|
||||
Left = data.Mid (offset + 48, 2).ToUShort (false);
|
||||
Top = data.Mid (offset + 50, 2).ToUShort (false);
|
||||
Right = data.Mid (offset + 52, 2).ToUShort (false);
|
||||
Bottom = data.Mid (offset + 54, 2).ToUShort (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream type.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A four-byte <see cref="ByteVector" /> object specifying
|
||||
/// stream type.
|
||||
/// </value>
|
||||
public ByteVector Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream handler (codec) ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A four-byte <see cref="ByteVector" /> object specifying
|
||||
/// stream handler ID.
|
||||
/// </value>
|
||||
public ByteVector Handler { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream flags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying stream flags.
|
||||
/// </value>
|
||||
public uint Flags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream priority.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying stream priority.
|
||||
/// </value>
|
||||
public uint Priority { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets how far ahead audio is from video.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying how far ahead
|
||||
/// audio is from video.
|
||||
/// </value>
|
||||
public uint InitialFrames { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale of the stream.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the scale of the
|
||||
/// stream.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// Dividing <see cref="Rate"/> by <see cref="Scale" /> gives
|
||||
/// the number of samples per second.
|
||||
/// </remarks>
|
||||
public uint Scale { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rate of the stream.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the rate of the
|
||||
/// stream.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// Dividing <see cref="Rate"/> by <see cref="Scale" /> gives
|
||||
/// the number of samples per second.
|
||||
/// </remarks>
|
||||
public uint Rate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start delay of the stream.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the start delay of
|
||||
/// the stream.
|
||||
/// </value>
|
||||
public uint Start { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the stream.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the length of the
|
||||
/// stream.
|
||||
/// </value>
|
||||
public uint Length { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the suggested buffer size for the stream.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the buffer size.
|
||||
/// </value>
|
||||
public uint SuggestedBufferSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the quality of the stream data.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the quality of the
|
||||
/// stream data between 0 and 10,000.
|
||||
/// </value>
|
||||
public uint Quality { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sample size of the stream data.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value specifying the sample size.
|
||||
/// </value>
|
||||
public uint SampleSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position at which the left of the video is to
|
||||
/// be displayed in the rectangle whose width is given in the
|
||||
/// the file's <see cref="AviHeader"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value specifying the left
|
||||
/// position.
|
||||
/// </value>
|
||||
public ushort Left { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position at which the top of the video is to be
|
||||
/// displayed in the rectangle whose height is given in the
|
||||
/// the file's <see cref="AviHeader"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value specifying the top
|
||||
/// position.
|
||||
/// </value>
|
||||
public ushort Top { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position at which the right of the video is to
|
||||
/// be displayed in the rectangle whose width is given in the
|
||||
/// the file's <see cref="AviHeader"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value specifying the right
|
||||
/// position.
|
||||
/// </value>
|
||||
public ushort Right { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position at which the bottom of the video is
|
||||
/// to be displayed in the rectangle whose height is given in
|
||||
/// the file's <see cref="AviHeader"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value specifying the bottom
|
||||
/// position.
|
||||
/// </value>
|
||||
public ushort Bottom { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eedf8b2276ea9a00a824c1315ce11965
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,783 @@
|
||||
//
|
||||
// BitmapInfoHeader.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Globalization;
|
||||
|
||||
namespace TagLib.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This structure provides a representation of a Microsoft
|
||||
/// BitmapInfoHeader structure.
|
||||
/// </summary>
|
||||
public struct BitmapInfoHeader : IVideoCodec
|
||||
{
|
||||
#region Private Fields
|
||||
/// <summary>
|
||||
/// Contains the video width.
|
||||
/// </summary>
|
||||
readonly uint width;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the video height.
|
||||
/// </summary>
|
||||
readonly uint height;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="BitmapInfoHeader" /> by reading the raw structure
|
||||
/// from the beginning of a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 40 bytes.
|
||||
/// </exception>
|
||||
[Obsolete ("Use BitmapInfoHeader(ByteVector,int)")]
|
||||
public BitmapInfoHeader (ByteVector data) : this (data, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="BitmapInfoHeader" /> by reading the raw structure
|
||||
/// from a specified position in a <see cref="ByteVector" />
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// A <see cref="int" /> value specifying the index in
|
||||
/// <paramref name="data"/> at which the structure begins.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="offset" /> is less than zero.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 16 bytes at
|
||||
/// <paramref name="offset" />.
|
||||
/// </exception>
|
||||
public BitmapInfoHeader (ByteVector data, int offset)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (offset + 40 > data.Count)
|
||||
throw new CorruptFileException ("Expected 40 bytes.");
|
||||
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (offset));
|
||||
|
||||
HeaderSize = data.Mid (offset + 0, 4).ToUInt (false);
|
||||
width = data.Mid (offset + 4, 4).ToUInt (false);
|
||||
height = data.Mid (offset + 8, 4).ToUInt (false);
|
||||
Planes = data.Mid (offset + 12, 2).ToUShort (false);
|
||||
BitCount = data.Mid (offset + 14, 2).ToUShort (false);
|
||||
CompressionId = data.Mid (offset + 16, 4);
|
||||
ImageSize = data.Mid (offset + 20, 4).ToUInt (false);
|
||||
XPixelsPerMeter = data.Mid (offset + 24, 4).ToUInt (false);
|
||||
YPixelsPerMeter = data.Mid (offset + 28, 4).ToUInt (false);
|
||||
ColorsUsed = data.Mid (offset + 32, 4).ToUInt (false);
|
||||
ImportantColors = data.Mid (offset + 36, 4).ToUInt (false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the structure in bytes.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// bytes in the structure.
|
||||
/// </value>
|
||||
public uint HeaderSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of planes in the image.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value containing the number of
|
||||
/// planes.
|
||||
/// </value>
|
||||
public ushort Planes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of bits per pixel.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ushort" /> value containing the number of
|
||||
/// bits per pixel, equivalent to the log base 2 of the
|
||||
/// maximum number of colors.
|
||||
/// </value>
|
||||
public ushort BitCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the compression ID for image.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A four-byte <see cref="ByteVector" /> object containing
|
||||
/// the ID of the compression system (codec) used by the
|
||||
/// image.
|
||||
/// </value>
|
||||
public ByteVector CompressionId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the image in bytes.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// bytes in the image.
|
||||
/// </value>
|
||||
public uint ImageSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the horizontal resolution of the target device.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// pixels-per-meter in the hoizontal direction for the
|
||||
/// target device.
|
||||
/// </value>
|
||||
public uint XPixelsPerMeter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertical resolution of the target device.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// pixels-per-meter in the vertical direction for the
|
||||
/// target device.
|
||||
/// </value>
|
||||
public uint YPixelsPerMeter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of colors in the image.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// colors.
|
||||
/// </value>
|
||||
public uint ColorsUsed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of colors important in displaying the
|
||||
/// image.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> value containing the number of
|
||||
/// important colors.
|
||||
/// </value>
|
||||
public uint ImportantColors { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region IVideoCodec
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the video represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="int" /> value containing the width of the
|
||||
/// video represented by the current instance.
|
||||
/// </value>
|
||||
public int VideoWidth {
|
||||
get { return (int)width; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height of the video represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="int" /> value containing the height of the
|
||||
/// video represented by the current instance.
|
||||
/// </value>
|
||||
public int VideoHeight {
|
||||
get { return (int)height; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the types of media represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="MediaTypes.Video" />.
|
||||
/// </value>
|
||||
public MediaTypes MediaTypes {
|
||||
get { return MediaTypes.Video; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the media represented by the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="TimeSpan.Zero" />.
|
||||
/// </value>
|
||||
public TimeSpan Duration {
|
||||
get { return TimeSpan.Zero; }
|
||||
}
|
||||
|
||||
/// <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 {
|
||||
string id = CompressionId.ToString (StringType.UTF8).ToUpper (CultureInfo.InvariantCulture);
|
||||
|
||||
switch (id) {
|
||||
case "AEMI":
|
||||
return "Array VideoONE MPEG1-I capture";
|
||||
case "ALPH":
|
||||
return "Ziracom Video";
|
||||
case "AMPG":
|
||||
return "Array VideoONE capture/compression";
|
||||
case "ANIM":
|
||||
return "Intel RDX";
|
||||
case "AP41":
|
||||
return "Microsoft Corporation Video";
|
||||
case "AUR2":
|
||||
return "AuraVision Aura 2 codec";
|
||||
case "AURA":
|
||||
return "AuraVision Aura 1 codec";
|
||||
case "AUVX":
|
||||
return "USH GmbH AUVX video codec";
|
||||
case "BT20":
|
||||
return "Brooktree MediaStream codec";
|
||||
case "BTCV":
|
||||
return "Brooktree composite video codec";
|
||||
case "CC12":
|
||||
return "Intel YUV12 codec";
|
||||
case "CDVC":
|
||||
return "Canopus DV codec";
|
||||
case "CGDI":
|
||||
return "Microsoft CamCorder in Office 97 (screen capture codec)";
|
||||
case "CHAM":
|
||||
return "Winnov Caviara Champagne";
|
||||
case "CM10":
|
||||
return "CyberLink Corporation MediaShow 1.0";
|
||||
case "CPLA":
|
||||
return "Weitek 4:2:0 YUV planar";
|
||||
case "CT10":
|
||||
return "CyberLink Corporation TalkingShow 1.0";
|
||||
case "CVID":
|
||||
return "Cinepak by SuperMac";
|
||||
case "CWLT":
|
||||
return "Microsoft Corporation Video";
|
||||
case "CYUV":
|
||||
return "Creative Labs YUV";
|
||||
case "DIV3":
|
||||
case "MP43":
|
||||
return "Microsoft MPEG-4 Version 3 Video";
|
||||
case "DIV4":
|
||||
return "Microsoft Corporation Video";
|
||||
case "DIVX":
|
||||
return "DivX Video";
|
||||
case "DJPG":
|
||||
return "Broadway 101 Motion JPEG codec";
|
||||
case "DP16":
|
||||
return "YUV411 with DPCM 6-bit compression";
|
||||
case "DP18":
|
||||
return "YUV411 with DPCM 8-bit compression";
|
||||
case "DP26":
|
||||
return "YUV422 with DPCM 6-bit compression";
|
||||
case "DP28":
|
||||
return "YUV422 with DPCM 8-bit compression";
|
||||
case "DP96":
|
||||
return "YVU9 with DPCM 6-bit compression";
|
||||
case "DP98":
|
||||
return "YVU9 with DPCM 8-bit compression";
|
||||
case "DP9L":
|
||||
return "YVU9 with DPCM 6-bit compression and thinned-out";
|
||||
case "DUCK":
|
||||
return "The Duck Corporation TrueMotion 1.0";
|
||||
case "DV25":
|
||||
return "SMPTE 314M 25Mb/s compressed";
|
||||
case "DV50":
|
||||
return "SMPTE 314M 50Mb/s compressed";
|
||||
case "DVE2":
|
||||
return "DVE-2 videoconferencing codec";
|
||||
case "DVH1":
|
||||
return "DVC Pro HD";
|
||||
case "DVHD":
|
||||
return "DV data as defined in Part 3 of the Specification of Consumer-use Digital VCRs";
|
||||
case "DVNM":
|
||||
return "Matsushita Electric Industrial Co., Ltd. Video";
|
||||
case "DVSD":
|
||||
return "DV data as defined in Part 2 of the Specification of Consumer-use Digital VCRs";
|
||||
case "DVSL":
|
||||
return "DV data as defined in Part 6 of Specification of Consumer-use Digital VCRs";
|
||||
case "DVX1":
|
||||
return "Lucent DVX1000SP video decoder.";
|
||||
case "DVX2":
|
||||
return "Lucent DVX2000S video decoder";
|
||||
case "DVX3":
|
||||
return "Lucent DVX3000S video decoder";
|
||||
case "DXTC":
|
||||
return "DirectX texture compression";
|
||||
case "DX50":
|
||||
return "DivX Version 5 Video";
|
||||
case "EMWC":
|
||||
return "EverAd Marquee WMA codec";
|
||||
case "ETV1":
|
||||
case "ETV2":
|
||||
case "ETVC":
|
||||
return "eTreppid video codec";
|
||||
case "FLJP":
|
||||
return "Field-encoded motion JPEG with LSI bitstream format";
|
||||
case "FRWA":
|
||||
return "Softlab-Nsk Ltd. Forward alpha";
|
||||
case "FRWD":
|
||||
return "Softlab-Nsk Ltd. Forward JPEG";
|
||||
case "FRWT":
|
||||
return "Softlab-Nsk Ltd. Forward JPEG+alpha";
|
||||
case "FVF1":
|
||||
return "Iterated Systems, Inc. Fractal video frame";
|
||||
case "FXT1":
|
||||
return "3dfx Interactive, Inc. Video";
|
||||
case "GWLT":
|
||||
return "Microsoft Corporation Video";
|
||||
case "H260":
|
||||
case "H261":
|
||||
case "H262":
|
||||
case "H263":
|
||||
case "H264":
|
||||
case "H265":
|
||||
case "H266":
|
||||
case "H267":
|
||||
case "H268":
|
||||
case "H269":
|
||||
return "Intel " + CompressionId.ToString (StringType.UTF8) + " Conferencing codec";
|
||||
case "I263":
|
||||
return "Intel I263";
|
||||
case "I420":
|
||||
return "Intel Indeo 4 codec";
|
||||
case "IAN":
|
||||
return "Intel RDX";
|
||||
case "ICLB":
|
||||
return "InSoft, Inc. CellB videoconferencing codec";
|
||||
case "IFO9":
|
||||
return "Intel intermediate YUV9";
|
||||
case "ILVC":
|
||||
return "Intel layered Video";
|
||||
case "ILVR":
|
||||
return "ITU-T's H.263+ compression standard";
|
||||
case "IMAC":
|
||||
return "Intel hardware motion compensation";
|
||||
case "IPDV":
|
||||
return "IEEE 1394 digital video control and capture board format";
|
||||
case "IRAW":
|
||||
return "Intel YUV uncompressed";
|
||||
case "ISME":
|
||||
return "Intel's next-generation video codec";
|
||||
case "IUYV":
|
||||
return "UYVY interlaced (even, then odd lines)";
|
||||
case "IV30":
|
||||
case "IV31":
|
||||
case "IV32":
|
||||
case "IV33":
|
||||
case "IV34":
|
||||
case "IV35":
|
||||
case "IV36":
|
||||
case "IV37":
|
||||
case "IV38":
|
||||
case "IV39":
|
||||
return "Intel Indeo Video Version 3";
|
||||
case "IV40":
|
||||
case "IV41":
|
||||
case "IV42":
|
||||
case "IV43":
|
||||
case "IV44":
|
||||
case "IV45":
|
||||
case "IV46":
|
||||
case "IV47":
|
||||
case "IV48":
|
||||
case "IV49":
|
||||
return "Intel Indeo Video Version 4";
|
||||
case "IV50":
|
||||
return "Intel Indeo Video Version 5";
|
||||
case "IY41":
|
||||
return "LEAD Technologies, Inc. Y41P interlaced (even, then odd lines)";
|
||||
case "IYU1":
|
||||
return "IEEE 1394 Digital Camera 1.04 Specification: mode 2, 12-bit YUV (4:1:1)";
|
||||
case "IYU2":
|
||||
return "IEEE 1394 Digital Camera 1.04 Specification: mode 2, 24 bit YUV (4:4:4)";
|
||||
case "JPEG":
|
||||
return "Microsoft Corporation Still image JPEG DIB.";
|
||||
case "LEAD":
|
||||
return "LEAD Technologies, Inc. Proprietary MCMP compression";
|
||||
case "LIA1":
|
||||
return "Liafail";
|
||||
case "LJPG":
|
||||
return "LEAD Technologies, Inc. Lossless JPEG compression";
|
||||
case "LSV0":
|
||||
return "Infinop Inc. Video";
|
||||
case "LSVC":
|
||||
return "Infinop Lightning Strike constant bit rate video codec";
|
||||
case "LSVW":
|
||||
return "Infinop Lightning Strike multiple bit rate video codec";
|
||||
case "M101":
|
||||
return "Matrox Electronic Systems, Ltd. Uncompressed field-based YUY2";
|
||||
case "M4S2":
|
||||
return "Microsoft ISO MPEG-4 video V1.1";
|
||||
case "MJPG":
|
||||
return "Motion JPEG";
|
||||
case "MMES":
|
||||
return "Matrox MPEG-2 elementary video stream";
|
||||
case "MMIF":
|
||||
return "Matrox MPEG-2 elementary I-frame-only video stream";
|
||||
case "MP2A":
|
||||
return "Media Excel Inc. MPEG-2 audio";
|
||||
case "MP2T":
|
||||
return "Media Excel Inc. MPEG-2 transport";
|
||||
case "MP2V":
|
||||
return "Media Excel Inc. MPEG-2 video";
|
||||
case "MP42":
|
||||
return "Microsoft MPEG-4 video codec V2";
|
||||
case "MP4A":
|
||||
return "Media Excel Inc. MPEG-4 audio";
|
||||
case "MP4S":
|
||||
return "Microsoft ISO MPEG-4 video V1.0";
|
||||
case "MP4T":
|
||||
return "Media Excel Inc. MPEG-4 transport";
|
||||
case "MP4V":
|
||||
return "Media Excel Inc. MPEG-4 video";
|
||||
case "MPEG":
|
||||
return "Chromatic Research, Inc. MPEG-1 video, I frame";
|
||||
case "MPG4":
|
||||
return "Microsoft MPEG-4 Version 1 Video";
|
||||
case "MRCA":
|
||||
return "FAST Multimedia AG Mrcodec";
|
||||
case "MRLE":
|
||||
return "Microsoft Run length encoding";
|
||||
case "MSS1":
|
||||
return "Microsoft screen codec V1";
|
||||
case "MSV1":
|
||||
return "Microsoft video codec V1";
|
||||
case "MSVC":
|
||||
return "Microsoft Video 1";
|
||||
case "MV10":
|
||||
case "MV11":
|
||||
case "MV12":
|
||||
case "MV99":
|
||||
case "MVC1":
|
||||
case "MVC2":
|
||||
case "MVC9":
|
||||
return "Nokia MVC video codec";
|
||||
case "NTN1":
|
||||
return "Nogatech video compression 1";
|
||||
case "NY12":
|
||||
return "Nogatech YUV 12 format";
|
||||
case "NYUV":
|
||||
return "Nogatech YUV 422 format";
|
||||
case "PCL2":
|
||||
return "Pinnacle RL video codec";
|
||||
case "PCLE":
|
||||
return "Pinnacle Studio 400 video codec";
|
||||
case "PHMO":
|
||||
return "IBM Corporation Photomotion";
|
||||
case "QPEG":
|
||||
return "Q-Team QPEG 1.1 format video codec";
|
||||
case "RGBT":
|
||||
return "Computer Concepts Ltd. 32-bit support";
|
||||
case "RIVA":
|
||||
return "NVIDIA Corporation Swizzled texture format";
|
||||
case "RLND":
|
||||
return "Roland Corporation Video";
|
||||
case "RT21":
|
||||
return "Intel Indeo 2.1";
|
||||
case "RVX":
|
||||
return "Intel RDX";
|
||||
case "S263":
|
||||
return "Sorenson Vision H.263";
|
||||
case "SCCD":
|
||||
return "Luminositi SoftCam codec";
|
||||
case "SDCC":
|
||||
return "Sun Digital Camera codec";
|
||||
case "SFMC":
|
||||
return "Crystal Net SFM codec";
|
||||
case "SMSC":
|
||||
case "SMSD":
|
||||
return "Radius Proprietary";
|
||||
case "SPLC":
|
||||
return "Splash Studios ACM audio codec";
|
||||
case "SQZ2":
|
||||
return "Microsoft VXtreme video codec V2";
|
||||
case "STVA":
|
||||
return "ST CMOS Imager Data (Bayer)";
|
||||
case "STVB":
|
||||
return "ST CMOS Imager Data (Nudged Bayer)";
|
||||
case "STVC":
|
||||
return "ST CMOS Imager Data (Bunched)";
|
||||
case "SV10":
|
||||
return "Sorenson Video R1";
|
||||
case "SV3M":
|
||||
return "Sorenson SV3 module decoder";
|
||||
case "TLMS":
|
||||
case "TLST":
|
||||
return "TeraLogic motion intraframe codec";
|
||||
case "TM20":
|
||||
return "The Duck Corporation TrueMotion 2.0";
|
||||
case "TMIC":
|
||||
return "TeraLogic motion intraframe codec";
|
||||
case "TMOT":
|
||||
return "TrueMotion video compression algorithm";
|
||||
case "TR20":
|
||||
return "The Duck Corporation TrueMotion RT 2.0";
|
||||
case "ULTI":
|
||||
return "IBM Corporation Ultimotion";
|
||||
case "UYVP":
|
||||
return "Evans & Sutherland YCbCr 4:2:2 extended precision, 10 bits per component (U0Y0V0Y1)";
|
||||
case "V261":
|
||||
return "Lucent VX3000S video codec";
|
||||
case "V422":
|
||||
return "VITEC Multimedia 24-bit YUV 4:2:2 format (CCIR 601)";
|
||||
case "V655":
|
||||
return "VITEC Multimedia 16-bit YUV 4:2:2 format";
|
||||
case "VCR1":
|
||||
return "ATI VCR 1.0";
|
||||
case "VCWV":
|
||||
return "VideoCon wavelet";
|
||||
case "VDCT":
|
||||
return "VITEC Multimedia Video Maker Pro DIB";
|
||||
case "VIDS":
|
||||
return "VITEC Multimedia YUV 4:2:2 CCIR 601 for v422";
|
||||
case "VGPX":
|
||||
return "Alaris VGPixel video";
|
||||
case "VIVO":
|
||||
return "Vivo H.263 video codec";
|
||||
case "VIXL":
|
||||
return "miro Computer Products AG";
|
||||
case "VJPG":
|
||||
return "Video Communication Systems - A JPEG-based compression scheme for RGB bitmaps";
|
||||
case "VLV1":
|
||||
return "VideoLogic Systems VLCAP.DRV";
|
||||
case "VQC1":
|
||||
return "ViewQuest Technologies Inc. 0x31435156";
|
||||
case "VQC2":
|
||||
return "ViewQuest Technologies Inc. 0x32435156";
|
||||
case "VQJP":
|
||||
return "ViewQuest Technologies Inc. VQ630 dual-mode digital camera";
|
||||
case "VQS4":
|
||||
return "ViewQuest Technologies Inc. VQ110 digital video camera";
|
||||
case "VX1K":
|
||||
return "Lucent VX1000S video codec";
|
||||
case "VX2K":
|
||||
return "Lucent VX2000S video codec";
|
||||
case "VXSP":
|
||||
return "Lucent VX1000SP video codec9";
|
||||
case "WBVC":
|
||||
return "Winbond Electronics Corporation W9960";
|
||||
case "WINX":
|
||||
return "Winnov, Inc. Video";
|
||||
case "WJPG":
|
||||
return "Winbond motion JPEG bitstream format";
|
||||
case "WMV1":
|
||||
return "Microsoft Windows Media Video Version 7";
|
||||
case "WMV2":
|
||||
return "Microsoft Windows Media Video Version 8";
|
||||
case "WMV3":
|
||||
return "Microsoft Windows Media Video Version 9";
|
||||
case "WNV1":
|
||||
case "WPY2":
|
||||
return "Winnov, Inc. Video";
|
||||
case "WZCD":
|
||||
return "CORE Co. Ltd. iScan";
|
||||
case "WZDC":
|
||||
return "CORE Co. Ltd. iSnap";
|
||||
case "XJPG":
|
||||
return "Xirlink JPEG-like compressor";
|
||||
case "XLV0":
|
||||
return "XL video decoder";
|
||||
case "XVID":
|
||||
return "XviD Video";
|
||||
case "YC12":
|
||||
return "Intel YUV12 Video";
|
||||
case "YCCK":
|
||||
return "Uncompressed YCbCr Video with key data";
|
||||
case "YU92":
|
||||
return "Intel YUV Video";
|
||||
case "YUV8":
|
||||
return "Winnov Caviar YUV8 Video";
|
||||
case "YUV9":
|
||||
return "Intel YUV Video";
|
||||
case "YUYP":
|
||||
return "Evans & Sutherland YCbCr 4:2:2 extended precision, 10 bits per component Video";
|
||||
case "YUYV":
|
||||
return "Canopus YUYV Compressor Video";
|
||||
case "ZPEG":
|
||||
return "Metheus Corporation Video Zipper";
|
||||
case "ZPG1":
|
||||
case "ZPG2":
|
||||
case "ZPG3":
|
||||
case "ZPG4":
|
||||
return "VoDeo Solutions Video";
|
||||
default:
|
||||
return string.Format (
|
||||
CultureInfo.InvariantCulture,
|
||||
"Unknown Image ({0})",
|
||||
CompressionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region IEquatable
|
||||
|
||||
/// <summary>
|
||||
/// Generates a hash code for the current instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="int" /> value containing the hash code for
|
||||
/// the current instance.
|
||||
/// </returns>
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
unchecked {
|
||||
return (int)(HeaderSize ^ width ^ height ^ Planes ^
|
||||
BitCount ^ CompressionId.ToUInt () ^
|
||||
ImageSize ^ XPixelsPerMeter ^
|
||||
YPixelsPerMeter ^ ColorsUsed ^
|
||||
ImportantColors);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the current instance is equal to
|
||||
/// another object.
|
||||
/// </summary>
|
||||
/// <param name="other">
|
||||
/// A <see cref="object" /> to compare to the current
|
||||
/// instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not the
|
||||
/// current instance is equal to <paramref name="other" />.
|
||||
/// </returns>
|
||||
/// <seealso cref="M:System.IEquatable`1.Equals" />
|
||||
public override bool Equals (object other)
|
||||
{
|
||||
if (!(other is BitmapInfoHeader))
|
||||
return false;
|
||||
|
||||
return Equals ((BitmapInfoHeader)other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the current instance is equal to
|
||||
/// another instance of <see cref="BitmapInfoHeader" />.
|
||||
/// </summary>
|
||||
/// <param name="other">
|
||||
/// A <see cref="BitmapInfoHeader" /> object to compare to
|
||||
/// the current instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not the
|
||||
/// current instance is equal to <paramref name="other" />.
|
||||
/// </returns>
|
||||
/// <seealso cref="M:System.IEquatable`1.Equals" />
|
||||
public bool Equals (BitmapInfoHeader other)
|
||||
{
|
||||
return HeaderSize == other.HeaderSize && width == other.width &&
|
||||
height == other.height && Planes == other.Planes &&
|
||||
BitCount == other.BitCount &&
|
||||
CompressionId == other.CompressionId &&
|
||||
ImageSize == other.ImageSize &&
|
||||
XPixelsPerMeter == other.XPixelsPerMeter &&
|
||||
YPixelsPerMeter == other.YPixelsPerMeter &&
|
||||
ColorsUsed == other.ColorsUsed &&
|
||||
ImportantColors == other.ImportantColors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not two instances of <see
|
||||
/// cref="WaveFormatEx" /> are equal to eachother.
|
||||
/// </summary>
|
||||
/// <param name="first">
|
||||
/// A <see cref="BitmapInfoHeader" /> object to compare.
|
||||
/// </param>
|
||||
/// <param name="second">
|
||||
/// A <see cref="BitmapInfoHeader" /> object to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="first" /> is
|
||||
/// equal to <paramref name="second" />. Otherwise, <see
|
||||
/// langword="false" />.
|
||||
/// </returns>
|
||||
public static bool operator == (BitmapInfoHeader first, BitmapInfoHeader second)
|
||||
{
|
||||
return first.Equals (second);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not two instances of <see
|
||||
/// cref="BitmapInfoHeader" /> differ.
|
||||
/// </summary>
|
||||
/// <param name="first">
|
||||
/// A <see cref="BitmapInfoHeader" /> object to compare.
|
||||
/// </param>
|
||||
/// <param name="second">
|
||||
/// A <see cref="BitmapInfoHeader" /> object to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="first" /> is
|
||||
/// unequal to <paramref name="second" />. Otherwise, <see
|
||||
/// langword="false" />.
|
||||
/// </returns>
|
||||
public static bool operator != (BitmapInfoHeader first, BitmapInfoHeader second)
|
||||
{
|
||||
return !first.Equals (second);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47ec323b1e494beffa5994f0535c0f1d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,384 @@
|
||||
//
|
||||
// DivXTag.cs: Provide support for reading and writing DivX tags.
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Original Source:
|
||||
// TagLib.Id3v1.Tag
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Globalization;
|
||||
|
||||
namespace TagLib.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="Tag" /> to provide support for
|
||||
/// reading and writing tags stored in the DivX format.
|
||||
/// </summary>
|
||||
public class DivXTag : Tag
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the title.
|
||||
/// </summary>
|
||||
string title;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the semicolon separated performers.
|
||||
/// </summary>
|
||||
string artist;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the 4 digit year.
|
||||
/// </summary>
|
||||
string year;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a comment on track.
|
||||
/// </summary>
|
||||
string comment;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the genre index.
|
||||
/// </summary>
|
||||
string genre;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the extra 6 bytes at the end of the tag.
|
||||
/// </summary>
|
||||
ByteVector extra_data;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region Public Static Fields
|
||||
|
||||
/// <summary>
|
||||
/// The size of a DivX tag.
|
||||
/// </summary>
|
||||
public const uint Size = 128;
|
||||
|
||||
/// <summary>
|
||||
/// The identifier used to recognize a DivX tags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// "DIVXTAG"
|
||||
/// </value>
|
||||
public static readonly ReadOnlyByteVector FileIdentifier = "DIVXTAG";
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="DivXTag" /> with no contents.
|
||||
/// </summary>
|
||||
public DivXTag ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="DivXTag" /> by reading the contents from a
|
||||
/// specified position in a specified file.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="File" /> object containing the file from
|
||||
/// which the contents of the new instance is to be read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the tag.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The file does not contain the file identifier at the
|
||||
/// correct offset from the given position.
|
||||
/// </exception>
|
||||
public DivXTag (File file, long position)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
|
||||
file.Mode = TagLib.File.AccessMode.Read;
|
||||
|
||||
if (position < 0 ||
|
||||
position > file.Length - Size)
|
||||
throw new ArgumentOutOfRangeException (nameof (position));
|
||||
|
||||
file.Seek (position);
|
||||
|
||||
// read the tag -- always 128 bytes
|
||||
|
||||
ByteVector data = file.ReadBlock ((int)Size);
|
||||
|
||||
// some initial sanity checking
|
||||
|
||||
if (!data.EndsWith (FileIdentifier))
|
||||
throw new CorruptFileException ("DivX tag data does not end with identifier.");
|
||||
|
||||
Parse (data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="DivXTag" /> by reading the contents raw tag data
|
||||
/// stored in a specified <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw DivX tag to
|
||||
/// read into the new instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The file does not contain the file identifier at the
|
||||
/// correct offset from the given position.
|
||||
/// </exception>
|
||||
public DivXTag (ByteVector data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (data.Count < Size)
|
||||
throw new CorruptFileException ("DivX tag data is less than 128 bytes long.");
|
||||
|
||||
if (!data.EndsWith (FileIdentifier))
|
||||
throw new CorruptFileException ("DivX tag data does not end with identifier.");
|
||||
|
||||
Parse (data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance as a raw DivX tag.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector" /> object containing the
|
||||
/// rendered tag.
|
||||
/// </returns>
|
||||
public ByteVector Render ()
|
||||
{
|
||||
var data = new ByteVector {
|
||||
ByteVector.FromString (title, StringType.Latin1).Resize (32, 0x20),
|
||||
ByteVector.FromString (artist, StringType.Latin1).Resize (28, 0x20),
|
||||
ByteVector.FromString (year, StringType.Latin1).Resize (4, 0x20),
|
||||
ByteVector.FromString (comment, StringType.Latin1).Resize (48, 0x20),
|
||||
ByteVector.FromString (genre, StringType.Latin1).Resize (3, 0x20),
|
||||
extra_data,
|
||||
FileIdentifier
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Populates the current instance by parsing the contents of
|
||||
/// a raw DivX tag.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the
|
||||
/// starting with an DivX tag.
|
||||
/// </param>
|
||||
void Parse (ByteVector data)
|
||||
{
|
||||
title = data.ToString (StringType.Latin1, 0, 32).Trim ();
|
||||
artist = data.ToString (StringType.Latin1, 32, 28).Trim ();
|
||||
year = data.ToString (StringType.Latin1, 60, 4).Trim ();
|
||||
comment = data.ToString (StringType.Latin1, 64, 48).Trim ();
|
||||
genre = data.ToString (StringType.Latin1, 112, 3).Trim ();
|
||||
extra_data = data.Mid (115, 6);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region TagLib.Tag
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag types contained in the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="TagTypes.Id3v1" />.
|
||||
/// </value>
|
||||
public override TagTypes TagTypes {
|
||||
get { return TagTypes.DivX; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the title for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the title for
|
||||
/// the media described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// When stored on disk, only the first 32 bytes of the
|
||||
/// Latin-1 encoded value will be stored. This may result in
|
||||
/// lost data.
|
||||
/// </remarks>
|
||||
public override string Title {
|
||||
get {
|
||||
return string.IsNullOrEmpty (title) ? null : title;
|
||||
}
|
||||
set {
|
||||
title = value != null ? value.Trim () : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the performers or artists who performed in
|
||||
/// the media described by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the performers or
|
||||
/// artists who performed in the media described by the
|
||||
/// current instance or an empty array if no value is
|
||||
/// present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// When stored on disk, only the first 28 bytes of the
|
||||
/// Latin-1 encoded value will be stored, minus a byte for
|
||||
/// each additionial performer (i.e. two performers will only
|
||||
/// have 27 bytes and three performers will only have 26
|
||||
/// bytes).This may result in lost data.
|
||||
/// </remarks>
|
||||
public override string[] Performers {
|
||||
get {
|
||||
return string.IsNullOrEmpty (artist) ? new string[0] : artist.Split (';');
|
||||
}
|
||||
set {
|
||||
artist = value != null ? string.Join (";", value) : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets a user comment on the media represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing user comments
|
||||
/// on the media represented by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// When stored on disk, only the first 48 bytes of the
|
||||
/// Latin-1 encoded value will be stored. This may result in
|
||||
/// lost data.
|
||||
/// </remarks>
|
||||
public override string Comment {
|
||||
get {
|
||||
return string.IsNullOrEmpty (comment) ? null : comment;
|
||||
}
|
||||
set {
|
||||
comment = value != null ? value.Trim () : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the genres of the media represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the genres of the
|
||||
/// media represented by the current instance or an empty
|
||||
/// array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// Only first genre will be stored and only if it is an
|
||||
/// exact match for a value appearing in <see
|
||||
/// cref="TagLib.Genres.Video" />. All other values will
|
||||
/// result in the property being cleared.
|
||||
/// </remarks>
|
||||
public override string[] Genres {
|
||||
get {
|
||||
string genre_name = TagLib.Genres.IndexToVideo (genre);
|
||||
|
||||
return (genre_name != null) ? new[] { genre_name } : new string[0];
|
||||
}
|
||||
set {
|
||||
genre = (value != null && value.Length > 0) ?
|
||||
TagLib.Genres.VideoToIndex (value[0].Trim ()).ToString (CultureInfo.InvariantCulture)
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the year that the media represented by the
|
||||
/// current instance was recorded.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the year that the media
|
||||
/// represented by the current instance was created or zero
|
||||
/// if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// Only values between 1 and 9999 will be stored, all other
|
||||
/// values will result in the property being zeroed.
|
||||
/// </remarks>
|
||||
public override uint Year {
|
||||
get {
|
||||
return uint.TryParse (year, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value) ? value : 0;
|
||||
}
|
||||
|
||||
set {
|
||||
year = (value > 0 && value < 10000) ? value.ToString (CultureInfo.InvariantCulture) : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the values stored in the current instance.
|
||||
/// </summary>
|
||||
public override void Clear ()
|
||||
{
|
||||
title = artist = genre = year = comment = string.Empty;
|
||||
extra_data = new ByteVector (6);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 111ed0c7de1644627a867e56300d9623
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,611 @@
|
||||
//
|
||||
// File.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="TagLib.File" /> to provide
|
||||
/// support for reading and writing tags and properties for files
|
||||
/// using the RIFF file format such as AVI and Wave files.
|
||||
/// </summary>
|
||||
[SupportedMimeType ("taglib/avi", "avi")]
|
||||
[SupportedMimeType ("taglib/wav", "wav")]
|
||||
[SupportedMimeType ("taglib/divx", "divx")]
|
||||
[SupportedMimeType ("video/avi")]
|
||||
[SupportedMimeType ("video/msvideo")]
|
||||
[SupportedMimeType ("video/x-msvideo")]
|
||||
[SupportedMimeType ("image/avi")]
|
||||
[SupportedMimeType ("application/x-troff-msvideo")]
|
||||
[SupportedMimeType ("audio/avi")]
|
||||
[SupportedMimeType ("audio/wav")]
|
||||
[SupportedMimeType ("audio/wave")]
|
||||
[SupportedMimeType ("audio/x-wav")]
|
||||
public class File : TagLib.File
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains all the tags of the file.
|
||||
/// </summary>
|
||||
readonly CombinedTag tag = new CombinedTag ();
|
||||
|
||||
/// <summary>
|
||||
/// Contains the INFO tag.
|
||||
/// </summary>
|
||||
InfoTag info_tag;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the MovieID tag.
|
||||
/// </summary>
|
||||
MovieIdTag mid_tag;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the DivX tag.
|
||||
/// </summary>
|
||||
DivXTag divx_tag;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the Id3v2 tag.
|
||||
/// </summary>
|
||||
Id3v2.Tag id32_tag;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the media properties.
|
||||
/// </summary>
|
||||
Properties properties;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Static Fields
|
||||
|
||||
/// <summary>
|
||||
/// The identifier used to recognize a RIFF files.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// "RIFF"
|
||||
/// </value>
|
||||
public static readonly ReadOnlyByteVector FileIdentifier = "RIFF";
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public 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)
|
||||
: this (new LocalFileAbstraction (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) : this (path, ReadStyle.Average)
|
||||
{
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
Mode = AccessMode.Read;
|
||||
try {
|
||||
Read (true, propertiesStyle, out var riff_size, out var tag_start, out var tag_end);
|
||||
} finally {
|
||||
Mode = AccessMode.Closed;
|
||||
}
|
||||
|
||||
TagTypesOnDisk = TagTypes;
|
||||
|
||||
GetTag (TagTypes.Id3v2, true);
|
||||
GetTag (TagTypes.RiffInfo, true);
|
||||
GetTag (TagTypes.MovieId, true);
|
||||
GetTag (TagTypes.DivX, true);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
: this (abstraction, ReadStyle.Average)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets a abstract representation of all tags stored in the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TagLib.Tag" /> object representing all tags
|
||||
/// stored in the current instance.
|
||||
/// </value>
|
||||
public override Tag Tag {
|
||||
get { return tag; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media properties of the file represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TagLib.Properties" /> object containing the
|
||||
/// media properties of the file represented by the current
|
||||
/// instance.
|
||||
/// </value>
|
||||
public override Properties Properties {
|
||||
get { return properties; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Saves the changes made in the current instance to the
|
||||
/// file it represents.
|
||||
/// </summary>
|
||||
public override void Save ()
|
||||
{
|
||||
// Boilerplate
|
||||
PreSave ();
|
||||
|
||||
Mode = AccessMode.Write;
|
||||
try {
|
||||
ByteVector data = new ByteVector ();
|
||||
|
||||
// Enclose the Id3v2 tag in an "id3 " item and
|
||||
// embed it as the first tag.
|
||||
if (id32_tag != null) {
|
||||
ByteVector tag_data = id32_tag.Render ();
|
||||
if (tag_data.Count > 10) {
|
||||
if (tag_data.Count % 2 == 1)
|
||||
tag_data.Add (0);
|
||||
data.Add ("id3 ");
|
||||
data.Add (ByteVector.FromUInt ((uint)tag_data.Count, false));
|
||||
data.Add (tag_data);
|
||||
}
|
||||
}
|
||||
|
||||
// Embed "INFO" as the second tag.
|
||||
if (info_tag != null)
|
||||
data.Add (info_tag.RenderEnclosed ());
|
||||
|
||||
// Embed "MID " as the third tag.
|
||||
if (mid_tag != null)
|
||||
data.Add (mid_tag.RenderEnclosed ());
|
||||
|
||||
// Embed the DivX tag in "IDVX and embed it as
|
||||
// the fourth tag.
|
||||
if (divx_tag != null && !divx_tag.IsEmpty) {
|
||||
ByteVector tag_data = divx_tag.Render ();
|
||||
data.Add ("IDVX");
|
||||
data.Add (ByteVector.FromUInt ((uint)tag_data.Count, false));
|
||||
data.Add (tag_data);
|
||||
}
|
||||
|
||||
Read (false, ReadStyle.None, out var riff_size, out var tag_start, out var tag_end);
|
||||
|
||||
// If tagging info cannot be found, place it at
|
||||
// the end of the file.
|
||||
if (tag_start < 12 || tag_end < tag_start)
|
||||
tag_start = tag_end = Length;
|
||||
|
||||
int length = (int)(tag_end - tag_start);
|
||||
|
||||
// If the tag isn't at the end of the file,
|
||||
// try appending using padding to improve
|
||||
// write time now or for subsequent writes.
|
||||
if (tag_end != Length) {
|
||||
int padding_size = length - data.Count - 8;
|
||||
if (padding_size < 0)
|
||||
padding_size = 1024;
|
||||
|
||||
|
||||
data.Add ("JUNK");
|
||||
data.Add (ByteVector.FromUInt ((uint)padding_size, false));
|
||||
data.Add (new ByteVector (padding_size));
|
||||
}
|
||||
|
||||
// Insert the tagging data.
|
||||
Insert (data, tag_start, length);
|
||||
|
||||
// If the data size changed, and the tagging
|
||||
// data is within the RIFF portion of the file,
|
||||
// update the riff size.
|
||||
if (data.Count - length != 0 && tag_start <= riff_size)
|
||||
Insert (ByteVector.FromUInt ((uint)(riff_size + data.Count - length), false), 4, 4);
|
||||
|
||||
// Update the tag types.
|
||||
TagTypesOnDisk = TagTypes;
|
||||
} finally {
|
||||
Mode = AccessMode.Closed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a set of tag types from the current instance.
|
||||
/// </summary>
|
||||
/// <param name="types">
|
||||
/// A bitwise combined <see cref="TagLib.TagTypes" /> value
|
||||
/// containing tag types to be removed from the file.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// In order to remove all tags from a file, pass <see
|
||||
/// cref="TagTypes.AllTags" /> as <paramref name="types" />.
|
||||
/// </remarks>
|
||||
public override void RemoveTags (TagTypes types)
|
||||
{
|
||||
if ((types & TagTypes.Id3v2) != TagTypes.None)
|
||||
id32_tag = null;
|
||||
if ((types & TagTypes.RiffInfo) != TagTypes.None)
|
||||
info_tag = null;
|
||||
if ((types & TagTypes.MovieId) != TagTypes.None)
|
||||
mid_tag = null;
|
||||
if ((types & TagTypes.DivX) != TagTypes.None)
|
||||
divx_tag = null;
|
||||
|
||||
tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public override Tag GetTag (TagTypes type, bool create)
|
||||
{
|
||||
Tag tag = null;
|
||||
|
||||
switch (type) {
|
||||
case TagTypes.Id3v2:
|
||||
if (id32_tag == null && create) {
|
||||
id32_tag = new Id3v2.Tag ();
|
||||
id32_tag.Version = 4;
|
||||
id32_tag.Flags |= Id3v2.HeaderFlags.FooterPresent;
|
||||
this.tag.CopyTo (id32_tag, true);
|
||||
}
|
||||
|
||||
tag = id32_tag;
|
||||
break;
|
||||
|
||||
case TagTypes.RiffInfo:
|
||||
if (info_tag == null && create) {
|
||||
info_tag = new InfoTag ();
|
||||
this.tag.CopyTo (info_tag, true);
|
||||
}
|
||||
|
||||
tag = info_tag;
|
||||
break;
|
||||
|
||||
case TagTypes.MovieId:
|
||||
if (mid_tag == null && create) {
|
||||
mid_tag = new MovieIdTag ();
|
||||
this.tag.CopyTo (mid_tag, true);
|
||||
}
|
||||
|
||||
tag = mid_tag;
|
||||
break;
|
||||
|
||||
case TagTypes.DivX:
|
||||
if (divx_tag == null && create) {
|
||||
divx_tag = new DivXTag ();
|
||||
this.tag.CopyTo (divx_tag, true);
|
||||
}
|
||||
|
||||
tag = divx_tag;
|
||||
break;
|
||||
}
|
||||
|
||||
this.tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Reads the contents of the current instance determining
|
||||
/// the size of the riff data, the area the tagging is in,
|
||||
/// and optionally reading in the tags and media properties.
|
||||
/// </summary>
|
||||
/// <param name="read_tags">
|
||||
/// If <see langword="true" />, any tags found will be read
|
||||
/// into the current instance.
|
||||
/// </param>
|
||||
/// <param name="style">
|
||||
/// A <see cref="ReadStyle"/> value specifying how the media
|
||||
/// data is to be read into the current instance.
|
||||
/// </param>
|
||||
/// <param name="riff_size">
|
||||
/// A <see cref="uint"/> value reference to be filled with
|
||||
/// the size of the RIFF data as read from the file.
|
||||
/// </param>
|
||||
/// <param name="tag_start">
|
||||
/// A <see cref="long" /> value reference to be filled with
|
||||
/// the absolute seek position at which the tagging data
|
||||
/// starts.
|
||||
/// </param>
|
||||
/// <param name="tag_end">
|
||||
/// A <see cref="long" /> value reference to be filled with
|
||||
/// the absolute seek position at which the tagging data
|
||||
/// ends.
|
||||
/// </param>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The file does not begin with <see cref="FileIdentifier"
|
||||
/// />.
|
||||
/// </exception>
|
||||
void Read (bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end)
|
||||
{
|
||||
Seek (0);
|
||||
if (ReadBlock (4) != FileIdentifier)
|
||||
throw new CorruptFileException ("File does not begin with RIFF identifier");
|
||||
|
||||
riff_size = ReadBlock (4).ToUInt (false);
|
||||
ByteVector stream_format = ReadBlock (4);
|
||||
tag_start = -1;
|
||||
tag_end = -1;
|
||||
|
||||
long position = 12;
|
||||
long length = Length;
|
||||
uint size = 0;
|
||||
TimeSpan duration = TimeSpan.Zero;
|
||||
ICodec[] codecs = new ICodec[0];
|
||||
|
||||
// Read until there are less than 8 bytes to read.
|
||||
do {
|
||||
bool tag_found = false;
|
||||
|
||||
// Check if the current position is an odd number and increment it so it is even
|
||||
// This is done when the previous chunk size was an odd number.
|
||||
// If this is not done, the chunk being read after the odd chunk will not be read.
|
||||
if (position > 12 && (position & 1) != 0)
|
||||
position++;
|
||||
|
||||
Seek (position);
|
||||
string fourcc = ReadBlock (4).ToString (StringType.UTF8);
|
||||
size = ReadBlock (4).ToUInt (false);
|
||||
|
||||
switch (fourcc) {
|
||||
|
||||
// "fmt " is used by Wave files to hold the
|
||||
// WaveFormatEx structure.
|
||||
case "fmt ":
|
||||
if (style == ReadStyle.None || stream_format != "WAVE")
|
||||
break;
|
||||
|
||||
Seek (position + 8);
|
||||
codecs = new ICodec[] {
|
||||
new WaveFormatEx (ReadBlock (18), 0)
|
||||
};
|
||||
break;
|
||||
|
||||
// "data" contains the audio data for wave
|
||||
// files. It's contents represent the invariant
|
||||
// portion of the file and is used to determine
|
||||
// the duration of a file. It should always
|
||||
// appear after "fmt ".
|
||||
case "data":
|
||||
if (stream_format != "WAVE")
|
||||
break;
|
||||
|
||||
InvariantStartPosition = position;
|
||||
InvariantEndPosition = position + size;
|
||||
|
||||
if (style == ReadStyle.None ||
|
||||
codecs.Length != 1 ||
|
||||
!(codecs[0] is WaveFormatEx))
|
||||
break;
|
||||
|
||||
duration += TimeSpan.FromSeconds (size / (double)((WaveFormatEx)codecs[0]).AverageBytesPerSecond);
|
||||
|
||||
break;
|
||||
|
||||
// Lists are used to store a variety of data
|
||||
// collections. Read the type and act on it.
|
||||
case "LIST": {
|
||||
switch (ReadBlock (4).ToString (StringType.UTF8)) {
|
||||
|
||||
// "hdlr" is used by AVI files to hold
|
||||
// a media header and BitmapInfoHeader
|
||||
// and WaveFormatEx structures.
|
||||
case "hdrl":
|
||||
if (style == ReadStyle.None || stream_format != "AVI ")
|
||||
continue;
|
||||
|
||||
var header_list = new AviHeaderList (this, position + 12, (int)(size - 4));
|
||||
duration = header_list.Header.Duration;
|
||||
codecs = header_list.Codecs;
|
||||
break;
|
||||
|
||||
// "INFO" is a tagging format handled by
|
||||
// the InfoTag class.
|
||||
case "INFO":
|
||||
if (read_tags && info_tag == null)
|
||||
info_tag = new InfoTag (this, position + 12, (int)(size - 4));
|
||||
|
||||
tag_found = true;
|
||||
break;
|
||||
|
||||
// "MID " is a tagging format handled by
|
||||
// the MovieIdTag class.
|
||||
case "MID ":
|
||||
if (read_tags && mid_tag == null)
|
||||
mid_tag = new MovieIdTag (this, position + 12, (int)(size - 4));
|
||||
|
||||
tag_found = true;
|
||||
break;
|
||||
|
||||
// "movi" contains the media data for
|
||||
// and AVI and its contents represent
|
||||
// the invariant portion of the file.
|
||||
case "movi":
|
||||
if (stream_format != "AVI ")
|
||||
break;
|
||||
|
||||
InvariantStartPosition = position;
|
||||
InvariantEndPosition = position + size;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// "ID32" is a custom box for this format that
|
||||
// contains an ID3v2 tag.
|
||||
// "ID3 " and "id3 " have become standard (de facto)
|
||||
case "id3 ":
|
||||
case "ID3 ":
|
||||
case "ID32":
|
||||
if (read_tags && id32_tag == null)
|
||||
id32_tag = new Id3v2.Tag (this, position + 8, style);
|
||||
|
||||
tag_found = true;
|
||||
break;
|
||||
|
||||
// "IDVX" is used by DivX and holds an ID3v1-
|
||||
// style tag.
|
||||
case "IDVX":
|
||||
if (read_tags && divx_tag == null)
|
||||
divx_tag = new DivXTag (this, position + 8);
|
||||
|
||||
tag_found = true;
|
||||
break;
|
||||
|
||||
// "JUNK" is a padding element that could be
|
||||
// associated with tag data.
|
||||
case "JUNK":
|
||||
if (tag_end == position)
|
||||
tag_end = position + 8 + size;
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine the region of the file that
|
||||
// contains tags.
|
||||
if (tag_found) {
|
||||
if (tag_start == -1) {
|
||||
tag_start = position;
|
||||
tag_end = position + 8 + size;
|
||||
} else if (tag_end == position) {
|
||||
tag_end = position + 8 + size;
|
||||
}
|
||||
}
|
||||
|
||||
// Move to the next item.
|
||||
} while ((position += 8L + size) + 8 < length);
|
||||
|
||||
// If we're reading properties, and one were found,
|
||||
// throw an exception. Otherwise, create the Properties
|
||||
// object.
|
||||
if (style != ReadStyle.None) {
|
||||
if (codecs.Length == 0)
|
||||
throw new UnsupportedFormatException ("Unsupported RIFF type.");
|
||||
|
||||
properties = new Properties (duration, codecs);
|
||||
}
|
||||
|
||||
// If we're reading tags, update the combined tag.
|
||||
if (read_tags)
|
||||
tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63abf712dfcf1342c880fca7e562a560
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,392 @@
|
||||
//
|
||||
// InfoTag.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="ListTag" /> to provide support for
|
||||
/// reading and writing standard INFO tags.
|
||||
/// </summary>
|
||||
public class InfoTag : ListTag
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="InfoTag" /> with no contents.
|
||||
/// </summary>
|
||||
public InfoTag ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="InfoTag" /> by reading the contents of a raw
|
||||
/// RIFF list stored in a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw RIFF list to
|
||||
/// read into the new instance.
|
||||
/// </param>
|
||||
public InfoTag (ByteVector data) : base (data)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="InfoTag" /> by reading the contents of a raw RIFF
|
||||
/// list from a specified position in a <see
|
||||
/// cref="TagLib.File"/>.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object containing the file
|
||||
/// from which the contents of the new instance is to be
|
||||
/// read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the list.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the number of bytes
|
||||
/// to read.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
public InfoTag (TagLib.File file, long position, int length)
|
||||
: base (file, position, length)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance enclosed in a "INFO" item.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
public override ByteVector RenderEnclosed ()
|
||||
{
|
||||
return RenderEnclosed ("INFO");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region TagLib.Tag
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag types contained in the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="TagTypes.RiffInfo" />.
|
||||
/// </value>
|
||||
public override TagTypes TagTypes {
|
||||
get { return TagTypes.RiffInfo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the title for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the title for
|
||||
/// the media described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "INAM" item.
|
||||
/// </remarks>
|
||||
public override string Title {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("INAM"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("INAM", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets a short description of the media.
|
||||
/// For a music, this could be the comment that the artist
|
||||
/// made of its artwork. For a video, this should be a
|
||||
/// short summary of the story/plot, but a spoiler. This
|
||||
/// should give the impression of what to expect in the
|
||||
/// media.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> containing the subtitle
|
||||
/// the media represented by the current instance
|
||||
/// or an empty array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ISBJ" item.
|
||||
/// </remarks>
|
||||
public override string Description {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("ISBJ"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("ISBJ", value); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the performers or artists who performed in
|
||||
/// the media described by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the performers or
|
||||
/// artists who performed in the media described by the
|
||||
/// current instance or an empty array if no value is
|
||||
/// present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ISTR" item.
|
||||
/// </remarks>
|
||||
public override string[] Performers {
|
||||
get { return GetValuesAsStrings ("ISTR"); }
|
||||
set { SetValue ("ISTR", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the band or artist who is credited in the
|
||||
/// creation of the entire album or collection containing the
|
||||
/// media described by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the band or artist
|
||||
/// who is credited in the creation of the entire album or
|
||||
/// collection containing the media described by the current
|
||||
/// instance or an empty array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IART" item.
|
||||
/// </remarks>
|
||||
public override string[] AlbumArtists {
|
||||
get { return GetValuesAsStrings ("IART"); }
|
||||
set { SetValue ("IART", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the composers of the media represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the composers of the
|
||||
/// media represented by the current instance or an empty
|
||||
/// array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IWRI" item.
|
||||
/// </remarks>
|
||||
public override string[] Composers {
|
||||
get { return GetValuesAsStrings ("IWRI"); }
|
||||
set { SetValue ("IWRI", value); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the album of the media represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the album of
|
||||
/// the media represented by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the non-standard
|
||||
/// "DIRC" (Directory) item.
|
||||
/// </remarks>
|
||||
public override string Album {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("DIRC"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("DIRC", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the conductor or director of the media
|
||||
/// represented by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the conductor
|
||||
/// or director of the media represented by the current
|
||||
/// instance or <see langword="null" /> if no value present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ICNM"
|
||||
/// (Cinematographer) non-standard item.
|
||||
/// </remarks>
|
||||
public override string Conductor {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("ICNM"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("ICNM", value); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets a user comment on the media represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing user comments
|
||||
/// on the media represented by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ICMT" item.
|
||||
/// </remarks>
|
||||
public override string Comment {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("ICMT"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("ICMT", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the genres of the media represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the genres of the
|
||||
/// media represented by the current instance or an empty
|
||||
/// array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IGNR" item.
|
||||
/// </remarks>
|
||||
public override string[] Genres {
|
||||
get { return GetValuesAsStrings ("IGNR"); }
|
||||
set { SetValue ("IGNR", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the year that the media represented by the
|
||||
/// current instance was recorded.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the year that the media
|
||||
/// represented by the current instance was created or zero
|
||||
/// if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ICRD" item.
|
||||
/// </remarks>
|
||||
public override uint Year {
|
||||
get { return GetValueAsUInt ("ICRD"); }
|
||||
set { SetValue ("ICRD", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the position of the media represented by
|
||||
/// the current instance in its containing album.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the position of the
|
||||
/// media represented by the current instance in its
|
||||
/// containing album or zero if not specified.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IPRT" item.
|
||||
/// </remarks>
|
||||
public override uint Track {
|
||||
get { return GetValueAsUInt ("IPRT"); }
|
||||
set { SetValue ("IPRT", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the number of tracks in the album
|
||||
/// containing the media represented by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the number of tracks in
|
||||
/// the album containing the media represented by the current
|
||||
/// instance or zero if not specified.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IFRM" item.
|
||||
/// </remarks>
|
||||
public override uint TrackCount {
|
||||
get { return GetValueAsUInt ("IFRM"); }
|
||||
set { SetValue ("IFRM", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the copyright information for the media
|
||||
/// represented by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the copyright
|
||||
/// information for the media represented by the current
|
||||
/// instance or <see langword="null" /> if no value present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "ICOP" item.
|
||||
/// </remarks>
|
||||
public override string Copyright {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("ICOP"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("ICOP", value); }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a2882ad50b55517b84bed378740164a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,622 @@
|
||||
//
|
||||
// List.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TagLib.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see
|
||||
/// cref="T:System.Collections.Generic.Dictionary`2" /> to provide
|
||||
/// support for reading and writing RIFF lists.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[ComVisible (false)]
|
||||
public class List : Dictionary<ByteVector, ByteVectorCollection>
|
||||
{
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the <see cref="StringType"/> value used for parsing
|
||||
/// and rendering the contents of this list.
|
||||
/// </summary>
|
||||
StringType string_type = StringType.UTF8;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="List" /> with no contents.
|
||||
/// </summary>
|
||||
public List ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="List" /> by reading the contents of a raw RIFF
|
||||
/// list stored in a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw RIFF list to
|
||||
/// read into the new instance.
|
||||
/// </param>
|
||||
public List (ByteVector data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
Parse (data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="List" /> by reading the contents of a raw RIFF list
|
||||
/// from a specified position in a <see cref="TagLib.File"/>.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object containing the file
|
||||
/// from which the contents of the new instance is to be
|
||||
/// read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the list.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the number of bytes
|
||||
/// to read.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
public List (TagLib.File file, long position, int length)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
|
||||
if (length < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (length));
|
||||
|
||||
if (position < 0 || position > file.Length - length)
|
||||
throw new ArgumentOutOfRangeException (nameof (position));
|
||||
|
||||
file.Seek (position);
|
||||
Parse (file.ReadBlock (length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="List" /> from a specified serialization info and
|
||||
/// streaming context.
|
||||
/// </summary>
|
||||
/// <param name="info">
|
||||
/// A <see cref="SerializationInfo" /> object containing the
|
||||
/// serialized data to be used for the new instance.
|
||||
/// </param>
|
||||
/// <param name="context">
|
||||
/// A <see cref="StreamingContext" /> object containing the
|
||||
/// streaming context information for the new instance.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// This constructor is implemented because <see
|
||||
/// cref="List" /> implements the <see cref="ISerializable"
|
||||
/// /> interface.
|
||||
/// </remarks>
|
||||
protected List (SerializationInfo info, StreamingContext context)
|
||||
: base (info, context)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="StringType"/> value used for parsing
|
||||
/// and rendering the contents of this list.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The value must be StringType.Latin1 or StringType.UTF8.
|
||||
/// </remarks>
|
||||
public StringType StringType {
|
||||
get => string_type;
|
||||
set {
|
||||
if (value != StringType.Latin1 && value != StringType.UTF8)
|
||||
throw new ArgumentException ("Must be Latin1 or UTF8.", nameof(value));
|
||||
|
||||
string_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance as a raw RIFF list.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
public ByteVector Render ()
|
||||
{
|
||||
ByteVector data = new ByteVector ();
|
||||
|
||||
foreach (ByteVector id in Keys)
|
||||
foreach (ByteVector value in this[id]) {
|
||||
if (value.Count == 0)
|
||||
continue;
|
||||
|
||||
data.Add (id);
|
||||
data.Add (ByteVector.FromUInt (
|
||||
(uint)value.Count, false));
|
||||
data.Add (value);
|
||||
|
||||
if (value.Count % 2 == 1)
|
||||
data.Add (0);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance enclosed in an item with a
|
||||
/// specified ID.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector"/> object containing the ID of
|
||||
/// the item to enclose the current instance in.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public ByteVector RenderEnclosed (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException (
|
||||
"ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
ByteVector data = Render ();
|
||||
|
||||
if (data.Count <= 8)
|
||||
return new ByteVector ();
|
||||
|
||||
var header = new ByteVector ("LIST") {
|
||||
ByteVector.FromUInt ((uint)(data.Count + 4), false),
|
||||
id
|
||||
};
|
||||
data.Insert (0, header);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="ByteVectorCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVectorCollection" /> object containing
|
||||
/// the values of the specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public ByteVectorCollection GetValues (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
|
||||
return TryGetValue (id, out var value) ? value : new ByteVectorCollection ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="T:string[]" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="T:string[]" /> containing the values of the
|
||||
/// specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public string[] GetValuesAsStrings (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
ByteVectorCollection values = GetValues (id);
|
||||
|
||||
string[] result = new string[values.Count];
|
||||
|
||||
for (int i = 0; i < result.Length; i++) {
|
||||
ByteVector data = values[i];
|
||||
|
||||
if (data == null) {
|
||||
result[i] = string.Empty;
|
||||
continue;
|
||||
}
|
||||
|
||||
int length = data.Count;
|
||||
while (length > 0 && data[length - 1] == 0)
|
||||
length--;
|
||||
|
||||
result[i] = data.ToString (StringType, 0, length);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="StringCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="StringCollection" /> object containing the
|
||||
/// values of the specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
[Obsolete ("Use GetValuesAsStrings(ByteVector)")]
|
||||
public StringCollection GetValuesAsStringCollection (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
return new StringCollection (GetValuesAsStrings (id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value for a specified item in the current
|
||||
/// instance as a <see cref="uint"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="uint" /> value containing the first value
|
||||
/// with the specified ID that could be converted to an
|
||||
/// integer, or zero if none could be found.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public uint GetValueAsUInt (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
foreach (string text in GetValuesAsStrings (id)) {
|
||||
if (uint.TryParse (text, out var value))
|
||||
return value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see
|
||||
/// cref="T:System.Collections.Generic.IEnumerable`1" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="values">
|
||||
/// A <see cref="T:System.Collections.Generic.IEnumerable`1"
|
||||
/// /> containing the <see cref="ByteVector"/> objects to
|
||||
/// store in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, IEnumerable<ByteVector> values)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (values == null)
|
||||
RemoveValue (id);
|
||||
else if (ContainsKey (id))
|
||||
this[id] = new ByteVectorCollection (values);
|
||||
else
|
||||
Add (id, new ByteVectorCollection (values));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see cref="T:ByteVector[]"
|
||||
/// />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="values">
|
||||
/// A <see cref="T:ByteVector[]" /> containing the values to
|
||||
/// store in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, params ByteVector[] values)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (values == null || values.Length == 0)
|
||||
RemoveValue (id);
|
||||
else
|
||||
SetValue (id, values as IEnumerable<ByteVector>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the value of a <see cref="uint"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="uint" /> value to store in the specified
|
||||
/// item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, uint value)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (value == 0)
|
||||
RemoveValue (id);
|
||||
else
|
||||
SetValue (id, value.ToString (CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see
|
||||
/// cref="T:System.Collections.Generic.IEnumerable`1" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="values">
|
||||
/// A <see cref="T:System.Collections.Generic.IEnumerable`1"
|
||||
/// /> containing the <see cref="string"/> objects to store
|
||||
/// in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, IEnumerable<string> values)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (values == null) {
|
||||
RemoveValue (id);
|
||||
return;
|
||||
}
|
||||
|
||||
var l = new ByteVectorCollection ();
|
||||
foreach (string value in values) {
|
||||
if (string.IsNullOrEmpty (value))
|
||||
continue;
|
||||
|
||||
ByteVector data = ByteVector.FromString (value, StringType);
|
||||
data.Add (0);
|
||||
l.Add (data);
|
||||
}
|
||||
|
||||
if (l.Count == 0)
|
||||
RemoveValue (id);
|
||||
else
|
||||
SetValue (id, l);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see cref="T:string[]" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="values">
|
||||
/// A <see cref="T:string[]" /> containing the values to store
|
||||
/// in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, params string[] values)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (values == null || values.Length == 0)
|
||||
RemoveValue (id);
|
||||
else
|
||||
SetValue (id, values as IEnumerable<string>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the item with the specified ID from the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector"/> object containing the ID of
|
||||
/// the item to remove from the current instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void RemoveValue (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
if (ContainsKey (id))
|
||||
Remove (id);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Populates the current instance by reading in the contents
|
||||
/// of a raw RIFF list stored in a <see cref="ByteVector" />
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw RIFF list to
|
||||
/// read into the current instance.
|
||||
/// </param>
|
||||
void Parse (ByteVector data)
|
||||
{
|
||||
int offset = 0;
|
||||
while (offset + 8 < data.Count) {
|
||||
ByteVector id = data.Mid (offset, 4);
|
||||
int length = (int)data.Mid (offset + 4, 4).ToUInt (false);
|
||||
|
||||
if (!ContainsKey (id))
|
||||
Add (id, new ByteVectorCollection ());
|
||||
|
||||
this[id].Add (data.Mid (offset + 8, length));
|
||||
|
||||
if (length % 2 == 1)
|
||||
length++;
|
||||
|
||||
offset += 8 + length;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 797e2ca39be1491eca498676dbe168bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,503 @@
|
||||
//
|
||||
// ListTag.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This abstract class extends <see cref="Tag" /> to provide support
|
||||
/// for reading and writing tags stored in the RIFF list format.
|
||||
/// </summary>
|
||||
public abstract class ListTag : Tag
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the <see cref="List" /> object.
|
||||
/// </summary>
|
||||
readonly List fields;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="ListTag" /> with no contents.
|
||||
/// </summary>
|
||||
protected ListTag ()
|
||||
{
|
||||
fields = new List ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="MovieIdTag" /> using a specified RIFF list.
|
||||
/// </summary>
|
||||
/// <param name="fields">
|
||||
/// A <see cref="List"/> object to use in the new instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="fields" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
protected ListTag (List fields)
|
||||
{
|
||||
if (fields == null)
|
||||
throw new ArgumentNullException (nameof (fields));
|
||||
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="ListTag" /> by reading the contents of a raw
|
||||
/// RIFF list stored in a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw RIFF list to
|
||||
/// read into the new instance.
|
||||
/// </param>
|
||||
protected ListTag (ByteVector data)
|
||||
{
|
||||
fields = new List (data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="ListTag" /> by reading the contents of a raw RIFF
|
||||
/// list from a specified position in a <see
|
||||
/// cref="TagLib.File" />.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object containing the file
|
||||
/// from which the contents of the new instance is to be
|
||||
/// read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the list.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the number of bytes
|
||||
/// to read.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
protected ListTag (TagLib.File file, long position, int length)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
|
||||
if (length < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (length));
|
||||
|
||||
if (position < 0 || position > file.Length - length)
|
||||
throw new ArgumentOutOfRangeException (nameof (position));
|
||||
|
||||
fields = new List (file, position, length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="StringType"/> value used for parsing
|
||||
/// and rendering the contents of this tag.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The value must be StringType.Latin1 or StringType.UTF8.
|
||||
/// </remarks>
|
||||
public StringType StringType {
|
||||
get => fields.StringType;
|
||||
set => fields.StringType = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance enclosed in the appropriate
|
||||
/// item.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
public abstract ByteVector RenderEnclosed ();
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance enclosed in an item with a
|
||||
/// specified ID.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector"/> object containing the ID of
|
||||
/// the item to enclose the current instance in.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
protected ByteVector RenderEnclosed (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
return fields.RenderEnclosed (id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance as a raw RIFF list.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
public ByteVector Render ()
|
||||
{
|
||||
return fields.Render ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="ByteVectorCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVectorCollection" /> object containing
|
||||
/// the values of the specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public ByteVectorCollection GetValues (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
return fields.GetValues (id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="T:string[]" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="T:string[]" /> containing the values of the
|
||||
/// specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public string[] GetValuesAsStrings (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
return fields.GetValuesAsStrings (id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values for a specified item in the current
|
||||
/// instance as a <see cref="StringCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="StringCollection" /> object containing the
|
||||
/// values of the specified item.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
[Obsolete ("Use GetValuesAsStrings(ByteVector)")]
|
||||
public StringCollection GetValuesAsStringCollection (ByteVector id)
|
||||
{
|
||||
return new StringCollection (
|
||||
fields.GetValuesAsStrings (id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value for a specified item in the current
|
||||
/// instance as a <see cref="uint"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="uint" /> value containing the first value
|
||||
/// with the specified ID that could be converted to an
|
||||
/// integer, or zero if none could be found.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public uint GetValueAsUInt (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
return fields.GetValueAsUInt (id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see cref="T:ByteVector[]"
|
||||
/// />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="T:ByteVector[]" /> containing the values to
|
||||
/// store in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, params ByteVector[] value)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
fields.SetValue (id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see
|
||||
/// cref="ByteVectorCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="ByteVectorCollection" /> object containing
|
||||
/// the values to store in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, ByteVectorCollection value)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
fields.SetValue (id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the value of a <see cref="uint"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="uint" /> value to store in the specified
|
||||
/// item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, uint value)
|
||||
{
|
||||
fields.SetValue (id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see
|
||||
/// cref="StringCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="StringCollection" /> object containing the
|
||||
/// values to store in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
[Obsolete ("Use SetValue(ByteVector,string[])")]
|
||||
public void SetValue (ByteVector id, StringCollection value)
|
||||
{
|
||||
fields.SetValue (id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value for a specified item in the current
|
||||
/// instance to the contents of a <see cref="T:string[]" />.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector" /> object containing the ID of
|
||||
/// the item to set.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// A <see cref="T:string[]" /> containing the values to store
|
||||
/// in the specified item.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void SetValue (ByteVector id, params string[] value)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
fields.SetValue (id, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the item with the specified ID from the current
|
||||
/// instance.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="ByteVector"/> object containing the ID of
|
||||
/// the item to remove from the current instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="id" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="id" /> isn't exactly four bytes long.
|
||||
/// </exception>
|
||||
public void RemoveValue (ByteVector id)
|
||||
{
|
||||
if (id == null)
|
||||
throw new ArgumentNullException (nameof (id));
|
||||
|
||||
if (id.Count != 4)
|
||||
throw new ArgumentException ("ID must be 4 bytes long.", nameof (id));
|
||||
|
||||
fields.RemoveValue (id);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region TagLib.Tag
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not the current instance is empty.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true" /> if the current instance does not
|
||||
/// any values. Otherwise <see langword="false" />.
|
||||
/// </value>
|
||||
public override bool IsEmpty {
|
||||
get { return fields.Count == 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the values stored in the current instance.
|
||||
/// </summary>
|
||||
public override void Clear ()
|
||||
{
|
||||
fields.Clear ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 506a556e0ad0577a69229948e87b11f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,238 @@
|
||||
//
|
||||
// MovieIdTag.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="ListTag" /> to provide support for
|
||||
/// reading and writing MovieID tags.
|
||||
/// </summary>
|
||||
public class MovieIdTag : ListTag
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="MovieIdTag" /> with no contents.
|
||||
/// </summary>
|
||||
public MovieIdTag ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="MovieIdTag" /> by reading the contents of a raw
|
||||
/// RIFF list stored in a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector"/> containing a raw RIFF list to
|
||||
/// read into the new instance.
|
||||
/// </param>
|
||||
public MovieIdTag (ByteVector data) : base (data)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="MovieIdTag" /> by reading the contents of a raw
|
||||
/// RIFF list from a specified position in a <see
|
||||
/// cref="TagLib.File"/>.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="TagLib.File" /> object containing the file
|
||||
/// from which the contents of the new instance is to be
|
||||
/// read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the list.
|
||||
/// </param>
|
||||
/// <param name="length">
|
||||
/// A <see cref="int" /> value specifying the number of bytes
|
||||
/// to read.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
public MovieIdTag (TagLib.File file, long position, int length)
|
||||
: base (file, position, length)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Renders the current instance enclosed in a "MID " item.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ByteVector"/> object containing the rendered
|
||||
/// version of the current instance.
|
||||
/// </returns>
|
||||
public override ByteVector RenderEnclosed ()
|
||||
{
|
||||
return RenderEnclosed ("MID ");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region TagLib.Tag
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag types contained in the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="TagTypes.MovieId" />.
|
||||
/// </value>
|
||||
public override TagTypes TagTypes {
|
||||
get { return TagTypes.MovieId; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the title for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the title for
|
||||
/// the media described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "TITL" item.
|
||||
/// </remarks>
|
||||
public override string Title {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("TITL"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("TITL", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the performers or artists who performed in
|
||||
/// the media described by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the performers or
|
||||
/// artists who performed in the media described by the
|
||||
/// current instance or an empty array if no value is
|
||||
/// present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "IART" item.
|
||||
/// </remarks>
|
||||
public override string[] Performers {
|
||||
get { return GetValuesAsStrings ("IART"); }
|
||||
set { SetValue ("IART", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets a user comment on the media represented by
|
||||
/// the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing user comments
|
||||
/// on the media represented by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "COMM" item.
|
||||
/// </remarks>
|
||||
public override string Comment {
|
||||
get {
|
||||
foreach (string s in GetValuesAsStrings ("COMM"))
|
||||
if (!string.IsNullOrEmpty (s))
|
||||
return s;
|
||||
|
||||
return null;
|
||||
}
|
||||
set { SetValue ("COMM", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the genres of the media represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> containing the genres of the
|
||||
/// media represented by the current instance or an empty
|
||||
/// array if no value is present.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "GENR" item.
|
||||
/// </remarks>
|
||||
public override string[] Genres {
|
||||
get { return GetValuesAsStrings ("GENR"); }
|
||||
set { SetValue ("GENR", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the position of the media represented by
|
||||
/// the current instance in its containing album.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the position of the
|
||||
/// media represented by the current instance in its
|
||||
/// containing album or zero if not specified.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "PRT1" item.
|
||||
/// </remarks>
|
||||
public override uint Track {
|
||||
get { return GetValueAsUInt ("PRT1"); }
|
||||
set { SetValue ("PRT1", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the number of tracks in the album
|
||||
/// containing the media represented by the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="uint" /> containing the number of tracks in
|
||||
/// the album containing the media represented by the current
|
||||
/// instance or zero if not specified.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This property is implemented using the "PRT2" item.
|
||||
/// </remarks>
|
||||
public override uint TrackCount {
|
||||
get { return GetValueAsUInt ("PRT2"); }
|
||||
set { SetValue ("PRT2", value); }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e35f343dc0482b3cae5ee678fa31b48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,746 @@
|
||||
//
|
||||
// WaveFormatEx.cs:
|
||||
//
|
||||
// Author:
|
||||
// Brian Nickel (brian.nickel@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Brian Nickel
|
||||
//
|
||||
// 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.Riff
|
||||
{
|
||||
/// <summary>
|
||||
/// This structure provides a representation of a Microsoft
|
||||
/// WaveFormatEx structure.
|
||||
/// </summary>
|
||||
public struct WaveFormatEx : IAudioCodec, ILosslessAudioCodec
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the number of audio channels.
|
||||
/// </summary>
|
||||
readonly ushort channels;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the number of samples per second.
|
||||
/// </summary>
|
||||
readonly uint samples_per_second;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="WaveFormatEx" /> by reading the raw structure from
|
||||
/// the beginning of a <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 16 bytes.
|
||||
/// </exception>
|
||||
[Obsolete ("Use WaveFormatEx(ByteVector,int)")]
|
||||
public WaveFormatEx (ByteVector data)
|
||||
: this (data, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="WaveFormatEx" /> by reading the raw structure from
|
||||
/// a specified position in a <see cref="ByteVector" />
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the raw
|
||||
/// data structure.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// A <see cref="int" /> value specifying the index in
|
||||
/// <paramref name="data"/> at which the structure begins.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="offset" /> is less than zero.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> contains less than 16 bytes at
|
||||
/// <paramref name="offset" />.
|
||||
/// </exception>
|
||||
public WaveFormatEx (ByteVector data, int offset)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException (nameof (offset));
|
||||
|
||||
if (offset + 16 > data.Count)
|
||||
throw new CorruptFileException ("Expected 16 bytes.");
|
||||
|
||||
FormatTag = data.Mid (offset, 2).ToUShort (false);
|
||||
channels = data.Mid (offset + 2, 2).ToUShort (false);
|
||||
samples_per_second = data.Mid (offset + 4, 4).ToUInt (false);
|
||||
AverageBytesPerSecond = data.Mid (offset + 8, 4).ToUInt (false);
|
||||
BitsPerSample = data.Mid (offset + 14, 2).ToUShort (false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format tag of the audio described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ushort" /> value containing the format tag
|
||||
/// of the audio.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Format tags indicate the codec of the audio contained in
|
||||
/// the file and are contained in a Microsoft registry. For
|
||||
/// a description of the format, use <see cref="Description"
|
||||
/// />.
|
||||
/// </remarks>
|
||||
public ushort FormatTag { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the average bytes per second of the audio described
|
||||
/// by the current instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ushort" /> value containing the average
|
||||
/// bytes per second of the audio.
|
||||
/// </returns>
|
||||
public uint AverageBytesPerSecond { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bits per sample of the audio described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ushort" /> value containing the bits per
|
||||
/// sample of the audio.
|
||||
/// </returns>
|
||||
public ushort BitsPerSample { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ILosslessAudioCodec
|
||||
|
||||
int ILosslessAudioCodec.BitsPerSample {
|
||||
get { return BitsPerSample; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAudioCodec
|
||||
|
||||
/// <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 (int)Math.Round (AverageBytesPerSecond * 8d / 1000d);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 (int)samples_per_second; }
|
||||
}
|
||||
|
||||
/// <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 channels; }
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Always <see cref="TimeSpan.Zero" />.
|
||||
/// </value>
|
||||
public TimeSpan Duration {
|
||||
get { return TimeSpan.Zero; }
|
||||
}
|
||||
|
||||
/// <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 {
|
||||
switch (FormatTag) {
|
||||
case 0x0000:
|
||||
return "Unknown Wave Format";
|
||||
case 0x0001:
|
||||
return "PCM Audio";
|
||||
case 0x0002:
|
||||
return "Microsoft Adaptive PCM Audio";
|
||||
case 0x0003:
|
||||
return "PCM Audio in IEEE floating-point format";
|
||||
case 0x0004:
|
||||
return "Compaq VSELP Audio";
|
||||
case 0x0005:
|
||||
return "IBM CVSD Audio";
|
||||
case 0x0006:
|
||||
return "Microsoft ALAW Audio";
|
||||
case 0x0007:
|
||||
return "Microsoft MULAW Audio";
|
||||
case 0x0008:
|
||||
return "Microsoft DTS Audio";
|
||||
case 0x0009:
|
||||
return "Microsoft DRM Encrypted Audio";
|
||||
case 0x000A:
|
||||
return "Microsoft Speech Audio";
|
||||
case 0x000B:
|
||||
return "Microsoft Windows Media RT Voice Audio";
|
||||
case 0x0010:
|
||||
return "OKI ADPCM Audio";
|
||||
case 0x0011:
|
||||
return "Intel ADPCM Audio";
|
||||
case 0x0012:
|
||||
return "VideoLogic ADPCM Audio";
|
||||
case 0x0013:
|
||||
return "Sierra ADPCM Audio";
|
||||
case 0x0014:
|
||||
return "Antex ADPCM Audio";
|
||||
case 0x0015:
|
||||
return "DSP DIGISTD Audio";
|
||||
case 0x0016:
|
||||
return "DSP DIGIFIX Audio";
|
||||
case 0x0017:
|
||||
return "Dialogic OKI ADPCM Audio";
|
||||
case 0x0018:
|
||||
return "Media Vision ADPCM Audio for Jazz 16";
|
||||
case 0x0019:
|
||||
return "Hewlett-Packard CU Audio";
|
||||
case 0x001A:
|
||||
return "Hewlett-Packard Dynamic Voice Audio";
|
||||
case 0x0020:
|
||||
return "Yamaha ADPCM Audio";
|
||||
case 0x0021:
|
||||
return "Speech Compression Audio";
|
||||
case 0x0022:
|
||||
return "DSP Group True Speech Audio";
|
||||
case 0x0023:
|
||||
return "Echo Speech Audio";
|
||||
case 0x0024:
|
||||
return "Ahead AF36 Audio";
|
||||
case 0x0025:
|
||||
return "Audio Processing Technology Audio";
|
||||
case 0x0026:
|
||||
return "Ahead AF10 Audio";
|
||||
case 0x0027:
|
||||
return "Aculab Prosody CTI Speech Card Audio";
|
||||
case 0x0028:
|
||||
return "Merging Technologies LRC Audio";
|
||||
case 0x0030:
|
||||
return "Dolby AC2 Audio";
|
||||
case 0x0031:
|
||||
return "Microsoft GSM6.10 Audio";
|
||||
case 0x0032:
|
||||
return "Microsoft MSN Audio";
|
||||
case 0x0033:
|
||||
return "Antex ADPCME Audio";
|
||||
case 0x0034:
|
||||
return "Control Resources VQLPC";
|
||||
case 0x0035:
|
||||
return "DSP REAL Audio";
|
||||
case 0x0036:
|
||||
return "DSP ADPCM Audio";
|
||||
case 0x0037:
|
||||
return "Control Resources CR10 Audio";
|
||||
case 0x0038:
|
||||
return "Natural MicroSystems VBXADPCM Audio";
|
||||
case 0x0039:
|
||||
return "Roland RDAC Proprietary Audio Format";
|
||||
case 0x003A:
|
||||
return "Echo Speech Proprietary Audio Compression Format";
|
||||
case 0x003B:
|
||||
return "Rockwell ADPCM Audio";
|
||||
case 0x003C:
|
||||
return "Rockwell DIGITALK Audio";
|
||||
case 0x003D:
|
||||
return "Xebec Proprietary Audio Compression Format";
|
||||
case 0x0040:
|
||||
return "Antex G721 ADPCM Audio";
|
||||
case 0x0041:
|
||||
return "Antex G728 CELP Audio";
|
||||
case 0x0042:
|
||||
return "Microsoft MSG723 Audio";
|
||||
case 0x0043:
|
||||
return "Microsoft MSG723.1 Audio";
|
||||
case 0x0044:
|
||||
return "Microsoft MSG729 Audio";
|
||||
case 0x0045:
|
||||
return "Microsoft SPG726 Audio";
|
||||
case 0x0050:
|
||||
return "Microsoft MPEG Audio";
|
||||
case 0x0052:
|
||||
return "InSoft RT24 Audio";
|
||||
case 0x0053:
|
||||
return "InSoft PAC Audio";
|
||||
case 0x0055:
|
||||
return "ISO/MPEG Layer 3 Audio";
|
||||
case 0x0059:
|
||||
return "Lucent G723 Audio";
|
||||
case 0x0060:
|
||||
return "Cirrus Logic Audio";
|
||||
case 0x0061:
|
||||
return "ESS Technology PCM Audio";
|
||||
case 0x0062:
|
||||
return "Voxware Audio";
|
||||
case 0x0063:
|
||||
return "Canopus ATRAC Audio";
|
||||
case 0x0064:
|
||||
return "APICOM G726 ADPCM Audio";
|
||||
case 0x0065:
|
||||
return "APICOM G722 ADPCM Audio";
|
||||
case 0x0067:
|
||||
return "Microsoft DSAT Display Audio";
|
||||
case 0x0069:
|
||||
return "Voxware Byte Aligned Audio";
|
||||
case 0x0070:
|
||||
return "Voxware AC8 Audio";
|
||||
case 0x0071:
|
||||
return "Voxware AC10 Audio";
|
||||
case 0x0072:
|
||||
return "Voxware AC16 Audio";
|
||||
case 0x0073:
|
||||
return "Voxware AC20 Audio";
|
||||
case 0x0074:
|
||||
return "Voxware RT24 Audio";
|
||||
case 0x0075:
|
||||
return "Voxware RT29 Audio";
|
||||
case 0x0076:
|
||||
return "Voxware RT29HW Audio";
|
||||
case 0x0077:
|
||||
return "Voxware VR12 Audio";
|
||||
case 0x0078:
|
||||
return "Voxware VR18 Audio";
|
||||
case 0x0079:
|
||||
return "Voxware TQ40 Audio";
|
||||
case 0x007A:
|
||||
return "Voxware SC3 Audio";
|
||||
case 0x007B:
|
||||
return "Voxware SC3 Audio";
|
||||
case 0x0080:
|
||||
return "SoftSound Audio";
|
||||
case 0x0081:
|
||||
return "Voxware TQ60 Audio";
|
||||
case 0x0082:
|
||||
return "Microsoft RT24 Audio";
|
||||
case 0x0083:
|
||||
return "AT&T G729A Audio";
|
||||
case 0x0084:
|
||||
return "Motion Pixels MVI2 Audio";
|
||||
case 0x0085:
|
||||
return "Datafusion Systems G726 Audio";
|
||||
case 0x0086:
|
||||
return "Datafusion Systems G610 Audio";
|
||||
case 0x0088:
|
||||
return "Iterated Systems Audio";
|
||||
case 0x0089:
|
||||
return "OnLive! Audio";
|
||||
case 0x008A:
|
||||
return "Multitude FT SX20 Audio";
|
||||
case 0x008B:
|
||||
return "InfoCom ITS ACM G721 Audio";
|
||||
case 0x008C:
|
||||
return "Convedia G729 Audio";
|
||||
case 0x008D:
|
||||
return "Congruency Audio";
|
||||
case 0x0091:
|
||||
return "Siemens Business Communications 24 Audio";
|
||||
case 0x0092:
|
||||
return "Sonic Foundary Dolby AC3 Audio";
|
||||
case 0x0093:
|
||||
return "MediaSonic G723 Audio";
|
||||
case 0x0094:
|
||||
return "Aculab Prosody CTI Speech Card Audio";
|
||||
case 0x0097:
|
||||
return "ZyXEL ADPCM";
|
||||
case 0x0098:
|
||||
return "Philips Speech Processing LPCBB Audio";
|
||||
case 0x0099:
|
||||
return "Studer Professional PACKED Audio";
|
||||
case 0x00A0:
|
||||
return "Malden Electronics Phony Talk Audio";
|
||||
case 0x00A1:
|
||||
return "Racal Recorder GSM Audio";
|
||||
case 0x00A2:
|
||||
return "Racal Recorder G720.a Audio";
|
||||
case 0x00A3:
|
||||
return "Racal G723.1 Audio";
|
||||
case 0x00A4:
|
||||
return "Racal Tetra ACELP Audio";
|
||||
case 0x00B0:
|
||||
return "NEC AAC Audio";
|
||||
case 0x0100:
|
||||
return "Rhetorex ADPCM Audio";
|
||||
case 0x0101:
|
||||
return "BeCubed IRAT Audio";
|
||||
case 0x0111:
|
||||
return "Vivo G723 Audio";
|
||||
case 0x0112:
|
||||
return "Vivo Siren Audio";
|
||||
case 0x0120:
|
||||
return "Philips Speach Processing CELP Audio";
|
||||
case 0x0121:
|
||||
return "Philips Speach Processing GRUNDIG Audio";
|
||||
case 0x0123:
|
||||
return "Digital Equipment Corporation G723 Audio";
|
||||
case 0x0125:
|
||||
return "Sanyo LD-ADPCM Audio";
|
||||
case 0x0130:
|
||||
return "Sipro Lab ACELPNET Audio";
|
||||
case 0x0131:
|
||||
return "Sipro Lab ACELP4800 Audio";
|
||||
case 0x0132:
|
||||
return "Sipro Lab ACELP8v3 Audio";
|
||||
case 0x0133:
|
||||
return "Sipro Lab G729 Audio";
|
||||
case 0x0134:
|
||||
return "Sipro Lab G729A Audio";
|
||||
case 0x0135:
|
||||
return "Sipro Lab KELVIN Audio";
|
||||
case 0x0136:
|
||||
return "VoiceAge AMR Audio";
|
||||
case 0x0140:
|
||||
return "Dictaphone G726 ADPCM Audio";
|
||||
case 0x0141:
|
||||
return "Dictaphone CELP68 Audio";
|
||||
case 0x0142:
|
||||
return "Dictaphone CELP54 Audio";
|
||||
case 0x0150:
|
||||
return "QUALCOMM Pure Voice Audio";
|
||||
case 0x0151:
|
||||
return "QUALCOMM Half Rate Audio";
|
||||
case 0x0155:
|
||||
return "Ring Zero TUBGSM Audio";
|
||||
case 0x0160:
|
||||
return "Microsoft WMA1 Audio";
|
||||
case 0x0161:
|
||||
return "Microsoft WMA2 Audio";
|
||||
case 0x0162:
|
||||
return "Microsoft Multichannel WMA Audio";
|
||||
case 0x0163:
|
||||
return "Microsoft Lossless WMA Audio";
|
||||
case 0x0170:
|
||||
return "Unisys NAP ADPCM Audio";
|
||||
case 0x0171:
|
||||
return "Unisys NAP ULAW Audio";
|
||||
case 0x0172:
|
||||
return "Unisys NAP ALAW Audio";
|
||||
case 0x0173:
|
||||
return "Unisys NAP 16K Audio";
|
||||
case 0X0174:
|
||||
return "SysCom ACM SYC008 Audio";
|
||||
case 0x0175:
|
||||
return "SysCom ACM SYC701 G726L Audio";
|
||||
case 0x0176:
|
||||
return "SysCom ACM SYC701 CELP54 Audio";
|
||||
case 0x0177:
|
||||
return "SysCom ACM SYC701 CELP68 Audio";
|
||||
case 0x0178:
|
||||
return "Knowledge Adventure ADPCM Audio";
|
||||
case 0x0180:
|
||||
return "MPEG2 AAC Audio";
|
||||
case 0x0190:
|
||||
return "Digital Theater Systems DTS DS Audio";
|
||||
case 0x1979:
|
||||
return "Innings ADPCM Audio";
|
||||
case 0x0200:
|
||||
return "Creative ADPCM Audio";
|
||||
case 0x0202:
|
||||
return "Creative FastSpeech8 Audio";
|
||||
case 0x0203:
|
||||
return "Creative FastSpeech10 Audio";
|
||||
case 0x0210:
|
||||
return "UHER ADPCM Audio";
|
||||
case 0x0220:
|
||||
return "Quarterdeck Audio";
|
||||
case 0x0230:
|
||||
return "I-Link VC Audio";
|
||||
case 0x0240:
|
||||
return "Aureal RAW SPORT Audio";
|
||||
case 0x0250:
|
||||
return "Interactive Prodcuts HSX Audio";
|
||||
case 0x0251:
|
||||
return "Interactive Products RPELP Audio";
|
||||
case 0x0260:
|
||||
return "Consistens Software CS2 Audio";
|
||||
case 0x0270:
|
||||
return "Sony SCX Audio";
|
||||
case 0x0271:
|
||||
return "Sony SCY Audio";
|
||||
case 0x0272:
|
||||
return "Sony ATRAC3 Audio";
|
||||
case 0x0273:
|
||||
return "Sony SPC Audio";
|
||||
case 0x0280:
|
||||
return "Telum Audio";
|
||||
case 0x0281:
|
||||
return "Telum IA Audio";
|
||||
case 0x0285:
|
||||
return "Norcom Voice Systems ADPCM Audio";
|
||||
case 0x0300:
|
||||
return "Fujitsu FM TOWNS SND Audio";
|
||||
case 0x0301:
|
||||
case 0x0302:
|
||||
case 0x0303:
|
||||
case 0x0304:
|
||||
case 0x0305:
|
||||
case 0x0306:
|
||||
case 0x0307:
|
||||
case 0x0308:
|
||||
return "Unknown Fujitsu Audio";
|
||||
case 0x0350:
|
||||
return "Micronas Semiconductors Development Audio";
|
||||
case 0x0351:
|
||||
return "Micronas Semiconductors CELP833 Audio";
|
||||
case 0x0400:
|
||||
return "Brooktree Digital Audio";
|
||||
case 0x0450:
|
||||
return "QDesign Audio";
|
||||
case 0x0680:
|
||||
return "AT&T VME VMPCM Audio";
|
||||
case 0x0681:
|
||||
return "AT&T TPC Audio";
|
||||
case 0x1000:
|
||||
return "Ing. C. Olivetti & C., S.p.A. GSM Audio";
|
||||
case 0x1001:
|
||||
return "Ing. C. Olivetti & C., S.p.A. ADPCM Audio";
|
||||
case 0x1002:
|
||||
return "Ing. C. Olivetti & C., S.p.A. CELP Audio";
|
||||
case 0x1003:
|
||||
return "Ing. C. Olivetti & C., S.p.A. SBC Audio";
|
||||
case 0x1004:
|
||||
return "Ing. C. Olivetti & C., S.p.A. OPR Audio";
|
||||
case 0x1100:
|
||||
return "Lernout & Hauspie Audio";
|
||||
case 0X1101:
|
||||
return "Lernout & Hauspie CELP Audio";
|
||||
case 0X1102:
|
||||
return "Lernout & Hauspie SB8 Audio";
|
||||
case 0X1103:
|
||||
return "Lernout & Hauspie SB12 Audio";
|
||||
case 0X1104:
|
||||
return "Lernout & Hauspie SB16 Audio";
|
||||
case 0x1400:
|
||||
return "Norris Audio";
|
||||
case 0x1500:
|
||||
return "AT&T Soundspace Musicompress Audio";
|
||||
case 0x1971:
|
||||
return "Sonic Foundry Lossless Audio";
|
||||
case 0x2000:
|
||||
return "FAST Multimedia DVM Audio";
|
||||
case 0x4143:
|
||||
return "Divio AAC";
|
||||
case 0x4201:
|
||||
return "Nokia Adaptive Multirate Audio";
|
||||
case 0x4243:
|
||||
return "Divio G726 Audio";
|
||||
case 0x7000:
|
||||
return "3Com NBX Audio";
|
||||
case 0x7A21:
|
||||
return "Microsoft Adaptive Multirate Audio";
|
||||
case 0x7A22:
|
||||
return "Microsoft Adaptive Multirate Audio with silence detection";
|
||||
case 0xA100:
|
||||
return "Comverse Infosys G723 1 Audio";
|
||||
case 0xA101:
|
||||
return "Comverse Infosys AVQSBC Audio";
|
||||
case 0xA102:
|
||||
return "Comverse Infosys OLDSBC Audio";
|
||||
case 0xA103:
|
||||
return "Symbol Technology G729A Audio";
|
||||
case 0xA104:
|
||||
return "VoiceAge AMR WB Audio";
|
||||
case 0xA105:
|
||||
return "Ingenient G726 Audio";
|
||||
case 0xA106:
|
||||
return "ISO/MPEG-4 Advanced Audio Coding";
|
||||
case 0xA107:
|
||||
return "Encore G726 Audio";
|
||||
default:
|
||||
return "Unknown Audio (" + FormatTag + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region IEquatable
|
||||
|
||||
/// <summary>
|
||||
/// Generates a hash code for the current instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="int" /> value containing the hash code for
|
||||
/// the current instance.
|
||||
/// </returns>
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
unchecked {
|
||||
return (int)(FormatTag ^ channels ^
|
||||
samples_per_second ^
|
||||
AverageBytesPerSecond ^
|
||||
BitsPerSample);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the current instance is equal to
|
||||
/// another object.
|
||||
/// </summary>
|
||||
/// <param name="other">
|
||||
/// A <see cref="object" /> to compare to the current
|
||||
/// instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not the
|
||||
/// current instance is equal to <paramref name="other" />.
|
||||
/// </returns>
|
||||
/// <seealso cref="M:System.IEquatable`1.Equals" />
|
||||
public override bool Equals (object other)
|
||||
{
|
||||
if (!(other is WaveFormatEx))
|
||||
return false;
|
||||
|
||||
return Equals ((WaveFormatEx)other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the current instance is equal to
|
||||
/// another instance of <see cref="WaveFormatEx" />.
|
||||
/// </summary>
|
||||
/// <param name="other">
|
||||
/// A <see cref="WaveFormatEx" /> object to compare to the
|
||||
/// current instance.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="bool" /> value indicating whether or not the
|
||||
/// current instance is equal to <paramref name="other" />.
|
||||
/// </returns>
|
||||
/// <seealso cref="M:System.IEquatable`1.Equals" />
|
||||
public bool Equals (WaveFormatEx other)
|
||||
{
|
||||
return FormatTag == other.FormatTag &&
|
||||
channels == other.channels &&
|
||||
samples_per_second == other.samples_per_second &&
|
||||
AverageBytesPerSecond == other.AverageBytesPerSecond &&
|
||||
BitsPerSample == other.BitsPerSample;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not two instances of <see
|
||||
/// cref="WaveFormatEx" /> are equal to eachother.
|
||||
/// </summary>
|
||||
/// <param name="first">
|
||||
/// A <see cref="WaveFormatEx" /> object to compare.
|
||||
/// </param>
|
||||
/// <param name="second">
|
||||
/// A <see cref="WaveFormatEx" /> object to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="first" /> is
|
||||
/// equal to <paramref name="second" />. Otherwise, <see
|
||||
/// langword="false" />.
|
||||
/// </returns>
|
||||
public static bool operator == (WaveFormatEx first, WaveFormatEx second)
|
||||
{
|
||||
return first.Equals (second);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not two instances of <see
|
||||
/// cref="WaveFormatEx" /> differ.
|
||||
/// </summary>
|
||||
/// <param name="first">
|
||||
/// A <see cref="WaveFormatEx" /> object to compare.
|
||||
/// </param>
|
||||
/// <param name="second">
|
||||
/// A <see cref="WaveFormatEx" /> object to compare.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="first" /> is
|
||||
/// unequal to <paramref name="second" />. Otherwise, <see
|
||||
/// langword="false" />.
|
||||
/// </returns>
|
||||
public static bool operator != (WaveFormatEx first, WaveFormatEx second)
|
||||
{
|
||||
return !first.Equals (second);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e1efda4c5ee8833fbbc1973f815afa3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user