/*************************************************************************** * * Copyright 2015-2019 BES. * All rights reserved. All unpublished rights reserved. * * No part of this work may be used or reproduced in any form or by any * means, or stored in a database or retrieval system, without prior written * permission of BES. * * Use of this work is governed by a license granted by BES. * This work contains confidential and proprietary information of * BES. which is protected by copyright, trade secret, * trademark and other intellectual property rights. * ****************************************************************************/ /* rbplay source */ /* playback control & rockbox codec porting & codec thread */ #include #include #include #include #include #include #include #include #include "SDFileSystem.h" #include "hal_trace.h" #include "metadata.h" #include "rbplaysd.h" #include "utils.h" #define SD_LABEL "sd" #define PLAYLIST_PATH "/sd/Playlist" static SDFileSystem *sdfs = NULL; // TODO: remove ? static playlist_item sd_curritem; playlist_struct sd_playlist; static void playlist_insert(playlist_item *item) { int fd; fd = open(PLAYLIST_PATH, O_RDWR | O_CREAT); if (fd <= 0) { error("Playlist open fail"); return; } lseek(fd, item->song_idx * sizeof(playlist_item), SEEK_SET); write(fd, item, sizeof(playlist_item)); close(fd); } static bool sdcard_mount(void) { if (sdfs) { info("SD card already mount"); return true; } sdfs = new SDFileSystem(SD_LABEL); if (sdfs == NULL) { error("No memory for sd file system"); return false; } DIR *d; d = opendir("/" SD_LABEL); if (!d) { warn("SD card mount error"); return false; } closedir(d); return true; } static void app_rbplay_gen_playlist(playlist_struct *list) { struct dirent *p; DIR *d; uint32_t total; int fd = 0; struct mp3entry current_id3; playlist_item *sd_curritem_p = &sd_curritem; memset(list, 0x0, sizeof(playlist_struct)); d = opendir("/" SD_LABEL); if (!d) { error("SD card open fail"); return; } info("---------gen audio list---------"); total = 0; while (p = readdir(d)) { if (probe_file_format(p->d_name) == AFMT_UNKNOWN) continue; memset(&sd_curritem, 0x0, sizeof(playlist_item)); sd_curritem.song_idx = total; sprintf(sd_curritem.file_path, "/" SD_LABEL "/%s", p->d_name); sprintf(sd_curritem.file_name, "%s", p->d_name); info("Adding music: %s", sd_curritem.file_path); fd = open(sd_curritem.file_path, O_RDONLY); if (fd <= 0) { error("File %s open error", p->d_name); break; } get_metadata(¤t_id3, fd, sd_curritem.file_path); close(fd); if (current_id3.bitrate == 0 || current_id3.filesize == 0 || current_id3.length == 0) break; info("bits:%d, type:%d, freq:%d", current_id3.bitrate, current_id3.codectype, current_id3.frequency); sd_curritem_p->bitrate = current_id3.bitrate; sd_curritem_p->codectype = current_id3.codectype; sd_curritem_p->filesize = current_id3.filesize; sd_curritem_p->length = current_id3.length; sd_curritem_p->frequency = current_id3.frequency; #ifdef PARSER_DETAIL char *str; str = current_id3.title; if (str != NULL) { memset(sd_curritem_p->title, 0x0, MP3_TITLE_LEN); memcpy(sd_curritem_p->title, str, strlen(str) > MP3_TITLE_LEN ? MP3_TITLE_LEN : strlen(str)); } str = current_id3.artist; if (str != NULL) { memset(sd_curritem_p->artist, 0x0, MP3_ARTIST_LEN); memcpy(sd_curritem_p->artist, str, strlen(str) > MP3_ARTIST_LEN ? MP3_ARTIST_LEN : strlen(str)); } str = current_id3.album; if (str != NULL) { memset(sd_curritem_p->album, 0x0, MP3_ALBUM_LEN); memcpy(sd_curritem_p->album, str, strlen(str) > MP3_ALBUM_LEN ? MP3_ALBUM_LEN : strlen(str)); } str = current_id3.genre_string; if (str != NULL) { memset(sd_curritem_p->genre, 0x0, MP3_GENRE_LEN); memcpy(sd_curritem_p->genre, str, strlen(str) > MP3_GENRE_LEN ? MP3_GENRE_LEN : strlen(str)); } str = current_id3.composer; if (str != NULL) { memset(sd_curritem_p->composer, 0x0, MP3_COMPOSER_LEN); memcpy(sd_curritem_p->composer, str, strlen(str) > MP3_COMPOSER_LEN ? MP3_COMPOSER_LEN : strlen(str)); } #endif playlist_insert(sd_curritem_p); total++; } list->total_songs = total; list->current_item = sd_curritem_p; closedir(d); info("---------%d audio file searched---------", total); } void app_rbplay_load_playlist(playlist_struct *list) { if (sdcard_mount() == false) return; remove(PLAYLIST_PATH); app_rbplay_gen_playlist(list); } playlist_item *app_rbplay_get_playitem(const int idx) { int fd; if (idx >= sd_playlist.total_songs) { warn("Index exceed: %d / %d", idx, sd_playlist.total_songs); return NULL; } fd = open(PLAYLIST_PATH, O_RDONLY); if (fd <= 0) { warn("SD card playlist can not open"); return NULL; } lseek(fd, sizeof(playlist_item) * idx, SEEK_SET); read(fd, sd_playlist.current_item, sizeof(playlist_item)); info("Get playitem: %d: %s", idx, sd_playlist.current_item->file_path); close(fd); return sd_playlist.current_item; } int app_ctl_remove_file(const int idx) { playlist_item *item = app_rbplay_get_playitem(idx); if (!item) return -1; remove(item->file_path); return 0; }