pinebuds/apps/audioplayers/rbplay/rbplaysd.cpp

223 lines
5.5 KiB
C++

/***************************************************************************
*
* 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 <ctype.h>
#include <fcntl.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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(&current_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;
}