util.c 5.2 KB

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