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 Renesas

Note

For a sample program of without LCD Board, please refer to GR-PEACH_Audio_Playback_Sample.

Introduction

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.

1. Overview of the Sample Code

1.1 Software Block Diagram

Figure 1.1 shows the software block diagram.

/media/uploads/1050186/lcd_figure1_1.png

1.2 Pin Definitions

Table 1.1 shows the pins used in this sample code.

/media/uploads/1050186/lcd_table1_1.png

2. Sample Code Operating Environment

In order to operate this sample code, GR-PEACH, Audio Camera Shield and 7.1 inch LCD Shield must be needed. For details on Audio Camera Shield and 7.1 inch LCD Shield, please refer to the following links, respectively:

In this section, it is described that how board is configured and to control audio playback via command line and touch screen.

2.1 Operating Environment

Figure 2.1 shows the overview of the operating environment for this sample code.

/media/uploads/1050186/lcd_figure2_1.png

Figure 2.2 and 2.3 show how to configure GR-PEACH, Audio Camera Shield and 7.1 inch LCD shield when using USB0 and USB1, respectively.

/media/uploads/1050186/lcd_figure2_2.png /media/uploads/1050186/lcd_figure2_3.png

Table 2.1 lists the overview of Graphical User Interface (GUI) of this sample code.

/media/uploads/1050186/lcd_table2_1.png

2.2 List of User Operations

Table 2.2 shows the relationship among Audio Playback, Command Line and Onboard Switch.

/media/uploads/1050186/lcd_table2_2.png

3. Function Outline

Table 3.1, 3.2 and 3.3 shows the overview of functions implemented in this sample code.

/media/uploads/1050186/lcd_table3_1.png /media/uploads/1050186/lcd_table3_2.png /media/uploads/1050186/lcd_table3_3.png /media/uploads/1050186/lcd_figure3_1.png

3.1 Playback Control

This sample program supports the operation "play", "pause", "stop", "play next song" and "play previous song".

3.2 Trick Play Control

In order to enable/disable Repeat Mode, user need to type "repeat" on command line or click the corresponding icon shown in Table 2.2. By derault, Repeat Mode is enabled. When Repeat Mode is enabled, the first song is played back after the playback of the last song is finished. Otherwise, the playback is shopped when finishing to play back the last song.

3.3 How to see Song Information

The information of the song being played back can be seen by typing playinfo on command line. Table 3.4 lists the items user can see on the terminal.

/media/uploads/dkato/audioplayback_table3_4.png

3.4 How to analyze the folder structure in USB stick

In this sample code, the folder structure in USB stick is analyzed in the breadth-first order. Table 3.5 shows how the files in USB stick are numbered.

/media/uploads/dkato/audioplayback_table3_5.png

4.Others

4.1 Serial Communication Setting

With respect to the default serial communication related setting on mbed, please refer to the follwing link:
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication
Please set up the terminal software you would like to use on your PC in consideration of the above. For example, 9600 should be specified for the baud rate on the terminal in order to control this sample via command line.

4.2 Necessary modification when using GCC ARM Embedded

If you would like to use GCC ARM Embedded, you must revise the following linker script incorporated in mbed OS 5 package as follows:

  • Linker Script to be modified
    $(PROJECT_ROOT)/mbed-os/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/TOOLCHAIN_GCC_ARM/RZA1H.ld

    Please note that $(PROJECT_ROOT) in the above denotes the root directory of this sample code

  • Before Modification

RZA1H.ld

/* Linker script for mbed RZ_A1H */

/* Linker script to configure memory regions. */
MEMORY
{
  ROM   (rx)  : ORIGIN = 0x00000000, LENGTH = 0x02000000
  BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000 
  SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000 
  L_TTB (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00004000 
  RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00700000
  RAM_NC (rwx) : ORIGIN = 0x20900000, LENGTH = 0x00100000
}
(snip)
  • After Modification

RZA1H.ld

/* Linker script for mbed RZ_A1H */

/* Linker script to configure memory regions. */
MEMORY
{
  ROM   (rx)  : ORIGIN = 0x00000000, LENGTH = 0x02000000
  BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000 
  SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000 
  L_TTB (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00004000 
  RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00180000
  RAM_NC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x00680000
}
(snip)
Committer:
Osamu Nakamura
Date:
Tue Apr 11 12:42:10 2017 +0900
Revision:
6:a957aaa284f0
Parent:
0:ee40da884cfc
Update R-BSP from rev. cbb9d60c8748 to fb9eda52224e so that this program can be compiled with IAR toolchain.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:ee40da884cfc 1 /*******************************************************************************
dkato 0:ee40da884cfc 2 * DISCLAIMER
dkato 0:ee40da884cfc 3 * This software is supplied by Renesas Electronics Corporation and is only
dkato 0:ee40da884cfc 4 * intended for use with Renesas products. No other uses are authorized. This
dkato 0:ee40da884cfc 5 * software is owned by Renesas Electronics Corporation and is protected under
dkato 0:ee40da884cfc 6 * all applicable laws, including copyright laws.
dkato 0:ee40da884cfc 7 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
dkato 0:ee40da884cfc 8 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
dkato 0:ee40da884cfc 9 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
dkato 0:ee40da884cfc 10 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
dkato 0:ee40da884cfc 11 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
dkato 0:ee40da884cfc 12 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
dkato 0:ee40da884cfc 13 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
dkato 0:ee40da884cfc 14 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
dkato 0:ee40da884cfc 15 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
dkato 0:ee40da884cfc 16 * Renesas reserves the right, without notice, to make changes to this software
dkato 0:ee40da884cfc 17 * and to discontinue the availability of this software. By using this software,
dkato 0:ee40da884cfc 18 * you agree to the additional terms and conditions found by accessing the
dkato 0:ee40da884cfc 19 * following link:
dkato 0:ee40da884cfc 20 * http://www.renesas.com/disclaimer*
dkato 0:ee40da884cfc 21 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
dkato 0:ee40da884cfc 22 *******************************************************************************/
dkato 0:ee40da884cfc 23
dkato 0:ee40da884cfc 24 #include "decode.h"
dkato 0:ee40da884cfc 25 #include "misratypes.h"
dkato 0:ee40da884cfc 26 #include "dec_flac.h"
dkato 0:ee40da884cfc 27
dkato 0:ee40da884cfc 28 static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 29 FLAC__byte buffer[], size_t *bytes, void *client_data);
dkato 0:ee40da884cfc 30 static FLAC__StreamDecoderWriteStatus write_cb (const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 31 const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data);
dkato 0:ee40da884cfc 32 static void meta_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 33 const FLAC__StreamMetadata *metadata, void *client_data);
dkato 0:ee40da884cfc 34 static void error_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 35 FLAC__StreamDecoderErrorStatus status, void *client_data);
dkato 0:ee40da884cfc 36 static void init_ctrl_data(flac_ctrl_t * const p_ctrl);
dkato 0:ee40da884cfc 37 static bool check_file_spec(const flac_ctrl_t * const p_ctrl);
dkato 0:ee40da884cfc 38 static bool check_end_of_stream(const flac_ctrl_t * const p_flac_ctrl);
dkato 0:ee40da884cfc 39
dkato 0:ee40da884cfc 40 bool flac_set_pcm_buf(flac_ctrl_t * const p_flac_ctrl,
dkato 0:ee40da884cfc 41 int32_t * const p_buf_addr, const uint32_t buf_num)
dkato 0:ee40da884cfc 42 {
dkato 0:ee40da884cfc 43 bool ret = false;
dkato 0:ee40da884cfc 44 if ((p_flac_ctrl != NULL) && (p_buf_addr != NULL) && (buf_num > 0u)) {
dkato 0:ee40da884cfc 45 p_flac_ctrl->p_pcm_buf = p_buf_addr;
dkato 0:ee40da884cfc 46 p_flac_ctrl->pcm_buf_num = buf_num;
dkato 0:ee40da884cfc 47 p_flac_ctrl->pcm_buf_used_cnt = 0u;
dkato 0:ee40da884cfc 48 ret = true;
dkato 0:ee40da884cfc 49 }
dkato 0:ee40da884cfc 50 return ret;
dkato 0:ee40da884cfc 51 }
dkato 0:ee40da884cfc 52
dkato 0:ee40da884cfc 53 uint32_t flac_get_pcm_cnt(const flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 54 {
dkato 0:ee40da884cfc 55 uint32_t ret = 0u;
dkato 0:ee40da884cfc 56 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 57 ret = p_flac_ctrl->pcm_buf_used_cnt;
dkato 0:ee40da884cfc 58 }
dkato 0:ee40da884cfc 59 return ret;
dkato 0:ee40da884cfc 60 }
dkato 0:ee40da884cfc 61
dkato 0:ee40da884cfc 62 uint32_t flac_get_play_time(const flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 63 {
dkato 0:ee40da884cfc 64 uint32_t play_time = 0u;
dkato 0:ee40da884cfc 65 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 66 if (p_flac_ctrl->sample_rate > 0u) { /* Prevents division by 0 */
dkato 0:ee40da884cfc 67 play_time = (uint32_t)(p_flac_ctrl->decoded_sample / p_flac_ctrl->sample_rate);
dkato 0:ee40da884cfc 68 }
dkato 0:ee40da884cfc 69 }
dkato 0:ee40da884cfc 70 return play_time;
dkato 0:ee40da884cfc 71 }
dkato 0:ee40da884cfc 72
dkato 0:ee40da884cfc 73 uint32_t flac_get_total_time(const flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 74 {
dkato 0:ee40da884cfc 75 uint32_t total_time = 0u;
dkato 0:ee40da884cfc 76 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 77 if (p_flac_ctrl->sample_rate > 0u) { /* Prevents division by 0 */
dkato 0:ee40da884cfc 78 total_time = (uint32_t)(p_flac_ctrl->total_sample / p_flac_ctrl->sample_rate);
dkato 0:ee40da884cfc 79 }
dkato 0:ee40da884cfc 80 }
dkato 0:ee40da884cfc 81 return total_time;
dkato 0:ee40da884cfc 82 }
dkato 0:ee40da884cfc 83
dkato 0:ee40da884cfc 84 bool flac_open(FILE * const p_handle, flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 85 {
dkato 0:ee40da884cfc 86 bool ret = false;
dkato 0:ee40da884cfc 87 FLAC__bool result;
dkato 0:ee40da884cfc 88 FLAC__StreamDecoderInitStatus result_init;
dkato 0:ee40da884cfc 89 FLAC__StreamDecoder *p_dec;
dkato 0:ee40da884cfc 90
dkato 0:ee40da884cfc 91 if ((p_handle != NULL) && (p_flac_ctrl != NULL)) {
dkato 0:ee40da884cfc 92 /* Initialises Internal memory */
dkato 0:ee40da884cfc 93 init_ctrl_data(p_flac_ctrl);
dkato 0:ee40da884cfc 94 p_flac_ctrl->p_file_handle = p_handle;
dkato 0:ee40da884cfc 95 /* Creates the instance of flac decoder. */
dkato 0:ee40da884cfc 96 p_dec = FLAC__stream_decoder_new();
dkato 0:ee40da884cfc 97 if (p_dec != NULL) {
dkato 0:ee40da884cfc 98 /* Sets the MD5 check. */
dkato 0:ee40da884cfc 99 (void) FLAC__stream_decoder_set_md5_checking(p_dec, true);
dkato 0:ee40da884cfc 100 /* Initialises the instance of flac decoder. */
dkato 0:ee40da884cfc 101 result_init = FLAC__stream_decoder_init_stream(p_dec, &read_cb, NULL, NULL,
dkato 0:ee40da884cfc 102 NULL, NULL, &write_cb, &meta_cb, &error_cb, (void *)p_flac_ctrl);
dkato 0:ee40da884cfc 103 if (result_init == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
dkato 0:ee40da884cfc 104 /* Decodes until end of metadata. */
dkato 0:ee40da884cfc 105 result = FLAC__stream_decoder_process_until_end_of_metadata(p_dec);
dkato 0:ee40da884cfc 106 if (result == true) {
dkato 0:ee40da884cfc 107 if (check_file_spec(p_flac_ctrl) == true) {
dkato 0:ee40da884cfc 108 p_flac_ctrl->p_decoder = p_dec;
dkato 0:ee40da884cfc 109 ret = true;
dkato 0:ee40da884cfc 110 }
dkato 0:ee40da884cfc 111 }
dkato 0:ee40da884cfc 112 }
dkato 0:ee40da884cfc 113 if (ret != true) {
dkato 0:ee40da884cfc 114 FLAC__stream_decoder_delete(p_dec);
dkato 0:ee40da884cfc 115 }
dkato 0:ee40da884cfc 116 }
dkato 0:ee40da884cfc 117 }
dkato 0:ee40da884cfc 118 return ret;
dkato 0:ee40da884cfc 119 }
dkato 0:ee40da884cfc 120
dkato 0:ee40da884cfc 121 bool flac_decode(const flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 122 {
dkato 0:ee40da884cfc 123 bool ret = false;
dkato 0:ee40da884cfc 124 bool eos;
dkato 0:ee40da884cfc 125 FLAC__bool result;
dkato 0:ee40da884cfc 126 uint32_t used_cnt;
dkato 0:ee40da884cfc 127
dkato 0:ee40da884cfc 128 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 129 eos = check_end_of_stream(p_flac_ctrl);
dkato 0:ee40da884cfc 130 if (eos != true) {
dkato 0:ee40da884cfc 131 /* Decoding position is not end of stream. */
dkato 0:ee40da884cfc 132 used_cnt = p_flac_ctrl->pcm_buf_used_cnt;
dkato 0:ee40da884cfc 133 result = FLAC__stream_decoder_process_single (p_flac_ctrl->p_decoder);
dkato 0:ee40da884cfc 134 if (result == true) {
dkato 0:ee40da884cfc 135 /* Did a decoded data increase? */
dkato 0:ee40da884cfc 136 if (p_flac_ctrl->pcm_buf_used_cnt > used_cnt) {
dkato 0:ee40da884cfc 137 /* FLAC decoder process succeeded. */
dkato 0:ee40da884cfc 138 ret = true;
dkato 0:ee40da884cfc 139 }
dkato 0:ee40da884cfc 140 }
dkato 0:ee40da884cfc 141 }
dkato 0:ee40da884cfc 142 }
dkato 0:ee40da884cfc 143 return ret;
dkato 0:ee40da884cfc 144 }
dkato 0:ee40da884cfc 145
dkato 0:ee40da884cfc 146 void flac_close(flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 147 {
dkato 0:ee40da884cfc 148 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 149 FLAC__stream_decoder_delete(p_flac_ctrl->p_decoder);
dkato 0:ee40da884cfc 150 p_flac_ctrl->p_decoder = NULL;
dkato 0:ee40da884cfc 151 }
dkato 0:ee40da884cfc 152 }
dkato 0:ee40da884cfc 153
dkato 0:ee40da884cfc 154 /** Read callback function of FLAC decoder library
dkato 0:ee40da884cfc 155 *
dkato 0:ee40da884cfc 156 * @param decoder Decoder instance.
dkato 0:ee40da884cfc 157 * @param buffer Pointer to the buffer to store the data of FLAC file.
dkato 0:ee40da884cfc 158 * @param bytes Pointer to the size of the buffer.
dkato 0:ee40da884cfc 159 * @param client_data Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 160 *
dkato 0:ee40da884cfc 161 * @returns
dkato 0:ee40da884cfc 162 * Results of process. Returns the following status.
dkato 0:ee40da884cfc 163 * FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
dkato 0:ee40da884cfc 164 * FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
dkato 0:ee40da884cfc 165 * FLAC__STREAM_DECODER_READ_STATUS_ABORT
dkato 0:ee40da884cfc 166 */
dkato 0:ee40da884cfc 167 static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 168 FLAC__byte buffer[], size_t *bytes, void *client_data)
dkato 0:ee40da884cfc 169 {
dkato 0:ee40da884cfc 170 FLAC__StreamDecoderReadStatus ret = FLAC__STREAM_DECODER_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 171 flac_ctrl_t * const p_ctrl = (flac_ctrl_t*)client_data;
dkato 0:ee40da884cfc 172 size_t read_size;
dkato 0:ee40da884cfc 173
dkato 0:ee40da884cfc 174 UNUSED_ARG(decoder);
dkato 0:ee40da884cfc 175 if ((buffer != NULL) && (bytes != NULL) && (p_ctrl != NULL)) {
dkato 0:ee40da884cfc 176 if (*bytes > 0u) {
dkato 0:ee40da884cfc 177 read_size = fread(&buffer[0], sizeof(FLAC__byte), *bytes, p_ctrl->p_file_handle);
dkato 0:ee40da884cfc 178 if (read_size > 0u) {
dkato 0:ee40da884cfc 179 ret = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
dkato 0:ee40da884cfc 180 *bytes = read_size;
dkato 0:ee40da884cfc 181 } else {
dkato 0:ee40da884cfc 182 ret = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
dkato 0:ee40da884cfc 183 *bytes = 0;
dkato 0:ee40da884cfc 184 }
dkato 0:ee40da884cfc 185 }
dkato 0:ee40da884cfc 186 }
dkato 0:ee40da884cfc 187 return ret;
dkato 0:ee40da884cfc 188 }
dkato 0:ee40da884cfc 189
dkato 0:ee40da884cfc 190 /** Write callback function of FLAC decoder library
dkato 0:ee40da884cfc 191 *
dkato 0:ee40da884cfc 192 * @param decoder Decoder instance.
dkato 0:ee40da884cfc 193 * @param frame The description of the decoded frame.
dkato 0:ee40da884cfc 194 * @param buffer Pointer to the decoded data.
dkato 0:ee40da884cfc 195 * @param client_data Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 196 *
dkato 0:ee40da884cfc 197 * @returns
dkato 0:ee40da884cfc 198 * Results of process. Returns the following status.
dkato 0:ee40da884cfc 199 * FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
dkato 0:ee40da884cfc 200 * FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
dkato 0:ee40da884cfc 201 */
dkato 0:ee40da884cfc 202 static FLAC__StreamDecoderWriteStatus write_cb (const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 203 const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
dkato 0:ee40da884cfc 204 {
dkato 0:ee40da884cfc 205 FLAC__StreamDecoderWriteStatus ret = FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
dkato 0:ee40da884cfc 206 const FLAC__int32 *p_ch0;
dkato 0:ee40da884cfc 207 const FLAC__int32 *p_ch1;
dkato 0:ee40da884cfc 208 flac_ctrl_t *const p_ctrl = (flac_ctrl_t*)client_data;
dkato 0:ee40da884cfc 209 uint32_t bit_shift_num;
dkato 0:ee40da884cfc 210 uint32_t i;
dkato 0:ee40da884cfc 211
dkato 0:ee40da884cfc 212 UNUSED_ARG(decoder);
dkato 0:ee40da884cfc 213 if ((frame != NULL) && (buffer != NULL) && (p_ctrl != NULL)) {
dkato 0:ee40da884cfc 214 if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER) {
dkato 0:ee40da884cfc 215 p_ctrl->decoded_sample = frame->header.number.sample_number + frame->header.blocksize;
dkato 0:ee40da884cfc 216 } else {
dkato 0:ee40da884cfc 217 p_ctrl->decoded_sample += frame->header.blocksize;
dkato 0:ee40da884cfc 218 }
dkato 0:ee40da884cfc 219 if (p_ctrl->p_pcm_buf == NULL) {
dkato 0:ee40da884cfc 220 /* Error */
dkato 0:ee40da884cfc 221 } else if (frame->header.blocksize > DEC_MAX_BLOCK_SIZE) {
dkato 0:ee40da884cfc 222 /* Error : Block size is illegal specification */
dkato 0:ee40da884cfc 223 } else {
dkato 0:ee40da884cfc 224 bit_shift_num = (DEC_OUTPUT_BITS_PER_SAMPLE + DEC_OUTPUT_PADDING_BITS)- p_ctrl->bits_per_sample;
dkato 0:ee40da884cfc 225 if (p_ctrl->channel_num == DEC_MAX_CHANNEL_NUM) {
dkato 0:ee40da884cfc 226 /* stereo */
dkato 0:ee40da884cfc 227 p_ch0 = buffer[0];
dkato 0:ee40da884cfc 228 p_ch1 = buffer[1];
dkato 0:ee40da884cfc 229 } else {
dkato 0:ee40da884cfc 230 /* mono */
dkato 0:ee40da884cfc 231 p_ch0 = buffer[0];
dkato 0:ee40da884cfc 232 p_ch1 = buffer[0];
dkato 0:ee40da884cfc 233 }
dkato 0:ee40da884cfc 234 if ((p_ctrl->pcm_buf_num - p_ctrl->pcm_buf_used_cnt) >= (frame->header.blocksize * DEC_MAX_CHANNEL_NUM)) {
dkato 0:ee40da884cfc 235 for (i = 0; i < frame->header.blocksize; i++) {
dkato 0:ee40da884cfc 236 /* ch 0 */
dkato 0:ee40da884cfc 237 p_ctrl->p_pcm_buf[p_ctrl->pcm_buf_used_cnt] = (int32_t)((uint32_t)p_ch0[i] << bit_shift_num);
dkato 0:ee40da884cfc 238 p_ctrl->pcm_buf_used_cnt++;
dkato 0:ee40da884cfc 239 /* ch 1 */
dkato 0:ee40da884cfc 240 p_ctrl->p_pcm_buf[p_ctrl->pcm_buf_used_cnt] = (int32_t)((uint32_t)p_ch1[i] << bit_shift_num);
dkato 0:ee40da884cfc 241 p_ctrl->pcm_buf_used_cnt++;
dkato 0:ee40da884cfc 242 }
dkato 0:ee40da884cfc 243 ret = FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
dkato 0:ee40da884cfc 244 }
dkato 0:ee40da884cfc 245 }
dkato 0:ee40da884cfc 246 }
dkato 0:ee40da884cfc 247 return ret;
dkato 0:ee40da884cfc 248 }
dkato 0:ee40da884cfc 249
dkato 0:ee40da884cfc 250 /** Metadata callback function of FLAC decoder library
dkato 0:ee40da884cfc 251 *
dkato 0:ee40da884cfc 252 * @param decoder Decoder instance.
dkato 0:ee40da884cfc 253 * @param metadata Block of the decoded metadata.
dkato 0:ee40da884cfc 254 * @param client_data Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 255 */
dkato 0:ee40da884cfc 256 static void meta_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 257 const FLAC__StreamMetadata *metadata, void *client_data)
dkato 0:ee40da884cfc 258 {
dkato 0:ee40da884cfc 259 flac_ctrl_t *const p_ctrl = (flac_ctrl_t*)client_data;
dkato 0:ee40da884cfc 260
dkato 0:ee40da884cfc 261 UNUSED_ARG(decoder);
dkato 0:ee40da884cfc 262 if ((metadata != NULL) && (p_ctrl != NULL)) {
dkato 0:ee40da884cfc 263 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
dkato 0:ee40da884cfc 264 p_ctrl->sample_rate = metadata->data.stream_info.sample_rate;
dkato 0:ee40da884cfc 265 p_ctrl->channel_num = metadata->data.stream_info.channels;
dkato 0:ee40da884cfc 266 p_ctrl->bits_per_sample = metadata->data.stream_info.bits_per_sample;
dkato 0:ee40da884cfc 267 p_ctrl->total_sample = metadata->data.stream_info.total_samples;
dkato 0:ee40da884cfc 268 }
dkato 0:ee40da884cfc 269 }
dkato 0:ee40da884cfc 270 }
dkato 0:ee40da884cfc 271
dkato 0:ee40da884cfc 272 /** Error callback function of FLAC decoder library
dkato 0:ee40da884cfc 273 *
dkato 0:ee40da884cfc 274 * @param decoder Decoder instance.
dkato 0:ee40da884cfc 275 * @param client_data Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 276 */
dkato 0:ee40da884cfc 277 static void error_cb(const FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 278 FLAC__StreamDecoderErrorStatus status, void *client_data)
dkato 0:ee40da884cfc 279 {
dkato 0:ee40da884cfc 280 /* DO NOTHING */
dkato 0:ee40da884cfc 281 UNUSED_ARG(decoder);
dkato 0:ee40da884cfc 282 UNUSED_ARG(status);
dkato 0:ee40da884cfc 283 UNUSED_ARG(client_data);
dkato 0:ee40da884cfc 284 }
dkato 0:ee40da884cfc 285
dkato 0:ee40da884cfc 286 /** Initialises the control data of FLAC module
dkato 0:ee40da884cfc 287 *
dkato 0:ee40da884cfc 288 * @param p_ctrl Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 289 */
dkato 0:ee40da884cfc 290 static void init_ctrl_data(flac_ctrl_t * const p_ctrl)
dkato 0:ee40da884cfc 291 {
dkato 0:ee40da884cfc 292 if (p_ctrl != NULL) {
dkato 0:ee40da884cfc 293 p_ctrl->p_decoder = NULL; /* Handle of flac decoder */
dkato 0:ee40da884cfc 294 p_ctrl->p_file_handle = NULL; /* Handle of flac file */
dkato 0:ee40da884cfc 295 p_ctrl->decoded_sample = 0uLL; /* Number of a decoded sample */
dkato 0:ee40da884cfc 296 p_ctrl->total_sample = 0uLL; /* Total number of sample */
dkato 0:ee40da884cfc 297 p_ctrl->sample_rate = 0u; /* Sample rate in Hz */
dkato 0:ee40da884cfc 298 p_ctrl->channel_num = 0u; /* Number of channels */
dkato 0:ee40da884cfc 299 p_ctrl->bits_per_sample = 0u; /* bit per sample */
dkato 0:ee40da884cfc 300 p_ctrl->p_pcm_buf = NULL; /* Pointer of PCM buffer */
dkato 0:ee40da884cfc 301 p_ctrl->pcm_buf_num = 0u; /* Number of elements in PCM buffer */
dkato 0:ee40da884cfc 302 p_ctrl->pcm_buf_used_cnt = 0u; /* Counter of used elements in PCM buffer */
dkato 0:ee40da884cfc 303 }
dkato 0:ee40da884cfc 304 }
dkato 0:ee40da884cfc 305
dkato 0:ee40da884cfc 306 /** Checks the playable file of the playback
dkato 0:ee40da884cfc 307 *
dkato 0:ee40da884cfc 308 * @param client_data Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 309 */
dkato 0:ee40da884cfc 310 static bool check_file_spec(const flac_ctrl_t * const p_ctrl)
dkato 0:ee40da884cfc 311 {
dkato 0:ee40da884cfc 312 bool ret = false;
dkato 0:ee40da884cfc 313
dkato 0:ee40da884cfc 314 if (p_ctrl == NULL) {
dkato 0:ee40da884cfc 315 /* Error : NULL pointer */
dkato 0:ee40da884cfc 316 } else if ((p_ctrl->channel_num <= 0u) ||
dkato 0:ee40da884cfc 317 (p_ctrl->channel_num > DEC_MAX_CHANNEL_NUM)) {
dkato 0:ee40da884cfc 318 /* Error : Channel number is illegal specification */
dkato 0:ee40da884cfc 319 } else if ((p_ctrl->bits_per_sample != DEC_16BITS_PER_SAMPLE) &&
dkato 0:ee40da884cfc 320 (p_ctrl->bits_per_sample != DEC_24BITS_PER_SAMPLE)) {
dkato 0:ee40da884cfc 321 /* Error : Bit per sample is illegal specification */
dkato 0:ee40da884cfc 322 } else if ((p_ctrl->sample_rate < DEC_INPUT_MIN_SAMPLE_RATE) ||
dkato 0:ee40da884cfc 323 (p_ctrl->sample_rate > DEC_INPUT_MAX_SAMPLE_RATE)) {
dkato 0:ee40da884cfc 324 /* Error : Sample rate is illegal specification */
dkato 0:ee40da884cfc 325 } else {
dkato 0:ee40da884cfc 326 /* OK */
dkato 0:ee40da884cfc 327 ret = true;
dkato 0:ee40da884cfc 328 }
dkato 0:ee40da884cfc 329 return ret;
dkato 0:ee40da884cfc 330 }
dkato 0:ee40da884cfc 331
dkato 0:ee40da884cfc 332 /** Checks the state of the FLAC decoder
dkato 0:ee40da884cfc 333 *
dkato 0:ee40da884cfc 334 * @param p_flac_ctrl Pointer to the control data of FLAC module.
dkato 0:ee40da884cfc 335 *
dkato 0:ee40da884cfc 336 * @returns
dkato 0:ee40da884cfc 337 * The state of FLAC decoder. true is end of stream. false is other state.
dkato 0:ee40da884cfc 338 */
dkato 0:ee40da884cfc 339 static bool check_end_of_stream(const flac_ctrl_t * const p_flac_ctrl)
dkato 0:ee40da884cfc 340 {
dkato 0:ee40da884cfc 341 bool ret = false;
dkato 0:ee40da884cfc 342 FLAC__StreamDecoderState state;
dkato 0:ee40da884cfc 343
dkato 0:ee40da884cfc 344 if (p_flac_ctrl != NULL) {
dkato 0:ee40da884cfc 345 state = FLAC__stream_decoder_get_state(p_flac_ctrl->p_decoder);
dkato 0:ee40da884cfc 346 if (state == FLAC__STREAM_DECODER_END_OF_STREAM) {
dkato 0:ee40da884cfc 347 ret = true;
dkato 0:ee40da884cfc 348 }
dkato 0:ee40da884cfc 349 }
dkato 0:ee40da884cfc 350 return ret;
dkato 0:ee40da884cfc 351 }