The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
Dependencies: GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom
Fork of GR-PEACH_Audio_Playback_Sample by
dec_flac.cpp
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer* 00021 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 #include "decode.h" 00025 #include "misratypes.h" 00026 #include "dec_flac.h" 00027 00028 static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, 00029 FLAC__byte buffer[], size_t *bytes, void *client_data); 00030 static FLAC__StreamDecoderWriteStatus write_cb (const FLAC__StreamDecoder *decoder, 00031 const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data); 00032 static void meta_cb(const FLAC__StreamDecoder *decoder, 00033 const FLAC__StreamMetadata *metadata, void *client_data); 00034 static void error_cb(const FLAC__StreamDecoder *decoder, 00035 FLAC__StreamDecoderErrorStatus status, void *client_data); 00036 static void init_ctrl_data(flac_ctrl_t * const p_ctrl); 00037 static bool check_file_spec(const flac_ctrl_t * const p_ctrl); 00038 static bool check_end_of_stream(const flac_ctrl_t * const p_flac_ctrl); 00039 00040 bool flac_set_pcm_buf(flac_ctrl_t * const p_flac_ctrl, 00041 int32_t * const p_buf_addr, const uint32_t buf_num) 00042 { 00043 bool ret = false; 00044 if ((p_flac_ctrl != NULL) && (p_buf_addr != NULL) && (buf_num > 0u)) { 00045 p_flac_ctrl->p_pcm_buf = p_buf_addr; 00046 p_flac_ctrl->pcm_buf_num = buf_num; 00047 p_flac_ctrl->pcm_buf_used_cnt = 0u; 00048 ret = true; 00049 } 00050 return ret; 00051 } 00052 00053 uint32_t flac_get_pcm_cnt(const flac_ctrl_t * const p_flac_ctrl) 00054 { 00055 uint32_t ret = 0u; 00056 if (p_flac_ctrl != NULL) { 00057 ret = p_flac_ctrl->pcm_buf_used_cnt; 00058 } 00059 return ret; 00060 } 00061 00062 uint32_t flac_get_play_time(const flac_ctrl_t * const p_flac_ctrl) 00063 { 00064 uint32_t play_time = 0u; 00065 if (p_flac_ctrl != NULL) { 00066 if (p_flac_ctrl->sample_rate > 0u) { /* Prevents division by 0 */ 00067 play_time = (uint32_t)(p_flac_ctrl->decoded_sample / p_flac_ctrl->sample_rate); 00068 } 00069 } 00070 return play_time; 00071 } 00072 00073 uint32_t flac_get_total_time(const flac_ctrl_t * const p_flac_ctrl) 00074 { 00075 uint32_t total_time = 0u; 00076 if (p_flac_ctrl != NULL) { 00077 if (p_flac_ctrl->sample_rate > 0u) { /* Prevents division by 0 */ 00078 total_time = (uint32_t)(p_flac_ctrl->total_sample / p_flac_ctrl->sample_rate); 00079 } 00080 } 00081 return total_time; 00082 } 00083 00084 bool flac_open(FILE * const p_handle, flac_ctrl_t * const p_flac_ctrl) 00085 { 00086 bool ret = false; 00087 FLAC__bool result; 00088 FLAC__StreamDecoderInitStatus result_init; 00089 FLAC__StreamDecoder *p_dec; 00090 00091 if ((p_handle != NULL) && (p_flac_ctrl != NULL)) { 00092 /* Initialises Internal memory */ 00093 init_ctrl_data(p_flac_ctrl); 00094 p_flac_ctrl->p_file_handle = p_handle; 00095 /* Creates the instance of flac decoder. */ 00096 p_dec = FLAC__stream_decoder_new(); 00097 if (p_dec != NULL) { 00098 /* Sets the MD5 check. */ 00099 (void) FLAC__stream_decoder_set_md5_checking(p_dec, true); 00100 /* Initialises the instance of flac decoder. */ 00101 result_init = FLAC__stream_decoder_init_stream(p_dec, &read_cb, NULL, NULL, 00102 NULL, NULL, &write_cb, &meta_cb, &error_cb, (void *)p_flac_ctrl); 00103 if (result_init == FLAC__STREAM_DECODER_INIT_STATUS_OK) { 00104 /* Decodes until end of metadata. */ 00105 result = FLAC__stream_decoder_process_until_end_of_metadata(p_dec); 00106 if (result == true) { 00107 if (check_file_spec(p_flac_ctrl) == true) { 00108 p_flac_ctrl->p_decoder = p_dec; 00109 ret = true; 00110 } 00111 } 00112 } 00113 if (ret != true) { 00114 FLAC__stream_decoder_delete(p_dec); 00115 } 00116 } 00117 } 00118 return ret; 00119 } 00120 00121 bool flac_decode(const flac_ctrl_t * const p_flac_ctrl) 00122 { 00123 bool ret = false; 00124 bool eos; 00125 FLAC__bool result; 00126 uint32_t used_cnt; 00127 00128 if (p_flac_ctrl != NULL) { 00129 eos = check_end_of_stream(p_flac_ctrl); 00130 if (eos != true) { 00131 /* Decoding position is not end of stream. */ 00132 used_cnt = p_flac_ctrl->pcm_buf_used_cnt; 00133 result = FLAC__stream_decoder_process_single (p_flac_ctrl->p_decoder); 00134 if (result == true) { 00135 /* Did a decoded data increase? */ 00136 if (p_flac_ctrl->pcm_buf_used_cnt > used_cnt) { 00137 /* FLAC decoder process succeeded. */ 00138 ret = true; 00139 } 00140 } 00141 } 00142 } 00143 return ret; 00144 } 00145 00146 void flac_close(flac_ctrl_t * const p_flac_ctrl) 00147 { 00148 if (p_flac_ctrl != NULL) { 00149 FLAC__stream_decoder_delete(p_flac_ctrl->p_decoder); 00150 p_flac_ctrl->p_decoder = NULL; 00151 } 00152 } 00153 00154 /** Read callback function of FLAC decoder library 00155 * 00156 * @param decoder Decoder instance. 00157 * @param buffer Pointer to the buffer to store the data of FLAC file. 00158 * @param bytes Pointer to the size of the buffer. 00159 * @param client_data Pointer to the control data of FLAC module. 00160 * 00161 * @returns 00162 * Results of process. Returns the following status. 00163 * FLAC__STREAM_DECODER_READ_STATUS_CONTINUE 00164 * FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM 00165 * FLAC__STREAM_DECODER_READ_STATUS_ABORT 00166 */ 00167 static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, 00168 FLAC__byte buffer[], size_t *bytes, void *client_data) 00169 { 00170 FLAC__StreamDecoderReadStatus ret = FLAC__STREAM_DECODER_READ_STATUS_ABORT; 00171 flac_ctrl_t * const p_ctrl = (flac_ctrl_t*)client_data; 00172 size_t read_size; 00173 00174 UNUSED_ARG(decoder); 00175 if ((buffer != NULL) && (bytes != NULL) && (p_ctrl != NULL)) { 00176 if (*bytes > 0u) { 00177 read_size = fread(&buffer[0], sizeof(FLAC__byte), *bytes, p_ctrl->p_file_handle); 00178 if (read_size > 0u) { 00179 ret = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; 00180 *bytes = read_size; 00181 } else { 00182 ret = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 00183 *bytes = 0; 00184 } 00185 } 00186 } 00187 return ret; 00188 } 00189 00190 /** Write callback function of FLAC decoder library 00191 * 00192 * @param decoder Decoder instance. 00193 * @param frame The description of the decoded frame. 00194 * @param buffer Pointer to the decoded data. 00195 * @param client_data Pointer to the control data of FLAC module. 00196 * 00197 * @returns 00198 * Results of process. Returns the following status. 00199 * FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE 00200 * FLAC__STREAM_DECODER_WRITE_STATUS_ABORT 00201 */ 00202 static FLAC__StreamDecoderWriteStatus write_cb (const FLAC__StreamDecoder *decoder, 00203 const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) 00204 { 00205 FLAC__StreamDecoderWriteStatus ret = FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; 00206 const FLAC__int32 *p_ch0; 00207 const FLAC__int32 *p_ch1; 00208 flac_ctrl_t *const p_ctrl = (flac_ctrl_t*)client_data; 00209 uint32_t bit_shift_num; 00210 uint32_t i; 00211 00212 UNUSED_ARG(decoder); 00213 if ((frame != NULL) && (buffer != NULL) && (p_ctrl != NULL)) { 00214 if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER) { 00215 p_ctrl->decoded_sample = frame->header.number.sample_number + frame->header.blocksize; 00216 } else { 00217 p_ctrl->decoded_sample += frame->header.blocksize; 00218 } 00219 if (p_ctrl->p_pcm_buf == NULL) { 00220 /* Error */ 00221 } else if (frame->header.blocksize > DEC_MAX_BLOCK_SIZE) { 00222 /* Error : Block size is illegal specification */ 00223 } else { 00224 bit_shift_num = (DEC_OUTPUT_BITS_PER_SAMPLE + DEC_OUTPUT_PADDING_BITS)- p_ctrl->bits_per_sample; 00225 if (p_ctrl->channel_num == DEC_MAX_CHANNEL_NUM) { 00226 /* stereo */ 00227 p_ch0 = buffer[0]; 00228 p_ch1 = buffer[1]; 00229 } else { 00230 /* mono */ 00231 p_ch0 = buffer[0]; 00232 p_ch1 = buffer[0]; 00233 } 00234 if ((p_ctrl->pcm_buf_num - p_ctrl->pcm_buf_used_cnt) >= (frame->header.blocksize * DEC_MAX_CHANNEL_NUM)) { 00235 for (i = 0; i < frame->header.blocksize; i++) { 00236 /* ch 0 */ 00237 p_ctrl->p_pcm_buf[p_ctrl->pcm_buf_used_cnt] = (int32_t)((uint32_t)p_ch0[i] << bit_shift_num); 00238 p_ctrl->pcm_buf_used_cnt++; 00239 /* ch 1 */ 00240 p_ctrl->p_pcm_buf[p_ctrl->pcm_buf_used_cnt] = (int32_t)((uint32_t)p_ch1[i] << bit_shift_num); 00241 p_ctrl->pcm_buf_used_cnt++; 00242 } 00243 ret = FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 00244 } 00245 } 00246 } 00247 return ret; 00248 } 00249 00250 /** Metadata callback function of FLAC decoder library 00251 * 00252 * @param decoder Decoder instance. 00253 * @param metadata Block of the decoded metadata. 00254 * @param client_data Pointer to the control data of FLAC module. 00255 */ 00256 static void meta_cb(const FLAC__StreamDecoder *decoder, 00257 const FLAC__StreamMetadata *metadata, void *client_data) 00258 { 00259 flac_ctrl_t *const p_ctrl = (flac_ctrl_t*)client_data; 00260 00261 UNUSED_ARG(decoder); 00262 if ((metadata != NULL) && (p_ctrl != NULL)) { 00263 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { 00264 p_ctrl->sample_rate = metadata->data.stream_info.sample_rate; 00265 p_ctrl->channel_num = metadata->data.stream_info.channels; 00266 p_ctrl->bits_per_sample = metadata->data.stream_info.bits_per_sample; 00267 p_ctrl->total_sample = metadata->data.stream_info.total_samples; 00268 } 00269 } 00270 } 00271 00272 /** Error callback function of FLAC decoder library 00273 * 00274 * @param decoder Decoder instance. 00275 * @param client_data Pointer to the control data of FLAC module. 00276 */ 00277 static void error_cb(const FLAC__StreamDecoder *decoder, 00278 FLAC__StreamDecoderErrorStatus status, void *client_data) 00279 { 00280 /* DO NOTHING */ 00281 UNUSED_ARG(decoder); 00282 UNUSED_ARG(status); 00283 UNUSED_ARG(client_data); 00284 } 00285 00286 /** Initialises the control data of FLAC module 00287 * 00288 * @param p_ctrl Pointer to the control data of FLAC module. 00289 */ 00290 static void init_ctrl_data(flac_ctrl_t * const p_ctrl) 00291 { 00292 if (p_ctrl != NULL) { 00293 p_ctrl->p_decoder = NULL; /* Handle of flac decoder */ 00294 p_ctrl->p_file_handle = NULL; /* Handle of flac file */ 00295 p_ctrl->decoded_sample = 0uLL; /* Number of a decoded sample */ 00296 p_ctrl->total_sample = 0uLL; /* Total number of sample */ 00297 p_ctrl->sample_rate = 0u; /* Sample rate in Hz */ 00298 p_ctrl->channel_num = 0u; /* Number of channels */ 00299 p_ctrl->bits_per_sample = 0u; /* bit per sample */ 00300 p_ctrl->p_pcm_buf = NULL; /* Pointer of PCM buffer */ 00301 p_ctrl->pcm_buf_num = 0u; /* Number of elements in PCM buffer */ 00302 p_ctrl->pcm_buf_used_cnt = 0u; /* Counter of used elements in PCM buffer */ 00303 } 00304 } 00305 00306 /** Checks the playable file of the playback 00307 * 00308 * @param client_data Pointer to the control data of FLAC module. 00309 */ 00310 static bool check_file_spec(const flac_ctrl_t * const p_ctrl) 00311 { 00312 bool ret = false; 00313 00314 if (p_ctrl == NULL) { 00315 /* Error : NULL pointer */ 00316 } else if ((p_ctrl->channel_num <= 0u) || 00317 (p_ctrl->channel_num > DEC_MAX_CHANNEL_NUM)) { 00318 /* Error : Channel number is illegal specification */ 00319 } else if ((p_ctrl->bits_per_sample != DEC_16BITS_PER_SAMPLE) && 00320 (p_ctrl->bits_per_sample != DEC_24BITS_PER_SAMPLE)) { 00321 /* Error : Bit per sample is illegal specification */ 00322 } else if ((p_ctrl->sample_rate < DEC_INPUT_MIN_SAMPLE_RATE) || 00323 (p_ctrl->sample_rate > DEC_INPUT_MAX_SAMPLE_RATE)) { 00324 /* Error : Sample rate is illegal specification */ 00325 } else { 00326 /* OK */ 00327 ret = true; 00328 } 00329 return ret; 00330 } 00331 00332 /** Checks the state of the FLAC decoder 00333 * 00334 * @param p_flac_ctrl Pointer to the control data of FLAC module. 00335 * 00336 * @returns 00337 * The state of FLAC decoder. true is end of stream. false is other state. 00338 */ 00339 static bool check_end_of_stream(const flac_ctrl_t * const p_flac_ctrl) 00340 { 00341 bool ret = false; 00342 FLAC__StreamDecoderState state; 00343 00344 if (p_flac_ctrl != NULL) { 00345 state = FLAC__stream_decoder_get_state(p_flac_ctrl->p_decoder); 00346 if (state == FLAC__STREAM_DECODER_END_OF_STREAM) { 00347 ret = true; 00348 } 00349 } 00350 return ret; 00351 }
Generated on Tue Jul 12 2022 19:32:28 by 1.7.2