init_deinit.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "init_deinit.h"
  2. #include "input_event.h"
  3. TrackerView *tracker_view_alloc(FlizzerTrackerApp *tracker)
  4. {
  5. TrackerView *tracker_view = malloc(sizeof(TrackerView));
  6. tracker_view->view = view_alloc();
  7. tracker_view->context = tracker;
  8. view_set_context(tracker_view->view, tracker_view);
  9. view_allocate_model(tracker_view->view, ViewModelTypeLocking, sizeof(TrackerViewModel));
  10. view_set_draw_callback(tracker_view->view, draw_callback);
  11. view_set_input_callback(tracker_view->view, input_callback);
  12. return tracker_view;
  13. }
  14. void tracker_view_free(TrackerView *tracker_view)
  15. {
  16. furi_assert(tracker_view);
  17. view_free(tracker_view->view);
  18. free(tracker_view);
  19. }
  20. FlizzerTrackerApp *init_tracker(uint32_t sample_rate, uint8_t rate, bool external_audio_output, uint32_t audio_buffer_size)
  21. {
  22. FlizzerTrackerApp *tracker = malloc(sizeof(FlizzerTrackerApp));
  23. memset(tracker, 0, sizeof(FlizzerTrackerApp));
  24. sound_engine_init(&tracker->sound_engine, sample_rate, external_audio_output, audio_buffer_size);
  25. tracker_engine_init(&tracker->tracker_engine, rate, &tracker->sound_engine);
  26. tracker->tracker_engine.song = &tracker->song;
  27. tracker->current_note = MIDDLE_C;
  28. // Очередь событий на 8 элементов размера FlizzerTrackerEvent
  29. tracker->event_queue = furi_message_queue_alloc(8, sizeof(FlizzerTrackerEvent));
  30. tracker->gui = furi_record_open(RECORD_GUI);
  31. tracker->view_dispatcher = view_dispatcher_alloc();
  32. tracker->tracker_view = tracker_view_alloc(tracker);
  33. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_TRACKER, tracker->tracker_view->view);
  34. view_dispatcher_attach_to_gui(tracker->view_dispatcher, tracker->gui, ViewDispatcherTypeFullscreen);
  35. with_view_model(
  36. tracker->tracker_view->view, TrackerViewModel * model, { model->tracker = tracker; }, true);
  37. tracker->storage = furi_record_open(RECORD_STORAGE);
  38. tracker->stream = file_stream_alloc(tracker->storage);
  39. tracker->text_input = text_input_alloc();
  40. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_KEYBOARD, text_input_get_view(tracker->text_input));
  41. tracker->pattern_submenu = submenu_alloc();
  42. tracker->instrument_submenu = submenu_alloc();
  43. submenu_add_item(tracker->pattern_submenu, "Return", SUBMENU_PATTERN_RETURN, submenu_callback, tracker);
  44. submenu_add_item(tracker->pattern_submenu, "Load song", SUBMENU_PATTERN_LOAD_SONG, submenu_callback, tracker);
  45. submenu_add_item(tracker->pattern_submenu, "Save song", SUBMENU_PATTERN_SAVE_SONG, submenu_callback, tracker);
  46. submenu_add_item(tracker->pattern_submenu, "Exit", SUBMENU_PATTERN_EXIT, submenu_callback, tracker);
  47. submenu_add_item(tracker->instrument_submenu, "Return", SUBMENU_INSTRUMENT_RETURN, submenu_callback, tracker);
  48. submenu_add_item(tracker->instrument_submenu, "Exit", SUBMENU_INSTRUMENT_EXIT, submenu_callback, tracker);
  49. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN, submenu_get_view(tracker->pattern_submenu));
  50. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT, submenu_get_view(tracker->instrument_submenu));
  51. tracker->overwrite_file_widget = widget_alloc();
  52. widget_add_button_element(
  53. tracker->overwrite_file_widget,
  54. GuiButtonTypeLeft,
  55. "No",
  56. (ButtonCallback)overwrite_file_widget_no_input_callback,
  57. tracker);
  58. widget_add_button_element(
  59. tracker->overwrite_file_widget,
  60. GuiButtonTypeRight,
  61. "Yes",
  62. (ButtonCallback)overwrite_file_widget_yes_input_callback,
  63. tracker);
  64. 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?");
  65. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE, widget_get_view(tracker->overwrite_file_widget));
  66. tracker->notification = furi_record_open(RECORD_NOTIFICATION);
  67. notification_message(tracker->notification, &sequence_display_backlight_enforce_on);
  68. return tracker;
  69. }
  70. void deinit_tracker(FlizzerTrackerApp *tracker)
  71. {
  72. notification_message(tracker->notification, &sequence_display_backlight_enforce_auto);
  73. furi_record_close(RECORD_NOTIFICATION);
  74. // Специальная очистка памяти, занимаемой очередью
  75. furi_message_queue_free(tracker->event_queue);
  76. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE);
  77. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT);
  78. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN);
  79. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_KEYBOARD);
  80. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_TRACKER);
  81. text_input_free(tracker->text_input);
  82. submenu_free(tracker->pattern_submenu);
  83. submenu_free(tracker->instrument_submenu);
  84. widget_free(tracker->overwrite_file_widget);
  85. view_dispatcher_free(tracker->view_dispatcher);
  86. tracker_view_free(tracker->tracker_view);
  87. furi_record_close(RECORD_GUI);
  88. stream_free(tracker->stream);
  89. furi_record_close(RECORD_STORAGE);
  90. sound_engine_deinit(&tracker->sound_engine);
  91. if (tracker->tracker_engine.song == NULL)
  92. {
  93. tracker_engine_set_song(&tracker->tracker_engine, &tracker->song);
  94. }
  95. tracker_engine_deinit(&tracker->tracker_engine, false);
  96. FURI_CRITICAL_ENTER();
  97. LL_TIM_DeInit(TRACKER_ENGINE_TIMER);
  98. LL_TIM_DeInit(SAMPLE_RATE_TIMER);
  99. LL_TIM_DeInit(SPEAKER_PWM_TIMER);
  100. FURI_CRITICAL_EXIT();
  101. free(tracker);
  102. }