// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** flac.h FLAC compression wrappers ***************************************************************************/ #ifndef MAME_UTIL_FLAC_H #define MAME_UTIL_FLAC_H #pragma once #include "osdcore.h" #include "corefile.h" #include //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> flac_encoder class flac_encoder { public: // construction/destruction flac_encoder(); flac_encoder(void *buffer, uint32_t buflength); flac_encoder(util::core_file &file); ~flac_encoder(); // configuration void set_sample_rate(uint32_t sample_rate) { m_sample_rate = sample_rate; } void set_num_channels(uint8_t num_channels) { m_channels = num_channels; } void set_block_size(uint32_t 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_t buflength); bool reset(util::core_file &file); // encode a buffer bool encode_interleaved(const int16_t *samples, uint32_t samples_per_channel, bool swap_endian = false); bool encode(int16_t *const *samples, uint32_t samples_per_channel, bool swap_endian = false); // finish up uint32_t 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 util::core_file * m_file; // output file uint32_t m_compressed_offset; // current offset with the compressed stream FLAC__byte * m_compressed_start; // start of compressed data uint32_t m_compressed_length; // length of the compressed stream // parameters uint32_t m_sample_rate; // sample rate uint8_t m_channels; // number of channels uint32_t m_block_size; // block size // header stripping bool m_strip_metadata; // strip the metadata? uint32_t 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_t length, const void *buffer2 = nullptr, uint32_t length2 = 0); flac_decoder(util::core_file &file); ~flac_decoder(); // getters (valid after reset) uint32_t sample_rate() const { return m_sample_rate; } uint8_t channels() const { return m_channels; } uint8_t bits_per_sample() const { return m_bits_per_sample; } uint32_t 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_t length, const void *buffer2 = nullptr, uint32_t length2 = 0); bool reset(uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length); bool reset(util::core_file &file); // decode to a buffer; num_samples must be a multiple of the block size bool decode_interleaved(int16_t *samples, uint32_t num_samples, bool swap_endian = false); bool decode(int16_t **samples, uint32_t num_samples, bool swap_endian = false); // finish up uint32_t 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 util::core_file * m_file; // output file uint32_t m_sample_rate; // decoded sample rate uint8_t m_channels; // decoded number of channels uint8_t m_bits_per_sample; // decoded bits per sample uint32_t m_compressed_offset; // current offset in compressed data const FLAC__byte * m_compressed_start; // start of compressed data uint32_t m_compressed_length; // length of compressed data const FLAC__byte * m_compressed2_start; // start of compressed data uint32_t m_compressed2_length; // length of compressed data int16_t * m_uncompressed_start[8];// pointer to start of uncompressed data (up to 8 streams) uint32_t m_uncompressed_offset; // current position in uncompressed data uint32_t m_uncompressed_length; // length of uncompressed data bool m_uncompressed_swap; // swap uncompressed sample data uint8_t m_custom_header[0x2a]; // custom header }; #endif // MAME_UTIL_FLAC_H