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
sys_scan_folder.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 "mbed.h" 00025 #include "rtos.h" 00026 #include "FATFileSystem.h" 00027 #include "USBHostMSD.h" 00028 #include "sys_scan_folder.h" 00029 00030 /*--- Macro definition of folder structure scan. ---*/ 00031 /* The character string to identify root directory. */ 00032 #define STR_ROOT_FOR_F_OPENDIR "" /* to use f_opendir() */ 00033 #define STR_ROOT_FOR_FOPEN "/" SYS_USB_MOUNT_NAME /* to use fopen() */ 00034 00035 /* The file extension of FLAC. */ 00036 #define FILE_EXT_FLAC ".flac" 00037 #define FILE_EXT_FLA ".fla" 00038 00039 #define CHR_FULL_STOP '.' /* 0x2E: FULL STOP */ 00040 #define CHR_SOLIDUS '/' /* 0x2F: SOLIDUS */ 00041 #define FOLD_ID_NOT_EXIST (0xFFFFFFFFu) 00042 #define OPEN_MODE_READ_ONLY "r" 00043 00044 /* File path maximum size including the usb mount name size */ 00045 #define USB_MOUNT_NAME_SIZE (sizeof(STR_ROOT_FOR_FOPEN "/")) 00046 #define FILE_PATH_MAX_LEN (60u) 00047 #define FILE_PATH_MAX_SIZE (USB_MOUNT_NAME_SIZE + FILE_PATH_MAX_LEN) 00048 00049 #define SCAN_WAIT_TIME_MS (1) 00050 00051 static const char_t *get_full_path(fid_scan_folder_t * const p_info, 00052 const item_t * const p_item); 00053 static bool open_dir(fid_scan_folder_t * const p_info, 00054 const item_t * const p_item, FATFS_DIR * const p_fdir); 00055 static bool read_dir(fid_scan_folder_t * const p_info, FATFS_DIR * const p_fdir, 00056 const char_t ** const p_name, bool * const p_flag_dir); 00057 static bool regist_item(item_t * const p_item, 00058 const char_t * const p_name, const uint32_t parent); 00059 static bool check_extension(const char_t * const p_name); 00060 00061 static bool check_folder_depth(const fid_scan_folder_t * const p_info, 00062 const uint32_t folder_id); 00063 00064 void fid_init(fid_scan_folder_t * const p_info) 00065 { 00066 if (p_info != NULL) { 00067 p_info->total_folder = 0u; 00068 p_info->total_track = 0u; 00069 } 00070 } 00071 00072 bool fid_scan_folder_struct(fid_scan_folder_t * const p_info) 00073 { 00074 bool ret = false; 00075 bool result; 00076 bool chk; 00077 uint32_t i; 00078 item_t *p_item; 00079 FATFS_DIR fdir; 00080 const char_t *p_name; 00081 bool flg_dir; 00082 bool chk_dep; 00083 00084 if (p_info != NULL) { 00085 /* Initializes the scan data. */ 00086 p_info->total_track = 0u; 00087 p_info->total_folder = 0u; 00088 00089 /* Registers the identifier of the root directory to use f_opendir(). */ 00090 (void) regist_item(&p_info->folder_list[0], STR_ROOT_FOR_F_OPENDIR, FOLD_ID_NOT_EXIST); 00091 p_info->total_folder++; 00092 00093 /* Checks the item in all registered directory. */ 00094 for (i = 0; i < p_info->total_folder; i++) { 00095 chk_dep = check_folder_depth(p_info, i); 00096 result = open_dir(p_info, &p_info->folder_list[i], &fdir); 00097 while (result == true) { 00098 result = read_dir(p_info, &fdir, &p_name, &flg_dir); 00099 if (result == true) { 00100 /* Checks the attribute of this item. */ 00101 if (flg_dir == true) { 00102 /* This item is directory. */ 00103 if ((chk_dep == true) && (p_info->total_folder < SYS_MAX_FOLDER_NUM)) { 00104 p_item = &p_info->folder_list[p_info->total_folder]; 00105 chk = regist_item(p_item, p_name, i); 00106 if (chk == true) { 00107 /* Register of directory item was success. */ 00108 p_info->total_folder++; 00109 } 00110 } 00111 } else { 00112 /* This item is file. */ 00113 chk = check_extension(p_name); 00114 if ((chk == true) && (p_info->total_track < SYS_MAX_TRACK_NUM)) { 00115 /* This item is FLAC file. */ 00116 p_item = &p_info->track_list[p_info->total_track]; 00117 chk = regist_item(p_item, p_name, i); 00118 if (chk == true) { 00119 /* Register of file item was success. */ 00120 p_info->total_track++; 00121 } 00122 } 00123 } 00124 Thread::wait(SCAN_WAIT_TIME_MS); 00125 } 00126 } 00127 } 00128 /* Changes the identifier of the root directory to use fopen(). */ 00129 (void) regist_item(&p_info->folder_list[0], STR_ROOT_FOR_FOPEN, FOLD_ID_NOT_EXIST); 00130 00131 if (p_info->total_track > 0u) { 00132 ret = true; 00133 } 00134 } 00135 00136 return ret; 00137 } 00138 00139 FILE *fid_open_track(fid_scan_folder_t * const p_info, const uint32_t track_id) 00140 { 00141 FILE *fp = NULL; 00142 const char_t *p_path; 00143 size_t path_len; 00144 00145 if (p_info != NULL) { 00146 if (track_id < p_info->total_track) { 00147 p_path = get_full_path(p_info, &p_info->track_list[track_id]); 00148 if (p_path != NULL) { 00149 path_len = strlen(p_path); 00150 /* File path maximum length is limited by the specification of "fopen". */ 00151 if (path_len < FILE_PATH_MAX_SIZE) { 00152 fp = fopen(p_path, OPEN_MODE_READ_ONLY); 00153 } 00154 } 00155 } 00156 } 00157 return fp; 00158 } 00159 00160 void fid_close_track(FILE * const fp) 00161 { 00162 if (fp != NULL) { 00163 (void) fclose(fp); 00164 } 00165 } 00166 00167 const char_t *fid_get_track_name(const fid_scan_folder_t * const p_info, 00168 const uint32_t track_id) 00169 { 00170 const char_t *p_name = NULL; 00171 00172 if (p_info != NULL) { 00173 if (track_id < p_info->total_track) { 00174 p_name = &p_info->track_list[track_id].name[0]; 00175 } 00176 } 00177 return p_name; 00178 } 00179 00180 uint32_t fid_get_total_track(const fid_scan_folder_t * const p_info) 00181 { 00182 uint32_t ret = 0u; 00183 00184 if (p_info != NULL) { 00185 ret = p_info->total_track; 00186 } 00187 return ret; 00188 } 00189 00190 /** Gets the full path 00191 * 00192 * @param p_info Pointer to the control data of folder scan module. 00193 * @param p_item Pointer to the item structure of the folder / track. 00194 * 00195 * @returns 00196 * Pointer to the full path. 00197 */ 00198 static const char_t *get_full_path(fid_scan_folder_t * const p_info, 00199 const item_t * const p_item) 00200 { 00201 const char_t *p_path = NULL; 00202 const item_t *p; 00203 const item_t *item_list[SYS_MAX_FOLDER_DEPTH]; 00204 uint32_t i; 00205 uint32_t item_cnt; 00206 uint32_t buf_cnt; 00207 uint32_t len; 00208 bool err; 00209 00210 if ((p_info != NULL) && (p_item != NULL)) { 00211 for (i = 0; i < SYS_MAX_FOLDER_DEPTH; i++) { 00212 item_list[i] = NULL; 00213 } 00214 p_info->work_buf[0] = '\0'; 00215 00216 /* Stores the item name until the root folder. */ 00217 p = p_item; 00218 item_cnt = 0; 00219 while ((item_cnt < SYS_MAX_FOLDER_DEPTH) && 00220 (p->parent_number < p_info->total_folder)) { 00221 item_list[item_cnt] = p; 00222 item_cnt++; 00223 p = &p_info->folder_list[p->parent_number]; 00224 } 00225 if (p->parent_number == FOLD_ID_NOT_EXIST) { 00226 buf_cnt = strlen(p->name); 00227 (void) strncpy(&p_info->work_buf[0], p->name, sizeof(p_info->work_buf)); 00228 err = false; 00229 while ((item_cnt > 0u) && (err != true)) { 00230 item_cnt--; 00231 p = item_list[item_cnt]; 00232 /* Concatenates SOLIDUS character to the "work_buf" variable. */ 00233 if ((buf_cnt + 1u) < sizeof(p_info->work_buf)) { 00234 p_info->work_buf[buf_cnt] = CHR_SOLIDUS; 00235 buf_cnt++; 00236 } else { 00237 err = true; 00238 } 00239 /* Concatenates the item name to the "work_buf" variable. */ 00240 if (p != NULL) { 00241 len = strlen(p->name); 00242 if ((buf_cnt + len) < sizeof(p_info->work_buf)) { 00243 (void) strncpy(&p_info->work_buf[buf_cnt], p->name, len); 00244 buf_cnt += len; 00245 } else { 00246 err = true; 00247 } 00248 } 00249 } 00250 if (err != true) { 00251 p_info->work_buf[buf_cnt] = '\0'; 00252 p_path = &p_info->work_buf[0]; 00253 } 00254 } 00255 } 00256 return p_path; 00257 } 00258 00259 /** Opens the directory 00260 * 00261 * @param p_info Pointer to the control data of folder scan module. 00262 * @param p_item Pointer to the item structure of the folder / track. 00263 * @param p_fdir Pointer to the structure to store the directory object. 00264 * 00265 * @returns 00266 * Results of process. true is success. false is failure. 00267 */ 00268 static bool open_dir(fid_scan_folder_t * const p_info, 00269 const item_t * const p_item, FATFS_DIR * const p_fdir) 00270 { 00271 bool ret = false; 00272 const char_t *p_path; 00273 FRESULT ferr; 00274 00275 if ((p_info != NULL) && (p_item != NULL) && (p_fdir != NULL)) { 00276 p_path = get_full_path(p_info, p_item); 00277 if (p_path != NULL) { 00278 ferr = f_opendir(p_fdir, p_path); 00279 if (ferr == FR_OK) { 00280 ret = true; 00281 } 00282 } 00283 } 00284 return ret; 00285 } 00286 00287 /** Reads the directory 00288 * 00289 * @param p_info Pointer to the control data of folder scan module. 00290 * @param p_fdir Pointer to the structure of the directory object. 00291 * @param p_flag_dir Pointer to the variable to store the directory flag. 00292 * 00293 * @returns 00294 * Pointer to the name. 00295 */ 00296 static bool read_dir(fid_scan_folder_t * const p_info, FATFS_DIR * const p_fdir, 00297 const char_t ** const p_name, bool * const p_flag_dir) 00298 { 00299 bool ret = false; 00300 FRESULT ferr; 00301 FILINFO finfo; 00302 00303 if ((p_info != NULL) && (p_fdir != NULL) && 00304 (p_name != NULL) && (p_flag_dir != NULL)) { 00305 /* Sets the buffer to store the long file name. */ 00306 finfo.lfname = &p_info->work_buf[0]; 00307 finfo.lfsize = sizeof(p_info->work_buf); 00308 ferr = f_readdir(p_fdir, &finfo); 00309 if ((ferr == FR_OK) && ((int32_t)finfo.fname[0] != '\0')) { 00310 if (finfo.lfname != NULL) { 00311 if ((int32_t)finfo.lfname[0] == '\0') { 00312 /* Long file name does not exist. */ 00313 (void) strncpy(finfo.lfname, finfo.fname, finfo.lfsize); 00314 } 00315 /* Adds the NULL terminal character. */ 00316 /* This is fail-safe processing. */ 00317 finfo.lfname[finfo.lfsize - 1u] = '\0'; 00318 00319 ret = true; 00320 *p_name = finfo.lfname; 00321 if ((finfo.fattrib & AM_DIR) != 0) { 00322 /* This item is directory. */ 00323 *p_flag_dir = true; 00324 } else { 00325 /* This item is file. */ 00326 *p_flag_dir = false; 00327 } 00328 } 00329 } 00330 } 00331 return ret; 00332 } 00333 00334 /** Registers the item of the folder / track 00335 * 00336 * @param p_item Pointer to the structure to store the item of the folder / track. 00337 * @param p_name Pointer to the name of the item. 00338 * @param parent Number of the parent folder of the item. 00339 * 00340 * @returns 00341 * Results of process. true is success. false is failure. 00342 */ 00343 static bool regist_item(item_t * const p_item, 00344 const char_t * const p_name, const uint32_t parent) 00345 { 00346 bool ret = false; 00347 uint32_t len; 00348 00349 if ((p_item != NULL) && (p_name != NULL)) { 00350 len = strlen(p_name); 00351 if ((len + 1u) < sizeof(p_item->name)) { 00352 (void) strncpy(p_item->name, p_name, sizeof(p_item->name)); 00353 p_item->name[sizeof(p_item->name) - 1u] = '\0'; 00354 p_item->parent_number = parent; 00355 ret = true; 00356 } 00357 } 00358 return ret; 00359 } 00360 00361 /** Checks the extension of the track name 00362 * 00363 * @param p_name Pointer to the name of the track. 00364 * 00365 * @returns 00366 * Results of the checking. true is FLAC file. false is other file. 00367 */ 00368 static bool check_extension(const char_t * const p_name) 00369 { 00370 bool ret = false; 00371 const char_t *p; 00372 00373 if (p_name != NULL) { 00374 p = strrchr(p_name, CHR_FULL_STOP); 00375 if (p != NULL) { 00376 if (strncasecmp(p, FILE_EXT_FLAC, sizeof(FILE_EXT_FLAC)) == 0) { 00377 ret = true; 00378 } else if (strncasecmp(p, FILE_EXT_FLA, sizeof(FILE_EXT_FLA)) == 0) { 00379 ret = true; 00380 } else { 00381 /* DO NOTHING */ 00382 } 00383 } 00384 } 00385 return ret; 00386 } 00387 00388 /** Checks the folder depth in the scan range 00389 * 00390 * @param p_info Pointer to the control data of folder scan module. 00391 * @param folder_id Folder ID [0 - (total folder - 1)] 00392 * 00393 * @returns 00394 * Results of the checking. true is the scan range. false is out of a scan range. 00395 */ 00396 static bool check_folder_depth(const fid_scan_folder_t * const p_info, 00397 const uint32_t folder_id) 00398 { 00399 bool ret = false; 00400 uint32_t depth; 00401 uint32_t parent_id; 00402 00403 if (p_info != NULL) { 00404 /* Counts the folder depth. */ 00405 parent_id = folder_id; 00406 depth = 0u; 00407 while ((depth < SYS_MAX_FOLDER_DEPTH) && 00408 (parent_id < p_info->total_folder)) { 00409 depth++; 00410 parent_id = p_info->folder_list[parent_id].parent_number; 00411 } 00412 if (parent_id == FOLD_ID_NOT_EXIST) { 00413 /* Found the root folder. */ 00414 if (depth < SYS_MAX_FOLDER_DEPTH) { 00415 ret = true; 00416 } 00417 } 00418 } 00419 return ret; 00420 }
Generated on Tue Jul 12 2022 19:32:30 by 1.7.2