Skip to content

Commit

Permalink
Read folders like playlists
Browse files Browse the repository at this point in the history
  • Loading branch information
Firepal committed May 16, 2024
1 parent 116202a commit 1a7a6e6
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 50 deletions.
22 changes: 11 additions & 11 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ void parse_entries(json_t* entries_elem, settings_t* todo_config) {
json_array_foreach(value, index, value_arr) {
if (json_is_string(value_arr)) {
std::string tmp_filepath(json_string_value(value_arr));
tmp_playlist.filepath.push_back(tmp_filepath);
tmp_playlist.files.push_back(tmp_filepath);
}
}
} else if (json_is_string(value)) {
std::string tmp_filepath(json_string_value(value));
tmp_playlist.filepath.push_back(tmp_filepath);
tmp_playlist.files.push_back(tmp_filepath);
}
}
}
todo_config->playlist.push_back(tmp_playlist);
todo_config->playlists.push_back(tmp_playlist);
}
else
{
Expand Down Expand Up @@ -202,20 +202,20 @@ int Cfg::WriteJson(const char* outpath, settings_t* settings) {
json_object_set_new(set_obj, SETTING_LANGUAGE, json_string(i18n::Int2Code(settings->language).c_str()));
json_object_set_new(root, CONFIG_STRING, set_obj);

for (uint32_t i = 0; settings->playlist.size() > i; i++) {
for (uint32_t i = 0; settings->playlists.size() > i; i++) {
json_t *pls_obj = json_object();
json_object_set_new(pls_obj, PLAYLIST_NAME, json_string(settings->playlist[i].name.c_str()));
json_object_set_new(pls_obj, PLAYLIST_NAME, json_string(settings->playlists[i].name.c_str()));

if (settings->playlist[i].filepath.size() > 1) {
if (settings->playlists[i].files.size() > 1) {
json_t *pls_obj_arr = json_array();

for (uint32_t j = 0; settings->playlist[i].filepath.size() > j; j++)
json_array_append_new(pls_obj_arr, json_string(settings->playlist[i].filepath[j].c_str()));
for (uint32_t j = 0; settings->playlists[i].files.size() > j; j++)
json_array_append_new(pls_obj_arr, json_string(settings->playlists[i].files[j].c_str()));

json_object_set_new(pls_obj, PLAYLIST_FILE, pls_obj_arr);

} else if (settings->playlist[i].filepath.size() == 1)
json_object_set_new(pls_obj, PLAYLIST_FILE, json_string(settings->playlist[i].filepath[0].c_str()));
} else if (settings->playlists[i].files.size() == 1)
json_object_set_new(pls_obj, PLAYLIST_FILE, json_string(settings->playlists[i].files[0].c_str()));

json_array_append_new(pls_json_arr, pls_obj);
}
Expand All @@ -229,5 +229,5 @@ int Cfg::WriteJson(const char* outpath, settings_t* settings) {
void Cfg::CleanSettings(settings_t* parsed_config)
{
parsed_config->wildMidiConfig.clear();
parsed_config->playlist.clear();
parsed_config->playlists.clear();
}
57 changes: 46 additions & 11 deletions src/gui/menus/PlayerMenu.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <set>
#include <algorithm>
#include "PlayerMenu.hpp"
#include "gui.hpp"
#include "app.hpp"
Expand Down Expand Up @@ -45,6 +47,18 @@ struct {
std::vector<ProgressBar> m_progressbars;
std::vector<Button> m_buttons;

static const std::set<std::string> SUPPORTED_EXTS = {
"mp3","wav","flac","ogg","opus",
"midi","xmi","mus","hmi","hmp","hmq",
"m3u","pls","json"
};

static bool is_extension_supported(std::string ext) {
std::string lower_ext = ext;
std::transform(lower_ext.begin(),lower_ext.end(),lower_ext.begin(),[](unsigned char c){ return std::tolower(c); });
return SUPPORTED_EXTS.find(lower_ext) != SUPPORTED_EXTS.end();
}

static void exitPlayback(void)
{
PlayerInterface::ExitPlayback();
Expand All @@ -54,10 +68,12 @@ static void exitPlayback(void)
thread = NULL;
}

static int changeFile(const std::string &filepath, playbackInfo_t* playbackInfo)
int PlayerMenu::changeFile(const std::string &filepath, playbackInfo_t* playbackInfo)
{
s32 prio;

std::string extension = filepath.substr(filepath.find_last_of('.') + 1);

/**
* If music is playing, stop it. Only one playback thread should be playing
* at any time.
Expand All @@ -67,25 +83,43 @@ static int changeFile(const std::string &filepath, playbackInfo_t* playbackInfo)

if(!playbackInfo)
return 0;

playbackInfo->playlist.files.clear();
playbackInfo->playlist.files.shrink_to_fit();

playbackInfo->usePlaylist = 0;

std::string extension = filepath.substr(filepath.find_last_of('.') + 1);
if (!strncmp(extension.c_str(), "json", 4)) {
std::string url;
Cfg::ParseNC(filepath.c_str(), &url);
playbackInfo->filepath = url;
playbackInfo->playlist.files.push_back(url);
} else if (!strncmp(extension.c_str(), "pls", 3)) {
// Note to future me.
// Add pls support to netfmt.
Pls::Parse(filepath, &playbackInfo->playlistfile);
playbackInfo->usePlaylist = 1;
Pls::Parse(filepath, &playbackInfo->playlist);
} else if (!strncmp(extension.c_str(), "m3u", 3)) {
M3u::Parse(filepath, &playbackInfo->playlistfile);
playbackInfo->usePlaylist = 1;
} else
playbackInfo->filepath = filepath;
M3u::Parse(filepath, &playbackInfo->playlist);
} else {
int idx = 0;
for (int i=0; i < expInst->Size(); i++) {
// rule out unsupporteds
auto e = expInst->GetEntry(i);
std::string ext = e.filename.substr(e.filename.find_last_of(".") + 1);
if (e.directory || e.filename == ".." || !is_extension_supported(ext)) {
DEBUG("%s wasn't recognised as supported, continuing\n", e.filename);
continue;
}

std::string name = expInst->GetAbsolutePath(i);
if (name == filepath) { playbackInfo->playindex = idx; }

DEBUG("%s",name);
playbackInfo->playlist.files.push_back(name);
idx++;
}
if (idx+1 == expInst->Size()) {
DEBUG("%s wasn't recognised as supported, aborting\n", e.filename);
return 0;
}
}
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
thread = threadCreate(PlayerInterface::ThreadMainFunct, (void *)playbackInfo, 32 * 1024, prio - 1, -2, false);

Expand All @@ -97,6 +131,7 @@ void PrintDir(const char* text, int startpoint)
Gui::PrintColor(text, 8.0f, startpoint, 0.4f, 0.4f, 0xFF000000);
}

/// Draws file browser
void PlayerMenu::fblist(int rows, int startpoint, float size) const
{
for (int i = 0; rows-seloffs > i && i <= MAX_LIST; i++) {
Expand Down
1 change: 1 addition & 0 deletions src/gui/menus/PlayerMenu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class PlayerMenu : public Menu
void drawTop() const override;
void drawBottom() const override;
void update(touchPosition* touch) override;
int changeFile(const std::string &filepath, playbackInfo_t* playbackInfo);
void fblist(int rows, int startpoint, float size) const;
private:
void BrowserControls(touchPosition* touch);
Expand Down
2 changes: 1 addition & 1 deletion src/parsecfg/m3uparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int M3u::Parse(const std::string& file, playlist_t* playlist) {
std::printf("Ignored.\n");
else {
std::string tmpfp(line);
playlist->filepath.push_back(tmpfp);
playlist->files.push_back(tmpfp);
}

}
Expand Down
4 changes: 2 additions & 2 deletions src/parsecfg/plsparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int Pls::Parse(const std::string& file, playlist_t* playlist) {
int entries = 0;
INIReader plsFile(file);

playlist->filepath.clear();
playlist->files.clear();

if (plsFile.ParseError() != 0) {
return 1;
Expand All @@ -25,7 +25,7 @@ int Pls::Parse(const std::string& file, playlist_t* playlist) {
std::string tmpfp;
tmpfp = plsFile.Get("playlist", "File"+std::to_string(i), "");
if (tmpfp.size()) {
playlist->filepath.push_back(tmpfp);
playlist->files.push_back(tmpfp);
}
}
return 0;
Expand Down
39 changes: 20 additions & 19 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,12 @@ void PlayerInterface::ThreadMainFunct(void *input) {
playbackInfo_t* info = static_cast<playbackInfo_t*>(input);
stop = false;

if (info->usePlaylist == 1) {
for (uint32_t i = 0; i < info->playlistfile.filepath.size() && !stop; i++) {
info->filepath = info->playlistfile.filepath[i];
Player::Play(info);
}
} else {
uint32_t idx = info->playindex;
for (uint32_t i = idx; i < info->playlist.files.size() && !stop; i++) {
info->playindex = i;
Player::Play(info);
}
info->usePlaylist = 0;

stop = true;
threadExit(0);
return;
Expand Down Expand Up @@ -225,20 +222,22 @@ void Player::Play(playbackInfo_t* playbackInfo) {
skip = false;
LightEvent_Init(&soundEvent, RESET_ONESHOT);

int filetype = File::GetFileType(playbackInfo->filepath);
std::string playing = playbackInfo->playlist.files[playbackInfo->playindex];
int filetype = File::GetFileType(playing);

if (filetype < 0) {
Error::Add(FILE_NOT_SUPPORTED);
return;
} else if (filetype != FMT_NETWORK)
playbackInfo->filename = playbackInfo->filepath.substr(playbackInfo->filepath.find_last_of('/') + 1);
}
else if (filetype != FMT_NETWORK)
playbackInfo->filename = playing.substr(playing.find_last_of('/') + 1);
else if (filetype == FMT_NETWORK)
playbackInfo->filename = playbackInfo->filepath;
playbackInfo->filename = playing;

transport = GetTransport(filetype);

if (transport != nullptr)
if (!transport->f_open(playbackInfo->filepath.c_str(), "rb"))
if (!transport->f_open(playing.c_str(), "rb"))
decoder = GetFormat(playbackInfo, filetype, transport.get());
else {
if (transport->GetError().empty())
Expand All @@ -248,8 +247,8 @@ void Player::Play(playbackInfo_t* playbackInfo) {
DEBUG("Failed to open transport.\n");
}
else {
Error::Add(DECODER_INIT_FAIL, "Failed initalize transport.");
DEBUG("Failed to initalize transport.\n");
Error::Add(DECODER_INIT_FAIL, "Failed initialize transport.");
DEBUG("Failed to initialize transport.\n");
}

if (decoder != nullptr) {
Expand Down Expand Up @@ -325,15 +324,17 @@ void Player::ClearMetadata(metaInfo_t* fileMeta) {
std::unique_ptr<Decoder> Player::GetFormat(const playbackInfo_t* playbackInfo, int filetype, FileTransport* transport) {
std::string errInfo;

const char *playing = playbackInfo->playlist.files[playbackInfo->playindex].c_str();

if (filetype == FILE_WAV) {
DEBUG("Attempting to load the Wav decoder.\n");
auto wavdec = std::make_unique<WavDecoder>(playbackInfo->filepath.c_str());
auto wavdec = std::make_unique<WavDecoder>(playing);
if (wavdec->GetIsInit())
return wavdec;
}
else if (filetype == FILE_FLAC) {
DEBUG("Attempting to load the Flac decoder.\n");
auto flacdec = std::make_unique<FlacDecoder>(playbackInfo->filepath.c_str());
auto flacdec = std::make_unique<FlacDecoder>(playing);
if (flacdec->GetIsInit())
return flacdec;
}
Expand All @@ -345,7 +346,7 @@ std::unique_ptr<Decoder> Player::GetFormat(const playbackInfo_t* playbackInfo, i
}
else if (filetype == FILE_VORBIS) {
DEBUG("Attempting to load the Vorbis decoder.\n");
auto vorbisdec = std::make_unique<VorbisDecoder>(playbackInfo->filepath.c_str());
auto vorbisdec = std::make_unique<VorbisDecoder>(playing);
if (vorbisdec->GetIsInit())
return vorbisdec;
}
Expand All @@ -357,13 +358,13 @@ std::unique_ptr<Decoder> Player::GetFormat(const playbackInfo_t* playbackInfo, i
}
else if (filetype == FILE_MIDI) {
DEBUG("Attempting to load the Midi decoder.\n");
auto mididec = std::make_unique<MidiDecoder>(playbackInfo->filepath.c_str(), playbackInfo->settings.wildMidiConfig.c_str());
auto mididec = std::make_unique<MidiDecoder>(playing, playbackInfo->settings.wildMidiConfig.c_str());
if (mididec->GetIsInit())
return mididec;
}
else if (filetype == FMT_NETWORK) {
DEBUG("Attempting to load the Network decoder.\n");
auto netdec = Netfmt::GetFormat(playbackInfo->filepath.c_str(), transport);
auto netdec = Netfmt::GetFormat(playing, transport);

if (netdec) {
if (netdec->GetIsInit())
Expand Down
6 changes: 2 additions & 4 deletions src/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ typedef struct

typedef struct
{
std::string filepath;
std::string filename;
metaInfo_t fileMeta;
settings_t settings;
playlist_t playlistfile;
int usePlaylist; // 0 do not use playlist, 1 use playlistfile, 2 use playlist from settings
uint32_t selectPlaylistOffset;
playlist_t playlist;
size_t playindex;
} playbackInfo_t;

enum Format {
Expand Down
5 changes: 3 additions & 2 deletions src/settings.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#ifndef __LIME_SETTINGS_H__
#define __LIME_SETTINGS_H__
#include <vector>
#include <string>

typedef struct
{
std::string name;
std::vector<std::string> filepath;
std::vector<std::string> files;
} playlist_t;

typedef std::vector<playlist_t> playvec;
Expand All @@ -15,7 +16,7 @@ typedef struct
std::string wildMidiConfig;
uint32_t theme;
int language;
playvec playlist;
playvec playlists;
} settings_t;

#endif

0 comments on commit 1a7a6e6

Please sign in to comment.