#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.Flac {
#if ENABLE_PINVOKE_FLAC_DECODER
internal static partial class UnsafeNativeMethods {
/// An enumeration of the available subframe types.
internal enum FLAC__SubframeType : int {
/// Constant signal
FLAC__SUBFRAME_TYPE_CONSTANT = 0,
/// Uncompressed signal
FLAC__SUBFRAME_TYPE_VERBATIM = 1,
/// Fixed polynomial prediction
FLAC__SUBFRAME_TYPE_FIXED = 2,
/// Linear prediction
FLAC__SUBFRAME_TYPE_LPC = 3
};
/// CONSTANT subframe.
[StructLayout(LayoutKind.Sequential)]
internal struct FLAC__Subframe_Constant {
/// The constant signal value.
public Int32 Value;
};
/// VERBATIM subframe.
[StructLayout(LayoutKind.Sequential)]
internal struct FLAC__Subframe_Verbatim {
/// A pointer to verbatim signal.
public IntPtr Data; // int32 *
}
/// FIXED subframe.
[StructLayout(LayoutKind.Sequential)]
internal struct FLAC__Subframe_Fixed {
/// The residual coding method.
public FLAC__EntropyCodingMethod entropy_coding_method;
/// The polynomial order.
public uint order;
/// Warmup samples to prime the predictor, length == order.
public Int32[] warmup; //[FLAC__MAX_FIXED_ORDER];
///
/// The residual signal, length == (blocksize minus order) samples.
///
public IntPtr Residual; // int32 *
};
/// LPC subframe.
internal struct FLAC__Subframe_LPC {
/// The residual coding method.
public FLAC__EntropyCodingMethod entropy_coding_method;
/// The FIR order.
public uint order;
/// Quantized FIR filter coefficient precision in bits.
public uint qlp_coeff_precision;
/// The qlp coeff shift needed.
public int quantization_level;
/// FIR filter coefficients.
public Int32[] qlp_coeff; // [FLAC__MAX_LPC_ORDER];
/// Warmup samples to prime the predictor, length == order.
public Int32[] warmup; // [FLAC__MAX_LPC_ORDER];
///
/// The residual signal, length == (blocksize minus order) samples.
///
public IntPtr Residual; // int32 *
};
/// FLAC subframe structure.
[StructLayout(LayoutKind.Explicit)]
internal struct FLAC__Subframe {
[FieldOffset(0)]
public FLAC__SubframeType Type;
[FieldOffset(4)]
public FLAC__Subframe_Constant constant;
[FieldOffset(4)]
public FLAC__Subframe_Fixed Fixed;
[FieldOffset(4)]
public FLAC__Subframe_LPC lpc;
[FieldOffset(4)]
public FLAC__Subframe_Verbatim verbatim;
[FieldOffset(8)]
public uint wasted_bits;
};
/// FLAC frame header structure.
[StructLayout(LayoutKind.Explicit)]
internal struct FLAC__FrameHeader {
/// The number of samples per subframe.
[FieldOffset(0)]
public uint blocksize;
/// The sample rate in Hz.
[FieldOffset(4)]
public uint sample_rate;
/// The number of channels (== number of subframes).
[FieldOffset(8)]
public uint channels;
/// The channel assignment for the frame.
[FieldOffset(12)]
public FLAC__ChannelAssignment channel_assignment;
/// The sample resolution.
[FieldOffset(16)]
public uint bits_per_sample;
/// The numbering scheme used for the frame.
///
/// As a convenience, the decoder will always convert a frame number to a sample number
/// because the rules are complex.
///
[FieldOffset(20)]
public FLAC__FrameNumberType number_type;
///
/// The frame number or sample number of first sample in frame; use the \a number_type
/// value to determine which to use.
///
[FieldOffset(24)]
public UInt32 frame_number;
///
/// The frame number or sample number of first sample in frame; use the \a number_type
/// value to determine which to use.
///
[FieldOffset(24)]
public UInt64 sample_number;
///
/// CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) of the raw frame
/// header bytes, meaning everything before the CRC byte including the sync code.
///
[FieldOffset(32)]
public byte crc;
};
/// FLAC frame footer structure.
internal struct FLAC__FrameFooter {
///
/// CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with 0) of the bytes
/// before the crc, back to and including the frame header sync code.
///
public UInt16 crc;
};
/// FLAC frame structure.
internal struct FLAC__Frame {
FLAC__FrameHeader header;
//FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
FLAC__FrameFooter footer;
}
/// Contents of a Rice partitioned residual
internal struct FLAC__EntropyCodingMethod_PartitionedRiceContents {
/// The Rice parameters for each context.
public uint[] parameters;
/// Widths for escape-coded partitions.
///
/// Will be non-zero for escaped partitions and zero for unescaped partitions.
///
public uint[] raw_bits;
///
/// The capacity of the \a parameters and \a raw_bits arrays specified as an order,
/// i.e. the number of array elements allocated is 2 ^ \a capacity_by_order.
///
public uint capacity_by_order;
}
/// Header for a Rice partitioned residual.
internal struct FLAC__EntropyCodingMethod_PartitionedRice {
/// The partition order, i.e. # of contexts = 2 ^ \a order.
public uint order;
/// The context's Rice parameters and/or raw bits.
public FLAC__EntropyCodingMethod_PartitionedRiceContents[] contents;
}
/// Header for the entropy coding method.
internal struct FLAC__EntropyCodingMethod {
public FLAC__EntropyCodingMethodType type;
//union {
public FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice;
//} data;
}
}
#endif // ENABLE_PINVOKE_FLAC_DECODER
} // namespace Nuclex.Audio.Formats.Flac