| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -32,10 +32,13 @@ float frequency = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					float frequency_alt = 0;
 | 
					 | 
					 | 
					 | 
					float frequency_alt = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					int volume = 0;
 | 
					 | 
					 | 
					 | 
					int volume = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					long position = 0;
 | 
					 | 
					 | 
					 | 
					long position = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					systime_t last_note_played_at;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					virtual_timer_t play_note_timer;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 | 
					 | 
					 | 
					 | 
					float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 | 
					 | 
					 | 
					 | 
					int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					bool sliding = false;
 | 
					 | 
					 | 
					 | 
					bool sliding = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					bool dac_on = true;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					float place = 0;
 | 
					 | 
					 | 
					 | 
					float place = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -78,20 +81,27 @@ bool glissando = true;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					float startup_song[][2] = STARTUP_SONG;
 | 
					 | 
					 | 
					 | 
					float startup_song[][2] = STARTUP_SONG;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void gpt_cb8(GPTDriver *gptp);
 | 
					 | 
					 | 
					 | 
					static void gpt_cb8(GPTDriver *gptp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static bool should_shutoff_dac(void);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void shutoff_dac(void);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void shutoff_dac_callback(void *arg);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					#define PLAY_NOTE_TIMEOUT MS2ST(5)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define DAC_BUFFER_SIZE 100
 | 
					 | 
					 | 
					 | 
					#define DAC_BUFFER_SIZE 100
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#ifndef DAC_SAMPLE_MAX
 | 
					 | 
					 | 
					 | 
					#ifndef DAC_SAMPLE_MAX
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define DAC_SAMPLE_MAX  65535U
 | 
					 | 
					 | 
					 | 
					#define DAC_SAMPLE_MAX  65535U
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#endif
 | 
					 | 
					 | 
					 | 
					#endif
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \
 | 
					 | 
					 | 
					 | 
					#define START_CHANNEL_1() dacStart(&DACD1, &dac1cfg1); \
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    gptStartContinuous(&GPTD6, 2U); \
 | 
					 | 
					 | 
					 | 
					  dacStart(&DACD2, &dac1cfg2); \
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
 | 
					 | 
					 | 
					 | 
					  dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); \
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  dac_on = true; \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  gptStart(&GPTD6, &gpt6cfg1); \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  gptStartContinuous(&GPTD6, 2U); \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define START_CHANNEL_2() gptStart(&GPTD7, &gpt7cfg1); \
 | 
					 | 
					 | 
					 | 
					#define START_CHANNEL_2() gptStart(&GPTD7, &gpt7cfg1); \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    gptStartContinuous(&GPTD7, 2U)
 | 
					 | 
					 | 
					 | 
					    gptStartContinuous(&GPTD7, 2U)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define STOP_CHANNEL_1() gptStopTimer(&GPTD6); \
 | 
					 | 
					 | 
					 | 
					#define STOP_CHANNEL_1() gptStopTimer(&GPTD6)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); \
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    palSetPad(GPIOA, 5);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define STOP_CHANNEL_2() gptStopTimer(&GPTD7)
 | 
					 | 
					 | 
					 | 
					#define STOP_CHANNEL_2() gptStopTimer(&GPTD7)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define RESTART_CHANNEL_1() STOP_CHANNEL_1(); \
 | 
					 | 
					 | 
					 | 
					#define RESTART_CHANNEL_1() STOP_CHANNEL_1(); \
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    START_CHANNEL_1()
 | 
					 | 
					 | 
					 | 
					    START_CHANNEL_1()
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -410,11 +420,13 @@ float vibrato(float average_freq) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#endif
 | 
					 | 
					 | 
					 | 
					#endif
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void gpt_cb8(GPTDriver *gptp) {
 | 
					 | 
					 | 
					 | 
					static void gpt_cb8(GPTDriver *gptp) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  float freq;
 | 
					 | 
					 | 
					 | 
					  float freq;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (playing_note) {
 | 
					 | 
					 | 
					 | 
					  if (playing_note) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    last_note_played_at = chVTGetSystemTime();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    chVTReset(&play_note_timer);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    chVTSet(&play_note_timer, PLAY_NOTE_TIMEOUT, shutoff_dac_callback, NULL);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (voices > 0) {
 | 
					 | 
					 | 
					 | 
					    if (voices > 0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      float freq_alt = 0;
 | 
					 | 
					 | 
					 | 
					      float freq_alt = 0;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -524,6 +536,7 @@ static void gpt_cb8(GPTDriver *gptp) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (playing_notes) {
 | 
					 | 
					 | 
					 | 
					  if (playing_notes) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    last_note_played_at = chVTGetSystemTime();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (note_frequency > 0) {
 | 
					 | 
					 | 
					 | 
					    if (note_frequency > 0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #ifdef VIBRATO_ENABLE
 | 
					 | 
					 | 
					 | 
					      #ifdef VIBRATO_ENABLE
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (vibrato_strength > 0) {
 | 
					 | 
					 | 
					 | 
					        if (vibrato_strength > 0) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -600,6 +613,28 @@ static void gpt_cb8(GPTDriver *gptp) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    playing_notes = false;
 | 
					 | 
					 | 
					 | 
					    playing_notes = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    playing_note = false;
 | 
					 | 
					 | 
					 | 
					    playing_note = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  if(should_shutoff_dac()) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    shutoff_dac();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					bool should_shutoff_dac() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  return ST2MS(chVTTimeElapsedSinceX(last_note_played_at)) > 5 && dac_on;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void shutoff_dac() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  dacStopConversion(&DACD2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  dacStop(&DACD2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  palSetPad(GPIOA, 5);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  dac_on = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void shutoff_dac_callback(void *args) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  if(!playing_note) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    shutoff_dac();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void play_note(float freq, int vol) {
 | 
					 | 
					 | 
					 | 
					void play_note(float freq, int vol) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -631,6 +666,8 @@ void play_note(float freq, int vol) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    gptStartContinuous(&GPTD8, 2U);
 | 
					 | 
					 | 
					 | 
					    gptStartContinuous(&GPTD8, 2U);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    RESTART_CHANNEL_1();
 | 
					 | 
					 | 
					 | 
					    RESTART_CHANNEL_1();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    RESTART_CHANNEL_2();
 | 
					 | 
					 | 
					 | 
					    RESTART_CHANNEL_2();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    chVTReset(&play_note_timer);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    chVTSet(&play_note_timer, PLAY_NOTE_TIMEOUT, shutoff_dac_callback, NULL);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }
 | 
					 | 
					 | 
					 | 
					  }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |