#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2009 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
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
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace Nuclex.Audio.Formats.Wave {
/// Carries the informations stored in an extensible wave format chunk
[StructLayout(LayoutKind.Sequential)]
public struct WaveFormatExtensible {
/// FormatTag specifier for normal, uncompressed PCM audio
public const ushort WAVEFORMATPCM = WaveFormatEx.WAVEFORMATPCM;
/// FormatTag specifier for the WaveFormatExtensible chunk
public const ushort WAVEFORMATEXTENSIBLE = 65534;
/// Signature by which this chunk can be recognized
public readonly static byte[] Signature = WaveFormatEx.Signature;
/// Size of the WaveFormatExtensible structure
public const int Size = 40;
/// Sample data is stored in analog format (unknown)
public static readonly Guid KSDATAFORMAT_SUBTYPE_ANALOG = new Guid(
"6dba3190-67bd-11cf-a0f7-0020afd156e4"
);
/// Sample data is stored in uncompressed PCM format
public static readonly Guid KSDATAFORMAT_SUBTYPE_PCM = new Guid(
"00000001-0000-0010-8000-00aa00389b71"
);
/// Sample data is stored in uncompressed IEEE float format
public static readonly Guid KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = new Guid(
"00000003-0000-0010-8000-00aa00389b71"
);
#if false // Undocumented sample data formats defined by windows
public static readonly Guid KSDATAFORMAT_SUBTYPE_DRM = new Guid(
"00000009-0000-0010-8000-00aa00389b71"
);
public static readonly Guid KSDATAFORMAT_SUBTYPE_ALAW = new Guid(
"00000006-0000-0010-8000-00aa00389b71"
);
public static readonly Guid KSDATAFORMAT_SUBTYPE_MULAW = new Guid(
"00000007-0000-0010-8000-00aa00389b71"
);
public static readonly Guid KSDATAFORMAT_SUBTYPE_ADPCM = new Guid(
"00000002-0000-0010-8000-00aa00389b71"
);
public static readonly Guid KSDATAFORMAT_SUBTYPE_MPEG = new Guid(
"00000050-0000-0010-8000-00aa00389b71"
);
#endif
/// Old style wave format description
public WaveFormatEx FormatEx;
/// Number of valid bits in each sample
///
///
/// The new wave format allows the number of valid bits in a sample to be less
/// than the number of bits per sample. This allows for easier handling of
/// non byte sized sample precisions because samples can be of a regular byte
/// size but the implementation doesn't have to use all of the bits.
///
///
/// Should be set to 0 (indicating it's not used) when all sample bits are
/// filled and the precision actually matches a byte size.
///
///
/// Can also contain the samples per block if the bits per sample field in the
/// wave format structure is 0.
///
///
public ushort ValidBitsPerSample;
/// Bit flags indicating which audio channels have been provided
public ChannelMaskFlags ChannelMask;
/// Specifies the actual sample data format used
public Guid SubFormat;
/// Reads the WaveFormat information structure from a binary stream
/// Reader from which to read the WaveFormat structure
/// Wave format structure to be written to the file
/// The total size of the structure as indicated in the size field
public static int Load(BinaryReader reader, out WaveFormatExtensible waveFormat) {
int totalSize = WaveFormatEx.Load(reader, out waveFormat.FormatEx);
waveFormat.ValidBitsPerSample = reader.ReadUInt16();
waveFormat.ChannelMask = (ChannelMaskFlags)reader.ReadUInt32();
byte[] subFormatGuidBytes = reader.ReadBytes(16);
waveFormat.SubFormat = new Guid(subFormatGuidBytes);
return totalSize;
}
/// Saves the WaveFormat information structure into a binary stream
/// Writer through which to write the WaveFormat structure
/// Wave format structure to be written to the file
public static void Save(BinaryWriter writer, ref WaveFormatExtensible waveFormat) {
WaveFormatEx.Save(writer, WaveFormatExtensible.Size, ref waveFormat.FormatEx);
writer.Write((UInt16)waveFormat.ValidBitsPerSample);
writer.Write((UInt32)waveFormat.ChannelMask);
byte[] subFormatGuidBytes = waveFormat.SubFormat.ToByteArray();
writer.Write(subFormatGuidBytes, 0, 16);
}
}
} // namespace Nuclex.Audio.Formats.Wave