diff options
Diffstat (limited to 'src/lib/util/flac.h')
-rw-r--r-- | src/lib/util/flac.h | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/lib/util/flac.h b/src/lib/util/flac.h new file mode 100644 index 00000000000..da37b49b75b --- /dev/null +++ b/src/lib/util/flac.h @@ -0,0 +1,167 @@ +/*************************************************************************** + + 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" +#include "../../lib/libflac/include/flac/all.h" + + +//************************************************************************** +// 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 FLAC__stream_decoder_get_sample_rate(m_decoder); } + UINT8 channels() const { return FLAC__stream_decoder_get_channels(m_decoder); } + UINT32 block_size() const { return FLAC__stream_decoder_get_blocksize(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 + void 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 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_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__ |