simplemad_sys 0.5.0

libmad 0.15.1b bindings for Rust
Documentation
#![crate_name = "simplemad_sys"]

extern crate libc;

use libc::{c_void, c_char, c_int, c_uint, c_ushort, c_long, uint16_t};
use std::fmt::{self, Result, Debug};
use std::ptr;

pub use libc::c_ulong;

#[link(name = "mad")]
extern {
    pub fn mad_decoder_init(decoder: *mut MadDecoder,
                            message: *mut c_void,
                            input_cb: extern fn(message: *mut c_void,
                                                stream: &MadStream) -> MadFlow,
                            header_cb: extern fn(message: *mut c_void,
                                                 header: &MadHeader) -> MadFlow,
                            filter_cb: extern fn(),
                            output_cb: extern fn(message: *mut c_void,
                                                 header: &MadHeader,
                                                 pcm: &MadPcm) -> MadFlow,
                            error_cb: extern fn(message: *mut c_void,
                                                stream: &MadStream,
                                                frame: *const c_void) -> MadFlow,
                            message_cb: extern fn());

    pub fn mad_decoder_run(decoder: &mut MadDecoder, mode: MadDecoderMode) -> c_int;
    pub fn mad_decoder_finish(decoder: &mut MadDecoder) -> c_int;
    pub fn mad_stream_buffer(stream: &MadStream, buf_start: *const u8, buf_len: c_ulong);

    pub fn mad_header_init(header: &mut MadHeader);
    pub fn mad_stream_init(stream: &mut MadStream);
    pub fn mad_frame_init(frame: &mut MadFrame);
    pub fn mad_synth_init(synth: &mut MadSynth);

    pub fn mad_stream_finish(stream: &mut MadStream);
    pub fn mad_frame_finish(frame: &mut MadFrame);

    pub fn mad_header_decode(header: &mut MadHeader, stream: &mut MadStream);
    pub fn mad_frame_decode(frame: &mut MadFrame, stream: &mut MadStream);
    pub fn mad_synth_frame(synth: &mut MadSynth, frame: &mut MadFrame);
}

/// libmad callbacks return MadFlow values, which are used to control the decoding process
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub enum MadFlow {
    /// continue normally
    Continue = 0x0000,

    /// stop decoding normally
    Stop = 0x0010,

    /// stop decoding and signal an error
    Break = 0x0011,

    /// ignore the current frame
    Ignore = 0x0020,
}

/// Errors generated by libmad
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub enum MadError {
    /// no error
    None = 0x0000,

    /// input buffer too small (or eof)
    BufLen = 0x0001,

    /// invalid (null) buffer pointer
    BufPtr = 0x0002,

    /// not enough memory
    NoMem = 0x0031,

    /// lost synchronization
    LostSync = 0x0101,

    /// reserved header layer value
    BadLayer = 0x0102,

    /// forbidden bitrate value
    BadBitRate = 0x0103,

    /// reserved sample frequency value
    BadSampleRate = 0x0104,

    /// reserved emphasis value
    BadEmphasis = 0x0105,

    /// crc check failed
    BadCRC = 0x0201,

    /// forbidden bit allocation value
    BadBitAlloc = 0x0211,

    /// bad scalefactor index
    BadScaleFactor = 0x0221,

    /// bad bitrate/mode combination
    BadMode = 0x0222,

    /// bad frame length
    BadFrameLen = 0x0231,

    /// bad big_values count
    BadBigValues = 0x0232,

    /// reserved block_type
    BadBlockType = 0x0233,

    /// bad scalefactor selection info
    BadScFSI = 0x0234,

    /// bad main_data_begin pointer
    BadDataPtr = 0x0235,

    /// bad audio data length
    BadPart3Len = 0x0236,

    /// bad huffman table select
    BadHuffTable = 0x0237,

    /// huffman data overrun
    BadHuffData = 0x0238,

    /// incompatible block_type for joint stereo
    BadStereo = 0x0239,
}

impl Default for MadError {
    fn default() -> MadError {
        MadError::None
    }
}

#[repr(C)]
pub struct MadBitPtr {
    pub byte: *mut c_char,
    pub cache: uint16_t,
    pub left: uint16_t,
}

impl Default for MadBitPtr {
    fn default() -> MadBitPtr {
        MadBitPtr {
            byte: ptr::null::<c_char>() as *mut c_char,
            cache: 0,
            left: 0,
        }
    }
}

#[repr(C)]
pub struct MadStream {
    pub buffer: *mut c_char,
    pub buff_end: *mut c_char,
    pub skip_len: c_ulong,
    pub sync: c_int,
    pub free_rate: c_ulong,
    pub this_frame: *mut c_char,
    pub next_frame: *mut c_char,
    pub ptr: MadBitPtr,
    pub anc_ptr: MadBitPtr,
    pub anc_bitlen: c_uint,
    pub buffer_mdlen: *mut c_char,
    pub md_len: c_uint,
    pub options: c_int,
    pub error: MadError,
}

impl Default for MadStream {
    fn default() -> MadStream {
        MadStream {
            buffer: ptr::null::<c_char>() as *mut c_char,
            buff_end: ptr::null::<c_char>() as *mut c_char,
            skip_len: 0,
            sync: 0,
            free_rate: 0,
            this_frame: ptr::null::<c_char>() as *mut c_char,
            next_frame: ptr::null::<c_char>() as *mut c_char,
            ptr: Default::default(),
            anc_ptr: Default::default(),
            anc_bitlen: 0,
            buffer_mdlen: ptr::null::<c_char>() as *mut c_char,
            md_len: 0,
            options: 0,
            error: MadError::None,
        }
    }
}

#[repr(C)]
pub struct MadFrame {
    pub header: MadHeader,
    pub options: c_int,
    pub sbsample: [[[i32; 32]; 36]; 2],
    pub overlap: *mut i32,
}

impl Default for MadFrame {
    fn default() -> MadFrame {
        MadFrame {
            header: Default::default(),
            options: 0,
            sbsample: [[[0; 32]; 36]; 2],
            overlap: ptr::null::<i32>() as *mut i32,
        }
    }
}

#[derive(Clone)]
#[repr(C)]
pub struct MadSynth {
    pub filter: [[[[[i32; 8]; 16]; 2]; 2]; 2],
    pub phase: c_uint,
    pub pcm: MadPcm,
}

impl Default for MadSynth {
    fn default() -> MadSynth {
        MadSynth {
            filter: [[[[[0; 8]; 16]; 2]; 2]; 2],
            phase: 0,
            pcm: Default::default(),
        }
    }
}

impl fmt::Debug for MadSynth {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "MadSynth {{phase: {}, pcm: {:?} }}",
               self.phase,
               self.pcm)
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub enum MadLayer {
    LayerI = 1,
    LayerII = 2,
    LayerIII = 3,
}

impl Default for MadLayer {
    fn default() -> MadLayer {
        MadLayer::LayerI
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub enum MadMode {
    SingleChannel = 0,
    DualChannel = 1,
    JointStereo = 2,
    Stereo = 3,
}

impl Default for MadMode {
    fn default() -> MadMode {
        MadMode::SingleChannel
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub enum MadEmphasis {
    None = 0,
    Fifty15Us = 1,
    CcittJ17 = 3,
    Reserved = 2,
}

impl Default for MadEmphasis {
    fn default() -> MadEmphasis {
        MadEmphasis::None
    }
}

#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MadTimer {
    pub seconds: c_long,
    pub fraction: c_ulong,
}

#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MadHeader {
    pub layer: MadLayer,
    pub mode: MadMode,
    pub mode_extension: c_int,
    pub emphasis: MadEmphasis,
    pub bit_rate: c_ulong,
    pub sample_rate: c_uint,
    pub crc_check: c_ushort,
    pub crc_target: c_ushort,
    pub flags: c_int,
    pub private_bits: c_int,
    pub duration: MadTimer,
}

#[derive(Clone, Copy)]
#[repr(C)]
pub struct MadPcm {
    pub sample_rate: c_uint,
    pub channels: uint16_t,
    pub length: uint16_t,
    pub samples: [[i32; 1152]; 2],
}

impl Default for MadPcm {
    fn default() -> MadPcm {
        MadPcm {
            sample_rate: 0,
            channels: 0,
            length: 0,
            samples: [[0; 1152]; 2],
        }
    }
}

impl fmt::Debug for MadPcm {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "MadPcm {{sample_rate: {}, channels: {}, length: {}}}",
               self.sample_rate,
               self.channels,
               self.length)
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub enum MadDecoderMode {
    Sync = 0,
    Async = 1,
}

impl Default for MadDecoderMode {
    fn default() -> MadDecoderMode {
        MadDecoderMode::Sync
    }
}

#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
struct MadAsyncParameters {
    pid: c_long,
    ain: c_int,
    aout: c_int,
}

#[repr(C)]
pub struct MadDecoder {
    mode: MadDecoderMode,
    options: c_int,
    async: MadAsyncParameters,
    sync: *const c_void,
    cb_data: *const c_void,
    input_func: *const c_void,
    header_func: *const c_void,
    filter_func: *const c_void,
    output_func: *const c_void,
    error_func: *const c_void,
    message_func: *const c_void,
}

impl Default for MadDecoder {
    fn default() -> MadDecoder {
        MadDecoder {
            mode: Default::default(),
            options: 0,
            async: Default::default(),
            sync: ptr::null::<c_void>(),
            cb_data: ptr::null::<c_void>(),
            input_func: ptr::null::<c_void>(),
            header_func: ptr::null::<c_void>(),
            filter_func: ptr::null::<c_void>(),
            output_func: ptr::null::<c_void>(),
            error_func: ptr::null::<c_void>(),
            message_func: ptr::null::<c_void>(),
        }
    }
}

#[cfg(test)]
mod test {
}