Skip to content

Commit

Permalink
add ability to save/load instruments in separate .fzi files (not test…
Browse files Browse the repository at this point in the history
…ed properly yet!)
  • Loading branch information
LTVA1 committed Apr 8, 2023
1 parent 71180d8 commit ac5943c
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 9 deletions.
60 changes: 60 additions & 0 deletions diskop.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,32 @@ void save_instrument_inner(Stream* stream, Instrument* inst) {
UNUSED(rwops);
}

bool save_instrument(FlizzerTrackerApp* tracker, FuriString* filepath)
{
bool file_removed =
storage_simply_remove(tracker->storage, furi_string_get_cstr(filepath)); // just in case
bool open_file = file_stream_open(
tracker->stream, furi_string_get_cstr(filepath), FSAM_WRITE, FSOM_OPEN_ALWAYS);

uint8_t version = TRACKER_ENGINE_VERSION;
size_t rwops =
stream_write(tracker->stream, (uint8_t*)INST_FILE_SIG, sizeof(INST_FILE_SIG) - 1);
rwops = stream_write(tracker->stream, (uint8_t*)&version, sizeof(uint8_t));

Instrument* inst = tracker->song.instrument[tracker->current_instrument];

save_instrument_inner(tracker->stream, inst);

file_stream_close(tracker->stream);
tracker->is_saving_instrument = false;
furi_string_free(filepath);

UNUSED(file_removed);
UNUSED(open_file);
UNUSED(rwops);
return false;
}

bool save_song(FlizzerTrackerApp* tracker, FuriString* filepath) {
bool file_removed =
storage_simply_remove(tracker->storage, furi_string_get_cstr(filepath)); // just in case
Expand Down Expand Up @@ -141,6 +167,40 @@ bool load_song_util(FlizzerTrackerApp* tracker, FuriString* filepath) {
return result;
}

bool load_instrument_disk(TrackerSong* song, uint8_t inst, Stream* stream) {
char header[sizeof(INST_FILE_SIG) + 2] = {0};
size_t rwops = stream_read(stream, (uint8_t*)&header, sizeof(INST_FILE_SIG) - 1);
header[sizeof(INST_FILE_SIG)] = '\0';

uint8_t version = 0;

if(strcmp(header, INST_FILE_SIG) == 0) {
rwops = stream_read(stream, (uint8_t*)&version, sizeof(version));

if(version <= TRACKER_ENGINE_VERSION)
{
load_instrument_inner(stream, song->instrument[inst], version);
}
}

UNUSED(rwops);
return false;
}

bool load_instrument_util(FlizzerTrackerApp* tracker, FuriString* filepath)
{
bool open_file = file_stream_open(
tracker->stream, furi_string_get_cstr(filepath), FSAM_READ, FSOM_OPEN_ALWAYS);

bool result = load_instrument_disk(&tracker->song, tracker->current_instrument, tracker->stream);

tracker->is_loading_instrument = false;
file_stream_close(tracker->stream);
furi_string_free(filepath);
UNUSED(open_file);
return result;
}

void save_config(FlizzerTrackerApp* tracker) {
// stream_read_line
FuriString* filepath = furi_string_alloc();
Expand Down
4 changes: 2 additions & 2 deletions diskop.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#include "flizzer_tracker.h"
#include "tracker_engine/diskop.h"

#define INST_FILE_SIG "FZT!INST"

bool save_song(FlizzerTrackerApp* tracker, FuriString* filepath);
bool save_instrument(FlizzerTrackerApp* tracker, FuriString* filepath);

bool load_song_util(FlizzerTrackerApp* tracker, FuriString* filepath);
bool load_instrument_util(FlizzerTrackerApp* tracker, FuriString* filepath);

void save_config(FlizzerTrackerApp* tracker);
void load_config(FlizzerTrackerApp* tracker);
42 changes: 40 additions & 2 deletions flizzer_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ void draw_callback(Canvas* canvas, void* ctx) {

canvas_set_color(canvas, ColorXOR);

if(tracker->is_loading) {
if(tracker->is_loading || tracker->is_loading_instrument) {
canvas_draw_str(canvas, 10, 10, "Loading...");
return;
}

if(tracker->is_saving) {
if(tracker->is_saving || tracker->is_saving_instrument) {
canvas_draw_str(canvas, 10, 10, "Saving...");
return;
}
Expand Down Expand Up @@ -95,6 +95,7 @@ int32_t flizzer_tracker_app(void* p) {
Storage* storage = furi_record_open(RECORD_STORAGE);
bool st = storage_simply_mkdir(storage, APPSDATA_FOLDER);
st = storage_simply_mkdir(storage, FLIZZER_TRACKER_FOLDER);
st = storage_simply_mkdir(storage, FLIZZER_TRACKER_INSTRUMENTS_FOLDER);
UNUSED(st);
furi_record_close(RECORD_STORAGE);

Expand All @@ -121,6 +122,10 @@ int32_t flizzer_tracker_app(void* p) {
save_song(tracker, tracker->filepath);
}

if(event.type == EventTypeSaveInstrument) {
save_instrument(tracker, tracker->filepath);
}

if(event.type == EventTypeLoadSong) {
stop_song(tracker);

Expand Down Expand Up @@ -157,6 +162,39 @@ int32_t flizzer_tracker_app(void* p) {
}
}

if(event.type == EventTypeLoadInstrument) {
stop_song(tracker);

tracker->dialogs = furi_record_open(RECORD_DIALOGS);
tracker->is_loading_instrument = true;

FuriString* path;
path = furi_string_alloc();
furi_string_set(path, FLIZZER_TRACKER_INSTRUMENTS_FOLDER);

DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options, INST_FILE_EXT, &I_flizzer_tracker_instrument);
browser_options.base_path = FLIZZER_TRACKER_FOLDER;
browser_options.hide_ext = false;

bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options);

furi_record_close(RECORD_DIALOGS);

const char* cpath = furi_string_get_cstr(path);

if(ret && strcmp(&cpath[strlen(cpath) - 4], INST_FILE_EXT) == 0) {
bool result = load_instrument_util(tracker, path);
UNUSED(result);
}

else {
furi_string_free(path);
tracker->is_loading = false;
}
}

if(event.type == EventTypeSetAudioMode) {
sound_engine_PWM_timer_init(tracker->external_audio);

Expand Down
9 changes: 9 additions & 0 deletions flizzer_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@

#define APPSDATA_FOLDER "/ext/apps_data"
#define FLIZZER_TRACKER_FOLDER "/ext/apps_data/flizzer_tracker"
#define FLIZZER_TRACKER_INSTRUMENTS_FOLDER "/ext/apps_data/flizzer_tracker/instruments"
#define FILE_NAME_LEN 64

typedef enum {
EventTypeInput,
EventTypeSaveSong,
EventTypeLoadSong,
EventTypeLoadInstrument,
EventTypeSaveInstrument,
EventTypeSetAudioMode,
} EventType;

Expand Down Expand Up @@ -132,6 +135,7 @@ typedef enum {
VIEW_SUBMENU_PATTERN,
VIEW_SUBMENU_INSTRUMENT,
VIEW_FILE_OVERWRITE,
VIEW_INSTRUMENT_FILE_OVERWRITE,
VIEW_SETTINGS,
} FlizzerTrackerViews;

Expand All @@ -144,6 +148,8 @@ typedef enum {
} PatternSubmenuParams;

typedef enum {
SUBMENU_INSTRUMENT_LOAD,
SUBMENU_INSTRUMENT_SAVE,
SUBMENU_INSTRUMENT_EXIT,
} InstrumentSubmenuParams;

Expand All @@ -162,6 +168,7 @@ typedef struct {
Submenu* instrument_submenu;
VariableItemList* settings_list;
Widget* overwrite_file_widget;
Widget* overwrite_instrument_file_widget;
char filename[FILE_NAME_LEN + 1];
bool was_it_back_keypress;
uint32_t current_time;
Expand All @@ -187,6 +194,8 @@ typedef struct {

bool is_loading;
bool is_saving;
bool is_loading_instrument;
bool is_saving_instrument;
bool showing_help;

bool quit;
Expand Down
33 changes: 33 additions & 0 deletions init_deinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ FlizzerTrackerApp* init_tracker(
submenu_add_item(
tracker->pattern_submenu, "Exit", SUBMENU_PATTERN_EXIT, submenu_callback, tracker);

submenu_add_item(
tracker->instrument_submenu, "Load instrument", SUBMENU_INSTRUMENT_LOAD, submenu_callback, tracker);
submenu_add_item(
tracker->instrument_submenu, "Save instrument", SUBMENU_INSTRUMENT_SAVE, submenu_callback, tracker);
submenu_add_item(
tracker->instrument_submenu, "Exit", SUBMENU_INSTRUMENT_EXIT, submenu_callback, tracker);

Expand Down Expand Up @@ -169,6 +173,34 @@ FlizzerTrackerApp* init_tracker(
VIEW_FILE_OVERWRITE,
widget_get_view(tracker->overwrite_file_widget));

tracker->overwrite_instrument_file_widget = widget_alloc();

widget_add_button_element(
tracker->overwrite_instrument_file_widget,
GuiButtonTypeLeft,
"No",
(ButtonCallback)overwrite_instrument_file_widget_no_input_callback,
tracker);
widget_add_button_element(
tracker->overwrite_instrument_file_widget,
GuiButtonTypeRight,
"Yes",
(ButtonCallback)overwrite_instrument_file_widget_yes_input_callback,
tracker);

widget_add_text_scroll_element(
tracker->overwrite_instrument_file_widget,
0,
0,
128,
64,
"This instrument file already\nexists, do you want to\noverwrite it?");

view_dispatcher_add_view(
tracker->view_dispatcher,
VIEW_INSTRUMENT_FILE_OVERWRITE,
widget_get_view(tracker->overwrite_instrument_file_widget));

tracker->notification = furi_record_open(RECORD_NOTIFICATION);
notification_message(tracker->notification, &sequence_display_backlight_enforce_on);

Expand Down Expand Up @@ -199,6 +231,7 @@ void deinit_tracker(FlizzerTrackerApp* tracker) {
submenu_free(tracker->instrument_submenu);

widget_free(tracker->overwrite_file_widget);
widget_free(tracker->overwrite_instrument_file_widget);

view_dispatcher_free(tracker->view_dispatcher);

Expand Down
72 changes: 70 additions & 2 deletions input_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
void return_from_keyboard_callback(void* ctx) {
FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx;

if(!tracker->is_loading && !tracker->is_saving) {
if(!tracker->is_loading && !tracker->is_saving && !tracker->is_loading_instrument && !tracker->is_saving_instrument) {
uint8_t string_length = 0;
char* string = NULL;

Expand Down Expand Up @@ -65,6 +65,24 @@ void return_from_keyboard_callback(void* ctx) {
furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
}
}

if(tracker->is_saving_instrument) {
stop_song(tracker);

tracker->filepath = furi_string_alloc();
furi_string_cat_printf(
tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_INSTRUMENTS_FOLDER, tracker->filename, INST_FILE_EXT);

if(storage_file_exists(tracker->storage, furi_string_get_cstr(tracker->filepath))) {
view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_INSTRUMENT_FILE_OVERWRITE);
return;
}

else {
FlizzerTrackerEvent event = {.type = EventTypeSaveInstrument, .input = {{0}}, .period = 0};
furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
}
}
}

void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx) {
Expand Down Expand Up @@ -93,6 +111,32 @@ void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType typ
}
}

void overwrite_instrument_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx) {
UNUSED(result);

FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx;

if(type == InputTypeShort) {
tracker->is_saving_instrument = true;
view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
// save_song(tracker, tracker->filepath);
static FlizzerTrackerEvent event = {.type = EventTypeSaveInstrument, .input = {{0}}, .period = 0};
furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
}
}

void overwrite_instrument_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx) {
UNUSED(result);

FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx;

if(type == InputTypeShort) {
tracker->is_saving_instrument = false;
furi_string_free(tracker->filepath);
view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
}
}

uint32_t submenu_settings_exit_callback(void* context) {
UNUSED(context);
return VIEW_SUBMENU_PATTERN;
Expand Down Expand Up @@ -181,6 +225,30 @@ void submenu_callback(void* context, uint32_t index) {
break;
}

case SUBMENU_INSTRUMENT_SAVE: {
text_input_set_header_text(tracker->text_input, "Instrument filename:");
memset(&tracker->filename, 0, FILE_NAME_LEN);
text_input_set_result_callback(
tracker->text_input,
return_from_keyboard_callback,
tracker,
(char*)&tracker->filename,
FILE_NAME_LEN,
true);

tracker->is_saving_instrument = true;

view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_KEYBOARD);
break;
}

case SUBMENU_INSTRUMENT_LOAD: {
FlizzerTrackerEvent event = {.type = EventTypeLoadInstrument, .input = {{0}}, .period = 0};
furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
break;
}

default:
break;
}
Expand Down Expand Up @@ -305,7 +373,7 @@ void process_input_event(FlizzerTrackerApp* tracker, FlizzerTrackerEvent* event)
}

case INST_EDITOR_VIEW: {
submenu_set_selected_item(tracker->instrument_submenu, SUBMENU_INSTRUMENT_EXIT);
submenu_set_selected_item(tracker->instrument_submenu, SUBMENU_INSTRUMENT_LOAD);
view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT);
break;
}
Expand Down
3 changes: 3 additions & 0 deletions input_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ void return_from_keyboard_callback(void* ctx);
void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx);
void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx);

void overwrite_instrument_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx);
void overwrite_instrument_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx);

uint32_t submenu_exit_callback(void* context);
uint32_t submenu_settings_exit_callback(void* context);
void submenu_callback(void* context, uint32_t index);
Expand Down
Loading

0 comments on commit ac5943c

Please sign in to comment.