init_deinit.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "init_deinit.h"
  2. #include "input_event.h"
  3. #include "diskop.h"
  4. #define AUDIO_MODES_COUNT 2
  5. TrackerView *tracker_view_alloc(FlizzerTrackerApp *tracker)
  6. {
  7. TrackerView *tracker_view = malloc(sizeof(TrackerView));
  8. tracker_view->view = view_alloc();
  9. tracker_view->context = tracker;
  10. view_set_context(tracker_view->view, tracker_view);
  11. view_allocate_model(tracker_view->view, ViewModelTypeLocking, sizeof(TrackerViewModel));
  12. view_set_draw_callback(tracker_view->view, draw_callback);
  13. view_set_input_callback(tracker_view->view, input_callback);
  14. return tracker_view;
  15. }
  16. void tracker_view_free(TrackerView *tracker_view)
  17. {
  18. furi_assert(tracker_view);
  19. view_free(tracker_view->view);
  20. free(tracker_view);
  21. }
  22. uint8_t my_value_index_bool(const bool value, const bool values[], uint8_t values_count) // why the fuck it gives unresolved symbol if I include it from toolbox???!!!
  23. {
  24. uint8_t index = 0;
  25. for (uint8_t i = 0; i < values_count; i++)
  26. {
  27. if (value == values[i])
  28. {
  29. index = i;
  30. break;
  31. }
  32. }
  33. return index;
  34. }
  35. FlizzerTrackerApp *init_tracker(uint32_t sample_rate, uint8_t rate, bool external_audio_output, uint32_t audio_buffer_size)
  36. {
  37. FlizzerTrackerApp *tracker = malloc(sizeof(FlizzerTrackerApp));
  38. memset(tracker, 0, sizeof(FlizzerTrackerApp));
  39. tracker->external_audio = external_audio_output;
  40. sound_engine_init(&tracker->sound_engine, sample_rate, external_audio_output, audio_buffer_size);
  41. tracker_engine_init(&tracker->tracker_engine, rate, &tracker->sound_engine);
  42. tracker->tracker_engine.song = &tracker->song;
  43. tracker->current_note = MIDDLE_C;
  44. // Очередь событий на 8 элементов размера FlizzerTrackerEvent
  45. tracker->event_queue = furi_message_queue_alloc(8, sizeof(FlizzerTrackerEvent));
  46. tracker->gui = furi_record_open(RECORD_GUI);
  47. tracker->view_dispatcher = view_dispatcher_alloc();
  48. tracker->tracker_view = tracker_view_alloc(tracker);
  49. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_TRACKER, tracker->tracker_view->view);
  50. view_dispatcher_attach_to_gui(tracker->view_dispatcher, tracker->gui, ViewDispatcherTypeFullscreen);
  51. with_view_model(
  52. tracker->tracker_view->view, TrackerViewModel * model, { model->tracker = tracker; }, true);
  53. tracker->storage = furi_record_open(RECORD_STORAGE);
  54. tracker->stream = file_stream_alloc(tracker->storage);
  55. tracker->text_input = text_input_alloc();
  56. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_KEYBOARD, text_input_get_view(tracker->text_input));
  57. tracker->pattern_submenu = submenu_alloc();
  58. tracker->instrument_submenu = submenu_alloc();
  59. view_set_previous_callback(submenu_get_view(tracker->pattern_submenu), submenu_exit_callback);
  60. view_set_previous_callback(submenu_get_view(tracker->instrument_submenu), submenu_exit_callback);
  61. submenu_add_item(tracker->pattern_submenu, "Load song", SUBMENU_PATTERN_LOAD_SONG, submenu_callback, tracker);
  62. submenu_add_item(tracker->pattern_submenu, "Save song", SUBMENU_PATTERN_SAVE_SONG, submenu_callback, tracker);
  63. submenu_add_item(tracker->pattern_submenu, "Settings", SUBMENU_PATTERN_SETTINGS, submenu_callback, tracker);
  64. submenu_add_item(tracker->pattern_submenu, "Exit", SUBMENU_PATTERN_EXIT, submenu_callback, tracker);
  65. submenu_add_item(tracker->instrument_submenu, "Exit", SUBMENU_INSTRUMENT_EXIT, submenu_callback, tracker);
  66. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN, submenu_get_view(tracker->pattern_submenu));
  67. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT, submenu_get_view(tracker->instrument_submenu));
  68. load_config(tracker);
  69. tracker->settings_list = variable_item_list_alloc();
  70. View *view = variable_item_list_get_view(tracker->settings_list);
  71. view_set_previous_callback(view, submenu_settings_exit_callback);
  72. VariableItem *item;
  73. uint8_t value_index;
  74. item = variable_item_list_add(tracker->settings_list, "Audio output", AUDIO_MODES_COUNT, audio_output_changed_callback, tracker);
  75. value_index = my_value_index_bool(tracker->external_audio, audio_modes_values, AUDIO_MODES_COUNT);
  76. variable_item_set_current_value_index(item, value_index);
  77. variable_item_set_current_value_text(item, audio_modes_text[value_index]);
  78. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SETTINGS, view);
  79. tracker->overwrite_file_widget = widget_alloc();
  80. widget_add_button_element(
  81. tracker->overwrite_file_widget,
  82. GuiButtonTypeLeft,
  83. "No",
  84. (ButtonCallback)overwrite_file_widget_no_input_callback,
  85. tracker);
  86. widget_add_button_element(
  87. tracker->overwrite_file_widget,
  88. GuiButtonTypeRight,
  89. "Yes",
  90. (ButtonCallback)overwrite_file_widget_yes_input_callback,
  91. tracker);
  92. widget_add_text_scroll_element(tracker->overwrite_file_widget, 0, 0, 128, 64, "This song file already exists,\n do you want to overwrite it?");
  93. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE, widget_get_view(tracker->overwrite_file_widget));
  94. tracker->notification = furi_record_open(RECORD_NOTIFICATION);
  95. notification_message(tracker->notification, &sequence_display_backlight_enforce_on);
  96. set_default_song(tracker);
  97. return tracker;
  98. }
  99. void deinit_tracker(FlizzerTrackerApp *tracker)
  100. {
  101. notification_message(tracker->notification, &sequence_display_backlight_enforce_auto);
  102. furi_record_close(RECORD_NOTIFICATION);
  103. // Специальная очистка памяти, занимаемой очередью
  104. furi_message_queue_free(tracker->event_queue);
  105. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SETTINGS);
  106. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE);
  107. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT);
  108. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN);
  109. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_KEYBOARD);
  110. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_TRACKER);
  111. text_input_free(tracker->text_input);
  112. variable_item_list_free(tracker->settings_list);
  113. submenu_free(tracker->pattern_submenu);
  114. submenu_free(tracker->instrument_submenu);
  115. widget_free(tracker->overwrite_file_widget);
  116. view_dispatcher_free(tracker->view_dispatcher);
  117. tracker_view_free(tracker->tracker_view);
  118. furi_record_close(RECORD_GUI);
  119. stream_free(tracker->stream);
  120. furi_record_close(RECORD_STORAGE);
  121. sound_engine_deinit(&tracker->sound_engine);
  122. if (tracker->tracker_engine.song == NULL)
  123. {
  124. tracker_engine_set_song(&tracker->tracker_engine, &tracker->song);
  125. }
  126. tracker_engine_deinit(&tracker->tracker_engine, false);
  127. FURI_CRITICAL_ENTER();
  128. LL_TIM_DeInit(TRACKER_ENGINE_TIMER);
  129. LL_TIM_DeInit(SAMPLE_RATE_TIMER);
  130. LL_TIM_DeInit(SPEAKER_PWM_TIMER);
  131. FURI_CRITICAL_EXIT();
  132. free(tracker);
  133. }