1 // license:BSD-3-Clause 2 // copyright-holders:Aaron Giles 3 /*************************************************************************** 4 5 flac.h 6 7 FLAC compression wrappers 8 9 ***************************************************************************/ 10 11 #ifndef MAME_UTIL_FLAC_H 12 #define MAME_UTIL_FLAC_H 13 14 #pragma once 15 16 #include "osdcore.h" 17 #include "corefile.h" 18 19 #include <FLAC/all.h> 20 21 22 //************************************************************************** 23 // TYPE DEFINITIONS 24 //************************************************************************** 25 26 // ======================> flac_encoder 27 28 class flac_encoder 29 { 30 public: 31 // construction/destruction 32 flac_encoder(); 33 flac_encoder(void *buffer, uint32_t buflength); 34 flac_encoder(util::core_file &file); 35 ~flac_encoder(); 36 37 // configuration set_sample_rate(uint32_t sample_rate)38 void set_sample_rate(uint32_t sample_rate) { m_sample_rate = sample_rate; } set_num_channels(uint8_t num_channels)39 void set_num_channels(uint8_t num_channels) { m_channels = num_channels; } set_block_size(uint32_t block_size)40 void set_block_size(uint32_t block_size) { m_block_size = block_size; } set_strip_metadata(bool strip)41 void set_strip_metadata(bool strip) { m_strip_metadata = strip; } 42 43 // getters (valid after reset) state()44 FLAC__StreamEncoderState state() const { return FLAC__stream_encoder_get_state(m_encoder); } state_string()45 const char *state_string() const { return FLAC__stream_encoder_get_resolved_state_string(m_encoder); } 46 47 // reset 48 bool reset(); 49 bool reset(void *buffer, uint32_t buflength); 50 bool reset(util::core_file &file); 51 52 // encode a buffer 53 bool encode_interleaved(const int16_t *samples, uint32_t samples_per_channel, bool swap_endian = false); 54 bool encode(int16_t *const *samples, uint32_t samples_per_channel, bool swap_endian = false); 55 56 // finish up 57 uint32_t finish(); 58 59 private: 60 // internal helpers 61 void init_common(); 62 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); 63 FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame); 64 65 // internal state 66 FLAC__StreamEncoder * m_encoder; // actual encoder 67 util::core_file * m_file; // output file 68 uint32_t m_compressed_offset; // current offset with the compressed stream 69 FLAC__byte * m_compressed_start; // start of compressed data 70 uint32_t m_compressed_length; // length of the compressed stream 71 72 // parameters 73 uint32_t m_sample_rate; // sample rate 74 uint8_t m_channels; // number of channels 75 uint32_t m_block_size; // block size 76 77 // header stripping 78 bool m_strip_metadata; // strip the metadata? 79 uint32_t m_ignore_bytes; // how many bytes to ignore when writing 80 bool m_found_audio; // have we hit the audio yet? 81 }; 82 83 84 // ======================> flac_decoder 85 86 class flac_decoder 87 { 88 public: 89 // construction/destruction 90 flac_decoder(); 91 flac_decoder(const void *buffer, uint32_t length, const void *buffer2 = nullptr, uint32_t length2 = 0); 92 flac_decoder(util::core_file &file); 93 ~flac_decoder(); 94 95 // getters (valid after reset) sample_rate()96 uint32_t sample_rate() const { return m_sample_rate; } channels()97 uint8_t channels() const { return m_channels; } bits_per_sample()98 uint8_t bits_per_sample() const { return m_bits_per_sample; } total_samples()99 uint32_t total_samples() const { return FLAC__stream_decoder_get_total_samples(m_decoder); } state()100 FLAC__StreamDecoderState state() const { return FLAC__stream_decoder_get_state(m_decoder); } state_string()101 const char *state_string() const { return FLAC__stream_decoder_get_resolved_state_string(m_decoder); } 102 103 // reset 104 bool reset(); 105 bool reset(const void *buffer, uint32_t length, const void *buffer2 = nullptr, uint32_t length2 = 0); 106 bool reset(uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length); 107 bool reset(util::core_file &file); 108 109 // decode to a buffer; num_samples must be a multiple of the block size 110 bool decode_interleaved(int16_t *samples, uint32_t num_samples, bool swap_endian = false); 111 bool decode(int16_t **samples, uint32_t num_samples, bool swap_endian = false); 112 113 // finish up 114 uint32_t finish(); 115 116 private: 117 // internal helpers 118 static FLAC__StreamDecoderReadStatus read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); 119 FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); 120 static void metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); 121 static FLAC__StreamDecoderTellStatus tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); 122 static FLAC__StreamDecoderWriteStatus write_callback_static(const FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); 123 FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); 124 static void error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); 125 126 // output state 127 FLAC__StreamDecoder * m_decoder; // actual encoder 128 util::core_file * m_file; // output file 129 uint32_t m_sample_rate; // decoded sample rate 130 uint8_t m_channels; // decoded number of channels 131 uint8_t m_bits_per_sample; // decoded bits per sample 132 uint32_t m_compressed_offset; // current offset in compressed data 133 const FLAC__byte * m_compressed_start; // start of compressed data 134 uint32_t m_compressed_length; // length of compressed data 135 const FLAC__byte * m_compressed2_start; // start of compressed data 136 uint32_t m_compressed2_length; // length of compressed data 137 int16_t * m_uncompressed_start[8];// pointer to start of uncompressed data (up to 8 streams) 138 uint32_t m_uncompressed_offset; // current position in uncompressed data 139 uint32_t m_uncompressed_length; // length of uncompressed data 140 bool m_uncompressed_swap; // swap uncompressed sample data 141 uint8_t m_custom_header[0x2a]; // custom header 142 }; 143 144 #endif // MAME_UTIL_FLAC_H 145