// // Structs. // typedef struct TriggerNote { bool active; Note note; } TriggerNote; typedef struct ChannelSquareParams { u8 env_volume; u8 env_time; u8 env_direction; u8 duty_cycle; u8 sweep_number; u8 sweep_time; u8 sweep_direction; u8 prob; s8 pan; } ChannelSquareParams; typedef struct ChannelWaveParams { u8 wave_volume; u8 wave_mode; u8 shape_a; u8 type_a; u8 shape_b; u8 type_b; u8 prob; s8 pan; } ChannelWaveParams; typedef struct ChannelNoiseParams { u8 env_volume; u8 env_time; u8 env_direction; u8 bit_mode; u8 prob; s8 pan; } ChannelNoiseParams; typedef struct ChannelSquare { bool active; TriggerNote notes[16]; ChannelSquareParams params[16]; } ChannelSquare; typedef struct ChannelWave { bool active; TriggerNote notes[16]; ChannelWaveParams params[16]; } ChannelWave; typedef struct ChannelNoise { bool active; TriggerNote notes[16]; ChannelNoiseParams params[16]; } ChannelNoise; typedef struct Pattern { ChannelSquare ch1; ChannelSquare ch2; ChannelWave ch3; ChannelNoise ch4; int bpm; u8 bank; } Pattern; // // Defaults. // const ChannelSquare default_ch1 = { .notes = { {true, NOTE_C_4}, {true, NOTE_D_SHARP_4}, {true, NOTE_G_4}, {true, NOTE_A_SHARP_4}, {true, NOTE_C_4}, {true, NOTE_D_SHARP_4}, {true, NOTE_G_4}, {true, NOTE_A_SHARP_4}, {true, NOTE_C_4}, {true, NOTE_D_SHARP_4}, {true, NOTE_G_4}, {true, NOTE_A_SHARP_4}, {true, NOTE_C_4}, {true, NOTE_D_SHARP_4}, {true, NOTE_G_4}, {true, NOTE_A_SHARP_4}, }, .params = { {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, }, .active = true, }; const ChannelSquare default_ch2 = { .notes = { {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, {true, NOTE_C_3}, }, .params = { {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}, }, .active = true, }; const ChannelWave default_ch3 = { .notes = { {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_A_SHARP_5}, {true, NOTE_A_SHARP_5}, {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_G_5}, {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_A_SHARP_5}, {true, NOTE_A_SHARP_5}, {true, NOTE_C_5}, {true, NOTE_C_5}, {true, NOTE_G_5}, }, .params = { {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}, }, .active = true, }; const ChannelNoise default_ch4 = { .notes = { {true, NOTE_D_SHARP_4}, {false, NOTE_E_6}, {false, NOTE_E_6}, {false, NOTE_E_6}, {true, NOTE_D_SHARP_4}, {false, NOTE_E_6}, {false, NOTE_E_6}, {false, NOTE_E_6}, {true, NOTE_D_SHARP_4}, {false, NOTE_E_6}, {false, NOTE_E_6}, {false, NOTE_E_6}, {true, NOTE_D_SHARP_4}, {false, NOTE_E_6}, {false, NOTE_E_6}, {false, NOTE_E_6}, }, .params = { {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, {0xF, 0x2, 0, 0, PROB_100, 0}, }, .active = true, }; const int default_bpm = 90; static Pattern patterns[8] = { {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, {default_ch1, default_ch2, default_ch3, default_ch4, default_bpm, 0}, }; static ChannelSquareParams ch1_params = {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}; static ChannelSquareParams ch2_params = {8, 4, 0, 2, 0, 0, 0, PROB_100, 0}; static ChannelWaveParams ch3_params = {3, 0, WAVE_SIN, 0, WAVE_SAW, 0, PROB_100, 0}; static ChannelNoiseParams ch4_params = {0xF, 0x2, 0, 0, PROB_100, 0};