/*************************************************************************** flac.h FLAC compression wrappers **************************************************************************** Copyright Aaron Giles All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name 'MAME' nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ #pragma once #ifndef __FLAC_H__ #define __FLAC_H__ #include "osdcore.h" #include "corefile.h" #ifdef FLAC__NO_DLL #include "../../lib/libflac/include/flac/all.h" #else #include #endif //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> flac_encoder class flac_encoder { public: // construction/destruction flac_encoder(); flac_encoder(void *buffer, UINT32 buflength); flac_encoder(core_file &file); ~flac_encoder(); // configuration void set_sample_rate(UINT32 sample_rate) { m_sample_rate = sample_rate; } void set_num_channels(UINT8 num_channels) { m_channels = num_channels; } void set_block_size(UINT32 block_size) { m_block_size = block_size; } void set_strip_metadata(bool strip) { m_strip_metadata = strip; } // getters (valid after reset) FLAC__StreamEncoderState state() const { return FLAC__stream_encoder_get_state(m_encoder); } const char *state_string() const { return FLAC__stream_encoder_get_resolved_state_string(m_encoder); } // reset bool reset(); bool reset(void *buffer, UINT32 buflength); bool reset(core_file &file); // encode a buffer bool encode_interleaved(const INT16 *samples, UINT32 samples_per_channel, bool swap_endian = false); bool encode(INT16 *const *samples, UINT32 samples_per_channel, bool swap_endian = false); // finish up UINT32 finish(); private: // internal helpers void init_common(); static FLAC__StreamEncoderWriteStatus write_callback_static(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame); // internal state FLAC__StreamEncoder * m_encoder; // actual encoder core_file * m_file; // output file UINT32 m_compressed_offset; // current offset with the compressed stream FLAC__byte * m_compressed_start; // start of compressed data UINT32 m_compressed_length; // length of the compressed stream // parameters UINT32 m_sample_rate; // sample rate UINT8 m_channels; // number of channels UINT32 m_block_size; // block size // header stripping bool m_strip_metadata; // strip the the metadata? UINT32 m_ignore_bytes; // how many bytes to ignore when writing bool m_found_audio; // have we hit the audio yet? }; // ======================> flac_decoder class flac_decoder { public: // construction/destruction flac_decoder(); flac_decoder(const void *buffer, UINT32 length, const void *buffer2 = NULL, UINT32 length2 = 0); flac_decoder(core_file &file); ~flac_decoder(); // getters (valid after reset) UINT32 sample_rate() const { return m_sample_rate; } UINT8 channels() const { return m_channels; } UINT8 bits_per_sample() const { return m_bits_per_sample; } UINT32 total_samples() const { return FLAC__stream_decoder_get_total_samples(m_decoder); } FLAC__StreamDecoderState state() const { return FLAC__stream_decoder_get_state(m_decoder); } const char *state_string() const { return FLAC__stream_decoder_get_resolved_state_string(m_decoder); } // reset bool reset(); bool reset(const void *buffer, UINT32 length, const void *buffer2 = NULL, UINT32 length2 = 0); bool reset(UINT32 sample_rate, UINT8 num_channels, UINT32 block_size, const void *buffer, UINT32 length); bool reset(core_file &file); // decode to a buffer; num_samples must be a multiple of the block size bool decode_interleaved(INT16 *samples, UINT32 num_samples, bool swap_endian = false); bool decode(INT16 **samples, UINT32 num_samples, bool swap_endian = false); // finish up UINT32 finish(); private: // internal helpers static FLAC__StreamDecoderReadStatus read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); static void metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); static FLAC__StreamDecoderTellStatus tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); static FLAC__StreamDecoderWriteStatus write_callback_static(const FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); static void error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); // output state FLAC__StreamDecoder * m_decoder; // actual encoder core_file * m_file; // output file UINT32 m_sample_rate; // decoded sample rate UINT8 m_channels; // decoded number of channels UINT8 m_bits_per_sample; // decoded bits per sample UINT32 m_compressed_offset; // current offset in compressed data const FLAC__byte * m_compressed_start; // start of compressed data UINT32 m_compressed_length; // length of compressed data const FLAC__byte * m_compressed2_start; // start of compressed data UINT32 m_compressed2_length; // length of compressed data INT16 * m_uncompressed_start[8];// pointer to start of uncompressed data (up to 8 streams) UINT32 m_uncompressed_offset; // current position in uncompressed data UINT32 m_uncompressed_length; // length of uncompressed data bool m_uncompressed_swap; // swap uncompressed sample data UINT8 m_custom_header[0x2a]; // custom header }; #endif // __FLAC_H__