util.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "util.h"
  2. #include "macros.h"
  3. void reset_buffer(SoundEngine* sound_engine) {
  4. for(uint16_t i = 0; i < sound_engine->audio_buffer_size; i++) {
  5. sound_engine->audio_buffer[i] = 512;
  6. }
  7. }
  8. void play_song(FlizzerTrackerApp* tracker, bool from_cursor) {
  9. reset_buffer(&tracker->sound_engine);
  10. sound_engine_dma_init(
  11. (uint32_t)tracker->sound_engine.audio_buffer, tracker->sound_engine.audio_buffer_size);
  12. tracker->tracker_engine.playing = true;
  13. tracker->was_editing = tracker->editing;
  14. tracker->editing = false;
  15. if(!(from_cursor)) {
  16. tracker->tracker_engine.pattern_position = 0;
  17. }
  18. tracker_engine_set_rate(tracker->song.rate);
  19. tracker->tracker_engine.current_tick = 0;
  20. tracker_engine_set_song(&tracker->tracker_engine, &tracker->song);
  21. play();
  22. }
  23. void stop_song(FlizzerTrackerApp* tracker) {
  24. tracker->tracker_engine.playing = false;
  25. tracker->editing = tracker->was_editing;
  26. for(int i = 0; i < SONG_MAX_CHANNELS; i++) {
  27. tracker->sound_engine.channel[i].adsr.volume = 0;
  28. }
  29. stop();
  30. }
  31. bool is_pattern_empty(TrackerSong* song, uint8_t pattern) {
  32. TrackerSongPattern song_pattern = song->pattern[pattern];
  33. for(int i = 0; i < song->pattern_length; i++) {
  34. TrackerSongPatternStep* step = &song_pattern.step[i];
  35. if(tracker_engine_get_note(step) != MUS_NOTE_NONE ||
  36. tracker_engine_get_instrument(step) != MUS_NOTE_INSTRUMENT_NONE ||
  37. tracker_engine_get_volume(step) != MUS_NOTE_VOLUME_NONE ||
  38. tracker_engine_get_command(step) != 0) {
  39. return false;
  40. }
  41. }
  42. return true;
  43. }
  44. bool check_and_allocate_pattern(TrackerSong* song, uint8_t pattern) {
  45. if(pattern < song->num_patterns) // we can set this pattern since it already exists
  46. {
  47. return true;
  48. }
  49. else {
  50. if(song->pattern[pattern - 1].step == NULL)
  51. return false; // if we hop through several patterns (e.g. editing upper digit)
  52. if(!(is_pattern_empty(
  53. song, pattern - 1))) // don't let the user flood the song with empty patterns
  54. {
  55. song->pattern[pattern].step =
  56. malloc(sizeof(TrackerSongPatternStep) * song->pattern_length);
  57. set_empty_pattern(&song->pattern[pattern], song->pattern_length);
  58. song->num_patterns++;
  59. return true;
  60. }
  61. else {
  62. return false;
  63. }
  64. }
  65. }
  66. void resize_pattern(TrackerSongPattern* pattern, uint16_t old_length, uint16_t new_length) {
  67. TrackerSongPattern temp;
  68. temp.step = malloc((new_length) * sizeof(TrackerSongPatternStep));
  69. set_empty_pattern(&temp, new_length);
  70. memcpy(
  71. temp.step, pattern->step, my_min(old_length, new_length) * sizeof(TrackerSongPatternStep));
  72. free(pattern->step);
  73. pattern->step = temp.step;
  74. }
  75. void change_pattern_length(TrackerSong* song, uint16_t new_length) {
  76. for(int i = 0; i < MAX_PATTERNS; i++) {
  77. if(song->pattern[i].step) {
  78. resize_pattern(&song->pattern[i], song->pattern_length, new_length);
  79. }
  80. }
  81. song->pattern_length = new_length;
  82. }
  83. bool is_default_instrument(Instrument* inst) {
  84. Instrument* ref = malloc(sizeof(Instrument));
  85. set_default_instrument(ref);
  86. bool is_default = memcmp(ref, inst, sizeof(Instrument)) != 0 ? false : true;
  87. free(ref);
  88. return is_default;
  89. }
  90. bool check_and_allocate_instrument(TrackerSong* song, uint8_t inst) {
  91. if(inst < song->num_instruments) // we can go to this instrument since it already exists
  92. {
  93. return true;
  94. }
  95. else {
  96. if(inst >= MAX_INSTRUMENTS) return false;
  97. if(!(is_default_instrument(
  98. song->instrument
  99. [inst - 1]))) // don't let the user flood the song with default instrument
  100. {
  101. song->instrument[inst] = malloc(sizeof(Instrument));
  102. set_default_instrument(song->instrument[inst]);
  103. song->num_instruments++;
  104. return true;
  105. }
  106. else {
  107. return false;
  108. }
  109. }
  110. }
  111. void set_default_song(FlizzerTrackerApp* tracker) {
  112. tracker->tracker_engine.master_volume = 0x80;
  113. tracker->song.speed = 6;
  114. tracker->song.rate = tracker->tracker_engine.rate;
  115. tracker->song.num_instruments = 1;
  116. tracker->song.num_patterns = 5;
  117. tracker->song.num_sequence_steps = 1;
  118. tracker->song.pattern_length = 64;
  119. tracker->song.sequence.sequence_step[0].pattern_indices[0] = 1;
  120. tracker->song.sequence.sequence_step[0].pattern_indices[1] = 2;
  121. tracker->song.sequence.sequence_step[0].pattern_indices[2] = 3;
  122. tracker->song.sequence.sequence_step[0].pattern_indices[3] = 4;
  123. for(int i = 0; i < 5; i++) {
  124. tracker->song.pattern[i].step = malloc(64 * sizeof(TrackerSongPatternStep));
  125. memset(tracker->song.pattern[i].step, 0, 64 * sizeof(TrackerSongPatternStep));
  126. }
  127. for(int i = 0; i < 64; ++i) {
  128. for(int j = 0; j < 5; j++) {
  129. set_note(&tracker->song.pattern[j].step[i], MUS_NOTE_NONE);
  130. set_instrument(&tracker->song.pattern[j].step[i], MUS_NOTE_INSTRUMENT_NONE);
  131. set_volume(&tracker->song.pattern[j].step[i], MUS_NOTE_VOLUME_NONE);
  132. }
  133. }
  134. tracker->song.instrument[0] = malloc(sizeof(Instrument));
  135. set_default_instrument(tracker->song.instrument[0]);
  136. tracker->tracker_engine.playing = false;
  137. }