Skip to content

Commit

Permalink
Merge pull request #439 from 4ms/presets-in-subdirs
Browse files Browse the repository at this point in the history
Load Presets from subdirs
  • Loading branch information
danngreen authored Dec 24, 2024
2 parents 9a1c625 + 06370a1 commit effc2cf
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 47 deletions.
3 changes: 1 addition & 2 deletions firmware/src/fs/asset_drive/untar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ Archive::Archive(std::span<const char> filedata)

bool update = true;

int count = 0;
unsigned offset = 0;
for (count = 0;; count++) {
while (true) {
TarRaw buffer;

if (update) {
Expand Down
54 changes: 25 additions & 29 deletions firmware/src/fs/fatfs/fat_file_io.hh
Original file line number Diff line number Diff line change
Expand Up @@ -364,35 +364,6 @@ public:
return true;
}

std::optional<std::string_view> get_file_name_by_index(const std::string_view path, unsigned idx) {
DIR dj;
FILINFO fno;

f_chdrive(_fatvol);

auto full_path = std::string(path);
// pr_trace("FatFS: scanning dir %s\n", full_path.c_str());

if (f_opendir(&dj, full_path.c_str()) != FR_OK) {
if (!mount_disk())
return std::nullopt;
if (f_opendir(&dj, full_path.c_str()) != FR_OK)
return std::nullopt;
}

f_rewinddir(&dj);
idx += 1;
while (idx--) {
if (f_readdir(&dj, &fno) != FR_OK) {
return std::nullopt;
}
if (fno.fname[0] == '\0') {
return std::nullopt;
}
}
return fno.fname;
}

// Returns false if dir cannot be opened
bool foreach_dir_entry(const std::string_view path, auto action) {
DIR dj;
Expand Down Expand Up @@ -424,6 +395,31 @@ public:
return true;
}

bool
foreach_dir_entry_recursive(const std::string_view path, auto action, unsigned max_depth, unsigned cur_depth = 0) {
if (cur_depth >= max_depth) {
return false;
}

return foreach_dir_entry(
path, [=, this](std::string_view filename, uint32_t filesize, uint32_t tmstmp, DirEntryKind kind) {
std::string fullpath;
if (path.length())
fullpath = std::string(path) + std::string("/") + std::string(filename);
else
fullpath = std::string(filename);

if (kind == DirEntryKind::File) {
action(fullpath, filesize, tmstmp, kind);
}

else if (kind == DirEntryKind::Dir)
{
foreach_dir_entry_recursive(fullpath, action, max_depth, cur_depth + 1);
}
});
}

void print_dir(std::string_view path, unsigned max_depth, unsigned cur_depth = 0) {
cur_depth++;

Expand Down
39 changes: 23 additions & 16 deletions firmware/src/gui/pages/module_view_action_menu.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace MetaModule
class ModuleViewActionMenu {
struct Preset {
std::string fname{};
int idx{};
std::string path{};
};

public:
Expand Down Expand Up @@ -82,18 +82,26 @@ public:
presets.clear();
preset_map.clear();

auto populate_vector = [this](std::string fname, unsigned time_stamp, unsigned size, DirEntryKind type) {
fname.erase(fname.find(".vcvm"));
preset_map.push_back({fname, (int)preset_map.size()});
auto populate_vector = [this](std::string fullpath, unsigned time_stamp, unsigned size, DirEntryKind type) {
if (fullpath.length() && type == DirEntryKind::File) {
if (auto ext_pos = fullpath.find(".vcvm"); ext_pos != std::string::npos) {
auto slash_pos = fullpath.find_last_of('/');
slash_pos = (slash_pos == std::string::npos) ? 0 : slash_pos + 1;
if (fullpath[slash_pos] != '.') {
preset_map.push_back({fullpath.substr(slash_pos, ext_pos - slash_pos), fullpath});
}
}
}
};

if (ramdisk.foreach_dir_entry(preset_path.c_str(), populate_vector)) {
if (ramdisk.foreach_dir_entry_recursive(preset_path.c_str(), populate_vector, 2)) {
std::ranges::sort(preset_map, std::less{}, &Preset::fname);

for (auto &p : preset_map) {
if (p.fname.find_first_of('_') == 2) {
// some vcv presets have an ugly 'xx_' prefix.. let's remove it
p.fname = p.fname.substr(3);
if (isdigit(p.fname[0]) && isdigit(p.fname[1]))
p.fname = p.fname.substr(3);
}
presets += p.fname + '\n';
}
Expand Down Expand Up @@ -190,7 +198,7 @@ private:

void reset_params() {
reset_params_.reset(module_idx, patches.get_view_patch());
patch_mod_queue.put(LoadModuleState{static_cast<uint16_t>(module_idx), ""});
patch_mod_queue.put(LoadModuleState{.module_id = static_cast<uint16_t>(module_idx), .data = ""});
}

static void menu_button_cb(lv_event_t *event) {
Expand Down Expand Up @@ -230,20 +238,19 @@ private:
void preset_but_cb() {
preset_popup.show(
[this](unsigned opt) {
const auto t = ramdisk.get_file_name_by_index(preset_path, preset_map[opt].idx);
if (!t.has_value()) {
return;
}
cur_preset_idx = opt;
const auto filename = preset_path + "/" + t.value().data();
const auto filename = preset_map[opt].path;
const auto preset_file_size = ramdisk.get_file_size(filename);

auto mod_request = LoadModuleState{static_cast<uint16_t>(module_idx)};
auto mod_request = LoadModuleState{.module_id = static_cast<uint16_t>(module_idx)};
mod_request.data.resize(preset_file_size);

pr_dbg("Loading preset: %s\n", filename.c_str());
ramdisk.read_file(filename, mod_request.data);
patch_mod_queue.put(std::move(mod_request));
auto bytes_read = ramdisk.read_file(filename, mod_request.data);
if (bytes_read == 0) {
pr_err("Failed to read preset file\n");
} else {
patch_mod_queue.put(std::move(mod_request));
}
},
"Presets",
presets.c_str(),
Expand Down

0 comments on commit effc2cf

Please sign in to comment.