Files
Momentum-Firmware/applications/external/flizzer_tracker/util.c
2023-06-17 22:12:41 +01:00

202 lines
6.2 KiB
C

#include "util.h"
#include "macros.h"
void reset_buffer(SoundEngine* sound_engine) {
for(uint16_t i = 0; i < sound_engine->audio_buffer_size; i++) {
sound_engine->audio_buffer[i] = 512;
}
}
void stop_song(FlizzerTrackerApp* tracker) {
tracker->tracker_engine.playing = false;
tracker->editing = tracker->was_editing;
for(int i = 0; i < SONG_MAX_CHANNELS; i++) {
tracker->sound_engine.channel[i].adsr.volume = 0;
tracker->tracker_engine.channel[i].channel_flags &= ~(TEC_PROGRAM_RUNNING);
}
stop();
reset_buffer(&tracker->sound_engine);
}
void play_song(FlizzerTrackerApp* tracker, bool from_cursor) {
uint16_t temppos = tracker->tracker_engine.pattern_position;
stop_song(tracker);
sound_engine_dma_init(
(uint32_t)tracker->sound_engine.audio_buffer, tracker->sound_engine.audio_buffer_size);
tracker->tracker_engine.playing = true;
tracker->was_editing = tracker->editing;
tracker->editing = false;
if(!(from_cursor)) {
tracker->tracker_engine.pattern_position = 0;
temppos = 0;
}
tracker_engine_timer_init(tracker->song.rate);
/*sound_engine_init_hardware(tracker->sound_engine.sample_rate,
tracker->sound_engine.external_audio_output,
tracker->sound_engine.audio_buffer,
tracker->sound_engine.audio_buffer_size);
tracker_engine_init_hardware(tracker->song.rate);*/
tracker->tracker_engine.current_tick = 0;
tracker_engine_set_song(&tracker->tracker_engine, &tracker->song);
for(uint8_t i = 0; i < SONG_MAX_CHANNELS; i++) {
bool was_disabled = tracker->tracker_engine.channel[i].channel_flags & TEC_DISABLED;
memset(&tracker->sound_engine.channel[i], 0, sizeof(SoundEngineChannel));
memset(&tracker->tracker_engine.channel[i], 0, sizeof(TrackerEngineChannel));
if(was_disabled) {
tracker->tracker_engine.channel[i].channel_flags |= TEC_DISABLED;
}
}
tracker->tracker_engine.pattern_position = temppos;
play();
}
bool is_pattern_empty(TrackerSong* song, uint8_t pattern) {
TrackerSongPattern song_pattern = song->pattern[pattern];
for(int i = 0; i < song->pattern_length; i++) {
TrackerSongPatternStep* step = &song_pattern.step[i];
if(tracker_engine_get_note(step) != MUS_NOTE_NONE ||
tracker_engine_get_instrument(step) != MUS_NOTE_INSTRUMENT_NONE ||
tracker_engine_get_volume(step) != MUS_NOTE_VOLUME_NONE ||
tracker_engine_get_command(step) != 0) {
return false;
}
}
return true;
}
bool check_and_allocate_pattern(TrackerSong* song, uint8_t pattern) {
if(pattern < song->num_patterns) // we can set this pattern since it already exists
{
return true;
}
else {
if(song->pattern[pattern - 1].step == NULL)
return false; // if we hop through several patterns (e.g. editing upper digit)
if(!(is_pattern_empty(
song, pattern - 1))) // don't let the user flood the song with empty patterns
{
song->pattern[pattern].step =
malloc(sizeof(TrackerSongPatternStep) * song->pattern_length);
set_empty_pattern(&song->pattern[pattern], song->pattern_length);
song->num_patterns++;
return true;
}
else {
return false;
}
}
}
void resize_pattern(TrackerSongPattern* pattern, uint16_t old_length, uint16_t new_length) {
TrackerSongPattern temp;
temp.step = malloc((new_length) * sizeof(TrackerSongPatternStep));
set_empty_pattern(&temp, new_length);
memcpy(
temp.step, pattern->step, my_min(old_length, new_length) * sizeof(TrackerSongPatternStep));
free(pattern->step);
pattern->step = temp.step;
}
void change_pattern_length(TrackerSong* song, uint16_t new_length) {
for(int i = 0; i < MAX_PATTERNS; i++) {
if(song->pattern[i].step) {
resize_pattern(&song->pattern[i], song->pattern_length, new_length);
}
}
song->pattern_length = new_length;
}
bool is_default_instrument(Instrument* inst) {
Instrument* ref = malloc(sizeof(Instrument));
set_default_instrument(ref);
bool is_default = memcmp(ref, inst, sizeof(Instrument)) != 0 ? false : true;
free(ref);
return is_default;
}
bool check_and_allocate_instrument(TrackerSong* song, uint8_t inst) {
if(inst < song->num_instruments) // we can go to this instrument since it already exists
{
return true;
}
else {
if(inst >= MAX_INSTRUMENTS) return false;
if(!(is_default_instrument(
song->instrument
[inst - 1]))) // don't let the user flood the song with default instrument
{
song->instrument[inst] = malloc(sizeof(Instrument));
set_default_instrument(song->instrument[inst]);
song->num_instruments++;
return true;
}
else {
return false;
}
}
}
void set_default_song(FlizzerTrackerApp* tracker) {
tracker->tracker_engine.master_volume = 0x80;
tracker->song.speed = 6;
tracker->song.rate = tracker->tracker_engine.rate;
tracker->song.num_instruments = 1;
tracker->song.num_patterns = 5;
tracker->song.num_sequence_steps = 1;
tracker->song.pattern_length = 64;
tracker->song.sequence.sequence_step[0].pattern_indices[0] = 1;
tracker->song.sequence.sequence_step[0].pattern_indices[1] = 2;
tracker->song.sequence.sequence_step[0].pattern_indices[2] = 3;
tracker->song.sequence.sequence_step[0].pattern_indices[3] = 4;
for(int i = 0; i < 5; i++) {
tracker->song.pattern[i].step = malloc(64 * sizeof(TrackerSongPatternStep));
memset(tracker->song.pattern[i].step, 0, 64 * sizeof(TrackerSongPatternStep));
}
for(int i = 0; i < 64; ++i) {
for(int j = 0; j < 5; j++) {
set_note(&tracker->song.pattern[j].step[i], MUS_NOTE_NONE);
set_instrument(&tracker->song.pattern[j].step[i], MUS_NOTE_INSTRUMENT_NONE);
set_volume(&tracker->song.pattern[j].step[i], MUS_NOTE_VOLUME_NONE);
}
}
tracker->song.instrument[0] = malloc(sizeof(Instrument));
set_default_instrument(tracker->song.instrument[0]);
tracker->tracker_engine.playing = false;
}