util.c 5.3 KB

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