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)

display/disp_tft_scrn.cpp

Committer:
Osamu Nakamura
Date:
2017-04-11
Revision:
6:a957aaa284f0
Parent:
4:2672de88a46b

File content as of revision 6:a957aaa284f0:

/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer*
* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/

#include "disp_graphics.h"
#include "disp_tft.h"
#include "disp_tft_scrn.h"
#include "img_tbl.h"
#include "system.h"

/*--- Macro definition ---*/
/*-- The making phase of the display image --*/
#define SCRN_PHASE_INIT1    (0)         /*  1st phase of the initialization process. */
#define SCRN_PHASE_INIT2    (1)         /*  2nd phase of the initialization process. */
#define SCRN_PHASE_INIT3    (2)         /*  3rd phase of the initialization process. */
#define SCRN_PHASE_INIT4    (3)         /*  4th phase of the initialization process. */
#define SCRN_PHASE_INIT5    (4)         /*  5th phase of the initialization process. */
#define SCRN_PHASE_INIT6    (5)         /*  6th phase of the initialization process. */
#define SCRN_PHASE_INIT7    (6)         /*  7th phase of the initialization process. */
#define SCRN_PHASE_INIT8    (7)         /*  8th phase of the initialization process. */
#define SCRN_PHASE_INIT9    (8)         /*  9th phase of the initialization process. */
#define SCRN_PHASE_INIT10   (9)         /* 10th phase of the initialization process. */
#define SCRN_PHASE_INIT11   (10)        /* 11th phase of the initialization process. */
#define SCRN_PHASE_INIT12   (11)        /* 12th phase of the initialization process. */
#define SCRN_PHASE_INIT13   (12)        /* 13th phase of the initialization process. */
#define SCRN_PHASE_INIT14   (13)        /* 14th phase of the initialization process. */
#define SCRN_PHASE_INIT15   (14)        /* 15th phase of the initialization process. */
#define SCRN_PHASE_INIT16   (15)        /* 16th phase of the initialization process. */
#define SCRN_PHASE_INIT17   (16)        /* 17th phase of the initialization process. */
#define SCRN_PHASE_INIT18   (17)        /* 18th phase of the initialization process. */
#define SCRN_PHASE_INIT19   (18)        /* 19th phase of the initialization process. */
#define SCRN_PHASE_INIT20   (19)        /* 20th phase of the initialization process. */
#define SCRN_PHASE_INIT21   (20)        /* 21th phase of the initialization process. */
#define SCRN_PHASE_INIT22   (21)        /* 22th phase of the initialization process. */
#define SCRN_PHASE_INIT23   (22)        /* 23th phase of the initialization process. */
#define SCRN_PHASE_INIT24   (23)        /* 24th phase of the initialization process. */
#define SCRN_PHASE_NORM1    (24)        /*  1st phase of the normal process. */
#define SCRN_PHASE_NORM2    (25)        /*  2nd phase of the normal process. */
#define SCRN_PHASE_NORM3    (26)        /*  3rd phase of the normal process. */
#define SCRN_PHASE_NORM4    (27)        /*  4th phase of the normal process. */
#define SCRN_PHASE_NORM5    (28)        /*  5th phase of the normal process. */
#define SCRN_PHASE_NORM6    (29)        /*  6th phase of the normal process. */

/*-- Display position of the picture --*/
/* DSP_IMG_ID_BACK1 */
#define XPOS_BACK1          (  0)
#define YPOS_BACK1          (  0)

/* DSP_IMG_ID_BACK2 */
#define XPOS_BACK2          (XPOS_BACK1)
#define YPOS_BACK2          (YPOS_BACK1 + (int32_t)DSP_IMG_HS_BACK1)

/* DSP_IMG_ID_BACK3 */
#define XPOS_BACK3          (XPOS_BACK2)
#define YPOS_BACK3          (YPOS_BACK2 + (int32_t)DSP_IMG_HS_BACK2)

/* DSP_IMG_ID_BACK4 */
#define XPOS_BACK4          (XPOS_BACK3)
#define YPOS_BACK4          (YPOS_BACK3 + (int32_t)DSP_IMG_HS_BACK3)

/* DSP_IMG_ID_BACK5 */
#define XPOS_BACK5          (XPOS_BACK4)
#define YPOS_BACK5          (YPOS_BACK4 + (int32_t)DSP_IMG_HS_BACK4)

/* DSP_IMG_ID_BACK6 */
#define XPOS_BACK6          (XPOS_BACK5)
#define YPOS_BACK6          (YPOS_BACK5 + (int32_t)DSP_IMG_HS_BACK5)

/* DSP_IMG_ID_AUDIO */
#define XPOS_AUDIO          ( 20)
#define YPOS_AUDIO          ( 25)

/* DSP_IMG_ID_RENESAS */
#define XPOS_RENESAS        (260)
#define YPOS_RENESAS        ( 25)

/* DSP_IMG_ID_AUDIO_BUTTON1 */
#define XPOS_BUTTON1        (230)
#define YPOS_BUTTON1        (410)

/* DSP_IMG_ID_AUDIO_BUTTON2 */
#define XPOS_BUTTON2        (370)
#define YPOS_BUTTON2        (YPOS_BUTTON1)

/* DSP_IMG_ID_AUDIO_BUTTON3 */
#define XPOS_BUTTON3        (510)
#define YPOS_BUTTON3        (YPOS_BUTTON1)

/* DSP_IMG_ID_AUDIO_BUTTON4 */
#define XPOS_BUTTON4        (650)
#define YPOS_BUTTON4        (YPOS_BUTTON1)

/* DSP_IMG_ID_AUDIO_BAR */
#define XPOS_AUDIO_BAR      (240)
#define YPOS_AUDIO_BAR      (385)

/* DSP_IMG_ID_AUDIO_WINDOW1 */
#define XPOS_AUDIO_WINDOW1  (0)
#define YPOS_AUDIO_WINDOW1  (105)

/* DSP_IMG_ID_AUDIO_WINDOW2 */
#define XPOS_AUDIO_WINDOW2  (XPOS_AUDIO_WINDOW1)
#define YPOS_AUDIO_WINDOW2  (YPOS_AUDIO_WINDOW1 + (int32_t)DSP_IMG_HS_AUDIO_WINDOW1)

/* DSP_IMG_ID_AUDIO_WINDOW3 */
#define XPOS_AUDIO_WINDOW3  (XPOS_AUDIO_WINDOW2)
#define YPOS_AUDIO_WINDOW3  (YPOS_AUDIO_WINDOW2 + (int32_t)DSP_IMG_HS_AUDIO_WINDOW2)

/* DSP_IMG_ID_AUDIO_WINDOW4 */
#define XPOS_AUDIO_WINDOW4  (XPOS_AUDIO_WINDOW3)
#define YPOS_AUDIO_WINDOW4  (YPOS_AUDIO_WINDOW3 + (int32_t)DSP_IMG_HS_AUDIO_WINDOW3)

/* DSP_IMG_ID_MODE */
#define XPOS_MODE           (30)
#define YPOS_MODE           (380)

/* DSP_IMG_ID_TV */
#define XPOS_TV             (60)
#define YPOS_TV             (400)

/* Mode Number */
#define XPOS_MODE_NUMBER    (90)
#define YPOS_MODE_NUMBER    (410)
#define MSG_FORM_MODE       "%ld"

/* DSP_IMG_ID_BAR_LEFT */
#define OFFSET_BAR_FROM_AUDIO_BAR  (2) /* offset level from audio bar */

#define XPOS_BAR_LEFT       (XPOS_AUDIO_BAR + OFFSET_BAR_FROM_AUDIO_BAR)
#define YPOS_BAR_LEFT       (YPOS_AUDIO_BAR + OFFSET_BAR_FROM_AUDIO_BAR)

/* DSP_IMG_ID_BAR_MID */
#define XPOS_BAR_MID        (int32_t)((uint32_t)XPOS_BAR_LEFT + DSP_IMG_WS_BAR_LEFT)
#define YPOS_BAR_MID        (YPOS_BAR_LEFT)

/* DSP_IMG_ID_BAR_RIGHT */
#define XPOS_BAR_RIGHT      (XPOS_BAR_MID)
#define YPOS_BAR_RIGHT      (YPOS_BAR_MID)

/* The range of the bar movement on the audio-bar. */
#define MOV_RANGE_BAR                                                       \
   ((DSP_IMG_WS_AUDIO_BAR - (DSP_IMG_WS_BAR_LEFT + DSP_IMG_WS_BAR_RIGHT)) - \
    (OFFSET_BAR_FROM_AUDIO_BAR + OFFSET_BAR_FROM_AUDIO_BAR))

/* Display position of text in the case of display mode 1. */
/* File Number */
#define M1_XPOS_FILE_NUM        (15)
#define M1_YPOS_FILE_NUM        (130)
#define M1_MSG_FORM_FILE_NUM    "T%03ld"

/* Playback Time */
#define M1_XPOS_PLAY_TIME       (165)
#define M1_YPOS_PLAY_TIME       (M1_YPOS_FILE_NUM)
#define M1_MSG_FORM_PLAY_TIME   "%3ld:%02ld:%02ld"

/* Total playback Time */
#define M1_XPOS_TOTAL_TIME      (435)
#define M1_YPOS_TOTAL_TIME      (M1_YPOS_FILE_NUM)
#define M1_MSG_FORM_TOTAL_TIME  " / %3ld:%02ld:%02ld"

/* EIGHTH NOTE */
#define M1_XPOS_EIGHTH_NOTE     (15)
#define M1_YPOS_EIGHTH_NOTE     (210)

/* FILE NAME */
#define M1_XPOS_FILE_NAME       (45)
#define M1_YPOS_FILE_NAME       (M1_YPOS_EIGHTH_NOTE)

/* PLAY INFO */
#define M1_XPOS_PLAY_INFO       (15)
#define M1_YPOS_PLAY_INFO       (290)
#define M1_MSG_FORM_PLAY_INFO   "FLAC %5ld Hz, %s"

/* Channel number */
#define M1_STR_CHANNEL_MONO     "Mono"
#define M1_STR_CHANNEL_STEREO   "Stereo"

/* Display position of text in the case of display mode 2. */
/* File Number */
#define M2_XPOS_FILE_NUM        (150)
#define M2_YPOS_FILE_NUM        (320)
#define M2_MSG_FORM_FILE_NUM    "T%03ld"

/* Playback Time */
#define M2_XPOS_PLAY_TIME       (450)
#define M2_YPOS_PLAY_TIME       (M2_YPOS_FILE_NUM)
#define M2_MSG_FORM_PLAY_TIME   "%3ld:%02ld:%02ld"

/* L-ch */
#define M2_XPOS_TEXT_LCH        (150)
#define M2_YPOS_TEXT_LCH        (130)
#define M2_STR_TEXT_LCH         "L-ch"
#define M2_XPOS_AUDIO_LCH       (0)
#define M2_YPOS_AUDIO_LCH       (238)
#define M2_XSIZE_AUDIO_LCH      (1)
#define M2_COL_AUDIO_LCH        (0xFF00FF00u)

/* R-ch */
#define M2_XPOS_TEXT_RCH        (530)
#define M2_YPOS_TEXT_RCH        (M2_YPOS_TEXT_LCH)
#define M2_STR_TEXT_RCH         "R-ch"
#define M2_XPOS_AUDIO_RCH       (401)
#define M2_YPOS_AUDIO_RCH       (M2_YPOS_AUDIO_LCH)
#define M2_XSIZE_AUDIO_RCH      (M2_XSIZE_AUDIO_LCH)
#define M2_COL_AUDIO_RCH        (0xFF0000FFu)

/* Center of the vertical line  */
#define M2_XPOS_VLINE           (399)
#define M2_YPOS_VLINE           (110)
#define M2_XSIZE_VLINE          (2)
#define M2_YSIZE_VLINE          (256)
#define M2_COL_VLINE            (DSP_IMG_FONT_FG_COL)

/* Center of the horizontal line  */
#define M2_XPOS_HLINE           (M2_XPOS_AUDIO_LCH)
#define M2_YPOS_HLINE           (M2_YPOS_AUDIO_LCH)
#define M2_XSIZE_HLINE          (800)
#define M2_YSIZE_HLINE          (1)
#define M2_COL_HLINE            (0xFFF02020u)

/* Display position of text in the case of display mode 3. */
/* File Number */
#define M3_XPOS_FILE_NUM        (15)
#define M3_YPOS_FILE_NUM        (130)
#define M3_MSG_FORM_FILE_NUM    "T%03ld"

/* Playback Time */
#define M3_XPOS_PLAY_TIME       (0)
#define M3_YPOS_PLAY_TIME       (335)
#define M3_MSG_FORM_PLAY_TIME   "%3ld:%02ld:%02ld"

/* L-ch + R-ch */
#define M3_XPOS_AUDIO           (0)
#define M3_YPOS_AUDIO           (238)
#define M3_XSIZE_AUDIO          (1)
#define M3_COL_AUDIO            (0xFF00FF00u)

/* Center of the vertical line  */
#define M3_XPOS_VLINE           (M3_XPOS_PLAY_TIME)
#define M3_YPOS_VLINE           (110)
#define M3_XSIZE_VLINE          (2)
#define M3_YSIZE_VLINE          (256)
#define M3_COL_VLINE            (DSP_IMG_FONT_FG_COL)

/* Center of the horizontal line  */
#define M3_XPOS_HLINE           (M3_XPOS_AUDIO)
#define M3_YPOS_HLINE           (M3_YPOS_AUDIO)
#define M3_XSIZE_HLINE          (800)
#define M3_YSIZE_HLINE          (1)
#define M3_COL_HLINE            (0xFFF02020u)

/* Interval in the seconds between the vertical line. */
#define M3_INTERVAL_TIME_SEC    (5u)
#define M3_INTERVAL_VLINE       (M3_INTERVAL_TIME_SEC * DSP_TFT_M3_AUDIO_SAMPLE_PER_SEC)
/* Maximum number of the drawing process of the vertical line. */
#define M3_MAX_DRAW_NUM_VLINE   ((DSP_TFT_WIDTH / M3_INTERVAL_VLINE) + 1u)

/* Fixed character string.  */
/* The maximum length of the file name in case of the display. */
#define FILE_NAME_MAX_LEN   (25)

/* The mark of eighth note */
#define STR_EIGHTH_NOTE     "\x1"

/* The number of key picture */
#define KEY_PIC_NUM         (5)

/* Converts the playback time. */
#define HOUR_TO_SEC         (3600u) /* Coefficient for conversion from hour to seconds. */
#define MIN_TO_SEC          (60u)   /* Coefficient for conversion from minute to seconds. */

static uint32_t get_time_hour(const uint32_t play_time);
static uint32_t get_time_min(const uint32_t play_time);
static uint32_t get_time_sec(const uint32_t play_time);
static uint32_t make_scrn_mode(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft);
static uint32_t make_scrn_mode1(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft);
static uint32_t make_scrn_mode2(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft);
static uint32_t make_scrn_mode3(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft);
static void draw_audio_wave(const dsp_tftlayer_t * const p_info, const int32_t start_x, 
        const int32_t start_y, const int32_t size_x, const int16_t audio_value, const uint32_t col_data);
static bool is_playbar_output(const SYS_PlayStat stat);

void dsp_init_tft_scrn(dsp_tft_ctrl_t * const p_tft)
{
    if (p_tft != NULL) {
        p_tft->disp_phase_no = SCRN_PHASE_INIT1;
        dsp_clear_tft_audio_data(p_tft);
    }
}

uint32_t dsp_make_tft_scrn(const dsp_com_ctrl_t * const p_com, dsp_tft_ctrl_t * const p_tft)
{
    uint32_t        ret = DSP_TFT_LAYER_NON;
    int32_t         img_id;
    uint32_t        cnt_x;
    uint32_t        offset_x;
    char_t          str[DSP_DISP_STR_MAX_LEN];
    
    if ((p_com != NULL) && (p_tft != NULL)) {
        switch (p_tft->disp_phase_no) {
            case SCRN_PHASE_INIT1:
            case SCRN_PHASE_INIT13:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK1, 
                                    YPOS_BACK1, DSP_IMG_ID_BACK1, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT2:
            case SCRN_PHASE_INIT14:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK2, 
                                    YPOS_BACK2, DSP_IMG_ID_BACK2, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT3:
            case SCRN_PHASE_INIT15:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK3, 
                                    YPOS_BACK3, DSP_IMG_ID_BACK3, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT4:
            case SCRN_PHASE_INIT16:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK4, 
                                    YPOS_BACK4, DSP_IMG_ID_BACK4, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT5:
            case SCRN_PHASE_INIT17:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK5, 
                                    YPOS_BACK5, DSP_IMG_ID_BACK5, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT6:
            case SCRN_PHASE_INIT18:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_BACK6, 
                                    YPOS_BACK6, DSP_IMG_ID_BACK6, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT7:
            case SCRN_PHASE_INIT19:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO_WINDOW1, 
                                    YPOS_AUDIO_WINDOW1, DSP_IMG_ID_AUDIO_WINDOW1, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT8:
            case SCRN_PHASE_INIT20:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO_WINDOW2, 
                                    YPOS_AUDIO_WINDOW2, DSP_IMG_ID_AUDIO_WINDOW2, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT9:
            case SCRN_PHASE_INIT21:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO_WINDOW3, 
                                    YPOS_AUDIO_WINDOW3, DSP_IMG_ID_AUDIO_WINDOW3, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT10:
            case SCRN_PHASE_INIT22:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO_WINDOW4, 
                                    YPOS_AUDIO_WINDOW4, DSP_IMG_ID_AUDIO_WINDOW4, DSP_IMG_FORM_AUTOSEL);
                break;
            case SCRN_PHASE_INIT11:
            case SCRN_PHASE_INIT23:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO_BAR, 
                                    YPOS_AUDIO_BAR, DSP_IMG_ID_AUDIO_BAR, DSP_IMG_FORM_AUTOSEL);
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_MODE, 
                                    YPOS_MODE, DSP_IMG_ID_MODE, DSP_IMG_FORM_AUTOSEL);
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_TV, 
                                    YPOS_TV, DSP_IMG_ID_TV, DSP_IMG_FORM_AUTOSEL);

                dsp_clear_all(&p_tft->tft_info[DSP_TFT_LAYER_1]);
                ret = DSP_TFT_LAYER_1;
                break;
            case SCRN_PHASE_INIT12:
            case SCRN_PHASE_INIT24:
                /* Outputs the picture. */
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_AUDIO, 
                                    YPOS_AUDIO, DSP_IMG_ID_AUDIO, DSP_IMG_FORM_AUTOSEL);
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_0], XPOS_RENESAS, 
                                    YPOS_RENESAS, DSP_IMG_ID_RENESAS, DSP_IMG_FORM_AUTOSEL);
                ret = DSP_TFT_LAYER_0;
                break;
            case SCRN_PHASE_NORM1:
                /* Outputs the picture. */
                /* Prev key */
                if (p_tft->key_code == SYS_KEYCODE_PREV) {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON1D;
                } else {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON1;
                }
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BUTTON1, 
                                    YPOS_BUTTON1, img_id, DSP_IMG_FORM_ARGB8888_NO_BLEND);
                break;
            case SCRN_PHASE_NORM2:
                /* Outputs the picture. */
                /* Play/Pause key */
                if (p_tft->key_code == SYS_KEYCODE_PLAYPAUSE) {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON2D;
                } else {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON2;
                }
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BUTTON2, 
                                    YPOS_BUTTON2, img_id, DSP_IMG_FORM_ARGB8888_NO_BLEND);
                break;
            case SCRN_PHASE_NORM3:
                /* Outputs the picture. */
                /* Next key */
                if (p_tft->key_code == SYS_KEYCODE_NEXT) {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON3D;
                } else {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON3;
                }
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BUTTON3, 
                                    YPOS_BUTTON3, img_id, DSP_IMG_FORM_ARGB8888_NO_BLEND);
                break;
            case SCRN_PHASE_NORM4:
                /* Outputs the picture. */
                /* Repeat key */
                if (p_tft->key_code == SYS_KEYCODE_REPEAT) {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON4D;
                } else {
                    img_id = DSP_IMG_ID_AUDIO_BUTTON4;
                }
                dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BUTTON4, 
                                    YPOS_BUTTON4, img_id, DSP_IMG_FORM_ARGB8888_NO_BLEND);
                break;
            case SCRN_PHASE_NORM5:
                /* Clears the img_audio_window picture area. */
                dsp_clear_area(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_AUDIO_WINDOW1, 
                        YPOS_AUDIO_WINDOW1, DSP_IMG_WS_AUDIO_WINDOW, DSP_IMG_HS_AUDIO_WINDOW);
                /* Outputs the picture of the play bar. */
                if (is_playbar_output(p_com->play_stat) == true) {
                    /* The bar indicates the position of current playback time */
                    /* in total playback time. */
                    if (p_com->total_time != 0u) {
                        offset_x = (MOV_RANGE_BAR * p_com->play_time) / p_com->total_time;
                    } else {
                        offset_x = 0u;
                    }
                    /* LEFT */
                    dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BAR_LEFT, 
                                        YPOS_BAR_LEFT, DSP_IMG_ID_BAR_LEFT, DSP_IMG_FORM_AUTOSEL);
                    /* MID */
                    for (cnt_x = 0; cnt_x < offset_x; cnt_x += DSP_IMG_WS_BAR_MID) {
                        dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BAR_MID + (int32_t)cnt_x, 
                                            YPOS_BAR_MID, DSP_IMG_ID_BAR_MID, DSP_IMG_FORM_AUTOSEL);
                    }
                    /* RIGHT */
                    dsp_draw_picture(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_BAR_RIGHT + (int32_t)offset_x, 
                                        YPOS_BAR_RIGHT, DSP_IMG_ID_BAR_RIGHT, DSP_IMG_FORM_AUTOSEL);
                }

                ret = make_scrn_mode(p_com, p_tft);
                break;
            case SCRN_PHASE_NORM6:
                /* Clears the img_tv picture area. */
                dsp_clear_area(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_TV, 
                                        YPOS_TV, DSP_IMG_WS_TV, DSP_IMG_HS_TV);
                /* Outputs a display mode number. */
                (void) sprintf(str, MSG_FORM_MODE, p_com->disp_mode);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], XPOS_MODE_NUMBER, YPOS_MODE_NUMBER, str);

                ret = make_scrn_mode(p_com, p_tft);
                break;
            default:
                ret = DSP_TFT_LAYER_NON;
                break;
        }
        
        if (p_tft->disp_phase_no < SCRN_PHASE_NORM6) {
            p_tft->disp_phase_no++;
        } else {
            p_tft->disp_phase_no = SCRN_PHASE_NORM1;
        }
    }
    return ret;
}

SYS_KeyCode dsp_convert_key_tft_scrn(const uint32_t pos_x, const uint32_t pos_y)
{
    static const dsp_cnv_key_t cnv_tbl[KEY_PIC_NUM] = {
        {   /* Prev key */
            XPOS_BUTTON1,                   /* X position */
            YPOS_BUTTON1,                   /* Y position */
            DSP_IMG_WS_AUDIO_BUTTON1,       /* Width size */
            DSP_IMG_HS_AUDIO_BUTTON1,       /* Height size */
            SYS_KEYCODE_PREV                /* Key code */
        },
        {   /* Play/Pause key */
            XPOS_BUTTON2,                   /* X position */
            YPOS_BUTTON2,                   /* Y position */
            DSP_IMG_WS_AUDIO_BUTTON2,       /* Width size */
            DSP_IMG_HS_AUDIO_BUTTON2,       /* Height size */
            SYS_KEYCODE_PLAYPAUSE           /* Key code */
        },
        {   /* Next key */
            XPOS_BUTTON3,                   /* X position */
            YPOS_BUTTON3,                   /* Y position */
            DSP_IMG_WS_AUDIO_BUTTON3,       /* Width size */
            DSP_IMG_HS_AUDIO_BUTTON3,       /* Height size */
            SYS_KEYCODE_NEXT                /* Key code */
        },
        {   /* Repeat key */
            XPOS_BUTTON4,                   /* X position */
            YPOS_BUTTON4,                   /* Y position */
            DSP_IMG_WS_AUDIO_BUTTON4,       /* Width size */
            DSP_IMG_HS_AUDIO_BUTTON4,       /* Height size */
            SYS_KEYCODE_REPEAT              /* Key code */
        },
        {   /* Mode key */
            XPOS_MODE,                      /* X position */
            YPOS_MODE,                      /* Y position */
            DSP_IMG_WS_MODE,                /* Width size */
            DSP_IMG_HS_MODE,                /* Height size */
            SYS_KEYCODE_MODE                /* Key code */
        }
    };
    int32_t         i;
    SYS_KeyCode     ret;
    
    ret = SYS_KEYCODE_NON;
    for (i = 0; (i < KEY_PIC_NUM) && (ret == SYS_KEYCODE_NON); i++) {
        /* Is X position within the picture of key? */
        if ((pos_x >= cnv_tbl[i].pic_pos_x) && 
            (pos_x <= (cnv_tbl[i].pic_pos_x + cnv_tbl[i].pic_siz_x))) {
            /* Is Y position within the picture of key? */
            if ((pos_y >= cnv_tbl[i].pic_pos_y) && 
                (pos_y <= (cnv_tbl[i].pic_pos_y + cnv_tbl[i].pic_siz_y))) {
                /* Decides the key code. */
                ret = cnv_tbl[i].key_code;
            }
        }
    }
    return ret;
}

/** Creates the display image of playback screen.
 *
 *  @param p_com Pointer to common data in all module.
 *  @param p_tft Pointer to management data of TFT module.
 *
 *  @returns 
 *    Returns the number of the display layer to update.
 */
static uint32_t make_scrn_mode(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft)
{
    uint32_t        ret = DSP_TFT_LAYER_NON;

    if ((p_com != NULL) && (p_tft != NULL)) {
        switch (p_com->disp_mode) {
            case DSP_DISPMODE_1:
                ret = make_scrn_mode1(p_com, p_tft);
                break;
            case DSP_DISPMODE_2:
                ret = make_scrn_mode2(p_com, p_tft);
                break;
            case DSP_DISPMODE_3:
                ret = make_scrn_mode3(p_com, p_tft);
                break;
            default:
                ret = DSP_TFT_LAYER_NON;
                break;
        }
    }
    return ret;
}

/** Creates the display image of TFT display mode 1.
 *
 *  @param p_com Pointer to common data in all module.
 *  @param p_tft Pointer to management data of TFT module.
 *
 *  @returns 
 *    Returns the number of the display layer to update.
 */
static uint32_t make_scrn_mode1(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft)
{
    uint32_t            ret = DSP_TFT_LAYER_NON;
    uint32_t            time_h;
    uint32_t            time_m;
    uint32_t            time_s;
    char_t              str[DSP_DISP_STR_MAX_LEN];
    const char_t        *p_str;
    
    if ((p_com != NULL) && (p_tft != NULL)) {
        switch (p_tft->disp_phase_no) {
            case SCRN_PHASE_NORM5:
                /* Outputs the mark of eighth note. */
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M1_XPOS_EIGHTH_NOTE, M1_YPOS_EIGHTH_NOTE, STR_EIGHTH_NOTE);
                
                /* Outputs a file name in less than 25 characters. */
                (void) strncpy(str, p_com->file_name, FILE_NAME_MAX_LEN);
                str[FILE_NAME_MAX_LEN] = '\0';
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M1_XPOS_FILE_NAME, M1_YPOS_FILE_NAME, str);
                break;
            case SCRN_PHASE_NORM6:
                /* Outputs the file number. */
                (void) sprintf(str, M1_MSG_FORM_FILE_NUM, p_com->track_id);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M1_XPOS_FILE_NUM, M1_YPOS_FILE_NUM, str);
                
                /* Outputs the playback time. */
                time_h = get_time_hour(p_com->play_time);
                time_m = get_time_min(p_com->play_time);
                time_s = get_time_sec(p_com->play_time);
                (void) sprintf(str, M1_MSG_FORM_PLAY_TIME, time_h, time_m, time_s);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M1_XPOS_PLAY_TIME, M1_YPOS_PLAY_TIME, str);
                
                /* Outputs the total playback time. */
                time_h = get_time_hour(p_com->total_time);
                time_m = get_time_min(p_com->total_time);
                time_s = get_time_sec(p_com->total_time);
                (void) sprintf(str, M1_MSG_FORM_TOTAL_TIME, time_h, time_m, time_s);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M1_XPOS_TOTAL_TIME, M1_YPOS_TOTAL_TIME, str);

                /* Outputs the playback information. */
                if ((p_com->channel > 0u) && (p_com->samp_freq > 0u)) {
                    if (p_com->channel == 1u) {
                        p_str = M1_STR_CHANNEL_MONO;
                    } else {
                        p_str = M1_STR_CHANNEL_STEREO;
                    }
                    (void) sprintf(str, M1_MSG_FORM_PLAY_INFO, p_com->samp_freq, p_str);
                    dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                        M1_XPOS_PLAY_INFO, M1_YPOS_PLAY_INFO, str);
                }
                ret = DSP_TFT_LAYER_1;
                break;
            default:
                ret = DSP_TFT_LAYER_NON;
                break;
        }
    }
    return ret;
}

/** Creates the display image of TFT display mode 2.
 *
 *  @param p_com Pointer to common data in all module.
 *  @param p_tft Pointer to management data of TFT module.
 *
 *  @returns 
 *    Returns the number of the display layer to update.
 */
static uint32_t make_scrn_mode2(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft)
{
    uint32_t            ret = DSP_TFT_LAYER_NON;
    uint32_t            time_h;
    uint32_t            time_m;
    uint32_t            time_s;
    int32_t             xpos_offset;
    int32_t             buf_id;
    char_t              str[DSP_DISP_STR_MAX_LEN];
    const dsp_audio_t   *p_aud;

    if ((p_com != NULL) && (p_tft != NULL)) {
        switch (p_tft->disp_phase_no) {
            case SCRN_PHASE_NORM5:
                /* Outputs the audio wave. */
                p_aud = &p_tft->audio_data;
                buf_id = 0;
                while (buf_id < (int32_t)p_aud->m2_buf_cnt) {
                    xpos_offset = buf_id;
                    /* L-ch */
                    draw_audio_wave(&p_tft->tft_info[DSP_TFT_LAYER_1], M2_XPOS_AUDIO_LCH + xpos_offset, 
                        M2_YPOS_AUDIO_LCH, M2_XSIZE_AUDIO_LCH, p_aud->m2_buf[buf_id], M2_COL_AUDIO_LCH);
                    buf_id++;
                    /* R-ch */
                    draw_audio_wave(&p_tft->tft_info[DSP_TFT_LAYER_1], M2_XPOS_AUDIO_RCH + xpos_offset, 
                        M2_YPOS_AUDIO_RCH, M2_XSIZE_AUDIO_RCH, p_aud->m2_buf[buf_id], M2_COL_AUDIO_RCH);
                    buf_id++;
                }
                /* Outputs the center line. */
                dsp_fill_rect(&p_tft->tft_info[DSP_TFT_LAYER_1], M2_XPOS_VLINE, 
                        M2_YPOS_VLINE, M2_XSIZE_VLINE, M2_YSIZE_VLINE, M2_COL_VLINE);
                dsp_fill_rect(&p_tft->tft_info[DSP_TFT_LAYER_1], M2_XPOS_HLINE, 
                        M2_YPOS_HLINE, M2_XSIZE_HLINE, M2_YSIZE_HLINE, M2_COL_HLINE);
                break;
            case SCRN_PHASE_NORM6:
                /* Outputs the text of the channel. */
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M2_XPOS_TEXT_LCH, M2_YPOS_TEXT_LCH, M2_STR_TEXT_LCH);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M2_XPOS_TEXT_RCH, M2_YPOS_TEXT_RCH, M2_STR_TEXT_RCH);

                /* Outputs the file number. */
                (void) sprintf(str, M2_MSG_FORM_FILE_NUM, p_com->track_id);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M2_XPOS_FILE_NUM, M2_YPOS_FILE_NUM, str);

                /* Outputs the playback time. */
                time_h = get_time_hour(p_com->play_time);
                time_m = get_time_min(p_com->play_time);
                time_s = get_time_sec(p_com->play_time);
                (void) sprintf(str, M2_MSG_FORM_PLAY_TIME, time_h, time_m, time_s);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M2_XPOS_PLAY_TIME, M2_YPOS_PLAY_TIME, str);
                ret = DSP_TFT_LAYER_1;
                break;
            default:
                ret = DSP_TFT_LAYER_NON;
                break;
        }
    }
    return ret;
}

/** Creates the display image of TFT display mode 3.
 *
 *  @param p_com Pointer to common data in all module.
 *  @param p_tft Pointer to management data of TFT module.
 *
 *  @returns 
 *    Returns the number of the display layer to update.
 */
static uint32_t make_scrn_mode3(const dsp_com_ctrl_t * const p_com, 
                                            const dsp_tft_ctrl_t * const p_tft)
{
    uint32_t            ret = DSP_TFT_LAYER_NON;
    uint32_t            i;
    uint32_t            time_h;
    uint32_t            time_m;
    uint32_t            time_s;
    uint32_t            xpos_time;
    int32_t             xpos_offset;
    int32_t             mod;
    char_t              str[DSP_DISP_STR_MAX_LEN];
    const dsp_audio_t   *p_aud;

    if ((p_com != NULL) && (p_tft != NULL)) {
        switch (p_tft->disp_phase_no) {
            case SCRN_PHASE_NORM5:
                p_aud = &p_tft->audio_data;
                for (i = 0u; i < p_aud->m3_buf_cnt; i++) {
                    draw_audio_wave(&p_tft->tft_info[DSP_TFT_LAYER_1], M3_XPOS_AUDIO + (int32_t) i, 
                            M3_YPOS_AUDIO, M3_XSIZE_AUDIO, p_aud->m3_buf[i], M3_COL_AUDIO);
                }
                /* Calculates the display position. */
                if (p_aud->m3_sample_cnt < DSP_TFT_M3_AUDIO_BUF_SIZE) {
                    xpos_offset = 0;
                    xpos_time = 0u;
                } else {
                    mod = (int32_t) (p_aud->m3_sample_cnt % M3_INTERVAL_VLINE);
                    xpos_offset = -mod;
                    /* Calculates the current time. */
                    time_s = (p_aud->m3_sample_cnt - DSP_TFT_M3_AUDIO_BUF_SIZE) - (uint32_t) mod;
                    xpos_time = time_s / DSP_TFT_M3_AUDIO_SAMPLE_PER_SEC;
                }
                for (i = 0u; i < M3_MAX_DRAW_NUM_VLINE; i++) {
                    /* Outputs the vertical line. */
                    dsp_fill_rect(&p_tft->tft_info[DSP_TFT_LAYER_1], M3_XPOS_VLINE + xpos_offset, 
                            M3_YPOS_VLINE, M3_XSIZE_VLINE, M3_YSIZE_VLINE, M3_COL_VLINE);
                    /* Outputs the playback time. */
                    time_h = get_time_hour(xpos_time);
                    time_m = get_time_min(xpos_time);
                    time_s = get_time_sec(xpos_time);
                    (void) sprintf(str, M3_MSG_FORM_PLAY_TIME, time_h, time_m, time_s);
                    dsp_draw_text15x17(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                        M3_XPOS_PLAY_TIME + xpos_offset, M3_YPOS_PLAY_TIME, str);
                    xpos_offset += (int32_t) M3_INTERVAL_VLINE;
                    xpos_time += M3_INTERVAL_TIME_SEC;
                }
                break;
            case SCRN_PHASE_NORM6:
                /* Outputs the horizontal line. */
                dsp_fill_rect(&p_tft->tft_info[DSP_TFT_LAYER_1], M3_XPOS_HLINE, 
                        M3_YPOS_HLINE, M3_XSIZE_HLINE, M3_YSIZE_HLINE, M3_COL_HLINE);
                /* Outputs the file number. */
                (void) sprintf(str, M3_MSG_FORM_FILE_NUM, p_com->track_id);
                dsp_draw_text30x34(&p_tft->tft_info[DSP_TFT_LAYER_1], 
                                    M3_XPOS_FILE_NUM, M3_YPOS_FILE_NUM, str);
                ret = DSP_TFT_LAYER_1;
                break;
            default:
                ret = DSP_TFT_LAYER_NON;
                break;
        }
    }

    return ret;
}

/** Draws the audio wave to VRAM.
 *
 *  @param p_info Pointer to VRAM structure
 *  @param start_x Display position X of the picture
 *  @param start_y Display position Y of the picture
 *  @param size_x The width of the audio wave
 *  @param audio_value The value of the audio wave
 *  @param col_data Color data of ARGB8888 format
 */
static void draw_audio_wave(const dsp_tftlayer_t * const p_info, const int32_t start_x, 
        const int32_t start_y, const int32_t size_x, const int16_t audio_value, const uint32_t col_data)
{
    int32_t             pos_y;
    int32_t             draw_size;
    
    if (p_info != NULL) {
        if (audio_value >= 0) {
            pos_y = start_y - audio_value;
            draw_size = audio_value;
        } else {
            pos_y = start_y;
            draw_size = -audio_value;
        }
        dsp_fill_rect(p_info, start_x, pos_y, size_x, draw_size, col_data);
    }
}

/** Gets the playback time. (Hours)
 *
 *  @param play_time Playback time
 *
 *  @returns 
 *    Hours
 */
static uint32_t get_time_hour(const uint32_t play_time)
{
    return (play_time / HOUR_TO_SEC);
}

/** Gets the playback time. (Minutes)
 *
 *  @param play_time Playback time
 *
 *  @returns 
 *    Minutes
 */
static uint32_t get_time_min(const uint32_t play_time)
{
    return ((play_time % HOUR_TO_SEC) / MIN_TO_SEC);
}

/** Gets the playback time. (Seconds)
 *
 *  @param play_time Playback time
 *
 *  @returns 
 *    Seconds
 */
static uint32_t get_time_sec(const uint32_t play_time)
{
    return (play_time % MIN_TO_SEC);
}

/** Checks the output status of play bar.
 *
 *  @param stat Playback status
 *
 *  @returns 
 *    true = output the play bar, false = don't output the play bar
 */
static bool is_playbar_output(const SYS_PlayStat stat)
{
    bool        ret;

    switch (stat) {
        case SYS_PLAYSTAT_PLAY:
        case SYS_PLAYSTAT_PAUSE:
            ret = true;
            break;
        case SYS_PLAYSTAT_STOP:
        default:
            ret = false;
            break;
    }
    return ret;
}