1 /* license:BSD-3-Clause
2 * copyright-holders:Aaron Giles
3 ***************************************************************************
7 FLAC compression wrappers
9 ***************************************************************************/
15 /***************************************************************************
17 ***************************************************************************
20 static FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
21 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes);
22 static void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
23 static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
24 static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
25 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void* client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
26 static void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
28 /* getters (valid after reset) */
29 static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
30 static uint8_t channels(flac_decoder *decoder) { return decoder->channels; }
31 static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
32 static uint32_t total_samples(flac_decoder *decoder) { return FLAC__stream_decoder_get_total_samples(decoder->decoder); }
33 static FLAC__StreamDecoderState state(flac_decoder *decoder) { return FLAC__stream_decoder_get_state(decoder->decoder); }
34 static const char *state_string(flac_decoder *decoder) { return FLAC__stream_decoder_get_resolved_state_string(decoder->decoder); }
36 /*-------------------------------------------------
37 * flac_decoder - constructor
38 *-------------------------------------------------
41 void flac_decoder_init(flac_decoder *decoder)
43 decoder->decoder = FLAC__stream_decoder_new();
44 decoder->sample_rate = 0;
45 decoder->channels = 0;
46 decoder->bits_per_sample = 0;
47 decoder->compressed_offset = 0;
48 decoder->compressed_start = NULL;
49 decoder->compressed_length = 0;
50 decoder->compressed2_start = NULL;
51 decoder->compressed2_length = 0;
52 decoder->uncompressed_offset = 0;
53 decoder->uncompressed_length = 0;
54 decoder->uncompressed_swap = 0;
57 /*-------------------------------------------------
58 * flac_decoder - destructor
59 *-------------------------------------------------
62 void flac_decoder_free(flac_decoder* decoder)
64 if ((decoder != NULL) && (decoder->decoder != NULL))
65 FLAC__stream_decoder_delete(decoder->decoder);
68 /*-------------------------------------------------
69 * reset - reset state with the original
71 *-------------------------------------------------
74 static int flac_decoder_internal_reset(flac_decoder* decoder)
76 decoder->compressed_offset = 0;
77 if (FLAC__stream_decoder_init_stream(decoder->decoder,
78 &flac_decoder_read_callback_static,
80 &flac_decoder_tell_callback_static,
83 &flac_decoder_write_callback_static,
84 &flac_decoder_metadata_callback_static,
85 &flac_decoder_error_callback_static, decoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
87 return FLAC__stream_decoder_process_until_end_of_metadata(decoder->decoder);
90 /*-------------------------------------------------
91 * reset - reset state with new memory parameters
92 * and a custom-generated header
93 *-------------------------------------------------
96 int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length)
98 /* modify the template header with our parameters */
99 static const uint8_t s_header_template[0x2a] =
101 0x66, 0x4C, 0x61, 0x43, /* +00: 'fLaC' stream header */
102 0x80, /* +04: metadata block type 0 (STREAMINFO), */
103 /* flagged as last block */
104 0x00, 0x00, 0x22, /* +05: metadata block length = 0x22 */
105 0x00, 0x00, /* +08: minimum block size */
106 0x00, 0x00, /* +0A: maximum block size */
107 0x00, 0x00, 0x00, /* +0C: minimum frame size (0 == unknown) */
108 0x00, 0x00, 0x00, /* +0F: maximum frame size (0 == unknown) */
109 0x0A, 0xC4, 0x42, 0xF0, 0x00, 0x00, 0x00, 0x00, /* +12: sample rate (0x0ac44 == 44100), */
110 /* numchannels (2), sample bits (16), */
111 /* samples in stream (0 == unknown) */
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* +1A: MD5 signature (0 == none) */
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
115 memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
116 decoder->custom_header[0x08] = decoder->custom_header[0x0a] = block_size >> 8;
117 decoder->custom_header[0x09] = decoder->custom_header[0x0b] = block_size & 0xff;
118 decoder->custom_header[0x12] = sample_rate >> 12;
119 decoder->custom_header[0x13] = sample_rate >> 4;
120 decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
122 /* configure the header ahead of the provided buffer */
123 decoder->compressed_start = (const FLAC__byte *)(decoder->custom_header);
124 decoder->compressed_length = sizeof(decoder->custom_header);
125 decoder->compressed2_start = (const FLAC__byte *)(buffer);
126 decoder->compressed2_length = length;
127 return flac_decoder_internal_reset(decoder);
130 /*-------------------------------------------------
131 * decode_interleaved - decode to an interleaved
133 *-------------------------------------------------
136 int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian)
138 /* configure the uncompressed buffer */
139 memset(decoder->uncompressed_start, 0, sizeof(decoder->uncompressed_start));
140 decoder->uncompressed_start[0] = samples;
141 decoder->uncompressed_offset = 0;
142 decoder->uncompressed_length = num_samples;
143 decoder->uncompressed_swap = swap_endian;
145 /* loop until we get everything we want */
146 while (decoder->uncompressed_offset < decoder->uncompressed_length)
147 if (!FLAC__stream_decoder_process_single(decoder->decoder))
153 /*-------------------------------------------------
154 * decode - decode to an multiple independent
156 *-------------------------------------------------
159 bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_endian)
161 /* make sure we don't have too many channels */
162 int chans = channels();
163 if (chans > ARRAY_LENGTH(m_uncompressed_start))
166 /* configure the uncompressed buffer */
167 memset(m_uncompressed_start, 0, sizeof(m_uncompressed_start));
168 for (int curchan = 0; curchan < chans; curchan++)
169 m_uncompressed_start[curchan] = samples[curchan];
170 m_uncompressed_offset = 0;
171 m_uncompressed_length = num_samples;
172 m_uncompressed_swap = swap_endian;
174 /* loop until we get everything we want */
175 while (m_uncompressed_offset < m_uncompressed_length)
176 if (!FLAC__stream_decoder_process_single(m_decoder))
182 /*-------------------------------------------------
183 * finish - finish up the decode
184 *-------------------------------------------------
187 uint32_t flac_decoder_finish(flac_decoder* decoder)
189 /* get the final decoding position and move forward */
190 FLAC__uint64 position = 0;
191 FLAC__stream_decoder_get_decode_position(decoder->decoder, &position);
192 FLAC__stream_decoder_finish(decoder->decoder);
194 /* adjust position if we provided the header */
197 if (decoder->compressed_start == (const FLAC__byte *)(decoder->custom_header))
198 position -= decoder->compressed_length;
202 /*-------------------------------------------------
203 * read_callback - handle reads from the input
205 *-------------------------------------------------
208 #define MIN(x, y) ((x) < (y) ? (x) : (y))
210 FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
212 return flac_decoder_read_callback(client_data, buffer, bytes);
215 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes)
217 flac_decoder* decoder = (flac_decoder*)client_data;
219 uint32_t expected = *bytes;
221 /* copy from primary buffer first */
222 uint32_t outputpos = 0;
223 if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length)
225 uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
226 memcpy(&buffer[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
227 outputpos += bytes_to_copy;
228 decoder->compressed_offset += bytes_to_copy;
231 /* once we're out of that, copy from the secondary buffer */
232 if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
234 uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
235 memcpy(&buffer[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
236 outputpos += bytes_to_copy;
237 decoder->compressed_offset += bytes_to_copy;
241 /* return based on whether we ran out of data */
242 return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
245 /*-------------------------------------------------
246 * metadata_callback - handle STREAMINFO metadata
247 *-------------------------------------------------
250 void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
252 flac_decoder *fldecoder;
253 /* ignore all but STREAMINFO metadata */
254 if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO)
257 /* parse out the data we care about */
258 fldecoder = (flac_decoder *)(client_data);
259 fldecoder->sample_rate = metadata->data.stream_info.sample_rate;
260 fldecoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
261 fldecoder->channels = metadata->data.stream_info.channels;
264 /*-------------------------------------------------
265 * tell_callback - handle requests to find out
266 * where in the input stream we are
267 *-------------------------------------------------
270 FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
272 *absolute_byte_offset = ((flac_decoder *)client_data)->compressed_offset;
273 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
276 /*-------------------------------------------------
277 * write_callback - handle writes to the output
279 *-------------------------------------------------
282 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
284 return flac_decoder_write_callback(client_data, frame, buffer);
287 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void *client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
290 int shift, blocksize;
291 flac_decoder * decoder = (flac_decoder *)client_data;
293 assert(frame->header.channels == channels(decoder));
295 /* interleaved case */
296 shift = decoder->uncompressed_swap ? 8 : 0;
297 blocksize = frame->header.blocksize;
298 if (decoder->uncompressed_start[1] == NULL)
300 int16_t *dest = decoder->uncompressed_start[0] + decoder->uncompressed_offset * frame->header.channels;
301 for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
302 for (chan = 0; chan < frame->header.channels; chan++)
303 *dest++ = (int16_t)((((uint16_t)buffer[chan][sampnum]) << shift) | (((uint16_t)buffer[chan][sampnum]) >> shift));
306 /* non-interleaved case */
309 for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
310 for (chan = 0; chan < frame->header.channels; chan++)
311 if (decoder->uncompressed_start[chan] != NULL)
312 decoder->uncompressed_start[chan][decoder->uncompressed_offset] = (int16_t) ( (((uint16_t)(buffer[chan][sampnum])) << shift) | ( ((uint16_t)(buffer[chan][sampnum])) >> shift) );
314 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
318 * @fn void flac_decoder::error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
320 * @brief -------------------------------------------------
321 * error_callback - handle errors (ignore them)
322 * -------------------------------------------------.
324 * @param decoder The decoder.
325 * @param status The status.
326 * @param [in,out] client_data If non-null, information describing the client.
329 void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)